kojo 0.3.7 → 0.4.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: f80fdd7c65e0cd8e431e54f2fa32119a1ca2f0557329207481290dd2ed09e241
4
- data.tar.gz: ebcd8acc4d7352efedb02baea82d2a22605141f88c719c9112cfb07c55261889
3
+ metadata.gz: 6fe6f0b9571a1cdd9a808cccaac4dcf5049647d1bc3190702ca45b811421ed61
4
+ data.tar.gz: 7fde526ad1d6efd84a8571c87ef419da1b7f672f06d55982efe68dc487399a29
5
5
  SHA512:
6
- metadata.gz: 68535d8c56fb7a354b1035fbc145093d03e4846ba195c2bf2d1ff03ddf539cf7b9b545a0302d96d34b99d651a7432b8a6ae0697425cd5aba3ea8fd1732e859ab
7
- data.tar.gz: 793ef15e654c1c3b2d1e900bcc5d86a6f8df966bc1d007951b749c61bdb5120b6cc413f18b52728608050429ebe711ed32e75a6c498c21d0dce61b0c0c5c736f
6
+ metadata.gz: e8fc1e607b10197997602db589b6e3ca4f692b7a17118b276fe2e2e5bfe7ee471b6217b3dcaf12f3a5cac85df2d9b50bbc8d2e77a2ccef542e5009a3952546d2
7
+ data.tar.gz: 2ea4b1943f5a6169881bcf4a68071718016041e0aa0a2e0d5a9673ead2eb5653dfa94f77533b320791d2c7fb8338b2cccfa3905b523b2d2a129c829d8ef4732e
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align='center'>
2
2
 
3
- ![kojo](images/kojo.png)
3
+ ![kojo](support/kojo.png)
4
4
 
5
5
  # Kojo Configuration Ninja
6
6
 
@@ -10,8 +10,8 @@
10
10
 
11
11
 
12
12
  Kojo helps you generate configuration files from templates, using variables
13
- and definition files.
14
- It is a command line utility, and it works on any text file format.
13
+ and definition files. It is a command line utility, and works on any text file
14
+ format.
15
15
 
16
16
  </div>
17
17
 
