ecg 0.1.2 → 0.2.0

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
  SHA256:
3
- metadata.gz: 81f7dd877779549c7b32707909f9165d0d3e4b51490764301c58315da585cbf7
4
- data.tar.gz: 48ab0baed120e7892e0398a312a9cc30532946d51e3a08b882094562e5d27601
3
+ metadata.gz: d22e44c0a03b9a540006d7c0502e8c3c73101f7c446c9c05393ba5319bdc57ae
4
+ data.tar.gz: 03e5ed33aacd6ef40dfb7d7c0da2533d572259f444ce08e57d6a077bf4a64436
5
5
  SHA512:
6
- metadata.gz: d281193f36bcbdd4de0ed51196a109e8e50baf27ce183d32012c4ac85805bf9c8668f8c590bb30439cd10cf4ec3931df156db351f23cc3ce6e8d3cf05322bd73
7
- data.tar.gz: aa9f2782085a6747227a04529ee6f7efacf0f338e562f5230e2b4e8a173c1dd75c35f864222127cf4876f5422bded891c08176168d93f67bd31957571e2d4b67
6
+ metadata.gz: a6177f797de5728e5daf1f30b2178cb4f25c6281dc1cf2c9452afa88c9d1f5de54eabd3aa5afb12a40a05512e819a551bc052a92d7bbbeb17f3b35b008c37272
7
+ data.tar.gz: 59e1caa2a49b47af62ce27ee6b7b008ad3c8df286d7e84a77d0224892b9dd14dc9226d3586a50f637efe13e55e6869055797ec9b78673172168bd6fbbe506c74
data/README.md CHANGED
@@ -14,7 +14,10 @@ Ruby: 2.4 or higher
14
14
  gem install ecg
15
15
  ```
16
16
 
17
- ## Simple Usage
17
+ ## Usage
18
+ See also `ecg --help`
19
+
20
+ ### Simple example
18
21
  ```sh
19
22
  ecg --values name=epaew --values email="epaew.333@gmail.com" < template.json.erb
20
23
  {
@@ -47,5 +50,88 @@ with
47
50
  email: epaew.333@gmail.com
48
51
  ```
49
52
 
53
+ ### Using nested keys
54
+ ```sh
55
+ ecg --values user.name=epaew --values user.email="epaew.333@gmail.com" < template.json.erb
56
+ {
57
+ "user": {
58
+ "name": "epaew",
59
+ "email": "epaew.333@gmail.com"
60
+ }
61
+ }
62
+ ```
63
+ or
64
+ ```sh
65
+ ecg config.yml < template.json.erb
66
+ {
67
+ "user": {
68
+ "name": "epaew",
69
+ "email": "epaew.333@gmail.com"
70
+ }
71
+ }
72
+ ```
73
+ with
74
+ * template.json.erb
75
+ ```json
76
+ {
77
+ "user": {
78
+ "name": "<%= user.name %>",
79
+ "email": "<%= user.email %>"
80
+ }
81
+ }
82
+ ```
83
+ * config.yml
84
+ ```yaml
85
+ user:
86
+ name: epaew
87
+ email: epaew.333@gmail.com
88
+ ```
89
+
90
+ ### Using array (JSON and YAML only)
91
+ ```sh
92
+ ecg config.yml < template.json.erb
93
+ {
94
+ "user": [
95
+ {
96
+ "name": "Kurimu"
97
+ },
98
+ {
99
+ "name": "Chizuru"
100
+ },
101
+ {
102
+ "name": "Minatsu"
103
+ },
104
+ {
105
+ "name": "Mahuyu"
106
+ }
107
+ ]
108
+ }
109
+ ```
110
+ with
111
+ * template.json.erb
112
+ ```json
113
+ {
114
+ "user": [
115
+ <% users.each_with_index do |user, i| %>
116
+ {
117
+ "name": "<%= user.name %>"
118
+ <% unless i == users.count - 1 %>
119
+ },
120
+ <% else %>
121
+ }
122
+ <% end %>
123
+ <% end %>
124
+ ]
125
+ }
126
+ ```
127
+ * config.yml
128
+ ```yaml
129
+ users:
130
+ - name: Kurimu
131
+ - name: Chizuru
132
+ - name: Minatsu
133
+ - name: Mahuyu
134
+ ```
135
+
50
136
  ## License
51
137
  [MIT](LICENSE)
data/lib/ecg/command.rb CHANGED
@@ -2,17 +2,19 @@
2
2
 
3
3
  require 'erb'
4
4
  require_relative 'option_parser'
5
- require_relative 'store'
6
5
 
7
6
  module ECG
8
7
  class Command
9
8
  def initialize(args)
10
- parser = OptionParser.new(args)
11
- @store = parser.parse!
9
+ @parser = OptionParser.new(args)
12
10
  end
13
11
 
14
12
  def execute(input = $stdin, output = $stdout)
15
- output.puts ERB.new(input.read).result(@store.binding)
13
+ context = @parser.context
14
+ # NOTE: ERB.new's non-keyword arguments are deprecated in 2.6
15
+ # erb = ERB.new(input.read, trim_mode: context.trim_mode)
16
+ erb = ERB.new(input.read, nil, context.trim_mode)
17
+ output.puts erb.result(context.values.binding)
16
18
  end
17
19
  end
18
20
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'store'
4
+
5
+ module ECG
6
+ class Context
7
+ attr_reader :trim_mode
8
+
9
+ def initialize(filepath:, trim_mode:, values:)
10
+ @trim_mode = trim_mode
11
+ @values_file = filepath
12
+ @values_option = values
13
+ end
14
+
15
+ def values
16
+ Store.new(merged_hash)
17
+ end
18
+
19
+ private
20
+
21
+ def load_file(path)
22
+ case File.extname(path)
23
+ when '.json'
24
+ require 'json'
25
+ File.open(path) { |f| JSON.parse(f.read) }
26
+ when /\A\.ya?ml\z/
27
+ require 'yaml'
28
+ # NOTE: YAML.safe_load's non-keyword arguments are deprecated in 2.6
29
+ # File.open(path) { |f| YAML.safe_load(f.read, aliases: true) }
30
+ File.open(path) { |f| YAML.safe_load(f.read, [], [], true) }
31
+ else
32
+ raise ArgumentError,
33
+ "Cannot load file `#{path}`. Only JSON/YAML are allowed."
34
+ end
35
+ end
36
+
37
+ def merged_hash
38
+ hash = @values_file.nil? ? {} : load_file(@values_file)
39
+ hash.merge(@values_option)
40
+ end
41
+ end
42
+ end
@@ -1,26 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'optparse'
4
- require_relative 'store'
4
+ require_relative 'context'
5
+ require_relative 'version'
5
6
 
