yaml_master 0.4.2 → 1.0.0.beta
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/.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
|