@@ -26,6 +26,7 @@ It is a command line utility, and it works on any text file format.
26
26
  - [Transform an Entire Folder](#transform-an-entire-folder)
27
27
  - [Transform One to Many using Config](#transform-one-to-many-using-config)
28
28
  - [Transform One to Many using Front Matter](#transform-one-to-many-using-front-matter)
29
+ - [Convert YAML to JSON](#convert-yaml-to-json)
29
30
  - [Interactive Form Templates](#interactive-form-templates)
30
31
  - [Conditions and Loops with ERB](#conditions-and-loops-with-erb)
31
32
  - [Interactive Fallback](#interactive-fallback)
@@ -54,7 +55,7 @@ relevant files, and the expected output.
54
55
 
55
56
  ### Variables
56
57
 
57
- ![kojo](images/features-vars.svg)
58
+ ![kojo](support/features-vars.svg)
58
59
 
59
60
  Include variables in your configuration templates by using this syntax:
60
61
  `%{varname}`
@@ -65,9 +66,13 @@ Include variables in your configuration templates by using this syntax:
65
66
  - Variables from the top level will be forwarded downstream, and aggregated
66
67
  with any additional variables that are defined in subsequent `@imports`.
67
68
 
69
+ Note that since the `%` sign is used for variable replacement, if you want
70
+ your generated file to include a literal percent sign, you need to escape it
71
+ as `%%` in your template.
72
+
68
73
  ### Import
69
74
 
70
- ![kojo](images/features-import.svg)
75
+ ![kojo](support/features-import.svg)
71
76
 
72
77
  Use the `@import filename` directive anywhere to include another file in the
73
78
  resulting configuration file.
@@ -84,11 +89,19 @@ resulting configuration file.
84
89
  @import filename (arg: "value", arg2: "value")
85
90
  ```
86
91
 
87
- The space after `filename` is optional.
92
+ The space after `filename` is optional, and the arguments list can be split to
93
+ multiple lines:
94
+
95
+ ```ruby
96
+ @import filename (
97
+ arg: "value",
98
+ arg2: "value"
99
+ )
100
+ ```
88
101
 
89
102
  ### Transform an Entire Folder
90
103
 
91
- ![kojo](images/features-dir.svg)
104
+ ![kojo](support/features-dir.svg)
92
105
 
93
106
  Process a folder containing templates and `@imports`, and generate a mirror
94
107
  output folder, with all the variables and `@imports` evaluated.
@@ -97,7 +110,7 @@ You may use `%{variables}` in filenames.
97
110
 
98
111
  ### Transform One to Many using Config
99
112
 
100
- ![kojo](images/features-config.svg)
113
+ ![kojo](support/features-config.svg)
101
114
 
102
115
  Using the `kojo config` command together with a simple definitions file, you
103
116
  can:
@@ -142,7 +155,7 @@ output:
142
155
 
143
156
  ### Transform One to Many using Front Matter
144
157
 
145
- ![kojo](images/features-single.svg)
158
+ ![kojo](support/features-single.svg)
146
159
 
147
160
  Define a template that contains the instructions on how to transform it as a
148
161
  YAML front matter.
@@ -150,7 +163,7 @@ YAML front matter.
150
163
  The YAML front matter should be structured like this:
151
164
 
152
165
  ```yaml
153
- filename2:
166
+ filename1:
154
167
  arg: value
155
168
  another_arg: value
156
169
 
@@ -165,9 +178,22 @@ Your template that uses %{arg} goes here
165
178
  Additional arguments provided to the command line, will also be transferred
166
179
  to the template.
167
180
 
181
+ ### Convert YAML to JSON
182
+
183
+ ![kojo](support/features-tojson.svg)
184
+
185
+ Convert one or more YAML files to JSON.
186
+
187
+ This can be useful when you require JSON files as output, but wish to edit
188
+ (or generate using Kojo) using the less error-prone and more aesthetically
189
+ pleasing YAML format.
190
+
191
+ Note that this Kojo command does not provide any additional preprocessing - the
192
+ input files should be valid YAML.
193
+
168
194
  ### Interactive Form Templates
169
195
 
170
- ![kojo](images/features-form.svg)
196
+ ![kojo](support/features-form.svg)
171
197
 
172
198
  Using the `kojo form` command lets you define an ERB or [ERBX][erbx] template, and include interactive prompts to enter the input.
173
199
 
@@ -177,11 +203,11 @@ Using the `kojo form` command lets you define an ERB or [ERBX][erbx] template, a
177
203
  4. If there is a file with the same name as the template, and with an `.rb` extension (for example `form.md` and `form.md.rb`), then the ruby file will be loaded into the ERB template as if it was written inside it.
178
204
  5. If you prefer using a single template file (without the ruby appendix), you can simply use regular ERB/ERBX tags, like demonstrated below.
179
205
 
180
- ![kojo](images/features-form-inline.svg)
206
+ ![kojo](support/features-form-inline.svg)
181
207
 
182
208
  ### Conditions and Loops with ERB
183
209
 
184
- ![kojo](images/features-erb.svg)
210
+ ![kojo](support/features-erb.svg)
185
211
 
186
212
  Template files are evaluated using ERB, so you can use any Ruby code for more
187
213
  advanced templates (for conditions, loops etc.).
@@ -197,7 +223,7 @@ Use this syntax for ruby code:
197
223
  When Kojo encounters a variable that was not supplied (either through the command
198
224
  line or through a configuration file), it will prompt for a value.
199
225
 
200
- ![kojo](images/interactive-mode.gif)
226
+ ![kojo](support/interactive-mode.gif)
201
227
 
202
228
  You can enable or disable interactive mode by setting the environment
203
229
  variable `KOJO_INTERACTIVE` to `yes` or `no`.
data/lib/kojo/cli.rb CHANGED
@@ -16,6 +16,7 @@ module Kojo
16
16
  runner.route 'config', to: Kojo::Commands::ConfigCmd
17
17
  runner.route 'single', to: Kojo::Commands::SingleCmd
18
18
  runner.route 'form', to: Kojo::Commands::FormCmd
19
+ runner.route 'tojson', to: Kojo::Commands::ToJsonCmd
19
20
 
20
21
  runner
21
22
  end
@@ -4,9 +4,8 @@ module Kojo
4
4
  module Commands
5
5
  class CommandBase < MisterBin::Command
6
6
  def save(file, output)
7
- outpath = "#{outdir}/#{file}"
8
- File.deep_write outpath, output
9
- say "Saved #{outpath}"
7
+ File.deep_write file, output
8
+ say "Saved #{file}"
10
9
  end
11
10
  end
12
11
  end
@@ -3,7 +3,7 @@ require 'mister_bin'
3
3
 
4
4
  module Kojo::Commands
5
5
  # Handle calls to the +kojo config+ command
6
- class ConfigCmd < MisterBin::Command
6
+ class ConfigCmd < CommandBase
7
7
  using Kojo::Refinements
8
8
 
9
9
  attr_reader :gen, :outdir, :opts, :import_base, :config_file
@@ -33,7 +33,7 @@ module Kojo::Commands
33
33
  argfile = args['--args']
34
34
 
35
35
  if argfile
36
- fileopts = YAML.load_file(argfile).symbolize_keys
36
+ fileopts = YAML.properly_load_file(argfile).symbolize_keys
37
37
  @opts = fileopts.merge opts
38
38
  end
39
39
 
@@ -59,13 +59,5 @@ module Kojo::Commands
59
59
  say output
60
60
  end
61
61
  end
62
-
63
- def save(path, output)
64
- dir = File.dirname path
65
- FileUtils.mkdir_p dir unless Dir.exist? dir
66
- File.write path, output
67
- say "Saved #{path}"
68
- end
69
-
70
62
  end
71
63
  end
@@ -33,7 +33,7 @@ module Kojo
33
33
  argfile = args['--args']
34
34
 
35
35
  if argfile
36
- fileopts = YAML.load_file(argfile).symbolize_keys
36
+ fileopts = YAML.properly_load_file(argfile).symbolize_keys
37
37
  @opts = fileopts.merge @opts
38
38
  end
39
39
 
@@ -62,7 +62,7 @@ module Kojo
62
62
 
63
63
  def write(collection)
64
64
  collection.render @opts do |file, output|
65
- save file, output
65
+ save "#{outdir}/#{file}", output
66
66
  end
67
67
  end
68
68
  end
@@ -3,7 +3,7 @@ require 'mister_bin'
3
3
  module Kojo
4
4
  module Commands
5
5
  # Handle calls to the +kojo file+ command
6
- class FileCmd < MisterBin::Command
6
+ class FileCmd < CommandBase
7
7
  using Kojo::Refinements
8
8
 
9
9
  attr_reader :opts, :outfile, :infile, :import_base
@@ -33,7 +33,7 @@ module Kojo
33
33
  argfile = args['--args']
34
34
 
35
35
  if argfile
36
- fileopts = YAML.load_file(argfile).symbolize_keys
36
+ fileopts = YAML.properly_load_file(argfile).symbolize_keys
37
37
  @opts = fileopts.merge opts
38
38
  end
39
39
 
@@ -48,8 +48,7 @@ module Kojo
48
48
  output = template.render(opts)
49
49
 
50
50
  if outfile
51
- File.write outfile, output
52
- say "Saved #{outfile}"
51
+ save outfile, output
53
52
  else
54
53
  puts output
55
54
  end
@@ -24,8 +24,7 @@ module Kojo
24
24
  template = Kojo::Form.new infile
25
25
 
26
26
  if outfile
27
- File.deep_write outfile, template.render
28
- say "Saved #{outfile}"
27
+ save outfile, template.render
29
28
  else
30
29
  puts template.render
31
30
  end
@@ -46,7 +46,7 @@ module Kojo
46
46
 
47
47
  def write(template)
48
48
  template.render opts do |file, output|
49
- save file, output
49
+ save "#{outdir}/#{file}", output
50
50
  end
51
51
  end
52
52
  end
@@ -0,0 +1,67 @@
1
+ require 'mister_bin'
2
+
3
+ module Kojo
4
+ module Commands
5
+ # Handle calls to the +kojo dir+ command
6
+ class ToJsonCmd < CommandBase
7
+ using Kojo::Refinements
8
+
9
+ attr_reader :input, :save_files, :replace_files
10
+
11
+ help "Convert one or more YAML files to JSON"
12
+
13
+ usage "kojo tojson INPUT... [(--save | --replace)]"
14
+ usage "kojo tojson (-h|--help)"
15
+
16
+ option "-s --save", "Save each input file in the same directory"
17
+ option "-r --replace", "Save each input file in the same directory and delete the input file"
18
+
19
+ param "INPUT", "Path to a YAML file or multiple files using a glob pattern"
20
+
21
+ example "kojo tojson myfile.yaml"
22
+ example "kojo tojson myfile.yaml --save"
23
+ example "kojo tojson indir/*.yaml"
24
+ example "kojo tojson indir/*.yaml --replace"
25
+ example "kojo tojson indir/**/*.yml"
26
+
27
+ def run
28
+ @input = get_input_files
29
+ @save_files = args['--save'] || args['--replace']
30
+ @replace_files = args['--replace']
31
+
32
+ save_files ? write : show
33
+ end
34
+
35
+ private
36
+
37
+ def tojson(path)
38
+ JSON.pretty_generate YAML.properly_load_file(path)
39
+ end
40
+
41
+ # Glob patterns are usually handled by the shell, but in case
42
+ # we still have '*' in our string (for example, if it was sent
43
+ # quoted), we will do the globbing ourselves
44
+ def get_input_files
45
+ args['INPUT'].map do |path|
46
+ path.include?('*') ? Dir[path].sort : path
47
+ end.flatten
48
+ end
49
+
50
+ def show
51
+ input.each do |infile|
52
+ outfile = infile.gsub(/\.ya?ml/, '.json')
53
+ say "\n!txtgrn!# #{outfile}"
54
+ say tojson(infile)
55
+ end
56
+ end
57
+
58
+ def write
59
+ input.each do |infile|
60
+ outfile = infile.gsub(/\.ya?ml/, '.json')
61
+ save outfile, tojson(infile)
62
+ File.delete infile if replace_files
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
data/lib/kojo/config.rb CHANGED
@@ -1,5 +1,3 @@
1
- require 'yaml'
2
-
3
1
  module Kojo
4
2
  # The Config class handles multiple template generation from a
5
3
  # definitions YAML file.
@@ -61,7 +59,7 @@ module Kojo
61
59
  end
62
60
 
63
61
  def config
64
- @config ||= YAML.load_file config_file
62
+ @config ||= YAML.properly_load_file config_file
65
63
  end
66
64
  end
67
65
 
@@ -0,0 +1,10 @@
1
+ require 'yaml'
2
+
3
+ module YAML
4
+ # ref: https://bugs.ruby-lang.org/issues/17866
5
+ def self.properly_load_file(path)
6
+ YAML.load_file path, aliases: true
7
+ rescue ArgumentError
8
+ YAML.load_file path
9
+ end
10
+ end
@@ -1,5 +1,3 @@
1
- require 'yaml'
2
-
3
1
  module Kojo
4
2
  # The FrontMatterTemplate class handles a single template file, that
5
3
  # contains a YAML front matter.
@@ -34,7 +32,7 @@ module Kojo
34
32
  def read_file(file)
35
33
  raise Kojo::NotFoundError, "File not found: #{file}" unless File.exist? file
36
34
 
37
- config = YAML.load_file file
35
+ config = YAML.properly_load_file file
38
36
  content = File.read(file)[/^---\s*$\n(.*)/m, 1]
39
37
 
40
38
  [config, content]
@@ -46,6 +46,12 @@ module Kojo
46
46
  raise Kojo::TemplateError, "#{e.message}\nin: #{filename}"
47
47
  end
48
48
 
49
+ def compress_imports
50
+ gsub /^ *@import +[^(\s]+\s*\([\S\s]*?\) *$/ do |match|
51
+ match.gsub /\r?\n\s*/, " "
52
+ end
53
+ end
54
+
49
55
  private
50
56
 
51
57
  def get_user_input
@@ -57,7 +63,7 @@ module Kojo
57
63
  end
58
64
 
59
65
  def erb(template, vars)
60
- ERB.new(template, nil, '-').result(OpenStruct.new(vars).instance_eval { binding })
66
+ ERB.new(template, trim_mode: '-').result(OpenStruct.new(vars).instance_eval { binding })
61
67
  end
62
68
 
63
69
  end
data/lib/kojo/template.rb CHANGED
@@ -38,8 +38,8 @@ module Kojo
38
38
 
39
39
  def eval_imports(content)
40
40
  result = []
41
-
42
- content.lines.each do |line|
41
+
42
+ content.compress_imports.lines.each do |line|
43
43
  line.chomp!
44
44
  spaces = line[/^\s*/].size
45
45
 
data/lib/kojo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Kojo
2
- VERSION = "0.3.7"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/kojo.rb CHANGED
@@ -1,8 +1,11 @@
1
1
  require 'requires'
2
2
  require 'byebug' if ENV['BYEBUG']
3
3
 
4
- requires 'kojo/refinements'
4
+ require 'yaml'
5
+ require 'json'
6
+
5
7
  requires 'kojo/extensions'
8
+ requires 'kojo/refinements'
6
9
 
7
10
  require 'kojo/exceptions'
8
11
  require 'kojo/template'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kojo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.7
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-18 00:00:00.000000000 Z
11
+ date: 2022-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mister_bin
@@ -99,9 +99,11 @@ files:
99
99
  - lib/kojo/commands/file.rb
100
100
  - lib/kojo/commands/form.rb
101
101
  - lib/kojo/commands/single.rb
102
+ - lib/kojo/commands/to_json.rb
102
103
  - lib/kojo/config.rb
103
104
  - lib/kojo/exceptions.rb
104
105
  - lib/kojo/extensions/file.rb
106
+ - lib/kojo/extensions/yaml.rb
105
107
  - lib/kojo/form.rb
106
108
  - lib/kojo/front_matter_template.rb
107
109
  - lib/kojo/refinements/array.rb
@@ -121,14 +123,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
121
123
  requirements:
122
124
  - - ">="
123
125
  - !ruby/object:Gem::Version
124
- version: 2.5.0
126
+ version: 2.6.0
125
127
  required_rubygems_version: !ruby/object:Gem::Requirement
126
128
  requirements:
127
129
  - - ">="
128
130
  - !ruby/object:Gem::Version
129
131
  version: '0'
130
132
  requirements: []
131
- rubygems_version: 3.1.2
133
+ rubygems_version: 3.2.15
132
134
  signing_key:
133
135
  specification_version: 4
134
136
  summary: Configuration Ninja