djin 0.5.0 → 0.6.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: a40e01844f1a9b034d592696cf6af915622c834a9e231f0c56209c03d11660ad
4
- data.tar.gz: facbe98a7362ec81b5f819af27a554807790a1445c7cc47161a85d5f0d5b7276
3
+ metadata.gz: 35900c4ab60e94710d24194ea2192edbf4e806527af87fe9d53e693bcec03704
4
+ data.tar.gz: 53a1b1caabf4ff2e7a708fa1e31ccd7b552514cc6eb882d7152ba015bb58db01
5
5
  SHA512:
6
- metadata.gz: 72f5ea393c498311acf74a482b02670d94f11704a75032e31e914e68b947de694bec077ba03e22b75fd73c9307f9f98242ea35009f5341c2ab9b3d1af0314901
7
- data.tar.gz: 4bf6650c80d7defc1dd3b2850c21b74c54ecdb7f4dd374c0a98dd3bfe2610c7175f7102a71de53d6367a4dfd1fcdae47437a2db24bee83bc1c195a4c0fea9da7
6
+ metadata.gz: 3cb346575e3426446ad0c2ea2043d386a6112b9414d84927b24a5f0e3dec6062c361a9a6f0910c34fb13819d978d1721d882f53fe36fcf4a5aa5231eac4b6cc3
7
+ data.tar.gz: 34888b78f7f7af5792fc75f373870792d41986f818bfef643ad8d27f954b9f5e92791226c282933e0f3d7fa57acc42a0f71838df45acff47d48b424d53c24051
@@ -1,3 +1,6 @@
1
+ ## 0.6.0 - 22/07/2020
2
+ * [FEATURE] Djin Variables
3
+
1
4
  ## 0.5.0 - 13/07/2020
2
5
  * [FEATURE] Adds local command task
3
6
  * [FEATURE] Template Args for entire djin.yml
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- djin (0.5.0)
4
+ djin (0.6.0)
5
5
  dry-cli (~> 0.6.0)
6
6
  dry-struct (~> 1.3.0)
7
7
  dry-validation (~> 1.5.1)
@@ -53,7 +53,7 @@ GEM
53
53
  dry-equalizer (~> 0.3)
54
54
  dry-inflector (~> 0.1, >= 0.1.2)
55
55
  dry-logic (~> 1.0, >= 1.0.2)
56
- dry-validation (1.5.1)
56
+ dry-validation (1.5.2)
57
57
  concurrent-ruby (~> 1.0)
58
58
  dry-container (~> 0.7, >= 0.7.1)
59
59
  dry-core (~> 0.4)
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Djin
2
2
 
