strada 0.0.3 → 0.0.4
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/README.md +35 -18
- data/lib/strada/adapter/json.rb +2 -1
- data/lib/strada/adapter/toml.rb +2 -2
- data/lib/strada/adapter/yaml.rb +2 -2
- data/lib/strada/config_struct.rb +39 -28
- data/lib/strada/version.rb +1 -1
- data/lib/strada.rb +42 -37
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 01c182cd152dc864606ef204f15b86d5770d214b305d760f508e721f74a491a3
|
4
|
+
data.tar.gz: 57bf00a4987bb3f4b2022c2797c7281315c1a160fbb97633008d77880ee91b3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9626789a1430f15384df5d926b20402bbf806127c8fdc4bbe02de8f44fa6889132ff00cafb8afbf89623fc4a28b77c5b1ea8a4c4dbf119f2f9a681fd68d1b132
|
7
|
+
data.tar.gz: 1461a09fb18ea04770d282cf9f2df8c0e0d3b2d2c12b9a9344c6b9831c4cab61ba2db66665710ab18fdbaa134364973d05e190cd2df1d95561b00f41329c044a
|
data/README.md
CHANGED
@@ -1,59 +1,76 @@
|
|
1
1
|
# Strada
|
2
|
-
|
3
|
-
access
|
2
|
+
|
3
|
+
Configuration library for ruby with YAML/JSON/TOML backends with unified object access
|
4
4
|
|
5
5
|
## Install
|
6
|
-
|
7
|
-
|
6
|
+
|
7
|
+
```shell
|
8
|
+
% gem install strada
|
8
9
|
```
|
9
10
|
|
10
11
|
## Use
|
12
|
+
|
11
13
|
### Simple
|
12
|
-
|
13
|
-
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
require 'strada'
|
17
|
+
require 'pp'
|
14
18
|
cfg = Strada.cfg
|
19
|
+
# print cfg datastructure
|
20
|
+
PP.pp cfg
|
21
|
+
|
15
22
|
port = cfg.server.port
|
16
23
|
user = cfg.auth.user
|
17
24
|
pw = cfg.auth.password
|
25
|
+
|
26
|
+
PP.pp cfg
|
18
27
|
```
|
28
|
+
|
19
29
|
It tried to detect your software name via caller_locations if no ':name'
|
20
30
|
argument was given.
|
21
31
|
It automatically loads /etc/name/config and ~/.config/name/config and merges
|
22
32
|
them together.
|
23
33
|
|
24
34
|
### Advanced
|
25
|
-
|
26
|
-
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
require 'strada'
|
38
|
+
|
27
39
|
Strada = Strada.new name: 'mykewlapp',
|
28
|
-
default: {'poop'=>'xyzzy'},
|
40
|
+
default: { 'poop' => 'xyzzy' },
|
29
41
|
adapter: 'yaml',
|
30
42
|
usrdir: '/home/app/config/',
|
31
43
|
sysdir: '/System/config/',
|
32
44
|
load: false
|
33
|
-
|
45
|
+
|
46
|
+
Strada.default.poop2 = [1, 2, 3, 4]
|
34
47
|
Strada.default.starship.poopers = 42
|
35
48
|
Strada.load :user
|
49
|
+
|
36
50
|
if Strada.user.empty?
|
37
51
|
Strada.user = Strada.default
|
38
52
|
Strada.save :user
|
39
53
|
end
|
40
|
-
|
41
|
-
Strada.
|
54
|
+
|
55
|
+
Strada.load # load+merges cfg, takes argument :default, :system, :user
|
56
|
+
Strada.cfg # merged default + system + user (merged on load)
|
42
57
|
Strada.default # default only
|
43
|
-
Strada.system
|
44
|
-
Strada.user
|
58
|
+
Strada.system # system only
|
59
|
+
Strada.user # user only
|
45
60
|
```
|
46
61
|
|
47
62
|
## Reserved methods
|
48
63
|
|
49
|
-
* each
|
64
|
+
* each - iterate all config keys in current level
|
50
65
|
* has_key?(arg) - check if current level has key arg
|
51
66
|
* [arg] - fetch arg (useful for non-literal retrieval, instead of using #send)
|
52
|
-
* key?
|
67
|
+
* key? - all keys have question mark version reserved, checks if key exists+true (true), exists+false (false),
|
68
|
+
not-exists (nil)
|
69
|
+
|
53
70
|
+ all object class methods
|
54
71
|
|
55
72
|
## TODO
|
56
73
|
|
57
|
-
|
58
|
-
|
74
|
+
* should I add feature to raise on unconfigured/unset?
|
75
|
+
* should I always merge to 'cfg' when default/system/config is set?
|
59
76
|
|
data/lib/strada/adapter/json.rb
CHANGED
@@ -13,13 +13,14 @@ class Strada
|
|
13
13
|
class JSON
|
14
14
|
# 定义类方法
|
15
15
|
class << self
|
16
|
-
require "json"
|
17
16
|
# 将 RUBY(HASH) 数据结构转换为 JSON
|
18
17
|
def to(hash)
|
18
|
+
require "json"
|
19
19
|
::JSON.pretty_generate hash
|
20
20
|
end
|
21
21
|
# 将 JSON 转换为 RUBY 数据结构
|
22
22
|
def from(json)
|
23
|
+
require "json"
|
23
24
|
::JSON.load json
|
24
25
|
end
|
25
26
|
end
|
data/lib/strada/adapter/toml.rb
CHANGED
@@ -13,14 +13,14 @@ class Strada
|
|
13
13
|
class TOML
|
14
14
|
# 定义类方法
|
15
15
|
class << self
|
16
|
-
require "toml"
|
17
|
-
|
18
16
|
# 将 RUBY(HASH) 数据结构转换为 TOML
|
19
17
|
def to(hash)
|
18
|
+
require "toml"
|
20
19
|
::TOML::Generator.new(hash).body
|
21
20
|
end
|
22
21
|
# 将 TOML 转换为 RUBY 数据结构
|
23
22
|
def from(toml)
|
23
|
+
require "toml"
|
24
24
|
::TOML.load toml
|
25
25
|
end
|
26
26
|
end
|
data/lib/strada/adapter/yaml.rb
CHANGED
@@ -13,14 +13,14 @@ class Strada
|
|
13
13
|
class YAML
|
14
14
|
# 定义类方法
|
15
15
|
class << self
|
16
|
-
require "yaml"
|
17
|
-
|
18
16
|
# 将 RUBY(HASH) 数据结构转换为 YAML
|
19
17
|
def to(hash)
|
18
|
+
require "yaml"
|
20
19
|
::YAML.dump hash
|
21
20
|
end
|
22
21
|
# 将 YAML 转换为 RUBY(HASH) 数据结构
|
23
22
|
def from(yaml)
|
23
|
+
require "yaml"
|
24
24
|
::YAML.load yaml
|
25
25
|
end
|
26
26
|
end
|
data/lib/strada/config_struct.rb
CHANGED
@@ -2,6 +2,39 @@
|
|
2
2
|
|
3
3
|
class Strada
|
4
4
|
class ConfigStruct
|
5
|
+
# 类对象初始化函数入口
|
6
|
+
def initialize(hash = nil, opts = {})
|
7
|
+
@key_to_s = opts.delete(:key_to_s) || false
|
8
|
+
@cfg = hash ? _config_from_hash(hash) : {}
|
9
|
+
end
|
10
|
+
|
11
|
+
# 方法反射
|
12
|
+
def method_missing(name, *args, &block)
|
13
|
+
name = name.to_s
|
14
|
+
# 检索 ConfigStruct 键值对
|
15
|
+
# strada.cfg['foo']
|
16
|
+
name = args.shift if name[0..1] == "[]"
|
17
|
+
arg = args.first
|
18
|
+
|
19
|
+
if name[-1..-1] == "?"
|
20
|
+
# 查询是否包含某个 KEY
|
21
|
+
# strada.cfg.foo.bar?
|
22
|
+
if @cfg.has_key? name[0..-2]
|
23
|
+
@cfg[name[0..-2]]
|
24
|
+
else
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
elsif name[-1..-1] == "="
|
28
|
+
# strada.cfg.foo.bar = 'bala'
|
29
|
+
# ConfigStruct 键值对赋值
|
30
|
+
_config_set name[0..-2], arg
|
31
|
+
else
|
32
|
+
# strada.cfg.foo.bar
|
33
|
+
# ConfigStruct 查询某个属性
|
34
|
+
_config_get name, arg
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
5
38
|
# 将配置信息转换为 HASH 对象
|
6
39
|
def _config_to_hash
|
7
40
|
hash = {}
|
@@ -9,7 +42,9 @@ class Strada
|
|
9
42
|
if value.class == ConfigStruct
|
10
43
|
value = value._config_to_hash
|
11
44
|
end
|
12
|
-
|
45
|
+
# 是否需要将 key 转为 to_s
|
46
|
+
key = key.to_s if @key_to_s
|
47
|
+
# 保存键值对数据到 HASH
|
13
48
|
hash[key] = value
|
14
49
|
end
|
15
50
|
hash
|
@@ -36,37 +71,13 @@ class Strada
|
|
36
71
|
end
|
37
72
|
|
38
73
|
private
|
39
|
-
def initialize(hash = nil, opts = {})
|
40
|
-
@key_to_s = opts.delete :key_to_s
|
41
|
-
@cfg = hash ? _config_from_hash(hash) : {}
|
42
|
-
end
|
43
|
-
|
44
|
-
# 方法反射
|
45
|
-
def method_missing(name, *args, &block)
|
46
|
-
name = name.to_s
|
47
|
-
name = args.shift if name[0..1] == "[]" # strada.cfg['foo']
|
48
|
-
arg = args.first
|
49
|
-
|
50
|
-
if name[-1..-1] == "?" # strada.cfg.foo.bar?
|
51
|
-
if @cfg.has_key? name[0..-2]
|
52
|
-
@cfg[name[0..-2]]
|
53
|
-
else
|
54
|
-
nil
|
55
|
-
end
|
56
|
-
elsif name[-1..-1] == "=" # strada.cfg.foo.bar = 'quux'
|
57
|
-
_config_set name[0..-2], arg
|
58
|
-
else
|
59
|
-
_config_get name, arg # strada.cfg.foo.bar
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# 设置键值对
|
64
74
|
def _config_set(key, value)
|
75
|
+
# 设置键值对
|
65
76
|
@cfg[key] = value
|
66
77
|
end
|
67
78
|
|
68
|
-
# 查询 KEY VALUE
|
69
79
|
def _config_get(key, value)
|
80
|
+
# 查询 KEY VALUE
|
70
81
|
if @cfg.has_key? key
|
71
82
|
@cfg[key]
|
72
83
|
else
|
@@ -74,8 +85,8 @@ class Strada
|
|
74
85
|
end
|
75
86
|
end
|
76
87
|
|
77
|
-
# 转换 HASH 数据为配置对象
|
78
88
|
def _config_from_hash(hash)
|
89
|
+
# 转换 HASH 数据为配置对象
|
79
90
|
cfg = {}
|
80
91
|
hash.each do |key, value|
|
81
92
|
if value.class == Hash
|
data/lib/strada/version.rb
CHANGED
data/lib/strada.rb
CHANGED
@@ -28,11 +28,6 @@ class UnknownOption < StradaError; end
|
|
28
28
|
# ssh_hosts = CFG.ssh.hosts
|
29
29
|
|
30
30
|
class Strada
|
31
|
-
CONFIG_FILE = "config"
|
32
|
-
# 类对象属性
|
33
|
-
attr_reader :cfg, :default, :file
|
34
|
-
attr_accessor :system, :user
|
35
|
-
|
36
31
|
# 类方法
|
37
32
|
class << self
|
38
33
|
def cfg(*args)
|
@@ -40,6 +35,42 @@ class Strada
|
|
40
35
|
end
|
41
36
|
end
|
42
37
|
|
38
|
+
# 类变量 - 常量,配置保存文件名
|
39
|
+
CONFIG_FILE = "config"
|
40
|
+
|
41
|
+
# 类对象属性
|
42
|
+
attr_reader :cfg, :default, :file, :usr_dir, :sys_dir
|
43
|
+
attr_accessor :system, :user
|
44
|
+
|
45
|
+
# 类对象实例化函数入口
|
46
|
+
def initialize(opts = {})
|
47
|
+
# @param [Hash] opts options for Strada.new
|
48
|
+
# @option opts [String] :name name to use for strada (/etc/name/, ~/.config/name/) - autodetected if not defined
|
49
|
+
# @option opts [String] :adapter adapter to use 'yaml', 'json' or 'toml' for now
|
50
|
+
# @option opts [String] :usr_dir directory for storing user config ~/.config/name/ by default
|
51
|
+
# @option opts [String] :sys_dir directory for storing system config /etc/name/ by default
|
52
|
+
# @option opts [String] :cfg_file configuration filename, by default CONFIG_FILE
|
53
|
+
# @option opts [Hash] :default default settings to use
|
54
|
+
# @option opts [boolean] :load automatically load+merge system+user config with defaults in #cfg
|
55
|
+
# @option opts [boolean] :key_to_s convert keys to string by calling #to_s for keys
|
56
|
+
@name = opts.delete(:name) || meta_name
|
57
|
+
@adapter = opts.delete(:adapter) || "yaml"
|
58
|
+
@usr_dir = opts.delete(:usr_dir) || File.join(Dir.home, ".config", @name)
|
59
|
+
@sys_dir = opts.delete(:sys_dir) || File.join("/etc", @name)
|
60
|
+
@cfg_file = opts.delete(:cfg_file) || CONFIG_FILE
|
61
|
+
|
62
|
+
# 配置对象属性
|
63
|
+
@default = ConfigStruct.new opts.delete(:default)
|
64
|
+
@system = ConfigStruct.new
|
65
|
+
@user = ConfigStruct.new
|
66
|
+
@cfg = ConfigStruct.new
|
67
|
+
@load = true
|
68
|
+
@load = opts.delete(:load) if opts.has_key?(:load)
|
69
|
+
@key_to_s = opts.delete(:key_to_s)
|
70
|
+
raise UnknownOption, "option '#{opts}' not recognized" unless opts.empty?
|
71
|
+
load :all if @load
|
72
|
+
end
|
73
|
+
|
43
74
|
# When this is called, by default :system and :user are loaded from
|
44
75
|
# filesystem and merged with default, so that user overrides system which
|
45
76
|
# overrides default
|
@@ -87,40 +118,12 @@ class Strada
|
|
87
118
|
src = instance_variable_get "@" + src.to_s
|
88
119
|
instance_variable_set("@" + dst.to_s, src.dup)
|
89
120
|
save dst
|
90
|
-
load if opts.delete
|
121
|
+
load if opts.delete(:load)
|
91
122
|
end
|
92
123
|
no_config
|
93
124
|
end
|
94
125
|
|
95
126
|
private
|
96
|
-
def initialize(opts = {})
|
97
|
-
# @param [Hash] opts options for Strada.new
|
98
|
-
# @option opts [String] :name name to use for strada (/etc/name/, ~/.config/name/) - autodetected if not defined
|
99
|
-
# @option opts [String] :adapter adapter to use 'yaml', 'json' or 'toml' for now
|
100
|
-
# @option opts [String] :usr_dir directory for storing user config ~/.config/name/ by default
|
101
|
-
# @option opts [String] :sys_dir directory for storing system config /etc/name/ by default
|
102
|
-
# @option opts [String] :cfg_file configuration filename, by default CONFIG_FILE
|
103
|
-
# @option opts [Hash] :default default settings to use
|
104
|
-
# @option opts [boolean] :load automatically load+merge system+user config with defaults in #cfg
|
105
|
-
# @option opts [boolean] :key_to_s convert keys to string by calling #to_s for keys
|
106
|
-
@name = opts.delete(:name) || meta_name
|
107
|
-
@adapter = opts.delete(:adapter) || "yaml"
|
108
|
-
@usr_dir = opts.delete(:usr_dir) || File.join(Dir.home, ".config", @name)
|
109
|
-
@sys_dir = opts.delete(:sys_dir) || File.join("/etc", @name)
|
110
|
-
@cfg_file = opts.delete(:cfg_file) || CONFIG_FILE
|
111
|
-
|
112
|
-
# 配置对象属性
|
113
|
-
@default = ConfigStruct.new opts.delete(:default)
|
114
|
-
@system = ConfigStruct.new
|
115
|
-
@user = ConfigStruct.new
|
116
|
-
@cfg = ConfigStruct.new
|
117
|
-
@load = true
|
118
|
-
@load = opts.delete(:load) if opts.has_key?(:load)
|
119
|
-
@key_to_s = opts.delete(:key_to_s)
|
120
|
-
raise UnknownOption, "option '#{opts}' not recognized" unless opts.empty?
|
121
|
-
load :all if @load
|
122
|
-
end
|
123
|
-
|
124
127
|
# 加载配置文件
|
125
128
|
def load_cfg(dir)
|
126
129
|
@file = File.join dir, @cfg_file
|
@@ -134,7 +137,9 @@ class Strada
|
|
134
137
|
def save_cfg(dir, config)
|
135
138
|
config = to(@adapter, config)
|
136
139
|
file = File.join dir, @cfg_file
|
137
|
-
|
140
|
+
|
141
|
+
# 判断目标文件夹是否存在,不存在则新建
|
142
|
+
FileUtils.mkdir_p dir unless Dir.exist? dir
|
138
143
|
File.write file, config
|
139
144
|
end
|
140
145
|
|
@@ -143,7 +148,7 @@ class Strada
|
|
143
148
|
hash = {}
|
144
149
|
# 将相关配置依次迭代并转换为 RUBY HASH 对象
|
145
150
|
configs.each do |config|
|
146
|
-
hash = hash._config_deep_merge
|
151
|
+
hash = hash._config_deep_merge(config._config_to_hash)
|
147
152
|
end
|
148
153
|
# 将合并后的 HASH 数据结构转换为配置对象
|
149
154
|
ConfigStruct.new hash
|
@@ -174,7 +179,7 @@ end
|
|
174
179
|
class Hash
|
175
180
|
def _config_deep_merge(new_hash)
|
176
181
|
merger = proc do |key, old_val, new_val|
|
177
|
-
Hash === old_val && Hash === new_val ? old_val.merge(new_val, &merger) : new_val
|
182
|
+
(Hash === old_val && Hash === new_val) ? old_val.merge(new_val, &merger) : new_val
|
178
183
|
end
|
179
184
|
merge new_hash, &merger
|
180
185
|
end
|