yaml_master 0.4.2 → 1.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -2
- data/Dockerfile +7 -0
- data/README.md +68 -0
- data/exe/yaml_master +48 -22
- data/lib/yaml_master.rb +52 -42
- data/lib/yaml_master/version.rb +1 -1
- data/lib/yaml_master/yaml_tree_builder.rb +74 -0
- data/yaml_master.gemspec +1 -3
- metadata +9 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 070d60a6d5c053d57f09ac3b78adbadc0624a221
|
4
|
+
data.tar.gz: ad225310f64d0f800a4d31134098a901a440942b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bfc70674eb8c9a0208e0c1232cceb98d551089fa1c5184e796a23c6042d4df2ca7a87fb188a48ff8fa888184b0f61699df53839238c7b073fa17e5d271ef88b9
|
7
|
+
data.tar.gz: 582379f1ee6357a8336c1b0c1c19c7a4554bf865a0c376471d84025de3a1c01efd711a860e779e954baff02e419839ad2c8b751fc28dc73926b2ea97a44a940d
|
data/.travis.yml
CHANGED
data/Dockerfile
ADDED
data/README.md
CHANGED
@@ -35,6 +35,17 @@ Usage: yaml_master [options]
|
|
35
35
|
--version print the version
|
36
36
|
```
|
37
37
|
|
38
|
+
### Support YAML tags
|
39
|
+
|
40
|
+
| tag | description |
|
41
|
+
| ------------------------ | ------------------------------------------------------------------------------------- |
|
42
|
+
| !include {yaml_filename} | Replace value by other yaml file content. included file can use alias in master file. |
|
43
|
+
| !master_path | Replace value by master file path |
|
44
|
+
| !user_home | Replace value by `ENV["HOME"]`. |
|
45
|
+
| !env {key} | Replace value by `ENV["{key}"]`. |
|
46
|
+
| !properties {key} | Replace value by fetched value from given properties. |
|
47
|
+
| !read_file_if_exist {filename} | Replace value by content of {filename}. if {filename} does not exist, Replace value by `null` |
|
48
|
+
|
38
49
|
at first, Write master.yml
|
39
50
|
|
40
51
|
```yaml
|
@@ -96,6 +107,15 @@ data:
|
|
96
107
|
database: my_database
|
97
108
|
table: my_table
|
98
109
|
mode: insert
|
110
|
+
|
111
|
+
tag_sample
|
112
|
+
included: !include included.yml
|
113
|
+
master_path: !master_path
|
114
|
+
user_home: !user_home
|
115
|
+
env: !env HOME
|
116
|
+
properties: !properties foo
|
117
|
+
read_file_if_exist: !read_file_if_exist sample.txt
|
118
|
+
read_file_if_exist_nothing: !read_file_if_exist nothing.txt
|
99
119
|
```
|
100
120
|
|
101
121
|
### single output
|
@@ -193,6 +213,54 @@ out:
|
|
193
213
|
mode: insert
|
194
214
|
```
|
195
215
|
|
216
|
+
```yaml
|
217
|
+
# ./tag_sample.yml
|
218
|
+
|
219
|
+
---
|
220
|
+
included:
|
221
|
+
xyz: hoge
|
222
|
+
db:
|
223
|
+
adapter: mysql2
|
224
|
+
encoding: utf8
|
225
|
+
database: development
|
226
|
+
pool: 5
|
227
|
+
host:
|
228
|
+
username: root
|
229
|
+
password:
|
230
|
+
socket: "/tmp/mysql.sock"
|
231
|
+
abc:
|
232
|
+
- 1
|
233
|
+
- 2.3
|
234
|
+
- a: 1
|
235
|
+
b: 2
|
236
|
+
included2:
|
237
|
+
- foo: bar
|
238
|
+
- hoge: fuga
|
239
|
+
- :abc:
|
240
|
+
- 1
|
241
|
+
- 2
|
242
|
+
- 3
|
243
|
+
master_path: "/home/joker/.ghq/github.com/joker1007/yaml_master/spec/sample.yml"
|
244
|
+
master_path2: "/home/joker/.ghq/github.com/joker1007/yaml_master/spec/sample.yml"
|
245
|
+
user_home: "/home/joker"
|
246
|
+
user_home2: "/home/joker"
|
247
|
+
env: "/home/joker"
|
248
|
+
properties: '24'
|
249
|
+
read_file_if_exist: 'dummy
|
250
|
+
|
251
|
+
'
|
252
|
+
read_file_if_exist_nothing:
|
253
|
+
read_file_if_exist2: 'dummy '
|
254
|
+
```
|
255
|
+
|
256
|
+
## How to use with Docker
|
257
|
+
|
258
|
+
```sh
|
259
|
+
docker run --rm \
|
260
|
+
-v `pwd`/:/vol \
|
261
|
+
joker1007/yaml_master -m /vol/spec/sample.yml -k database_yml -o /vol/test.yml
|
262
|
+
```
|
263
|
+
|
196
264
|
## Development
|
197
265
|
|
198
266
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/exe/yaml_master
CHANGED
@@ -1,45 +1,71 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
require "optparse"
|
3
4
|
require "yaml_master"
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
on
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
on
|
13
|
-
|
14
|
-
|
5
|
+
|
6
|
+
options = {properties: []}
|
7
|
+
|
8
|
+
opt_parser = OptionParser.new do |opts|
|
9
|
+
opts.on("-m", "--master=MASTER_FILE", "master yaml file") do |master|
|
10
|
+
options[:master] = master
|
11
|
+
end
|
12
|
+
|
13
|
+
opts.on("-k", "--key=KEY", "single generate target key (in data: block)") do |key|
|
14
|
+
options[:key] = key
|
15
|
+
end
|
16
|
+
|
17
|
+
opts.on("-o", "--output=OUTPUT", "output filename for single generate target") do |output|
|
18
|
+
options[:output] = output
|
19
|
+
end
|
20
|
+
|
21
|
+
opts.on("-a", "--all", "target all key (defined in yaml_master: block)") do |all|
|
22
|
+
options[:all] = true
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on("-d", "--dump", "dump evaluated master yaml") do ||
|
26
|
+
options[:dump] = true
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on("-p", "--properties=PROPERTIES", %q{set property (--properties="NAME=VALUE,NAME=VALUE" or -p "NAME=VALUE" -p "NAME=VALUE")}) do |properties|
|
30
|
+
options[:properties].concat(properties.split(/\s*,\s*/))
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on("-v", "--verbose", "verbose mode") do |verbose|
|
34
|
+
options[:verbose] = true
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on("--version", "Print version") do
|
15
38
|
puts YamlMaster::VERSION
|
16
39
|
exit
|
17
40
|
end
|
18
|
-
end
|
19
41
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
exit
|
42
|
+
opts.on("-h", "--help", "Prints this help") do
|
43
|
+
puts opts
|
44
|
+
exit
|
45
|
+
end
|
25
46
|
end
|
26
47
|
|
48
|
+
opt_parser.parse!(ARGV)
|
49
|
+
|
27
50
|
unless options[:master]
|
28
51
|
puts "--master options is necessary"
|
29
|
-
puts
|
52
|
+
puts opt_parser
|
30
53
|
exit 1
|
31
54
|
end
|
32
55
|
|
33
|
-
if options[:all].nil? && options[:key].nil?
|
34
|
-
puts "--all or --key is necessary"
|
35
|
-
puts
|
56
|
+
if options[:all].nil? && options[:key].nil? && options[:dump].nil?
|
57
|
+
puts "--all or --key or --dump is necessary"
|
58
|
+
puts opt_parser
|
36
59
|
exit 1
|
37
60
|
end
|
38
61
|
|
39
|
-
yaml_master = YamlMaster.new(options[:master], options[:properties]
|
62
|
+
yaml_master = YamlMaster.new(options[:master], options[:properties])
|
40
63
|
|
41
64
|
if options[:all]
|
42
65
|
yaml_master.generate_all(verbose: options[:verbose])
|
66
|
+
elsif options[:dump]
|
67
|
+
result = yaml_master.dump(options[:output], {verbose: options[:verbose]})
|
68
|
+
puts result unless options[:output]
|
43
69
|
else
|
44
70
|
result = yaml_master.generate(options[:key], options[:output], {verbose: options[:verbose]})
|
45
71
|
puts result unless options[:output]
|
data/lib/yaml_master.rb
CHANGED
@@ -3,11 +3,8 @@ require "yaml_master/version"
|
|
3
3
|
require "yaml"
|
4
4
|
require "erb"
|
5
5
|
require "pathname"
|
6
|
-
require "pp"
|
7
6
|
|
8
|
-
|
9
|
-
YAML.load_file(val)
|
10
|
-
end
|
7
|
+
require "yaml_master/yaml_tree_builder"
|
11
8
|
|
12
9
|
class YamlMaster
|
13
10
|
class KeyFetchError < StandardError
|
@@ -15,36 +12,36 @@ class YamlMaster
|
|
15
12
|
super("cannot fetch key \"#{key}\" from\n#{data.pretty_inspect}")
|
16
13
|
end
|
17
14
|
end
|
18
|
-
class PropertyParseError < StandardError; end
|
19
|
-
|
20
15
|
attr_reader :master, :master_path, :properties
|
21
16
|
|
22
17
|
def initialize(io_or_filename, property_strings = [])
|
23
|
-
|
18
|
+
case io_or_filename
|
19
|
+
when String
|
20
|
+
@master_path = Pathname(io_or_filename).expand_path
|
21
|
+
when File
|
22
|
+
@master_path = Pathname(io_or_filename.absolute_path)
|
23
|
+
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
25
|
+
@properties = PropertyParser.parse_properties(property_strings)
|
26
|
+
yaml = Context.new(master_path, @properties).render_master
|
27
|
+
|
28
|
+
parser = YAML::Parser.new
|
29
|
+
parser.handler = YamlMaster::YAMLTreeBuilder.new(@master_path, @properties, parser)
|
30
|
+
@tree = parser.parse(yaml).handler.root
|
31
|
+
@master = @tree.to_ruby[0]
|
33
32
|
|
34
|
-
@master = YAML.load(data)
|
35
33
|
raise "yaml_master key is necessary on toplevel" unless @master["yaml_master"]
|
36
34
|
raise "data key is necessary on toplevel" unless @master["data"]
|
37
35
|
end
|
38
36
|
|
39
37
|
def generate(key, output = nil, options = {})
|
40
|
-
puts "gen: #{output}" if options[:verbose]
|
41
38
|
yaml = YAML.dump(fetch_data_from_master(key))
|
39
|
+
write_to_output(yaml, output, options[:verbose])
|
40
|
+
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
f.write(yaml)
|
47
|
-
end
|
42
|
+
def dump(output = nil, options = {})
|
43
|
+
yaml = @tree.to_yaml
|
44
|
+
write_to_output(yaml, output, options[:verbose])
|
48
45
|
end
|
49
46
|
|
50
47
|
def generate_all(options = {})
|
@@ -76,30 +73,43 @@ class YamlMaster
|
|
76
73
|
end
|
77
74
|
end
|
78
75
|
|
79
|
-
def
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
key, value = str.split("=")
|
86
|
-
raise PropertyParseError.new("#{str} is invalid format") unless key && value
|
87
|
-
hash[key] = value
|
88
|
-
end
|
76
|
+
def write_to_output(yaml, output, verbose)
|
77
|
+
if output && verbose
|
78
|
+
puts <<~VERBOSE
|
79
|
+
gen: #{output}
|
80
|
+
#{yaml}
|
81
|
+
VERBOSE
|
89
82
|
end
|
90
|
-
end
|
91
83
|
|
92
|
-
|
93
|
-
|
94
|
-
|
84
|
+
return yaml unless output
|
85
|
+
|
86
|
+
File.open(output, 'w') do |f|
|
87
|
+
f.write(yaml)
|
95
88
|
end
|
89
|
+
end
|
90
|
+
|
91
|
+
module PropertyParser
|
92
|
+
class ParseError < StandardError; end
|
96
93
|
|
97
|
-
def
|
98
|
-
|
94
|
+
def self.parse_properties(property_strings_or_hash)
|
95
|
+
if property_strings_or_hash.is_a?(Hash)
|
96
|
+
property_strings_or_hash
|
97
|
+
else
|
98
|
+
property_strings_or_hash.each_with_object({}) do |str, hash|
|
99
|
+
key, value = str.split("=")
|
100
|
+
raise ParseError.new("#{str} is invalid format") unless key && value
|
101
|
+
hash[key] = value
|
102
|
+
end
|
103
|
+
end
|
99
104
|
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class Context
|
108
|
+
attr_reader :master_path, :properties
|
100
109
|
|
101
|
-
def properties
|
102
|
-
@
|
110
|
+
def initialize(master_path, properties)
|
111
|
+
@master_path = master_path
|
112
|
+
@properties = properties
|
103
113
|
end
|
104
114
|
|
105
115
|
def user_home
|
@@ -111,8 +121,8 @@ class YamlMaster
|
|
111
121
|
File.read(path)
|
112
122
|
end
|
113
123
|
|
114
|
-
def
|
115
|
-
binding
|
124
|
+
def render_master
|
125
|
+
ERB.new(File.read(@master_path)).result(binding)
|
116
126
|
end
|
117
127
|
end
|
118
128
|
end
|
data/lib/yaml_master/version.rb
CHANGED
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
require 'yaml'
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
class YamlMaster::YAMLTreeBuilder < YAML::TreeBuilder
|
6
|
+
def initialize(master_path, properties, parser)
|
7
|
+
super()
|
8
|
+
@master_path = master_path
|
9
|
+
@properties = properties
|
10
|
+
@parser = parser
|
11
|
+
end
|
12
|
+
|
13
|
+
def scalar(value, anchor, tag, plain, quoted, style)
|
14
|
+
case tag
|
15
|
+
when "!include"
|
16
|
+
ensure_tag_argument(tag, value)
|
17
|
+
|
18
|
+
path = Pathname(value)
|
19
|
+
path = path.absolute? ? path : @master_path.dirname.join(path)
|
20
|
+
tree = YAML.parse(File.read(path))
|
21
|
+
@last.children << tree.children[0]
|
22
|
+
when "!master_path"
|
23
|
+
s = build_scalar_node(@master_path.to_s)
|
24
|
+
@last.children << s
|
25
|
+
s
|
26
|
+
when "!user_home"
|
27
|
+
s = build_scalar_node(ENV["HOME"])
|
28
|
+
@last.children << s
|
29
|
+
s
|
30
|
+
when "!properties"
|
31
|
+
ensure_tag_argument(tag, value)
|
32
|
+
|
33
|
+
s = build_scalar_node(@properties[value])
|
34
|
+
@last.children << s
|
35
|
+
s
|
36
|
+
when "!env"
|
37
|
+
ensure_tag_argument(tag, value)
|
38
|
+
|
39
|
+
s = build_scalar_node(ENV[value])
|
40
|
+
@last.children << s
|
41
|
+
s
|
42
|
+
when "!read_file_if_exist"
|
43
|
+
ensure_tag_argument(tag, value)
|
44
|
+
|
45
|
+
path = Pathname(value)
|
46
|
+
path = path.absolute? ? path : @master_path.dirname.join(path)
|
47
|
+
content = path.file? && path.readable? ? File.read(path) : nil
|
48
|
+
s = build_scalar_node(content, false, true, 4)
|
49
|
+
@last.children << s
|
50
|
+
s
|
51
|
+
else
|
52
|
+
super
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def ensure_tag_argument(tag, value)
|
59
|
+
if value.empty?
|
60
|
+
mark = @parser.mark
|
61
|
+
$stderr.puts "tag format error"
|
62
|
+
$stderr.puts "#{tag} requires 1 argument at #{mark.line}:#{mark.column}"
|
63
|
+
exit 1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def build_scalar_node(value, plain = true, quoted = true, style = 1)
|
68
|
+
if value
|
69
|
+
YAML::Nodes::Scalar.new(value, nil, nil, plain, quoted, style)
|
70
|
+
else
|
71
|
+
YAML::Nodes::Scalar.new("null", nil, nil, true, false, 1)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/yaml_master.gemspec
CHANGED
@@ -18,9 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.
|
22
|
-
|
23
|
-
spec.add_development_dependency "bundler", "~> 1.10"
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.15"
|
24
22
|
spec.add_development_dependency "rake", "~> 10.0"
|
25
23
|
spec.add_development_dependency "rspec"
|
26
24
|
spec.add_development_dependency "fakefs"
|
metadata
CHANGED
@@ -1,43 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yaml_master
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.beta
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- joker1007
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: slop
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '3.6'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '3.6'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: bundler
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
17
|
- - "~>"
|
32
18
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
19
|
+
version: '1.15'
|
34
20
|
type: :development
|
35
21
|
prerelease: false
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
37
23
|
requirements:
|
38
24
|
- - "~>"
|
39
25
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
26
|
+
version: '1.15'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: rake
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,6 +77,7 @@ files:
|
|
91
77
|
- ".gitignore"
|
92
78
|
- ".rspec"
|
93
79
|
- ".travis.yml"
|
80
|
+
- Dockerfile
|
94
81
|
- Gemfile
|
95
82
|
- README.md
|
96
83
|
- Rakefile
|
@@ -99,6 +86,7 @@ files:
|
|
99
86
|
- exe/yaml_master
|
100
87
|
- lib/yaml_master.rb
|
101
88
|
- lib/yaml_master/version.rb
|
89
|
+
- lib/yaml_master/yaml_tree_builder.rb
|
102
90
|
- yaml_master.gemspec
|
103
91
|
homepage: https://github.com/joker1007/yaml_master
|
104
92
|
licenses: []
|
@@ -114,12 +102,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
114
102
|
version: '0'
|
115
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
104
|
requirements:
|
117
|
-
- - "
|
105
|
+
- - ">"
|
118
106
|
- !ruby/object:Gem::Version
|
119
|
-
version:
|
107
|
+
version: 1.3.1
|
120
108
|
requirements: []
|
121
109
|
rubyforge_project:
|
122
|
-
rubygems_version: 2.
|
110
|
+
rubygems_version: 2.6.12
|
123
111
|
signing_key:
|
124
112
|
specification_version: 4
|
125
113
|
summary: Helper of YAML file generation from single master YAML file
|