djin 0.9.0 → 0.10.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: e763f1dad923699c768e998f4dd5caa53ac7a8b0ad4d7acd84c708effdcb627c
4
- data.tar.gz: 9ab841b39557b775ec7832a3c1cd0befaf983e89ba931459b89a52d5a5df0bda
3
+ metadata.gz: 5e44393cb2f47b9b3a68d2ce59ae997e5e1d6b252e68778293b5e62a7600374b
4
+ data.tar.gz: 5c02ed7dc956357e31b07c6ade84c5f660cb26469f7434ea0128b42f0ebec74f
5
5
  SHA512:
6
- metadata.gz: e22bc8b7d3deb635180db1d5c49f1e7d5df1eef3f1b4184b13d65b24eaa45b6f716edfae1bb4799abfe4d4255387958f5f078d931c72cf0b5e407abf9d85ee51
7
- data.tar.gz: e603ff5f1bab170ed9758331e7c64e39f1832424fc2c0e069aeef2ce85372081ccc15e1a2080cae3c5edc4c8d8fd1286643e4aaa02616249f7173c6d660ffcf2
6
+ metadata.gz: 1d8d9dbd993757586e35679c12e1d03b98c940e5bca58e6ab2b3b8955c84c78b2fad6ae2053a0430b85aa580217a8540b3196ab3489c0ae76c4426e712142822
7
+ data.tar.gz: be25638d743e46c62a452891298003d3dd93905ea38b6bbe51420d44549ba001785f7b9a631cc4e4b83c61ffa541688420df9bd9339023b1cb86747ad2ae87c4
@@ -1,3 +1,6 @@
1
+ ## 0.10.0 - 08/10/2020
2
+ * [FEATURE] -f command option
3
+
1
4
  ## 0.9.0 - 17/09/2020
2
5
  * [FEATURE] Include Option
3
6
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- djin (0.9.0)
4
+ djin (0.10.0)
5
5
  dry-cli (~> 0.6.0)
6
6
  dry-equalizer (~> 0.3.0)
7
7
  dry-struct (~> 1.3.0)
@@ -29,12 +29,12 @@ GEM
29
29
  concurrent-ruby (~> 1.0)
30
30
  dry-equalizer (0.3.0)
31
31
  dry-inflector (0.2.0)
32
- dry-initializer (3.0.3)
33
- dry-logic (1.0.7)
32
+ dry-initializer (3.0.4)
33
+ dry-logic (1.0.8)
34
34
  concurrent-ruby (~> 1.0)
35
35
  dry-core (~> 0.2)
36
36
  dry-equalizer (~> 0.2)
37
- dry-schema (1.5.4)
37
+ dry-schema (1.5.5)
38
38
  concurrent-ruby (~> 1.0)
39
39
  dry-configurable (~> 0.8, >= 0.8.3)
40
40
  dry-core (~> 0.4)
data/README.md CHANGED
@@ -26,7 +26,7 @@ If you use Rbenv you can install djin only once and create a alias in your .basr
26
26
  To use djin first you need to create a djin.yml file:
27
27
 
28
28
  ```yaml
29
- djin_version: '0.9.0'
29
+ djin_version: '0.10.0'
30
30
 
31
31
  tasks:
32
32
  # With a docker image
@@ -53,7 +53,7 @@ You can also set task dependencies with depends_on option:
53
53
 
54
54
 
55
55
  ```yaml
56
- djin_version: '0.9.0'
56
+ djin_version: '0.10.0'
57
57
 
58
58
  _default_run_options: &default_run_options
59
59
  options: "--rm"
@@ -82,7 +82,7 @@ tasks:
82
82
  Or mix local commands and docker/docker-compose commands:
83
83
 
84
84
  ```yaml
85
- djin_version: '0.9.0'
85
+ djin_version: '0.10.0'
86
86
 
87
87
  _default_run_options: &default_run_options
88
88
  options: "--rm"
@@ -121,7 +121,7 @@ After that you can run `djin {{task_name}}`, like `djin script` or `djin test`
121
121
  You can also use environment variables using the '{{YOUR_ENV_HERE}}' syntax, like so:
122
122
 
123
123
  ```yaml
124
- djin_version: '0.9.0'
124
+ djin_version: '0.10.0'
125
125
 
126
126
  _default_run_options: &default_run_options
127
127
  options: "--rm"
