ecg 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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