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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6b92fa420cc7d3c24f1bb62a31383d801a9723fb
4
- data.tar.gz: 18dc5fe8f6ac65c4b5944bca3ab5a1cc1beb05c2
3
+ metadata.gz: 070d60a6d5c053d57f09ac3b78adbadc0624a221
4
+ data.tar.gz: ad225310f64d0f800a4d31134098a901a440942b
5
5
  SHA512:
6
- metadata.gz: 77f5487fa6c68e326d89277ff4e94e6cb8c4338e28c817009921df0697c807b8533f25736b37c85eca140d53c285b1aba7cc5bfd287f5e748e1eacec0ec55b39
7
- data.tar.gz: 1ac82cbab64bd30db593e37bac4db1d3913a0540b30e5e5312948390d70a8edfa740be60ef30d54d0a6e779a3ddc30b59b797d42192c6f810146e2b6e01ce9ef
6
+ metadata.gz: bfc70674eb8c9a0208e0c1232cceb98d551089fa1c5184e796a23c6042d4df2ca7a87fb188a48ff8fa888184b0f61699df53839238c7b073fa17e5d271ef88b9
7
+ data.tar.gz: 582379f1ee6357a8336c1b0c1c19c7a4554bf865a0c376471d84025de3a1c01efd711a860e779e954baff02e419839ad2c8b751fc28dc73926b2ea97a44a940d
data/.travis.yml CHANGED
@@ -1,6 +1,7 @@
1
1
  language: ruby
2
2
  sudo: false
3
3
  rvm:
4
- - 2.2.3
5
- before_install: gem install bundler -v 1.10.5
4
+ - 2.3.4
5
+ - 2.4.1
6
+ before_install: gem install bundler -v 1.15.4
6
7
  cache: bundler
data/Dockerfile ADDED
@@ -0,0 +1,7 @@
1
+ FROM ruby:2.4-alpine
2
+
3
+ ARG version
4
+
5
+ RUN if [[ "$version" = "" ]]; then gem install yaml_master --no-document; else gem install yaml_master --no-document --version ${version}; fi
6
+
7
+ ENTRYPOINT ["yaml_master"]
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
- require "slop"
5
-
6
- opts = Slop.parse(strict: true) do
7
- on 'm', 'master=', 'master yaml file'
8
- on 'k', 'key=', 'single generate target key (in data: block)'
9
- on 'o', 'output=', 'output filename for single generate target'
10
- on 'a', 'all', 'target all key (defined in yaml_master: block)'
11
- on 'p', 'properties=', 'set property (--properties="NAME=VALUE,NAME=VALUE" or -p "NAME=VALUE" -p "NAME=VALUE")', as: Array
12
- on 'h', 'help', 'display this help'
13
- on 'v', 'verbose', 'verbose mode'
14
- on '--version', 'print the version' do
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
- options = opts.to_hash
21
-
22
- if options[:help]
23
- puts opts
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 opts
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 opts
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
- YAML.add_domain_type(nil, "include") do |type, val|
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
- parse_properties(property_strings)
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
- embedded_methods_binding = EmbeddedMethods.new(self).get_binding
26
- data =
27
- if io_or_filename.is_a?(IO)
28
- ERB.new(io_or_filename.read).result(embedded_methods_binding)
29
- else
30
- @master_path = File.expand_path(io_or_filename)
31
- ERB.new(File.read(io_or_filename)).result(embedded_methods_binding)
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
- return yaml unless output
44
-
45
- File.open(output, 'w') do |f|
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 parse_properties(property_strings)
80
- @properties = {}
81
- if property_strings.is_a?(Hash)
82
- @properties = property_strings
83
- else
84
- property_strings.each_with_object(@properties) do |str, hash|
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
- class EmbeddedMethods
93
- def initialize(yaml_master)
94
- @yaml_master = yaml_master
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 master_path
98
- Pathname(@yaml_master.master_path)
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
- @yaml_master.properties
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 get_binding
115
- binding
124
+ def render_master
125
+ ERB.new(File.read(@master_path)).result(binding)
116
126
  end
117
127
  end
118
128
  end
@@ -1,3 +1,3 @@
1
1
  class YamlMaster
2
- VERSION = "0.4.2"
2
+ VERSION = "1.0.0.beta"
3
3
  end
@@ -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.add_runtime_dependency "slop", "~> 3.6"
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.2
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: 2016-03-24 00:00:00.000000000 Z
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.10'
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.10'
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: '0'
107
+ version: 1.3.1
120
108
  requirements: []
121
109
  rubyforge_project:
122
- rubygems_version: 2.5.1
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