djin 0.9.0 → 0.10.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: 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