djin 0.5.0 → 0.9.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 +4 -4
- data/.github/workflows/ruby.yml +8 -4
- data/CHANGELOG.md +15 -0
- data/Gemfile.lock +7 -6
- data/README.md +198 -83
- data/djin.gemspec +1 -0
- data/djin.yml +29 -27
- data/examples/djin.yml +30 -24
- data/examples/djin_lib/test.yml +12 -0
- data/examples/local_tasks/.djin/server_tasks.yml +17 -0
- data/examples/local_tasks/djin.yml +22 -0
- data/lib/djin.rb +18 -7
- data/lib/djin/cli.rb +2 -2
- data/lib/djin/config_loader.rb +136 -0
- data/lib/djin/entities/file_config.rb +31 -0
- data/lib/djin/entities/task.rb +3 -5
- data/lib/djin/extensions/hash_extensions.rb +18 -0
- data/lib/djin/interpreter.rb +18 -17
- data/lib/djin/interpreter/base_command_builder.rb +1 -0
- data/lib/djin/memory_cache.rb +17 -0
- data/lib/djin/task_contract.rb +1 -0
- data/lib/djin/version.rb +1 -1
- metadata +24 -4
- data/lib/djin/template_renderer.rb +0 -34
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e763f1dad923699c768e998f4dd5caa53ac7a8b0ad4d7acd84c708effdcb627c
|
|
4
|
+
data.tar.gz: 9ab841b39557b775ec7832a3c1cd0befaf983e89ba931459b89a52d5a5df0bda
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e22bc8b7d3deb635180db1d5c49f1e7d5df1eef3f1b4184b13d65b24eaa45b6f716edfae1bb4799abfe4d4255387958f5f078d931c72cf0b5e407abf9d85ee51
|
|
7
|
+
data.tar.gz: e603ff5f1bab170ed9758331e7c64e39f1832424fc2c0e069aeef2ce85372081ccc15e1a2080cae3c5edc4c8d8fd1286643e4aaa02616249f7173c6d660ffcf2
|
data/.github/workflows/ruby.yml
CHANGED
|
@@ -14,10 +14,12 @@ jobs:
|
|
|
14
14
|
- uses: actions/setup-ruby@v1
|
|
15
15
|
with:
|
|
16
16
|
ruby-version: ${{ matrix.ruby }}
|
|
17
|
-
-
|
|
17
|
+
- name: Install Gems
|
|
18
|
+
run: |
|
|
18
19
|
gem install bundler
|
|
19
20
|
bundle install --jobs 4 --retry 3
|
|
20
|
-
|
|
21
|
+
- name: Run tests
|
|
22
|
+
run: bundle exec rake
|
|
21
23
|
|
|
22
24
|
lint:
|
|
23
25
|
runs-on: ubuntu-16.04
|
|
@@ -27,8 +29,10 @@ jobs:
|
|
|
27
29
|
- uses: actions/setup-ruby@v1
|
|
28
30
|
with:
|
|
29
31
|
ruby-version: '2.6'
|
|
30
|
-
-
|
|
32
|
+
- name: Install Gems
|
|
33
|
+
run: |
|
|
31
34
|
gem install bundler
|
|
32
35
|
bundle install --jobs 4 --retry 3
|
|
33
|
-
|
|
36
|
+
- name: Rubocop
|
|
37
|
+
run: bundle exec rubocop
|
|
34
38
|
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
## 0.9.0 - 17/09/2020
|
|
2
|
+
* [FEATURE] Include Option
|
|
3
|
+
|
|
4
|
+
## 0.8.0 - 31/08/2020
|
|
5
|
+
* [FEATURE] Adds aliases option
|
|
6
|
+
|
|
7
|
+
## 0.7.0 - 20/08/2020
|
|
8
|
+
* [FEATURE] Adds description option
|
|
9
|
+
|
|
10
|
+
## 0.6.1 - 11/08/2020
|
|
11
|
+
* [TECH] Better Error Handling
|
|
12
|
+
|
|
13
|
+
## 0.6.0 - 22/07/2020
|
|
14
|
+
* [FEATURE] Djin Variables
|
|
15
|
+
|
|
1
16
|
## 0.5.0 - 13/07/2020
|
|
2
17
|
* [FEATURE] Adds local command task
|
|
3
18
|
* [FEATURE] Template Args for entire djin.yml
|
data/Gemfile.lock
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
djin (0.
|
|
4
|
+
djin (0.9.0)
|
|
5
5
|
dry-cli (~> 0.6.0)
|
|
6
|
+
dry-equalizer (~> 0.3.0)
|
|
6
7
|
dry-struct (~> 1.3.0)
|
|
7
8
|
dry-validation (~> 1.5.1)
|
|
8
9
|
mustache (~> 1.1.1)
|
|
@@ -13,7 +14,7 @@ GEM
|
|
|
13
14
|
specs:
|
|
14
15
|
ast (2.4.1)
|
|
15
16
|
byebug (11.1.1)
|
|
16
|
-
concurrent-ruby (1.1.
|
|
17
|
+
concurrent-ruby (1.1.7)
|
|
17
18
|
diff-lcs (1.3)
|
|
18
19
|
dry-cli (0.6.0)
|
|
19
20
|
concurrent-ruby (~> 1.0)
|
|
@@ -29,11 +30,11 @@ GEM
|
|
|
29
30
|
dry-equalizer (0.3.0)
|
|
30
31
|
dry-inflector (0.2.0)
|
|
31
32
|
dry-initializer (3.0.3)
|
|
32
|
-
dry-logic (1.0.
|
|
33
|
+
dry-logic (1.0.7)
|
|
33
34
|
concurrent-ruby (~> 1.0)
|
|
34
35
|
dry-core (~> 0.2)
|
|
35
36
|
dry-equalizer (~> 0.2)
|
|
36
|
-
dry-schema (1.5.
|
|
37
|
+
dry-schema (1.5.4)
|
|
37
38
|
concurrent-ruby (~> 1.0)
|
|
38
39
|
dry-configurable (~> 0.8, >= 0.8.3)
|
|
39
40
|
dry-core (~> 0.4)
|
|
@@ -53,13 +54,13 @@ GEM
|
|
|
53
54
|
dry-equalizer (~> 0.3)
|
|
54
55
|
dry-inflector (~> 0.1, >= 0.1.2)
|
|
55
56
|
dry-logic (~> 1.0, >= 1.0.2)
|
|
56
|
-
dry-validation (1.5.
|
|
57
|
+
dry-validation (1.5.6)
|
|
57
58
|
concurrent-ruby (~> 1.0)
|
|
58
59
|
dry-container (~> 0.7, >= 0.7.1)
|
|
59
60
|
dry-core (~> 0.4)
|
|
60
61
|
dry-equalizer (~> 0.2)
|
|
61
62
|
dry-initializer (~> 3.0)
|
|
62
|
-
dry-schema (~> 1.5)
|
|
63
|
+
dry-schema (~> 1.5, >= 1.5.2)
|
|
63
64
|
ice_nine (0.11.2)
|
|
64
65
|
mustache (1.1.1)
|
|
65
66
|
parallel (1.19.2)
|
data/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Djin
|
|
2
2
|
|
|
3
3
|

|
|
4
|
+
[](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,253 @@ 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.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
29
|
+
djin_version: '0.9.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:
|
|
43
|
+
docker-compose:
|
|
44
|
+
service: app
|
|
45
|
+
run:
|
|
46
|
+
commands: rspec
|
|
47
|
+
options: "--rm"
|
|
48
|
+
aliases: # Optional Array of strings
|
|
49
|
+
- rspec
|
|
47
50
|
```
|
|
48
51
|
|
|
49
52
|
You can also set task dependencies with depends_on option:
|
|
50
53
|
|
|
51
54
|
|
|
52
55
|
```yaml
|
|
53
|
-
djin_version: '0.
|
|
56
|
+
djin_version: '0.9.0'
|
|
54
57
|
|
|
55
58
|
_default_run_options: &default_run_options
|
|
56
59
|
options: "--rm"
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
61
|
+
tasks:
|
|
62
|
+
"db:create":
|
|
63
|
+
docker-compose:
|
|
64
|
+
service: app
|
|
65
|
+
run:
|
|
66
|
+
commands: rake db:create
|
|
67
|
+
<<: *default_run_options
|
|
68
|
+
|
|
69
|
+
"db:migrate":
|
|
70
|
+
docker-compose:
|
|
71
|
+
service: app
|
|
72
|
+
run:
|
|
73
|
+
commands: rake db:migrate
|
|
74
|
+
<<: *default_run_options
|
|
75
|
+
|
|
76
|
+
"db:setup":
|
|
77
|
+
depends_on:
|
|
78
|
+
- "db:create"
|
|
79
|
+
- "db:migrate"
|
|
77
80
|
```
|
|
78
81
|
|
|
79
82
|
Or mix local commands and docker/docker-compose commands:
|
|
80
83
|
|
|
81
84
|
```yaml
|
|
82
|
-
djin_version: '0.
|
|
85
|
+
djin_version: '0.9.0'
|
|
83
86
|
|
|
84
87
|
_default_run_options: &default_run_options
|
|
85
88
|
options: "--rm"
|
|
86
89
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
90
|
+
tasks:
|
|
91
|
+
"db:create":
|
|
92
|
+
docker-compose:
|
|
93
|
+
service: app
|
|
94
|
+
run:
|
|
95
|
+
commands: rake db:create
|
|
96
|
+
<<: *default_run_options
|
|
97
|
+
|
|
98
|
+
"db:migrate":
|
|
99
|
+
docker-compose:
|
|
100
|
+
service: app
|
|
101
|
+
run:
|
|
102
|
+
commands: rake db:migrate
|
|
103
|
+
<<: *default_run_options
|
|
104
|
+
|
|
105
|
+
"setup:copy_samples":
|
|
106
|
+
local:
|
|
107
|
+
run:
|
|
108
|
+
- cp config/database.yml.sample config/database.yml
|
|
109
|
+
|
|
110
|
+
"setup":
|
|
111
|
+
depends_on:
|
|
112
|
+
- "setup:copy_samples"
|
|
113
|
+
- "db:create"
|
|
114
|
+
- "db:migrate"
|
|
112
115
|
```
|
|
113
116
|
|
|
114
117
|
After that you can run `djin {{task_name}}`, like `djin script` or `djin test`
|
|
115
118
|
|
|
116
|
-
## Using Environment variables and custom args in djin.yml
|
|
119
|
+
## Using Environment variables, custom variables and custom args in djin.yml tasks
|
|
117
120
|
|
|
118
121
|
You can also use environment variables using the '{{YOUR_ENV_HERE}}' syntax, like so:
|
|
119
122
|
|
|
120
123
|
```yaml
|
|
121
|
-
djin_version: '0.
|
|
124
|
+
djin_version: '0.9.0'
|
|
122
125
|
|
|
123
126
|
_default_run_options: &default_run_options
|
|
124
127
|
options: "--rm"
|
|
125
128
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
tasks:
|
|
130
|
+
"db:migrate":
|
|
131
|
+
docker-compose:
|
|
132
|
+
service: app
|
|
133
|
+
run:
|
|
134
|
+
commands: ENV={{ENV}} rake db:migrate
|
|
135
|
+
<<: *default_run_options
|
|
132
136
|
|
|
133
137
|
```
|
|
134
138
|
|
|
135
|
-
|
|
139
|
+
Or define some variables to use in multiple locations
|
|
140
|
+
```yaml
|
|
141
|
+
djin_version: '0.9.0'
|
|
142
|
+
|
|
143
|
+
_default_run_options: &default_run_options
|
|
144
|
+
options: "--rm"
|
|
145
|
+
|
|
146
|
+
variables:
|
|
147
|
+
my_ssh_user: user
|
|
148
|
+
some_host: test.local
|
|
149
|
+
|
|
150
|
+
tasks:
|
|
151
|
+
"some_host:ssh":
|
|
152
|
+
local:
|
|
153
|
+
run:
|
|
154
|
+
- ssh {{my_ssh_user}}@{{some_host}}
|
|
155
|
+
|
|
156
|
+
"some_host:logs":
|
|
157
|
+
local:
|
|
158
|
+
run:
|
|
159
|
+
- ssh -t {{my_ssh_user}}@{{some_host}} 'tail -f /var/log/syslog'
|
|
160
|
+
```
|
|
161
|
+
|
|
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:
|
|
136
163
|
|
|
137
164
|
```yaml
|
|
138
|
-
djin_version: '0.
|
|
165
|
+
djin_version: '0.9.0'
|
|
139
166
|
|
|
140
167
|
_default_run_options: &default_run_options
|
|
141
168
|
options: "--rm"
|
|
142
169
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
170
|
+
tasks:
|
|
171
|
+
"rubocop":
|
|
172
|
+
docker-compose:
|
|
173
|
+
service: app
|
|
174
|
+
run:
|
|
175
|
+
commands: rubocop {{args}}
|
|
176
|
+
<<: *default_run_options
|
|
177
|
+
aliases:
|
|
178
|
+
- lint
|
|
149
179
|
|
|
150
180
|
```
|
|
151
181
|
|
|
152
182
|
With that you can pass custom args after `--`, eg: `djin rubocop -- --parallel`, which wil make djin runs `rubocop --parallel` inside the service `app`.
|
|
153
183
|
|
|
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)
|
|
184
|
+
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)
|
|
185
|
+
|
|
186
|
+
### Reusing tasks
|
|
187
|
+
|
|
188
|
+
If you have multiple tasks with similar behaviour and with small differences you can use the `include` keyword, so this:
|
|
189
|
+
|
|
190
|
+
```yaml
|
|
191
|
+
djin_version: '0.9.0'
|
|
192
|
+
|
|
193
|
+
tasks:
|
|
194
|
+
"host1:ssh":
|
|
195
|
+
local:
|
|
196
|
+
run:
|
|
197
|
+
- ssh my_user@host1.com.br
|
|
198
|
+
|
|
199
|
+
"host1:restart":
|
|
200
|
+
local:
|
|
201
|
+
run:
|
|
202
|
+
- ssh -t my_user@host1.com.br restart
|
|
203
|
+
|
|
204
|
+
"host1:logs":
|
|
205
|
+
local:
|
|
206
|
+
run:
|
|
207
|
+
- ssh -t my_user@host1.com.br tail -f /var/log/my_log
|
|
208
|
+
|
|
209
|
+
"host2:ssh":
|
|
210
|
+
local:
|
|
211
|
+
run:
|
|
212
|
+
- ssh my_user@host2.com.br
|
|
213
|
+
|
|
214
|
+
"host2:restart":
|
|
215
|
+
local:
|
|
216
|
+
run:
|
|
217
|
+
- ssh -t my_user@host2.com.br restart
|
|
218
|
+
|
|
219
|
+
"host2:logs":
|
|
220
|
+
local:
|
|
221
|
+
run:
|
|
222
|
+
- ssh -t my_user@host2.com.br tail -f /var/log/my_file
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
can become this:
|
|
227
|
+
|
|
228
|
+
```yaml
|
|
229
|
+
# djin.yml
|
|
230
|
+
djin_version: '0.9.0'
|
|
231
|
+
|
|
232
|
+
include:
|
|
233
|
+
- file: '.djin/server_tasks.yml'
|
|
234
|
+
context:
|
|
235
|
+
variables:
|
|
236
|
+
namespace: host1
|
|
237
|
+
host: host1.com
|
|
238
|
+
ssh_user: my_user
|
|
239
|
+
|
|
240
|
+
- file: '.djin/server_tasks.yml'
|
|
241
|
+
context:
|
|
242
|
+
variables:
|
|
243
|
+
namespace: host2
|
|
244
|
+
host: host2.com
|
|
245
|
+
ssh_user: my_user
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
```yaml
|
|
251
|
+
# .djin/server_tasks.yml
|
|
252
|
+
djin_version: '0.9.0'
|
|
253
|
+
|
|
254
|
+
tasks:
|
|
255
|
+
"{{namespace}}:ssh":
|
|
256
|
+
local:
|
|
257
|
+
run:
|
|
258
|
+
- ssh {{ssh_user}}@{{host}}
|
|
259
|
+
|
|
260
|
+
"{{namespace}}:restart":
|
|
261
|
+
local:
|
|
262
|
+
run:
|
|
263
|
+
- ssh -t {{ssh_user}}@{{host}} restart
|
|
264
|
+
|
|
265
|
+
"{{namespace}}:logs":
|
|
266
|
+
local:
|
|
267
|
+
run:
|
|
268
|
+
- ssh -t {{ssh_user}}@{{host}} tail -f /var/log/my_log
|
|
269
|
+
```
|
|
155
270
|
|
|
156
271
|
## Development
|
|
157
272
|
|
|
158
273
|
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
274
|
|
|
160
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version,
|
|
275
|
+
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
276
|
|
|
162
277
|
## TODO:
|
|
163
278
|
|
data/djin.gemspec
CHANGED
|
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
spec.require_paths = ['lib']
|
|
29
29
|
|
|
30
30
|
spec.add_dependency 'dry-cli', '~> 0.6.0'
|
|
31
|
+
spec.add_dependency 'dry-equalizer', '~> 0.3.0'
|
|
31
32
|
spec.add_dependency 'dry-struct', '~> 1.3.0'
|
|
32
33
|
spec.add_dependency 'dry-validation', '~> 1.5.1'
|
|
33
34
|
spec.add_dependency 'mustache', '~> 1.1.1'
|
data/djin.yml
CHANGED
|
@@ -1,33 +1,35 @@
|
|
|
1
|
-
djin_version: '0.
|
|
1
|
+
djin_version: '0.9.0'
|
|
2
2
|
|
|
3
3
|
_default_run_options: &default_run_options
|
|
4
4
|
options: "--rm --entrypoint=''"
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
+
description: Runs Specs
|
|
9
|
+
docker-compose:
|
|
10
|
+
service: app
|
|
11
|
+
run:
|
|
12
|
+
commands: "cd /usr/src/djin && rspec {{args}}"
|
|
13
|
+
<<: *default_run_options
|
|
14
|
+
aliases:
|
|
15
|
+
- rspec
|
|
32
16
|
|
|
17
|
+
sh:
|
|
18
|
+
description: Enter app service shell
|
|
19
|
+
docker-compose:
|
|
20
|
+
service: app
|
|
21
|
+
run:
|
|
22
|
+
commands: "sh"
|
|
23
|
+
<<: *default_run_options
|
|
24
|
+
run:
|
|
25
|
+
docker-compose:
|
|
26
|
+
service: app
|
|
27
|
+
run:
|
|
28
|
+
commands: "sh -c '{{args}}'"
|
|
29
|
+
<<: *default_run_options
|
|
33
30
|
|
|
31
|
+
release:
|
|
32
|
+
local:
|
|
33
|
+
run:
|
|
34
|
+
- verto tag up {{args}}
|
|
35
|
+
- bundle exec rake release
|
data/examples/djin.yml
CHANGED
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
---
|
|
2
|
-
djin_version: '0.
|
|
2
|
+
djin_version: '0.9.0'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
test:
|
|
10
|
-
docker-compose:
|
|
11
|
-
service: app
|
|
12
|
-
run:
|
|
13
|
-
commands: rspec
|
|
14
|
-
options: "--rm"
|
|
4
|
+
include:
|
|
5
|
+
- file: 'djin_lib/test.yml'
|
|
6
|
+
context:
|
|
7
|
+
variables:
|
|
8
|
+
namespace: 'test:'
|
|
15
9
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
commands:
|
|
21
|
-
- "ruby /scripts/my_ruby_script.rb"
|
|
22
|
-
options: "--rm -v $(pwd)/my_ruby_script.rb:/scripts/my_ruby_script.rb"
|
|
10
|
+
- file: 'djin_lib/test.yml'
|
|
11
|
+
context:
|
|
12
|
+
variables:
|
|
13
|
+
namespace: 'test2:'
|
|
23
14
|
|
|
24
15
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
16
|
+
tasks:
|
|
17
|
+
default:
|
|
18
|
+
docker:
|
|
19
|
+
image: "ruby:2.5"
|
|
20
|
+
run:
|
|
21
|
+
- "ruby -e 'puts \\\" Hello\\\"'"
|
|
22
|
+
|
|
23
|
+
script:
|
|
24
|
+
docker:
|
|
25
|
+
image: "ruby:2.6"
|
|
26
|
+
run:
|
|
27
|
+
commands:
|
|
28
|
+
- "ruby /scripts/my_ruby_script.rb"
|
|
29
|
+
options: "--rm -v $(pwd)/my_ruby_script.rb:/scripts/my_ruby_script.rb"
|
|
30
|
+
|
|
31
|
+
with_build:
|
|
32
|
+
docker:
|
|
33
|
+
build: .
|
|
34
|
+
run:
|
|
35
|
+
- "ruby -e 'puts \" Hello\"'"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
djin_version: '0.8.0'
|
|
2
|
+
|
|
3
|
+
tasks:
|
|
4
|
+
"{{namespace}}:ssh":
|
|
5
|
+
local:
|
|
6
|
+
run:
|
|
7
|
+
- ssh {{ssh_user}}@{{host}}
|
|
8
|
+
|
|
9
|
+
"{{namespace}}:restart":
|
|
10
|
+
local:
|
|
11
|
+
run:
|
|
12
|
+
- ssh -t {{ssh_user}}@{{host}} restart
|
|
13
|
+
|
|
14
|
+
"{{namespace}}:logs":
|
|
15
|
+
local:
|
|
16
|
+
run:
|
|
17
|
+
- ssh -t {{ssh_user}}@{{host}} tail -f /var/log/my_log
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
djin_version: '0.9.0'
|
|
2
|
+
|
|
3
|
+
include:
|
|
4
|
+
- file: '.djin/server_tasks.yml'
|
|
5
|
+
context:
|
|
6
|
+
variables:
|
|
7
|
+
namespace: host1
|
|
8
|
+
host: host1.com
|
|
9
|
+
ssh_user: my_user
|
|
10
|
+
|
|
11
|
+
- file: '.djin/server_tasks.yml'
|
|
12
|
+
context:
|
|
13
|
+
variables:
|
|
14
|
+
namespace: host2
|
|
15
|
+
host: host2.com
|
|
16
|
+
ssh_user: my_user
|
|
17
|
+
|
|
18
|
+
tasks:
|
|
19
|
+
hello_command:
|
|
20
|
+
local:
|
|
21
|
+
run:
|
|
22
|
+
- echo 'Hello Djin'
|
data/lib/djin.rb
CHANGED
|
@@ -11,32 +11,35 @@ require 'mustache'
|
|
|
11
11
|
require 'djin/extensions/hash_extensions'
|
|
12
12
|
require 'djin/entities/types'
|
|
13
13
|
require 'djin/entities/task'
|
|
14
|
+
require 'djin/entities/file_config'
|
|
14
15
|
require 'djin/interpreter/base_command_builder'
|
|
15
16
|
require 'djin/interpreter/docker_command_builder'
|
|
16
17
|
require 'djin/interpreter/docker_compose_command_builder'
|
|
17
18
|
require 'djin/interpreter/local_command_builder'
|
|
18
19
|
require 'djin/interpreter'
|
|
19
|
-
require 'djin/
|
|
20
|
+
require 'djin/config_loader'
|
|
20
21
|
require 'djin/executor'
|
|
21
22
|
require 'djin/cli'
|
|
22
23
|
require 'djin/task_contract'
|
|
23
24
|
require 'djin/repositories/task_repository'
|
|
25
|
+
require 'djin/memory_cache'
|
|
24
26
|
|
|
25
27
|
module Djin
|
|
26
28
|
class Error < StandardError; end
|
|
27
29
|
|
|
28
|
-
def self.load_tasks!(
|
|
29
|
-
abort 'Error: djin.yml not found' unless
|
|
30
|
+
def self.load_tasks!(file_path = Pathname.getwd.join('djin.yml'))
|
|
31
|
+
abort 'Error: djin.yml not found' unless file_path.exist?
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
djin_config = YAML.safe_load(rendered_djin_file, [], [], true)
|
|
33
|
+
file_config = ConfigLoader.load!(file_path)
|
|
33
34
|
|
|
34
|
-
tasks
|
|
35
|
+
# TODO: Make all tasks be under 'tasks' key, passing only the tasks here
|
|
36
|
+
tasks = Interpreter.load!(file_config)
|
|
35
37
|
|
|
36
38
|
@task_repository = TaskRepository.new(tasks)
|
|
37
39
|
CLI.load_tasks!(tasks)
|
|
38
40
|
rescue Djin::Interpreter::InvalidConfigurationError => e
|
|
39
|
-
|
|
41
|
+
error_name = e.class.name.split('::').last
|
|
42
|
+
abort("[#{error_name}] #{e.message}")
|
|
40
43
|
end
|
|
41
44
|
|
|
42
45
|
def self.tasks
|
|
@@ -46,4 +49,12 @@ module Djin
|
|
|
46
49
|
def self.task_repository
|
|
47
50
|
@task_repository ||= TaskRepository.new
|
|
48
51
|
end
|
|
52
|
+
|
|
53
|
+
def self.cache
|
|
54
|
+
@cache ||= MemoryCache.new
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.root_path
|
|
58
|
+
Pathname.new File.expand_path(File.dirname(__FILE__) + '/..')
|
|
59
|
+
end
|
|
49
60
|
end
|
data/lib/djin/cli.rb
CHANGED
|
@@ -7,7 +7,7 @@ module Djin
|
|
|
7
7
|
def self.load_tasks!(tasks)
|
|
8
8
|
tasks.each do |task|
|
|
9
9
|
command = Class.new(Dry::CLI::Command) do
|
|
10
|
-
desc
|
|
10
|
+
desc task.description
|
|
11
11
|
|
|
12
12
|
define_method(:task) { task }
|
|
13
13
|
|
|
@@ -16,7 +16,7 @@ module Djin
|
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
register
|
|
19
|
+
register(task.name, command, aliases: task.aliases)
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
@@ -0,0 +1,136 @@
|
|
|
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 include].freeze
|
|
10
|
+
|
|
11
|
+
def self.load!(template_file, runtime_config: {})
|
|
12
|
+
new(template_file, runtime_config: runtime_config).load!
|
|
13
|
+
end
|
|
14
|
+
|
|
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 }
|
|
18
|
+
@runtime_config = runtime_config
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def load!
|
|
22
|
+
validate_version!
|
|
23
|
+
|
|
24
|
+
file_config
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def file_config
|
|
30
|
+
FileConfig.new(
|
|
31
|
+
djin_version: version,
|
|
32
|
+
variables: variables,
|
|
33
|
+
tasks: tasks,
|
|
34
|
+
raw_tasks: raw_tasks
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def version
|
|
39
|
+
# TODO: Deprecates djin_version and use version instead
|
|
40
|
+
@version || raw_djin_config['djin_version']
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def variables
|
|
44
|
+
@variables ||= included_variables.merge(raw_djin_config['variables']&.symbolize_keys || {})
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def tasks
|
|
48
|
+
included_tasks.merge(rendered_djin_config['tasks'] || legacy_tasks)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def raw_tasks
|
|
52
|
+
included_raw_tasks.merge(raw_djin_config['tasks'] || legacy_raw_tasks)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def legacy_tasks
|
|
56
|
+
warn '[DEPRECATED] Root tasks are deprecated and will be removed in Djin 1.0.0,' \
|
|
57
|
+
' put the tasks under \'tasks\' keyword'
|
|
58
|
+
|
|
59
|
+
rendered_djin_config.except(*RESERVED_WORDS).reject { |task| task.start_with?('_') }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def legacy_raw_tasks
|
|
63
|
+
raw_djin_config.except(*RESERVED_WORDS).reject { |task| task.start_with?('_') }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def included_variables
|
|
67
|
+
return {} unless included_config
|
|
68
|
+
|
|
69
|
+
included_config.variables
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def included_tasks
|
|
73
|
+
return {} unless included_config
|
|
74
|
+
|
|
75
|
+
included_config.tasks
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def included_raw_tasks
|
|
79
|
+
return {} unless included_config
|
|
80
|
+
|
|
81
|
+
included_config.raw_tasks
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def included_config
|
|
85
|
+
@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'] || {})
|
|
89
|
+
end&.reduce(:deep_merge)
|
|
90
|
+
rescue Errno::ENOENT => e
|
|
91
|
+
raise Interpreter::InvalidConfigFileError, e.message
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def args
|
|
95
|
+
index = ARGV.index('--')
|
|
96
|
+
|
|
97
|
+
return [] unless index
|
|
98
|
+
|
|
99
|
+
ARGV.slice((index + 1)..ARGV.size)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def env
|
|
103
|
+
@env ||= ENV.to_h.symbolize_keys
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def raw_djin_config
|
|
107
|
+
@raw_djin_config ||= yaml_load(@template_file_content).deep_merge(@runtime_config)
|
|
108
|
+
rescue Psych::SyntaxError => e
|
|
109
|
+
raise Interpreter::InvalidConfigFileError, "File: #{@template_file.realpath}\n #{e.message}"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def rendered_djin_config
|
|
113
|
+
@rendered_djin_config ||= begin
|
|
114
|
+
locals = env.merge(variables)
|
|
115
|
+
|
|
116
|
+
rendered_yaml = Mustache.render(@template_file_content,
|
|
117
|
+
args: args.join(' '),
|
|
118
|
+
args?: args.any?,
|
|
119
|
+
**locals)
|
|
120
|
+
yaml_load(rendered_yaml).merge(@runtime_config)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def yaml_load(text)
|
|
125
|
+
YAML.safe_load(text, [], [], true)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def validate_version!
|
|
129
|
+
raise Interpreter::MissingVersionError, 'Missing djin_version' unless version
|
|
130
|
+
|
|
131
|
+
return if file_config.version_supported?
|
|
132
|
+
|
|
133
|
+
raise Interpreter::VersionNotSupportedError, "Version #{version} is not supported, use #{Djin::VERSION} or higher"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Djin
|
|
4
|
+
class FileConfig < Dry::Struct
|
|
5
|
+
using HashExtensions
|
|
6
|
+
|
|
7
|
+
attribute :djin_version, Types::String
|
|
8
|
+
attribute :variables, Types::Hash.optional.default({}.freeze)
|
|
9
|
+
attribute :tasks, Types::Hash
|
|
10
|
+
attribute :raw_tasks, Types::Hash
|
|
11
|
+
# TODO: Add env and args
|
|
12
|
+
|
|
13
|
+
include Dry::Equalizer(:djin_version, :variables, :tasks, :raw_tasks)
|
|
14
|
+
|
|
15
|
+
def version_supported?
|
|
16
|
+
Vseries::SemanticVersion.new(Djin::VERSION) >= Vseries::SemanticVersion.new(djin_version)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def merge(file_config)
|
|
20
|
+
merged_hash = to_h.merge(file_config.to_h)
|
|
21
|
+
|
|
22
|
+
FileConfig.new(merged_hash)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def deep_merge(file_config)
|
|
26
|
+
merged_hash = to_h.deep_merge(file_config.to_h)
|
|
27
|
+
|
|
28
|
+
FileConfig.new(merged_hash)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/djin/entities/task.rb
CHANGED
|
@@ -6,12 +6,10 @@ module Djin
|
|
|
6
6
|
attribute :description, Types::String.optional.default(nil)
|
|
7
7
|
attribute :build_command, Types::String.optional.default(nil)
|
|
8
8
|
attribute :command, Types::String.optional.default(nil)
|
|
9
|
+
attribute :raw_command, Types::String.optional.default(nil)
|
|
10
|
+
attribute :aliases, Types::Array.of(Types::String).optional.default([].freeze)
|
|
9
11
|
attribute :depends_on, Types::Array.of(Types::String).optional.default([].freeze)
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
name == other.name &&
|
|
13
|
-
command == other.command &&
|
|
14
|
-
build_command == other.build_command
|
|
15
|
-
end
|
|
13
|
+
include Dry::Equalizer(:name, :command, :build_command)
|
|
16
14
|
end
|
|
17
15
|
end
|
|
@@ -6,6 +6,24 @@ 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
|
|
13
|
+
|
|
14
|
+
def deep_merge(other_hash)
|
|
15
|
+
dup.deep_merge!(other_hash)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def deep_merge!(other_hash)
|
|
19
|
+
merge!(other_hash) do |_, this_val, other_val|
|
|
20
|
+
if this_val.is_a?(Hash) && other_val.is_a?(Hash)
|
|
21
|
+
this_val.deep_merge(other_val)
|
|
22
|
+
else
|
|
23
|
+
other_val
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
9
27
|
end
|
|
10
28
|
end
|
|
11
29
|
end
|
data/lib/djin/interpreter.rb
CHANGED
|
@@ -4,41 +4,46 @@ module Djin
|
|
|
4
4
|
class Interpreter
|
|
5
5
|
using Djin::HashExtensions
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
# TODO: Move Errors to ConfigLoader
|
|
9
8
|
InvalidConfigurationError = Class.new(StandardError)
|
|
9
|
+
InvalidConfigFileError = Class.new(InvalidConfigurationError)
|
|
10
10
|
MissingVersionError = Class.new(InvalidConfigurationError)
|
|
11
11
|
VersionNotSupportedError = Class.new(InvalidConfigurationError)
|
|
12
12
|
InvalidSyntaxError = Class.new(InvalidConfigurationError)
|
|
13
13
|
|
|
14
14
|
class << self
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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?('_') }
|
|
23
|
-
contract = TaskContract.new
|
|
15
|
+
# rubocop:disable Metrics/AbcSize
|
|
16
|
+
def load!(file_config)
|
|
17
|
+
# TODO: Move task validation to ConfigLoader and add variables/include validations
|
|
18
|
+
task_contract = TaskContract.new
|
|
24
19
|
|
|
25
|
-
|
|
26
|
-
result =
|
|
20
|
+
file_config.tasks.map do |task_name, options|
|
|
21
|
+
result = task_contract.call(options)
|
|
27
22
|
|
|
28
23
|
raise InvalidSyntaxError, { task_name.to_sym => result.errors.to_h } if result.failure?
|
|
29
24
|
|
|
30
25
|
command, build_command = build_commands(options, task_name: task_name)
|
|
31
26
|
|
|
27
|
+
# FIXME(1): Handle dynamic named tasks, eg: {{namespace}}unit and remove condition
|
|
28
|
+
if file_config.raw_tasks[task_name]
|
|
29
|
+
raw_command, = build_commands(file_config.raw_tasks[task_name], task_name: task_name)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
32
|
task_params = {
|
|
33
33
|
name: task_name,
|
|
34
34
|
build_command: build_command,
|
|
35
|
+
# TODO: Remove `|| command` after FIXME(1)
|
|
36
|
+
description: options['description'] || "Runs: #{raw_command || command}",
|
|
35
37
|
command: command,
|
|
38
|
+
raw_command: raw_command,
|
|
39
|
+
aliases: options['aliases'],
|
|
36
40
|
depends_on: options['depends_on']
|
|
37
41
|
}.compact
|
|
38
42
|
|
|
39
43
|
Djin::Task.new(**task_params)
|
|
40
44
|
end
|
|
41
45
|
end
|
|
46
|
+
# rubocop:enable Metrics/AbcSize
|
|
42
47
|
|
|
43
48
|
private
|
|
44
49
|
|
|
@@ -54,10 +59,6 @@ module Djin
|
|
|
54
59
|
|
|
55
60
|
LocalCommandBuilder.call(local_params) if local_params
|
|
56
61
|
end
|
|
57
|
-
|
|
58
|
-
def version_supported?(version)
|
|
59
|
-
Vseries::SemanticVersion.new(Djin::VERSION) >= Vseries::SemanticVersion.new(version)
|
|
60
|
-
end
|
|
61
62
|
end
|
|
62
63
|
end
|
|
63
64
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Djin
|
|
4
|
+
class MemoryCache
|
|
5
|
+
def initialize(hash_store = {})
|
|
6
|
+
@hash_store = hash_store
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def fetch(key)
|
|
10
|
+
@hash_store[key] || @hash_store[key] = yield
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def clear
|
|
14
|
+
@hash_store = {}
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/djin/task_contract.rb
CHANGED
data/lib/djin/version.rb
CHANGED
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.
|
|
4
|
+
version: 0.9.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-
|
|
11
|
+
date: 2020-09-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: dry-cli
|
|
@@ -24,6 +24,20 @@ dependencies:
|
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: 0.6.0
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: dry-equalizer
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 0.3.0
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 0.3.0
|
|
27
41
|
- !ruby/object:Gem::Dependency
|
|
28
42
|
name: dry-struct
|
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -178,9 +192,14 @@ files:
|
|
|
178
192
|
- djin.yml
|
|
179
193
|
- docker-compose.yml
|
|
180
194
|
- examples/djin.yml
|
|
195
|
+
- examples/djin_lib/test.yml
|
|
196
|
+
- examples/local_tasks/.djin/server_tasks.yml
|
|
197
|
+
- examples/local_tasks/djin.yml
|
|
181
198
|
- exe/djin
|
|
182
199
|
- lib/djin.rb
|
|
183
200
|
- lib/djin/cli.rb
|
|
201
|
+
- lib/djin/config_loader.rb
|
|
202
|
+
- lib/djin/entities/file_config.rb
|
|
184
203
|
- lib/djin/entities/task.rb
|
|
185
204
|
- lib/djin/entities/types.rb
|
|
186
205
|
- lib/djin/executor.rb
|
|
@@ -190,9 +209,9 @@ files:
|
|
|
190
209
|
- lib/djin/interpreter/docker_command_builder.rb
|
|
191
210
|
- lib/djin/interpreter/docker_compose_command_builder.rb
|
|
192
211
|
- lib/djin/interpreter/local_command_builder.rb
|
|
212
|
+
- lib/djin/memory_cache.rb
|
|
193
213
|
- lib/djin/repositories/task_repository.rb
|
|
194
214
|
- lib/djin/task_contract.rb
|
|
195
|
-
- lib/djin/template_renderer.rb
|
|
196
215
|
- lib/djin/version.rb
|
|
197
216
|
homepage: https://github.com/catks/djin
|
|
198
217
|
licenses:
|
|
@@ -213,7 +232,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
213
232
|
- !ruby/object:Gem::Version
|
|
214
233
|
version: '0'
|
|
215
234
|
requirements: []
|
|
216
|
-
|
|
235
|
+
rubyforge_project:
|
|
236
|
+
rubygems_version: 2.7.6
|
|
217
237
|
signing_key:
|
|
218
238
|
specification_version: 4
|
|
219
239
|
summary: djin is a make-like utility for docker containers
|
|
@@ -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
|