6
7
  module ECG
7
- class LoadError < ::StandardError; end
8
-
9
8
  class OptionParser
10
- attr_reader :args, :option
11
-
12
9
  def initialize(args = [])
13
10
  @args = args
14
- @option = {}
11
+ @options = { filepath: nil, trim_mode: '<>', values: {} }
15
12
  end
16
13
 
17
- def parse!
18
- print_help(false) if @args.empty?
14
+ def context
15
+ return @context if instance_variable_defined?(:@context)
19
16
 
20
- parser.parse!(@args)
21
- print_help(false) if @args.length > 1
22
-
23
- Store.new(hash)
17
+ parse!
18
+ @context = Context.new(@options)
24
19
  end
25
20
 
26
21
  private
@@ -31,39 +26,46 @@ module ECG
31
26
  __BANNER__
32
27
  end
33
28
 
34
- def hash
35
- hash = @args.empty? ? {} : load_file(@args.first)
36
-
37
- hash.merge(@option)
38
- end
29
+ def filepath
30
+ print_help(false) if @args.length > 1
31
+ return nil if @args.empty?
39
32
 
40
- def load_file(path)
41
- case File.extname(path)
42
- when '.json'
43
- require 'json'
44
- File.open(path) { |f| JSON.parse(f.read) }
45
- when /\A\.ya?ml\z/
46
- require 'yaml'
47
- File.open(path) { |f| YAML.safe_load(f.read, [], [], true) }
48
- else
33
+ path = @args.first
34
+ extname = File.extname(path)
35
+ if %w[.json .yml .yaml].none? { |ext| ext == extname }
49
36
  raise ArgumentError,
50
37
  "Cannot load file `#{path}`. Only JSON/YAML are allowed."
51
38
  end
39
+
40
+ path
41
+ end
42
+
43
+ def parse!
44
+ print_help(false) if @args.empty?
45
+
46
+ parser.parse!(@args)
47
+ @options[:filepath] = filepath
48
+ self
52
49
  end
53
50
 
