config_manager 0.0.9 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/config_manager/settings_controller.rb +20 -0
- data/app/controllers/config_manager/toggles_controller.rb +13 -17
- data/app/views/config_manager/settings/index.html.slim +10 -0
- data/app/views/config_manager/toggles/index.html.slim +6 -13
- data/config/routes.rb +8 -3
- data/lib/config_manager/setting.rb +9 -96
- data/lib/config_manager/settings/persistence.rb +59 -0
- data/lib/config_manager/settings/querying.rb +55 -0
- data/lib/config_manager/settings/values.rb +39 -0
- data/lib/config_manager/settings/yaml.rb +41 -0
- data/lib/config_manager/toggle.rb +4 -6
- data/lib/config_manager/version.rb +1 -1
- data/spec/dummy/log/development.log +2343 -0
- data/spec/dummy/log/test.log +710 -0
- data/spec/dummy/tmp/pids/server.pid +1 -1
- data/spec/dummy/tmp/settings.yml +10 -0
- metadata +7 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83bed3fc27cfd3df8f900fc2e124ffa9c6a34975
|
4
|
+
data.tar.gz: 9fa864a17f89669e0274031f52e9c95aca13c945
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8159683de5b762192127ccc7a0839f329397271f9c669103539b2952fd4c881f4bfce2eff6277541c65dad1217cbae7ce3aba19b53650b89fe6d165f8627eaef
|
7
|
+
data.tar.gz: b3851cb20b512e75e1cbed524a78d32c6eebcd6aa792cfff35318e067baa3eab98b273a1a1b231d924e61f7a37bdb5bcaae4def7222ec4e9082ed4b14adf7ffe
|
@@ -27,5 +27,25 @@ module ConfigManager
|
|
27
27
|
|
28
28
|
redirect_to settings_url
|
29
29
|
end
|
30
|
+
|
31
|
+
# GET /settings/dump
|
32
|
+
def dump
|
33
|
+
send_data Setting.to_yaml, :filename => 'setting.yml'
|
34
|
+
end
|
35
|
+
|
36
|
+
# POST /settings/load
|
37
|
+
def load
|
38
|
+
if params[:file]
|
39
|
+
loads, failures = Setting.from_yaml(params[:file].tempfile)
|
40
|
+
flash[:notice] = "#{loads} settings have been loaded from the yaml file." if loads > 0
|
41
|
+
flash[:error] = "#{failures} settings failed to be loaded from the yaml file." if failures > 0
|
42
|
+
else
|
43
|
+
flash[:error] = "You must choose a file."
|
44
|
+
end
|
45
|
+
rescue
|
46
|
+
flash[:error] = "Couldn't load settings. Did you choose a valid file?"
|
47
|
+
ensure
|
48
|
+
redirect_to settings_url
|
49
|
+
end
|
30
50
|
end
|
31
51
|
end
|
@@ -30,28 +30,24 @@ module ConfigManager
|
|
30
30
|
redirect_to toggles_url
|
31
31
|
end
|
32
32
|
|
33
|
-
# POST /toggles/
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
33
|
+
# POST /toggles/load
|
34
|
+
def load
|
35
|
+
if params[:file]
|
36
|
+
loads, failures = Toggle.from_yaml(params[:file].tempfile)
|
37
|
+
flash[:notice] = "#{loads} toggles have been loaded from the yaml file." if loads > 0
|
38
|
+
flash[:error] = "#{failures} toggles failed to be loaded from the yaml file" if failures > 0
|
39
|
+
else
|
40
|
+
flash[:error] = "You must choose a file"
|
41
|
+
end
|
42
|
+
rescue
|
43
|
+
flash[:error] = "Couldn't load toggles. Did you choose a valid file?"
|
44
|
+
ensure
|
43
45
|
redirect_to toggles_url
|
44
46
|
end
|
45
47
|
|
46
48
|
# POST /toggles/dump
|
47
49
|
def dump
|
48
|
-
|
49
|
-
Toggle.to_yaml(path)
|
50
|
-
flash[:notice] = "Toggles dumped to #{path}"
|
51
|
-
rescue
|
52
|
-
flash[:error] = "Failed to dump toggles to #{path}"
|
53
|
-
ensure
|
54
|
-
redirect_to toggles_url
|
50
|
+
send_data Toggle.to_yaml, :filename => 'toggles.yml'
|
55
51
|
end
|
56
52
|
end
|
57
53
|
end
|
@@ -26,3 +26,13 @@ section.clearfix
|
|
26
26
|
div.col-sm-4
|
27
27
|
h3 Create/Edit Setting
|
28
28
|
= render 'form'
|
29
|
+
- unless Rails.env.production?
|
30
|
+
h3 Load From YAML
|
31
|
+
= form_tag load_settings_path, :multipart => true do
|
32
|
+
div.form-group
|
33
|
+
= file_field_tag :file
|
34
|
+
div.buttons
|
35
|
+
= submit_tag "Load", :class => "btn-block btn btn-warning"
|
36
|
+
h3 Dump to YAML
|
37
|
+
div.text-center
|
38
|
+
= link_to "Dump", dump_settings_path, :class => 'btn-block btn btn-warning'
|
@@ -29,18 +29,11 @@ section.clearfix
|
|
29
29
|
= render 'form'
|
30
30
|
- unless Rails.env.production?
|
31
31
|
h3 Load From YAML
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
:method => :post,
|
38
|
-
:class => 'btn-block btn btn-warning'
|
32
|
+
= form_tag load_toggles_path, :multipart => true do
|
33
|
+
div.form-group
|
34
|
+
= file_field_tag :file
|
35
|
+
div.buttons
|
36
|
+
= submit_tag "Load", :class => "btn-block btn btn-warning"
|
39
37
|
h3 Dump To YAML
|
40
|
-
p.text-muted
|
41
|
-
small Dump toggles to config/config_manager_toggles.yml
|
42
38
|
div.text-center
|
43
|
-
= link_to "Dump",
|
44
|
-
dump_toggles_path,
|
45
|
-
:method => :post,
|
46
|
-
:class => 'btn-block btn btn-warning'
|
39
|
+
= link_to "Dump", dump_toggles_path, :class => 'btn-block btn btn-warning'
|
data/config/routes.rb
CHANGED
@@ -6,11 +6,16 @@ ConfigManager::Engine.routes.draw do
|
|
6
6
|
resources :admins, :except => [:show]
|
7
7
|
resources :toggles, :only => [:index, :create, :destroy] do
|
8
8
|
collection do
|
9
|
-
post :
|
10
|
-
|
9
|
+
post :load
|
10
|
+
get :dump
|
11
|
+
end
|
12
|
+
end
|
13
|
+
resources :settings, :only => [:index, :create, :destroy] do
|
14
|
+
collection do
|
15
|
+
post :load
|
16
|
+
get :dump
|
11
17
|
end
|
12
18
|
end
|
13
|
-
resources :settings, :only => [:index, :create, :destroy]
|
14
19
|
|
15
20
|
# change root later
|
16
21
|
root :to => "admins#index"
|
@@ -1,5 +1,10 @@
|
|
1
1
|
module ConfigManager
|
2
2
|
class Setting
|
3
|
+
include Settings::Persistence
|
4
|
+
include Settings::Querying
|
5
|
+
include Settings::Values
|
6
|
+
include Settings::Yaml
|
7
|
+
|
3
8
|
attr_reader :id, :value, :tags
|
4
9
|
|
5
10
|
def initialize(id, value, tags)
|
@@ -16,109 +21,17 @@ module ConfigManager
|
|
16
21
|
@tags && @tags.join(', ')
|
17
22
|
end
|
18
23
|
|
19
|
-
def persist
|
20
|
-
Setting.persist(@id, @value, *@tags)
|
21
|
-
end
|
22
|
-
|
23
24
|
def message
|
24
25
|
return "missing name(id)" unless @id.present?
|
25
26
|
return "missing value" unless !!@value
|
26
27
|
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
gsub(/\s*,\s*/,',').
|
32
|
-
split(',')
|
33
|
-
new(params[:id], params[:value], tags)
|
34
|
-
end
|
35
|
-
|
36
|
-
def value(id)
|
37
|
-
(find(id) || build({})).value
|
38
|
-
end
|
39
|
-
|
40
|
-
def create(params)
|
41
|
-
setting = build(params)
|
42
|
-
if setting.valid?
|
43
|
-
setting.persist
|
44
|
-
find(params[:id], true)
|
45
|
-
else
|
46
|
-
setting
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def persist(id, value, *indexes)
|
51
|
-
$redis.set(generate_key(id), value)
|
52
|
-
unless indexes.empty?
|
53
|
-
$redis.sadd(generate_tags_key(id), indexes)
|
54
|
-
$redis.sadd(tag_global_key, indexes)
|
55
|
-
end
|
56
|
-
|
57
|
-
# update global and tag indexes
|
58
|
-
indexes = indexes.map{|index| generate_index(index)}
|
59
|
-
indexes << global_key
|
60
|
-
index_by(id, indexes)
|
61
|
-
end
|
62
|
-
|
63
|
-
def find(id, with_tags=false)
|
64
|
-
key = generate_key(id)
|
65
|
-
value = $redis.get(key)
|
66
|
-
|
67
|
-
return nil unless value
|
68
|
-
|
69
|
-
index = generate_tags_key(id)
|
70
|
-
tags = with_tags ? $redis.smembers(index) : []
|
71
|
-
|
72
|
-
new(id, value, tags)
|
73
|
-
end
|
74
|
-
|
75
|
-
def all
|
76
|
-
keys = $redis.smembers(global_key)
|
77
|
-
return [] if keys.empty?
|
78
|
-
|
79
|
-
values = $redis.mget(*keys)
|
80
|
-
|
81
|
-
# remove deleted keys
|
82
|
-
obsolete_keys = Range.new(0, keys.size, true).inject([]) do |memo, i|
|
83
|
-
values.at(i) ? memo : (memo << keys.at(i))
|
84
|
-
end
|
85
|
-
|
86
|
-
unless obsolete_keys.empty?
|
87
|
-
Rails.logger.info("DELETING OBSOLETE KEYS IN GLOBAL INDEX: #{obsolete_keys}")
|
88
|
-
$redis.srem(global_key, obsolete_keys)
|
89
|
-
keys = keys - obsolete_keys
|
90
|
-
values.compact!
|
91
|
-
end
|
92
|
-
|
93
|
-
# get tags
|
94
|
-
ids = keys.map {|k| k.gsub("#{prefix}:", '') }
|
95
|
-
tag_keys = ids.map {|id| generate_tags_key(id) }
|
96
|
-
tags = tag_keys.map {|key| $redis.smembers(key) }
|
97
|
-
|
98
|
-
ids.zip(values, tags).map do |i,v, t|
|
99
|
-
Setting.new(i, v, t)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def tags
|
104
|
-
$redis.smembers(tag_global_key)
|
105
|
-
end
|
106
|
-
|
107
|
-
def delete(id)
|
108
|
-
$redis.del(generate_key(id), generate_tags_key(id))
|
109
|
-
end
|
29
|
+
def to_hash
|
30
|
+
{'id' => id, 'value' => value, 'tags' => formatted_tags}
|
31
|
+
end
|
110
32
|
|
33
|
+
class << self
|
111
34
|
private
|
112
|
-
|
113
|
-
# stores the setting id under the requested indexes
|
114
|
-
# this allows us to search all keys for a given index
|
115
|
-
# such as the global index returning all keys or a tag
|
116
|
-
def index_by(id, indexes)
|
117
|
-
indexes.each do |index|
|
118
|
-
$redis.sadd(index, generate_key(id))
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
35
|
def generate_key(id)
|
123
36
|
"#{prefix}:#{id}"
|
124
37
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module ConfigManager
|
2
|
+
module Settings
|
3
|
+
module Persistence
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
def persist
|
9
|
+
Setting.persist(@id, @value, *@tags)
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def build(params)
|
14
|
+
tags = (params[:tags] || params[:formatted_tags] || "").
|
15
|
+
gsub(/\s*,\s*/,',').
|
16
|
+
split(',')
|
17
|
+
new(params[:id], params[:value], tags)
|
18
|
+
end
|
19
|
+
|
20
|
+
def create(params)
|
21
|
+
setting = build(params)
|
22
|
+
if setting.valid?
|
23
|
+
setting.persist
|
24
|
+
find(params[:id], true)
|
25
|
+
else
|
26
|
+
setting
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def persist(id, value, *indexes)
|
31
|
+
$redis.set(generate_key(id), value)
|
32
|
+
unless indexes.empty?
|
33
|
+
$redis.sadd(generate_tags_key(id), indexes)
|
34
|
+
$redis.sadd(tag_global_key, indexes)
|
35
|
+
end
|
36
|
+
|
37
|
+
# update global and tag indexes
|
38
|
+
indexes = indexes.map{|index| generate_index(index)}
|
39
|
+
indexes << global_key
|
40
|
+
index_by(id, indexes)
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete(id)
|
44
|
+
$redis.del(generate_key(id), generate_tags_key(id))
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
# stores the setting id under the requested indexes
|
49
|
+
# this allows us to search all keys for a given index
|
50
|
+
# such as the global index returning all keys or a tag
|
51
|
+
def index_by(id, indexes)
|
52
|
+
indexes.each do |index|
|
53
|
+
$redis.sadd(index, generate_key(id))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module ConfigManager
|
2
|
+
module Settings
|
3
|
+
module Querying
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def find(id, with_tags=false)
|
10
|
+
key = generate_key(id)
|
11
|
+
value = $redis.get(key)
|
12
|
+
|
13
|
+
return nil unless value
|
14
|
+
|
15
|
+
index = generate_tags_key(id)
|
16
|
+
tags = with_tags ? $redis.smembers(index) : []
|
17
|
+
|
18
|
+
new(id, value, tags)
|
19
|
+
end
|
20
|
+
|
21
|
+
def all
|
22
|
+
keys = $redis.smembers(global_key)
|
23
|
+
return [] if keys.empty?
|
24
|
+
|
25
|
+
values = $redis.mget(*keys)
|
26
|
+
|
27
|
+
# remove deleted keys
|
28
|
+
obsolete_keys = Range.new(0, keys.size, true).inject([]) do |memo, i|
|
29
|
+
values.at(i) ? memo : (memo << keys.at(i))
|
30
|
+
end
|
31
|
+
|
32
|
+
unless obsolete_keys.empty?
|
33
|
+
Rails.logger.info("DELETING OBSOLETE KEYS IN GLOBAL INDEX: #{obsolete_keys}")
|
34
|
+
$redis.srem(global_key, obsolete_keys)
|
35
|
+
keys = keys - obsolete_keys
|
36
|
+
values.compact!
|
37
|
+
end
|
38
|
+
|
39
|
+
# get tags
|
40
|
+
ids = keys.map {|k| k.gsub("#{prefix}:", '') }
|
41
|
+
tag_keys = ids.map {|id| generate_tags_key(id) }
|
42
|
+
tags = tag_keys.map {|key| $redis.smembers(key) }
|
43
|
+
|
44
|
+
ids.zip(values, tags).map do |i,v, t|
|
45
|
+
Setting.new(i, v, t)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def tags
|
50
|
+
$redis.smembers(tag_global_key)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module ConfigManager
|
2
|
+
module Settings
|
3
|
+
module Values
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def value(id)
|
10
|
+
(find(id) || build({})).value
|
11
|
+
end
|
12
|
+
|
13
|
+
def date_value(id)
|
14
|
+
value(id).to_date
|
15
|
+
rescue NoMethodError
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def time_value(id)
|
20
|
+
value(id).to_time
|
21
|
+
rescue NoMethodError
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def integer_value(id)
|
26
|
+
value(id).to_i
|
27
|
+
rescue NoMethodError
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def number_value(id)
|
32
|
+
value(id).to_f
|
33
|
+
rescue NoMethodError
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module ConfigManager
|
2
|
+
module Settings
|
3
|
+
module Yaml
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
#def to_yaml(path)
|
10
|
+
# File.open(path, 'w') do |file|
|
11
|
+
# settings_hash = all.map(&:to_hash)
|
12
|
+
# YAML.dump(settings_hash, file)
|
13
|
+
# end
|
14
|
+
#end
|
15
|
+
def to_yaml
|
16
|
+
YAML.dump(all.map(&:to_hash))
|
17
|
+
end
|
18
|
+
|
19
|
+
def from_yaml(path)
|
20
|
+
settings = YAML::load(File.open path)
|
21
|
+
settings.reduce([0,0]) do |memo, hash|
|
22
|
+
begin
|
23
|
+
setting = create(hash.symbolize_keys)
|
24
|
+
if setting.valid?
|
25
|
+
memo[0] += 1
|
26
|
+
else
|
27
|
+
Rails.logger.error "Bad setting definition. #{setting.message}"
|
28
|
+
memo[1] += 1
|
29
|
+
end
|
30
|
+
rescue RuntimeError
|
31
|
+
Rails.logger.error "Bad setting definition. #{$!}"
|
32
|
+
memo[1] += 1
|
33
|
+
end
|
34
|
+
|
35
|
+
memo
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -50,7 +50,7 @@ module ConfigManager
|
|
50
50
|
:formatted_acceptable_values => values['acceptable_values']})
|
51
51
|
counts[0] += 1
|
52
52
|
rescue RuntimeError
|
53
|
-
Rails.logger.error "
|
53
|
+
Rails.logger.error "Bad toggle definition. #{$!}"
|
54
54
|
counts[1] += 1
|
55
55
|
end
|
56
56
|
end
|
@@ -58,11 +58,9 @@ module ConfigManager
|
|
58
58
|
counts
|
59
59
|
end
|
60
60
|
|
61
|
-
def self.to_yaml
|
62
|
-
|
63
|
-
|
64
|
-
YAML.dump(toggles_hash, file)
|
65
|
-
end
|
61
|
+
def self.to_yaml
|
62
|
+
toggles_hash = Hash[toggles.map(&:to_hash).map{|t| [t.keys.first, t.values.first]}]
|
63
|
+
YAML.dump(toggles_hash)
|
66
64
|
end
|
67
65
|
|
68
66
|
def self.quick(name, acceptable_values='test')
|