@@ -138,7 +138,7 @@ tasks:
138
138
 
139
139
  Or define some variables to use in multiple locations
140
140
  ```yaml
141
- djin_version: '0.9.0'
141
+ djin_version: '0.10.0'
142
142
 
143
143
  _default_run_options: &default_run_options
144
144
  options: "--rm"
@@ -162,7 +162,7 @@ tasks:
162
162
  It's also possible to pass custom arguments to the command, which means is possible to make a djin task act like the command itself:
163
163
 
164
164
  ```yaml
165
- djin_version: '0.9.0'
165
+ djin_version: '0.10.0'
166
166
 
167
167
  _default_run_options: &default_run_options
168
168
  options: "--rm"
@@ -188,7 +188,7 @@ Under the hood djin uses [Mustache](https://mustache.github.io/), so you can use
188
188
  If you have multiple tasks with similar behaviour and with small differences you can use the `include` keyword, so this:
189
189
 
190
190
  ```yaml
191
- djin_version: '0.9.0'
191
+ djin_version: '0.10.0'
192
192
 
193
193
  tasks:
194
194
  "host1:ssh":
@@ -227,7 +227,7 @@ can become this:
227
227
 
228
228
  ```yaml
229
229
  # djin.yml
230
- djin_version: '0.9.0'
230
+ djin_version: '0.10.0'
231
231
 
232
232
  include:
233
233
  - file: '.djin/server_tasks.yml'
@@ -249,7 +249,7 @@ include:
249
249
 
250
250
  ```yaml
251
251
  # .djin/server_tasks.yml
252
- djin_version: '0.9.0'
252
+ djin_version: '0.10.0'
253
253
 
254
254
  tasks:
255
255
  "{{namespace}}:ssh":
@@ -268,15 +268,37 @@ tasks:
268
268
  - ssh -t {{ssh_user}}@{{host}} tail -f /var/log/my_log
269
269
  ```
270
270
 
271
+ ### Loading custom files
272
+
273
+ You can also specify a file to be read by djin with `-f`, eg:
274
+
275
+ ```bash
276
+ djin -f my_file.yml # Returns the help for all tasks in my_file
277
+ djin -f my_file.yml build # Execute the build task defined in my_file.yml
278
+ ```
279
+
280
+ You can also specify multiple files to join tasks between files:
281
+
282
+ ```bash
283
+ # Mix the tasks
284
+ djin -f my_file.yml -f my_file2.yml # Returns the help for all tasks in my_file
285
+ djin -f my_file.yml -f my_file2.yml build # Execute the build task defined in my_file.yml or my_file2.yml
286
+ ```
287
+
288
+
271
289
  ## Development
272
290
 
273
291
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
274
292
 
275
293
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, run `djin release -- {{increment_option}}` (where {{incremment_option}} can be `--patch`, `--minor` or `major`), which will change version, update the CHANGELOG.md, create a new commit, create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
276
294
 
277
- ## TODO:
278
295
 
279
- 1. Adds a `-f` option to load custom djin files
296
+ ## TODO
297
+
298
+ 1. Enable multiple -f options to merge configuration between files
299
+ 2. Option to export tasks to Makefile
300
+ 3. djin-export docker image to create and sync makefiles
301
+ 4. include key option to add tasks in git repositories files (maybe with a local cache)
280
302
 
281
303
  ## Contributing
282
304
 
data/Vertofile CHANGED
@@ -28,12 +28,15 @@ context(branch('master')) {
28
28
  file('CHANGELOG.md').prepend(version_changes)
29
29
  git!('add CHANGELOG.md')
30
30
 
31
- file('lib/djin/version.rb').replace(latest_version.to_s, new_version.to_s)
32
- file('djin.yml').replace(latest_version.to_s, new_version.to_s)
33
- file('examples/djin.yml').replace(latest_version.to_s, new_version.to_s)
31
+ files_to_change_version_once = %w[lib/djin/version.rb djin.yml] + Dir['examples/**/*.yml'] + Dir['spec/support/fixtures/**/*.yml']
32
+
33
+ files_to_change_version_once.each do |filename|
34
+ file(filename).replace(latest_version.to_s, new_version.to_s)
35
+ end
36
+
34
37
  file('README.md').replace_all(latest_version.to_s, new_version.to_s)
35
38
 
36
- git!('add lib/djin/version.rb djin.yml examples/djin.yml README.md')
39
+ git!("add #{files_to_change_version_once.join(' ')} README.md")
37
40
 
38
41
  sh!('bundle install')
39
42
  sh!('rake install')
data/djin.yml CHANGED
@@ -1,4 +1,4 @@
1
- djin_version: '0.9.0'
1
+ djin_version: '0.10.0'
2
2
 
3
3
  _default_run_options: &default_run_options
4
4
  options: "--rm --entrypoint=''"
@@ -1,5 +1,5 @@
1
1
  ---
2
- djin_version: '0.9.0'
2
+ djin_version: '0.10.0'
3
3
 
4
4
  include:
5
5
  - file: 'djin_lib/test.yml'
@@ -1,4 +1,4 @@
1
- djin_version: '0.9.0'
1
+ djin_version: '0.10.0'
2
2
 
3
3
  _default_run_options: &default_run_options
4
4
  options: "--rm --entrypoint=''"
@@ -1,4 +1,4 @@
1
- djin_version: '0.9.0'
1
+ djin_version: '0.10.0'
2
2
 
3
3
  include:
4
4
  - file: '.djin/server_tasks.yml'
@@ -8,7 +8,9 @@ require 'dry-validation'
8
8
  require 'vseries'
9
9
  require 'dry/cli'
10
10
  require 'mustache'
11
+ require 'optparse'
11
12
  require 'djin/extensions/hash_extensions'
13
+ require 'djin/extensions/object_extensions'
12
14
  require 'djin/entities/types'
13
15
  require 'djin/entities/task'
14
16
  require 'djin/entities/file_config'
@@ -19,6 +21,7 @@ require 'djin/interpreter/local_command_builder'
19
21
  require 'djin/interpreter'
20
22
  require 'djin/config_loader'
21
23
  require 'djin/executor'
24
+ require 'djin/root_cli_parser'
22
25
  require 'djin/cli'
23
26
  require 'djin/task_contract'
24
27
  require 'djin/repositories/task_repository'
@@ -27,10 +30,12 @@ require 'djin/memory_cache'
27
30
  module Djin
28
31
  class Error < StandardError; end
29
32
 
30
- def self.load_tasks!(file_path = Pathname.getwd.join('djin.yml'))
31
- abort 'Error: djin.yml not found' unless file_path.exist?
33
+ using Djin::ObjectExtensions
32
34
 
33
- file_config = ConfigLoader.load!(file_path)
35
+ def self.load_tasks!(*file_paths)
36
+ files = file_paths.presence || RootCliParser.parse![:files] || ['djin.yml']
37
+
38
+ file_config = ConfigLoader.load_files!(*files)
34
39
 
35
40
  # TODO: Make all tasks be under 'tasks' key, passing only the tasks here
36
41
  tasks = Interpreter.load!(file_config)
@@ -28,6 +28,16 @@ module Djin
28
28
  end
29
29
  end
30
30
 
31
+ class File < Dry::CLI::Command
32
+ desc 'Specify a djin file to load (default: djin.yml)'
33
+ argument :filepath, required: true, desc: 'The file path to load'
34
+
35
+ def call(filename:, **)
36
+ # The actual behaviour is on RootCliParser
37
+ end
38
+ end
39
+
40
+ register '-f', File, aliases: ['--file']
31
41
  register '--version', Version, aliases: ['-v']
32
42
  end
33
43
  end
@@ -8,13 +8,26 @@ module Djin
8
8
  using Djin::HashExtensions
9
9
  RESERVED_WORDS = %w[djin_version variables tasks include].freeze
10
10
 
11
- def self.load!(template_file, runtime_config: {})
12
- new(template_file, runtime_config: runtime_config).load!
11
+ # CHange Base Error
12
+ FileNotFoundError = Class.new(Interpreter::InvalidConfigurationError)
13
+
14
+ def self.load_files!(*files, runtime_config: {}, base_directory: '.')
15
+ files.map do |file_path|
16
+ ConfigLoader.load!(file_path, runtime_config: runtime_config, base_directory: base_directory)
17
+ end&.reduce(:deep_merge)
18
+ end
19
+
20
+ def self.load!(template_file_path, runtime_config: {}, base_directory: '.')
21
+ new(template_file_path, runtime_config: runtime_config, base_directory: base_directory).load!
13
22
  end
14
23
 
15
- def initialize(template_file, runtime_config: {})
16
- @template_file = template_file
17
- @template_file_content = Djin.cache.fetch(template_file.realpath.to_s) { template_file.read }
24
+ def initialize(template_file_path, runtime_config: {}, base_directory: '.')
25
+ @base_directory = Pathname.new(base_directory)
26
+ @template_file = @base_directory.join(template_file_path)
27
+
28
+ raise FileNotFoundError, "File '#{@template_file}' not found" unless @template_file.exist?
29
+
30
+ @template_file_content = Djin.cache.fetch(@template_file.realpath.to_s) { @template_file.read }
18
31
  @runtime_config = runtime_config
19
32
  end
20
33
 
@@ -83,12 +96,9 @@ module Djin
83
96
 
84
97
  def included_config
85
98
  @included_config ||= raw_djin_config['include']&.map do |tasks_reference|
86
- external_config_file = Pathname.new(tasks_reference['file'])
87
-
88
- ConfigLoader.load!(external_config_file, runtime_config: tasks_reference['context'] || {})
99
+ ConfigLoader.load!(tasks_reference['file'], base_directory: @template_file.dirname,
100
+ runtime_config: tasks_reference['context'] || {})
89
101
  end&.reduce(:deep_merge)
90
- rescue Errno::ENOENT => e
91
- raise Interpreter::InvalidConfigFileError, e.message
92
102
  end
93
103
 
94
104
  def args
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Djin
4
+ module ObjectExtensions
5
+ refine Object do
6
+ def presence(default = nil)
7
+ present? ? self : default
8
+ end
9
+
10
+ def present?
11
+ !blank?
12
+ end
13
+
14
+ def blank?
15
+ return true unless self
16
+
17
+ # TODO: Improve Validations
18
+ return empty? if respond_to?(:empty?)
19
+
20
+ false
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Djin
4
+ ## This class is responsible to handle options that must be evaluated
5
+ # before the load of tasks in djin file(eg: djin.yml)
6
+ class RootCliParser
7
+ class << self
8
+ def parse!(args = ARGV)
9
+ options = {}
10
+
11
+ # TODO: Find a better way to handle -f/--file option,
12
+ # throw, catch and delete in ARGV are necessary
13
+ # to only remove the -f/--file option
14
+ # and bypass everything else to Dry::CLI
15
+ catch(:root_cli_exit) do
16
+ OptionParser.new do |opts|
17
+ opts.on('-f FILE', '--file FILE') do |v|
18
+ options[:files] ||= []
19
+ options[:files] << v
20
+ end
21
+
22
+ opts.on('-h', '--help') do
23
+ throw :root_cli_exit
24
+ end
25
+ end.parse(args)
26
+ end
27
+
28
+ remove_file_args!(args)
29
+ options
30
+ end
31
+
32
+ def remove_file_args!(args)
33
+ file_option = ['-f', '--file']
34
+ args_indexes_to_remove = args.each_with_index.map do |value, index|
35
+ index if (file_option.include?(args[index - 1]) && index.positive?) || file_option.include?(value)
36
+ end.compact
37
+
38
+ args_indexes_to_remove.reverse.each { |index| args.delete_at(index) }
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Djin
4
- VERSION = '0.9.0'
4
+ VERSION = '0.10.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: djin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carlos Atkinson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-17 00:00:00.000000000 Z
11
+ date: 2020-10-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-cli
@@ -204,6 +204,7 @@ files:
204
204
  - lib/djin/entities/types.rb
205
205
  - lib/djin/executor.rb
206
206
  - lib/djin/extensions/hash_extensions.rb
207
+ - lib/djin/extensions/object_extensions.rb
207
208
  - lib/djin/interpreter.rb
208
209
  - lib/djin/interpreter/base_command_builder.rb
209
210
  - lib/djin/interpreter/docker_command_builder.rb
@@ -211,6 +212,7 @@ files:
211
212
  - lib/djin/interpreter/local_command_builder.rb
212
213
  - lib/djin/memory_cache.rb
213
214
  - lib/djin/repositories/task_repository.rb
215
+ - lib/djin/root_cli_parser.rb
214
216
  - lib/djin/task_contract.rb
215
217
  - lib/djin/version.rb
216
218
  homepage: https://github.com/catks/djin