54
- def parser
51
+ def parser # rubocop:disable Style/MethodLength
55
52
  ::OptionParser.new do |opt|
56
53
  opt.banner = banner
54
+ opt.version = VERSION
57
55
 
58
56
  opt.on('-v', '--values Key=Value', <<~__DESC__) do |str|
59
57
  Set the key-value mapping to be embedded in the template.
60
58
  __DESC__
61
59
 
62
- key, value = str.split('=', 2)
63
- @option[key] = value
60
+ set_option_value(*str.split('=', 2))
61
+ end
62
+ opt.on('-t', '--trim-mode MODE', <<~__DESC__) do |v|
63
+ Set ERB's trim_mode. Default is "<>".
64
+ __DESC__
65
+ @options[:trim_mode] = v
64
66
  end
65
67
  opt.on('-V', '--version', 'Print version information') do
66
- puts "#{File.basename($PROGRAM_NAME)} #{ECG::VERSION}"
68
+ puts opt.ver
67
69
  exit
68
70
  end
69
71
  opt.on('-h', '--help', 'Print this help message', &method(:print_help))
@@ -74,5 +76,40 @@ module ECG
74
76
  warn parser.help
75
77
  exit bool
76
78
  end
79
+
80
+ def set_option_value(key, value)
81
+ keys = key.split('.').map(&:to_sym)
82
+ if keys.count == 1
83
+ set_single_option_value(keys.first, value)
84
+ else
85
+ set_nested_option_value(keys, value)
86
+ end
87
+ end
88
+
89
+ def set_single_option_value(key, value)
90
+ values = @options[:values]
91
+ if values[key].is_a? Hash
92
+ raise ArgumentError, 'Reaf keys cannot have own value.'
93
+ end
94
+
95
+ values[key] = value
96
+ values
97
+ end
98
+
99
+ def set_nested_option_value(keys, value)
100
+ values = @options[:values]
101
+ last_key = keys.pop
102
+
103
+ nested = keys.inject(values) do |result, key|
104
+ result[key] ||= {}
105
+ unless result[key].is_a? Hash
106
+ raise ArgumentError, 'Reaf keys cannot have own value.'
107
+ end
108
+
109
+ result[key]
110
+ end
111
+ nested[last_key] = value
112
+ values
113
+ end
77
114
  end
78
115
  end
data/lib/ecg/store.rb CHANGED
@@ -40,18 +40,7 @@ module ECG
40
40
  end
41
41
 
42
42
  def to_h
43
- @store.transform_values do |value|
44
- case value
45
- when self.class
46
- value.to_h
47
- when Array
48
- value.map do |element|
49
- element.respond_to?(:to_h) ? element.to_h : element
50
- end
51
- else
52
- value
53
- end
54
- end
43
+ @store.transform_values(&method(:intransform_value))
55
44
  end
56
45
 
57
46
  def to_json(*args)
@@ -59,8 +48,25 @@ module ECG
59
48
  to_h.to_json(args)
60
49
  end
61
50
 
51
+ def ==(other)
52
+ return false unless other.is_a?(self.class)
53
+
54
+ to_h == other.to_h
55
+ end
56
+
62
57
  private
63
58
 
59
+ def intransform_value(value)
60
+ case value
61
+ when self.class
62
+ value.to_h
63
+ when Array
64
+ value.map(&method(:intransform_value))
65
+ else
66
+ value
67
+ end
68
+ end
69
+
64
70
  def transform_value(value)
65
71
  case value
66
72
  when Hash
data/lib/ecg/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ECG
4
- VERSION = '0.1.2'
4
+ VERSION = '0.2.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ecg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - epaew
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-19 00:00:00.000000000 Z
11
+ date: 2019-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -136,6 +136,7 @@ files:
136
136
  - bin/ecg
137
137
  - lib/ecg.rb
138
138
  - lib/ecg/command.rb
139
+ - lib/ecg/context.rb
139
140
  - lib/ecg/option_parser.rb
140
141
  - lib/ecg/store.rb
141
142
  - lib/ecg/version.rb
@@ -159,7 +160,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
160
  - !ruby/object:Gem::Version
160
161
  version: '0'
161
162
  requirements: []
162
- rubygems_version: 3.0.3
163
+ rubyforge_project:
164
+ rubygems_version: 2.7.6.2
163
165
  signing_key:
164
166
  specification_version: 4
165
167
  summary: ecg is an ERB(eRuby) based, simple and powerful configration file generator