3
3
  ![](https://github.com/catks/djin/workflows/Ruby/badge.svg?branch=master)
4
+ [![Maintainability](https://api.codeclimate.com/v1/badges/824a2e78399813543212/maintainability)](https://codeclimate.com/github/catks/djin/maintainability)
4
5
 
5
6
  Djin is a make-like utility for docker containers
6
7
 
@@ -25,139 +26,164 @@ If you use Rbenv you can install djin only once and create a alias in your .basr
25
26
  To use djin first you need to create a djin.yml file:
26
27
 
27
28
  ```yaml
28
- djin_version: '0.5.0'
29
-
30
- # With a docker image
31
- script:
32
- docker:
33
- image: "ruby:2.6"
34
- run:
35
- commands:
36
- - "ruby /scripts/my_ruby_script.rb"
37
- options: "--rm -v $(pwd)/my_ruby_script.rb:/scripts/my_ruby_script.rb"
38
-
39
- # Using a docker-compose service
40
- test:
29
+ djin_version: '0.6.0'
30
+
31
+ tasks:
32
+ # With a docker image
33
+ script:
34
+ docker:
35
+ image: "ruby:2.6"
36
+ run:
37
+ commands:
38
+ - "ruby /scripts/my_ruby_script.rb"
39
+ options: "--rm -v $(pwd)/my_ruby_script.rb:/scripts/my_ruby_script.rb"
40
+
41
+ # Using a docker-compose service
42
+ test:
41
43
  docker-compose:
42
44
  service: app
43
45
  run:
44
46
  commands: rspec
45
47
  options: "--rm"
46
-
47
48
  ```
48
49
 
49
50
  You can also set task dependencies with depends_on option:
50
51
 
51
52
 
52
53
  ```yaml
53
- djin_version: '0.5.0'
54
+ djin_version: '0.6.0'
54
55
 
55
56
  _default_run_options: &default_run_options
56
57
  options: "--rm"
57
58
 
58
- "db:create":
59
- docker-compose:
60
- service: app
61
- run:
62
- commands: rake db:create
63
- <<: *default_run_options
64
-
65
- "db:migrate":
66
- docker-compose:
67
- service: app
68
- run:
69
- commands: rake db:migrate
70
- <<: *default_run_options
71
-
72
- "db:setup":
73
- depends_on:
74
- - "db:create"
75
- - "db:migrate"
76
-
59
+ tasks:
60
+ "db:create":
61
+ docker-compose:
62
+ service: app
63
+ run:
64
+ commands: rake db:create
65
+ <<: *default_run_options
66
+
67
+ "db:migrate":
68
+ docker-compose:
69
+ service: app
70
+ run:
71
+ commands: rake db:migrate
72
+ <<: *default_run_options
73
+
74
+ "db:setup":
75
+ depends_on:
76
+ - "db:create"
77
+ - "db:migrate"
77
78
  ```
78
79
 
79
80
  Or mix local commands and docker/docker-compose commands:
80
81
 
81
82
  ```yaml
82
- djin_version: '0.5.0'
83
+ djin_version: '0.6.0'
83
84
 
84
85
  _default_run_options: &default_run_options
85
86
  options: "--rm"
86
87
 
87
- "db:create":
88
- docker-compose:
89
- service: app
90
- run:
91
- commands: rake db:create
92
- <<: *default_run_options
88
+ tasks:
89
+ "db:create":
90
+ docker-compose:
91
+ service: app
92
+ run:
93
+ commands: rake db:create
94
+ <<: *default_run_options
95
+
96
+ "db:migrate":
97
+ docker-compose:
98
+ service: app
99
+ run:
100
+ commands: rake db:migrate
101
+ <<: *default_run_options
102
+
103
+ "setup:copy_samples":
104
+ local:
105
+ run:
106
+ - cp config/database.yml.sample config/database.yml
107
+
108
+ "setup":
109
+ depends_on:
110
+ - "setup:copy_samples"
111
+ - "db:create"
112
+ - "db:migrate"
113
+ ```
93
114
 
94
- "db:migrate":
95
- docker-compose:
96
- service: app
97
- run:
98
- commands: rake db:migrate
99
- <<: *default_run_options
115
+ After that you can run `djin {{task_name}}`, like `djin script` or `djin test`
100
116
 
101
- "setup:copy_samples":
102
- local:
103
- run:
104
- - cp config/database.yml.sample config/database.yml
117
+ ## Using Environment variables, custom variables and custom args in djin.yml tasks
105
118
 
106
- "setup":
107
- depends_on:
108
- - "setup:copy_samples"
109
- - "db:create"
110
- - "db:migrate"
119
+ You can also use environment variables using the '{{YOUR_ENV_HERE}}' syntax, like so:
111
120
 
112
- ```
121
+ ```yaml
122
+ djin_version: '0.6.0'
113
123
 
114
- After that you can run `djin {{task_name}}`, like `djin script` or `djin test`
124
+ _default_run_options: &default_run_options
125
+ options: "--rm"
115
126
 
116
- ## Using Environment variables and custom args in djin.yml run tasks
127
+ tasks:
128
+ "db:migrate":
129
+ docker-compose:
130
+ service: app
131
+ run:
132
+ commands: ENV={{ENV}} rake db:migrate
133
+ <<: *default_run_options
117
134
 
118
- You can also use environment variables using the '{{YOUR_ENV_HERE}}' syntax, like so:
135
+ ```
119
136
 
137
+ Or define some variables to use in multiple locations
120
138
  ```yaml
121
- djin_version: '0.5.0'
139
+ djin_version: '0.6.0'
122
140
 
123
141
  _default_run_options: &default_run_options
124
142
  options: "--rm"
125
143
 
126
- "db:migrate":
127
- docker-compose:
128
- service: app
129
- run:
130
- commands: ENV={{ENV}} rake db:migrate
131
- <<: *default_run_options
144
+ variables:
145
+ my_ssh_user: user
146
+ some_host: test.local
132
147
 
148
+ tasks:
149
+ "some_host:ssh":
150
+ local:
151
+ run:
152
+ - ssh {{my_ssh_user}}@{{some_host}}
153
+
154
+ "some_host:logs":
155
+ local:
156
+ run:
157
+ - ssh -t {{my_ssh_user}}@{{some_host}} 'tail -f /var/log/syslog'
133
158
  ```
134
159
 
135
- It's also possible to pass custom arguments to the command, wich means is possible to make a djin task act like the command itself:
160
+ 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:
136
161
 
137
162
  ```yaml
138
- djin_version: '0.5.0'
163
+ djin_version: '0.6.0'
139
164
 
140
165
  _default_run_options: &default_run_options
141
166
  options: "--rm"
142
167
 
143
- "rubocop":
144
- docker-compose:
145
- service: app
146
- run:
147
- commands: rubocop {{args}}
148
- <<: *default_run_options
168
+ tasks:
169
+ "rubocop":
170
+ docker-compose:
171
+ service: app
172
+ run:
173
+ commands: rubocop {{args}}
174
+ <<: *default_run_options
149
175
 
150
176
  ```
151
177
 
152
178
  With that you can pass custom args after `--`, eg: `djin rubocop -- --parallel`, which wil make djin runs `rubocop --parallel` inside the service `app`.
153
179
 
154
- Under the hood djin uses [Mustache](https://mustache.github.io/), so you can use other features like conditionals: `{{#IS_ENABLE}} Enabled {{/IS_ENABLE}}` (for args use the `args?`, eg: {{#args} {{args}} --and-other-thing{{/args?}}), to see more more options you can access this [Link](https://mustache.github.io/mustache.5.html)
180
+ Under the hood djin uses [Mustache](https://mustache.github.io/), so you can use other features like conditionals: `{{#IS_ENABLE}} Enabled {{/IS_ENABLE}}` (for args use the `args?`, eg: `{{#args?} {{args}} --and-other-thing{{/args?}}`), to see more more options you can access this [Link](https://mustache.github.io/mustache.5.html)
155
181
 
156
182
  ## Development
157
183
 
158
184
  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.
159
185
 
160
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
186
+ 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).
161
187
 
162
188
  ## TODO:
163
189
 
data/djin.yml CHANGED
@@ -1,33 +1,31 @@
1
- djin_version: '0.5.0'
1
+ djin_version: '0.6.0'
2
2
 
3
3
  _default_run_options: &default_run_options
4
4
  options: "--rm --entrypoint=''"
5
5
 
6
- test:
7
- docker-compose:
8
- service: app
9
- run:
10
- commands: "cd /usr/src/djin && rspec {{args}}"
11
- <<: *default_run_options
12
-
13
- sh:
14
- docker-compose:
15
- service: app
16
- run:
17
- commands: "sh"
18
- <<: *default_run_options
19
- run:
20
- docker-compose:
21
- service: app
22
- run:
23
- commands: "sh -c '{{args}}'"
24
- <<: *default_run_options
25
-
26
- release:
27
- local:
28
- run:
29
- - verto tag up {{args}}
30
- - rake release
31
-
6
+ tasks:
7
+ test:
8
+ docker-compose:
9
+ service: app
10
+ run:
11
+ commands: "cd /usr/src/djin && rspec {{args}}"
12
+ <<: *default_run_options
32
13
 
14
+ sh:
15
+ docker-compose:
16
+ service: app
17
+ run:
18
+ commands: "sh"
19
+ <<: *default_run_options
20
+ run:
21
+ docker-compose:
22
+ service: app
23
+ run:
24
+ commands: "sh -c '{{args}}'"
25
+ <<: *default_run_options
33
26
 
27
+ release:
28
+ local:
29
+ run:
30
+ - verto tag up {{args}}
31
+ - bundle exec rake release
@@ -1,29 +1,29 @@
1
1
  ---
2
- djin_version: '0.5.0'
2
+ djin_version: '0.6.0'
3
3
 
4
- default:
5
- docker:
6
- image: "ruby:2.5"
7
- run:
8
- - "ruby -e 'puts \\\" Hello\\\"'"
9
- test:
10
- docker-compose:
11
- service: app
12
- run:
13
- commands: rspec
14
- options: "--rm"
4
+ tasks:
5
+ default:
6
+ docker:
7
+ image: "ruby:2.5"
8
+ run:
9
+ - "ruby -e 'puts \\\" Hello\\\"'"
10
+ test:
11
+ docker-compose:
12
+ service: app
13
+ run:
14
+ commands: rspec
15
+ options: "--rm"
15
16
 
16
- script:
17
- docker:
18
- image: "ruby:2.6"
19
- run:
20
- commands:
21
- - "ruby /scripts/my_ruby_script.rb"
22
- options: "--rm -v $(pwd)/my_ruby_script.rb:/scripts/my_ruby_script.rb"
17
+ script:
18
+ docker:
19
+ image: "ruby:2.6"
20
+ run:
21
+ commands:
22
+ - "ruby /scripts/my_ruby_script.rb"
23
+ options: "--rm -v $(pwd)/my_ruby_script.rb:/scripts/my_ruby_script.rb"
23
24
 
24
-
25
- with_build:
26
- docker:
27
- build: .
28
- run:
29
- - "ruby -e 'puts \" Hello\"'"
25
+ with_build:
26
+ docker:
27
+ build: .
28
+ run:
29
+ - "ruby -e 'puts \" Hello\"'"
@@ -16,7 +16,7 @@ require 'djin/interpreter/docker_command_builder'
16
16
  require 'djin/interpreter/docker_compose_command_builder'
17
17
  require 'djin/interpreter/local_command_builder'
18
18
  require 'djin/interpreter'
19
- require 'djin/template_renderer'
19
+ require 'djin/config_loader'
20
20
  require 'djin/executor'
21
21
  require 'djin/cli'
22
22
  require 'djin/task_contract'
@@ -28,9 +28,9 @@ module Djin
28
28
  def self.load_tasks!(path = Pathname.getwd.join('djin.yml'))
29
29
  abort 'Error: djin.yml not found' unless path.exist?
30
30
 
31
- rendered_djin_file = TemplateRenderer.render(path.read)
32
- djin_config = YAML.safe_load(rendered_djin_file, [], [], true)
31
+ djin_config = ConfigLoader.load!(path.read)
33
32
 
33
+ # TODO: Make all tasks be under 'tasks' key, passing only the tasks here
34
34
  tasks = Interpreter.load!(djin_config)
35
35
 
36
36
  @task_repository = TaskRepository.new(tasks)
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Djin
4
+ # TODO: Refactor this class to be the Interpreter
5
+ # class and use the current interpreter as
6
+ # a TaskLoader
7
+ class ConfigLoader
8
+ using Djin::HashExtensions
9
+ RESERVED_WORDS = %w[djin_version variables tasks].freeze
10
+
11
+ def self.load!(template_file)
12
+ new(template_file).load!
13
+ end
14
+
15
+ def initialize(template_file)
16
+ @template_file = template_file
17
+ end
18
+
19
+ def load!
20
+ validate_version!
21
+
22
+ # TODO: Return a DjinConfig Entity
23
+ tasks
24
+ end
25
+
26
+ private
27
+
28
+ def raw_djin_config
29
+ @raw_djin_config ||= yaml_load(@template_file)
30
+ end
31
+
32
+ def rendered_djin_config
33
+ @rendered_djin_config ||= begin
34
+ locals = env.merge(variables)
35
+
36
+ rendered_yaml = Mustache.render(@template_file,
37
+ args: args.join(' '),
38
+ args?: args.any?,
39
+ **locals)
40
+ yaml_load(rendered_yaml)
41
+ end
42
+ end
43
+
44
+ def version
45
+ # TODO: Deprecates djin_version and use version instead
46
+ @version || raw_djin_config['djin_version']
47
+ end
48
+
49
+ def variables
50
+ @variables ||= raw_djin_config['variables']&.symbolize_keys || {}
51
+ end
52
+
53
+ def tasks
54
+ rendered_djin_config['tasks'] || legacy_tasks
55
+ end
56
+
57
+ def legacy_tasks
58
+ warn '[DEPRECATED] Root tasks are deprecated and will be removed in Djin 1.0.0,' \
59
+ ' put the tasks under \'tasks\' keyword'
60
+
61
+ rendered_djin_config.except(*RESERVED_WORDS).reject { |task| task.start_with?('_') }
62
+ end
63
+
64
+ def args
65
+ index = ARGV.index('--')
66
+
67
+ return [] unless index
68
+
69
+ ARGV.slice((index + 1)..ARGV.size)
70
+ end
71
+
72
+ def env
73
+ @env ||= ENV.to_h.symbolize_keys
74
+ end
75
+
76
+ def yaml_load(text)
77
+ YAML.safe_load(text, [], [], true)
78
+ end
79
+
80
+ def version_supported?
81
+ Vseries::SemanticVersion.new(Djin::VERSION) >= Vseries::SemanticVersion.new(version)
82
+ end
83
+
84
+ def validate_version!
85
+ raise Interpreter::MissingVersionError, 'Missing djin_version' unless version
86
+
87
+ return if version_supported?
88
+
89
+ raise Interpreter::VersionNotSupportedError, "Version #{version} is not supported, use #{Djin::VERSION} or higher"
90
+ end
91
+ end
92
+ end
@@ -6,6 +6,10 @@ module Djin
6
6
  def except(*keys)
7
7
  reject { |key, _| keys.include?(key) }
8
8
  end
9
+
10
+ def symbolize_keys
11
+ map { |key, value| [key.to_sym, value] }.to_h
12
+ end
9
13
  end
10
14
  end
11
15
  end
@@ -4,22 +4,14 @@ module Djin
4
4
  class Interpreter
5
5
  using Djin::HashExtensions
6
6
 
7
- RESERVED_WORDS = %w[djin_version _default_options].freeze
8
-
7
+ # TODO: Move Errors to ConfigLoader
9
8
  InvalidConfigurationError = Class.new(StandardError)
10
9
  MissingVersionError = Class.new(InvalidConfigurationError)
11
10
  VersionNotSupportedError = Class.new(InvalidConfigurationError)
12
11
  InvalidSyntaxError = Class.new(InvalidConfigurationError)
13
12
 
14
13
  class << self
15
- def load!(params)
16
- version = params['djin_version']
17
- raise MissingVersionError, 'Missing djin_version' unless version
18
- unless version_supported?(version)
19
- raise VersionNotSupportedError, "Version #{version} is not supported, use #{Djin::VERSION} or higher"
20
- end
21
-
22
- tasks_params = params.except(*RESERVED_WORDS).reject { |task| task.start_with?('_') }
14
+ def load!(tasks_params)
23
15
  contract = TaskContract.new
24
16
 
25
17
  tasks_params.map do |task_name, options|
@@ -54,10 +46,6 @@ module Djin
54
46
 
55
47
  LocalCommandBuilder.call(local_params) if local_params
56
48
  end
57
-
58
- def version_supported?(version)
59
- Vseries::SemanticVersion.new(Djin::VERSION) >= Vseries::SemanticVersion.new(version)
60
- end
61
49
  end
62
50
  end
63
51
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Djin
4
- VERSION = '0.5.0'
4
+ VERSION = '0.6.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.5.0
4
+ version: 0.6.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-07-14 00:00:00.000000000 Z
11
+ date: 2020-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-cli
@@ -181,6 +181,7 @@ files:
181
181
  - exe/djin
182
182
  - lib/djin.rb
183
183
  - lib/djin/cli.rb
184
+ - lib/djin/config_loader.rb
184
185
  - lib/djin/entities/task.rb
185
186
  - lib/djin/entities/types.rb
186
187
  - lib/djin/executor.rb
@@ -192,7 +193,6 @@ files:
192
193
  - lib/djin/interpreter/local_command_builder.rb
193
194
  - lib/djin/repositories/task_repository.rb
194
195
  - lib/djin/task_contract.rb
195
- - lib/djin/template_renderer.rb
196
196
  - lib/djin/version.rb
197
197
  homepage: https://github.com/catks/djin
198
198
  licenses:
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Djin
4
- class TemplateRenderer
5
- def self.render(template_file)
6
- new(template_file).render
7
- end
8
-
9
- def initialize(template_file)
10
- @template_file = template_file
11
- end
12
-
13
- def render
14
- Mustache.render(@template_file,
15
- args: args.join(' '),
16
- args?: args.any?,
17
- **env)
18
- end
19
-
20
- private
21
-
22
- def args
23
- index = ARGV.index('--')
24
-
25
- return [] unless index
26
-
27
- ARGV.slice((index + 1)..ARGV.size)
28
- end
29
-
30
- def env
31
- @env ||= ENV.to_h.map { |k, v| [k.to_sym, v] }.to_h
32
- end
33
- end
34
- end