djin 0.11.3 → 0.11.4
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/CHANGELOG.md +3 -0
- data/Dockerfile +5 -1
- data/Gemfile.lock +2 -2
- data/README.md +10 -10
- data/djin.yml +1 -1
- data/docker-entrypoint.sh +2 -0
- data/examples/djin.yml +1 -1
- data/examples/djin_lib/test.yml +1 -1
- data/examples/local_tasks/djin.yml +1 -1
- data/examples/remote_tasks/djin.yml +1 -1
- data/lib/djin.rb +4 -2
- data/lib/djin/config_loader.rb +17 -29
- data/lib/djin/errors.rb +10 -0
- data/lib/djin/{include_resolver.rb → include_config_loader.rb} +26 -4
- data/lib/djin/include_contract.rb +29 -0
- data/lib/djin/interpreter.rb +1 -7
- data/lib/djin/version.rb +1 -1
- data/wait-for-it.sh +183 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20d3e4379f1a66394b34708a76c8c362b4ce996bea8fba4a449856260533c288
|
4
|
+
data.tar.gz: e6d6713bc9a6a81f7bdc34ae56a75fc962a6c0c76719747c044e9557f8ff6f42
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e809bb84de4f96ad4054e07020460502b6fded297074356d2255b649298986c06881f1719946e7fd3731bccf6d6f23cb2b6c0597a9255a629837028e9866eb1
|
7
|
+
data.tar.gz: ddb2334bfa660b5114bf8dd5eb83c3aebcedd32087bf880f616e5630e6259c34ad2e9c264cc0c8e2ce04fd9d3b05ad5d89b89c212059cc71ce40007837a47838
|
data/CHANGELOG.md
CHANGED
data/Dockerfile
CHANGED
@@ -2,6 +2,7 @@ ARG RUBY_VERSION
|
|
2
2
|
FROM ruby:${RUBY_VERSION:-2.6.5}-alpine AS builder
|
3
3
|
|
4
4
|
ENV BUILD_PACKAGES build-base git
|
5
|
+
ENV DEV_PACKAGES bash
|
5
6
|
|
6
7
|
RUN mkdir /bundle
|
7
8
|
|
@@ -20,6 +21,9 @@ RUN bundle install
|
|
20
21
|
|
21
22
|
FROM builder AS dev
|
22
23
|
|
24
|
+
RUN apk add $DEV_PACKAGES && \
|
25
|
+
rm -rf /var/cache/apk/*
|
26
|
+
|
23
27
|
WORKDIR /usr/src/djin
|
24
28
|
|
25
29
|
COPY . .
|
@@ -45,4 +49,4 @@ RUN rake install
|
|
45
49
|
|
46
50
|
WORKDIR /usr/src/project
|
47
51
|
|
48
|
-
ENTRYPOINT ["/usr/src/
|
52
|
+
ENTRYPOINT ["/usr/src/djin/docker-entrypoint.sh"]
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
djin (0.11.
|
4
|
+
djin (0.11.4)
|
5
5
|
dry-cli (~> 0.6.0)
|
6
6
|
dry-equalizer (~> 0.3.0)
|
7
7
|
dry-struct (~> 1.3.0)
|
@@ -40,7 +40,7 @@ GEM
|
|
40
40
|
dry-logic (1.1.0)
|
41
41
|
concurrent-ruby (~> 1.0)
|
42
42
|
dry-core (~> 0.5, >= 0.5)
|
43
|
-
dry-schema (1.6.
|
43
|
+
dry-schema (1.6.1)
|
44
44
|
concurrent-ruby (~> 1.0)
|
45
45
|
dry-configurable (~> 0.8, >= 0.8.3)
|
46
46
|
dry-core (~> 0.5, >= 0.5)
|
data/README.md
CHANGED
@@ -27,7 +27,7 @@ If you use Rbenv you can install djin only once and create an alias in your .bas
|
|
27
27
|
To use djin first you need to create a djin.yml file:
|
28
28
|
|
29
29
|
```yaml
|
30
|
-
djin_version: '0.11.
|
30
|
+
djin_version: '0.11.4'
|
31
31
|
|
32
32
|
tasks:
|
33
33
|
# With a docker image
|
@@ -54,7 +54,7 @@ You can also set task dependencies with depends_on option:
|
|
54
54
|
|
55
55
|
|
56
56
|
```yaml
|
57
|
-
djin_version: '0.11.
|
57
|
+
djin_version: '0.11.4'
|
58
58
|
|
59
59
|
_default_run_options: &default_run_options
|
60
60
|
options: "--rm"
|
@@ -83,7 +83,7 @@ tasks:
|
|
83
83
|
Or mix local commands and docker/docker-compose commands:
|
84
84
|
|
85
85
|
```yaml
|
86
|
-
djin_version: '0.11.
|
86
|
+
djin_version: '0.11.4'
|
87
87
|
|
88
88
|
_default_run_options: &default_run_options
|
89
89
|
options: "--rm"
|
@@ -122,7 +122,7 @@ After that you can run `djin {{task_name}}`, like `djin script` or `djin test`
|
|
122
122
|
You can also use environment variables using the '{{YOUR_ENV_HERE}}' syntax, like so:
|
123
123
|
|
124
124
|
```yaml
|
125
|
-
djin_version: '0.11.
|
125
|
+
djin_version: '0.11.4'
|
126
126
|
|
127
127
|
_default_run_options: &default_run_options
|
128
128
|
options: "--rm"
|
@@ -139,7 +139,7 @@ tasks:
|
|
139
139
|
|
140
140
|
Or define some variables to use in multiple locations
|
141
141
|
```yaml
|
142
|
-
djin_version: '0.11.
|
142
|
+
djin_version: '0.11.4'
|
143
143
|
|
144
144
|
_default_run_options: &default_run_options
|
145
145
|
options: "--rm"
|
@@ -163,7 +163,7 @@ tasks:
|
|
163
163
|
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:
|
164
164
|
|
165
165
|
```yaml
|
166
|
-
djin_version: '0.11.
|
166
|
+
djin_version: '0.11.4'
|
167
167
|
|
168
168
|
_default_run_options: &default_run_options
|
169
169
|
options: "--rm"
|
@@ -189,7 +189,7 @@ Under the hood djin uses [Mustache](https://mustache.github.io/), so you can use
|
|
189
189
|
If you have multiple tasks with similar behavior and with small differences you can use the `include` keyword, so this:
|
190
190
|
|
191
191
|
```yaml
|
192
|
-
djin_version: '0.11.
|
192
|
+
djin_version: '0.11.4'
|
193
193
|
|
194
194
|
tasks:
|
195
195
|
"host1:ssh":
|
@@ -228,7 +228,7 @@ can become this:
|
|
228
228
|
|
229
229
|
```yaml
|
230
230
|
# djin.yml
|
231
|
-
djin_version: '0.11.
|
231
|
+
djin_version: '0.11.4'
|
232
232
|
|
233
233
|
include:
|
234
234
|
- file: '.djin/server_tasks.yml'
|
@@ -250,7 +250,7 @@ include:
|
|
250
250
|
|
251
251
|
```yaml
|
252
252
|
# .djin/server_tasks.yml
|
253
|
-
djin_version: '0.11.
|
253
|
+
djin_version: '0.11.4'
|
254
254
|
|
255
255
|
tasks:
|
256
256
|
"{{namespace}}:ssh":
|
@@ -272,7 +272,7 @@ tasks:
|
|
272
272
|
You can also reuse tasks in some git repository, to do that you need to declare a git source and optionally a version:
|
273
273
|
|
274
274
|
```yaml
|
275
|
-
djin_version: '0.11.
|
275
|
+
djin_version: '0.11.4'
|
276
276
|
|
277
277
|
include:
|
278
278
|
- git: 'https://github.com/catks/djin.git'
|
data/djin.yml
CHANGED
data/docker-entrypoint.sh
CHANGED
data/examples/djin.yml
CHANGED
data/examples/djin_lib/test.yml
CHANGED
data/lib/djin.rb
CHANGED
@@ -10,18 +10,20 @@ require 'dry/cli'
|
|
10
10
|
require 'mustache'
|
11
11
|
require 'optparse'
|
12
12
|
require 'git'
|
13
|
+
require 'djin/errors'
|
13
14
|
require 'djin/extensions/hash_extensions'
|
14
15
|
require 'djin/extensions/object_extensions'
|
15
16
|
require 'djin/entities/types'
|
16
17
|
require 'djin/entities/task'
|
17
18
|
require 'djin/entities/include_config.rb'
|
18
19
|
require 'djin/entities/main_config'
|
20
|
+
require 'djin/include_contract'
|
19
21
|
require 'djin/interpreter/base_command_builder'
|
20
22
|
require 'djin/interpreter/docker_command_builder'
|
21
23
|
require 'djin/interpreter/docker_compose_command_builder'
|
22
24
|
require 'djin/interpreter/local_command_builder'
|
23
25
|
require 'djin/interpreter'
|
24
|
-
require 'djin/
|
26
|
+
require 'djin/include_config_loader'
|
25
27
|
require 'djin/config_loader'
|
26
28
|
require 'djin/executor'
|
27
29
|
require 'djin/root_cli_parser'
|
@@ -51,7 +53,7 @@ module Djin
|
|
51
53
|
@remote_config_repository = RemoteConfigRepository.new(remote_configs)
|
52
54
|
|
53
55
|
CLI.load_tasks!(tasks)
|
54
|
-
rescue Djin::
|
56
|
+
rescue Djin::InvalidConfigurationError => e
|
55
57
|
error_name = e.class.name.split('::').last
|
56
58
|
abort("[#{error_name}] #{e.message}")
|
57
59
|
end
|
data/lib/djin/config_loader.rb
CHANGED
@@ -1,36 +1,33 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Djin
|
4
|
-
# TODO: Refactor this class to
|
5
|
-
#
|
6
|
-
#
|
4
|
+
# TODO: Refactor this class to delegate the responsability of complex fields
|
5
|
+
# to a specific Loader (like include for IncludeConfigLoader),
|
6
|
+
# maybe renaming to RootConfigLoader
|
7
7
|
|
8
8
|
# rubocop:disable Metrics/ClassLength
|
9
9
|
class ConfigLoader
|
10
10
|
using Djin::HashExtensions
|
11
11
|
RESERVED_WORDS = %w[djin_version variables tasks include].freeze
|
12
12
|
|
13
|
-
|
14
|
-
FileNotFoundError = Class.new(Interpreter::InvalidConfigurationError)
|
15
|
-
|
16
|
-
def self.load_files!(*files, runtime_config: {}, base_directory: '.')
|
13
|
+
def self.load_files!(*files, context_config: {}, base_directory: '.')
|
17
14
|
files.map do |file_path|
|
18
|
-
ConfigLoader.load!(file_path,
|
15
|
+
ConfigLoader.load!(file_path, context_config: context_config, base_directory: base_directory)
|
19
16
|
end&.reduce(:deep_merge)
|
20
17
|
end
|
21
18
|
|
22
|
-
def self.load!(template_file_path,
|
23
|
-
new(template_file_path,
|
19
|
+
def self.load!(template_file_path, context_config: {}, base_directory: '.')
|
20
|
+
new(template_file_path, context_config: context_config, base_directory: base_directory).load!
|
24
21
|
end
|
25
22
|
|
26
|
-
def initialize(template_file_path,
|
23
|
+
def initialize(template_file_path, context_config: {}, base_directory: '.')
|
27
24
|
@base_directory = Pathname.new(base_directory)
|
28
25
|
@template_file = @base_directory.join(template_file_path)
|
29
26
|
|
30
27
|
file_not_found!(@template_file) unless @template_file.exist?
|
31
28
|
|
32
29
|
@template_file_content = Djin.cache.fetch(@template_file.realpath.to_s) { @template_file.read }
|
33
|
-
@
|
30
|
+
@context_config = context_config
|
34
31
|
end
|
35
32
|
|
36
33
|
def load!
|
@@ -107,7 +104,7 @@ module Djin
|
|
107
104
|
present_include_configs&.map do |present_include|
|
108
105
|
ConfigLoader.load!(present_include.file, base_directory: @template_file.dirname,
|
109
106
|
# TODO: Rename to context_config
|
110
|
-
|
107
|
+
context_config: present_include.context)
|
111
108
|
end&.reduce(:deep_merge)
|
112
109
|
end
|
113
110
|
end
|
@@ -120,18 +117,9 @@ module Djin
|
|
120
117
|
include_configs&.select(&:missing?)
|
121
118
|
end
|
122
119
|
|
123
|
-
# TODO: Refactor to move include methods to a specific IncludeConfigLoader, maybe rename IncludeResolver
|
124
120
|
def include_configs
|
125
|
-
@include_configs ||=
|
126
|
-
|
127
|
-
resolver = IncludeResolver.new(base_directory: @template_file.dirname)
|
128
|
-
|
129
|
-
include_djin_config = raw_djin_config['include'] || []
|
130
|
-
|
131
|
-
include_djin_config.map do |include_config|
|
132
|
-
resolver.call(include_config)
|
133
|
-
end
|
134
|
-
end
|
121
|
+
@include_configs ||= Djin::IncludeConfigLoader.load!(raw_djin_config['include'],
|
122
|
+
base_directory: @template_file.dirname)
|
135
123
|
end
|
136
124
|
|
137
125
|
def args
|
@@ -147,9 +135,9 @@ module Djin
|
|
147
135
|
end
|
148
136
|
|
149
137
|
def raw_djin_config
|
150
|
-
@raw_djin_config ||= yaml_load(@template_file_content).deep_merge(@
|
138
|
+
@raw_djin_config ||= yaml_load(@template_file_content).deep_merge(@context_config)
|
151
139
|
rescue Psych::SyntaxError => e
|
152
|
-
raise
|
140
|
+
raise InvalidConfigFileError, "File: #{@template_file.realpath}\n #{e.message}"
|
153
141
|
end
|
154
142
|
|
155
143
|
def rendered_djin_config
|
@@ -160,7 +148,7 @@ module Djin
|
|
160
148
|
args: args.join(' '),
|
161
149
|
args?: args.any?,
|
162
150
|
**locals)
|
163
|
-
yaml_load(rendered_yaml).merge(@
|
151
|
+
yaml_load(rendered_yaml).merge(@context_config)
|
164
152
|
end
|
165
153
|
end
|
166
154
|
|
@@ -169,11 +157,11 @@ module Djin
|
|
169
157
|
end
|
170
158
|
|
171
159
|
def validate_version!
|
172
|
-
raise
|
160
|
+
raise MissingVersionError, 'Missing djin_version' unless version
|
173
161
|
|
174
162
|
return if file_config.version_supported?
|
175
163
|
|
176
|
-
raise
|
164
|
+
raise VersionNotSupportedError, "Version #{version} is not supported, use #{Djin::VERSION} or higher"
|
177
165
|
end
|
178
166
|
|
179
167
|
def validate_missing_config!
|
data/lib/djin/errors.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Djin
|
4
|
+
InvalidConfigurationError = Class.new(StandardError)
|
5
|
+
InvalidConfigFileError = Class.new(InvalidConfigurationError)
|
6
|
+
MissingVersionError = Class.new(InvalidConfigurationError)
|
7
|
+
VersionNotSupportedError = Class.new(InvalidConfigurationError)
|
8
|
+
InvalidSyntaxError = Class.new(InvalidConfigurationError)
|
9
|
+
FileNotFoundError = Class.new(InvalidConfigurationError)
|
10
|
+
end
|
@@ -1,10 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Djin
|
4
|
-
class
|
4
|
+
class IncludeConfigLoader
|
5
5
|
using ObjectExtensions
|
6
6
|
using HashExtensions
|
7
7
|
|
8
|
+
def self.load!(include_djin_config, **options)
|
9
|
+
new(**options).load!(include_djin_config)
|
10
|
+
end
|
11
|
+
|
8
12
|
def initialize(base_directory: '.', remote_directory: '~/.djin/remote', entity_class: Djin::IncludeConfig)
|
9
13
|
# TODO: Use chain of responsability
|
10
14
|
@base_directory = Pathname.new(base_directory)
|
@@ -12,15 +16,33 @@ module Djin
|
|
12
16
|
@entity_class = entity_class
|
13
17
|
end
|
14
18
|
|
15
|
-
def
|
19
|
+
def load!(include_djin_config)
|
20
|
+
load_configs(include_djin_config)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def load_configs(include_djin_config)
|
26
|
+
include_djin_config ||= []
|
27
|
+
|
28
|
+
include_contract = IncludeContract.new
|
29
|
+
|
30
|
+
include_djin_config.map do |include_params|
|
31
|
+
result = include_contract.call(include_params)
|
32
|
+
|
33
|
+
raise InvalidSyntaxError, { include: result.errors.to_h } if result.failure?
|
34
|
+
|
35
|
+
resolve_include(include_params)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def resolve_include(params)
|
16
40
|
include_config_params = remote_handler(params)
|
17
41
|
include_config_params ||= local_handler(params)
|
18
42
|
|
19
43
|
build_entity(include_config_params)
|
20
44
|
end
|
21
45
|
|
22
|
-
private
|
23
|
-
|
24
46
|
def remote_handler(params)
|
25
47
|
return if params['git'].blank?
|
26
48
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Djin
|
4
|
+
class IncludeContract < Dry::Validation::Contract
|
5
|
+
using Djin::ObjectExtensions
|
6
|
+
|
7
|
+
GIT_URI_REGEXP = Regexp.new('(\w+://)(.+@)*([\w\d\.]+)(:[\d]+){0,1}/*(.*)')
|
8
|
+
|
9
|
+
ContextSchema = Dry::Schema.Params do
|
10
|
+
optional(:variables).filled(:hash)
|
11
|
+
# TODO: Add the rest
|
12
|
+
end
|
13
|
+
|
14
|
+
params do
|
15
|
+
optional(:context).filled do
|
16
|
+
hash(ContextSchema)
|
17
|
+
end
|
18
|
+
required(:file).filled(:string)
|
19
|
+
optional(:git).filled(:string)
|
20
|
+
optional(:version).filled(:string)
|
21
|
+
end
|
22
|
+
|
23
|
+
rule(:git) do
|
24
|
+
key.failure("Invalid git uri in: #{value}") if value.present? && !GIT_URI_REGEXP.match?(value)
|
25
|
+
end
|
26
|
+
|
27
|
+
# TODO: Add more validations to file and to restricted unespected keys
|
28
|
+
end
|
29
|
+
end
|
data/lib/djin/interpreter.rb
CHANGED
@@ -1,16 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Djin
|
4
|
+
# TODO: Refactor to TaskConfigLoader and make COnfigLoader to use this class
|
4
5
|
class Interpreter
|
5
6
|
using Djin::HashExtensions
|
6
7
|
|
7
|
-
# TODO: Move Errors to ConfigLoader
|
8
|
-
InvalidConfigurationError = Class.new(StandardError)
|
9
|
-
InvalidConfigFileError = Class.new(InvalidConfigurationError)
|
10
|
-
MissingVersionError = Class.new(InvalidConfigurationError)
|
11
|
-
VersionNotSupportedError = Class.new(InvalidConfigurationError)
|
12
|
-
InvalidSyntaxError = Class.new(InvalidConfigurationError)
|
13
|
-
|
14
8
|
class << self
|
15
9
|
# rubocop:disable Metrics/AbcSize
|
16
10
|
def load!(file_config)
|
data/lib/djin/version.rb
CHANGED
data/wait-for-it.sh
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
# Use this script to test if a given TCP host/port are available
|
3
|
+
# Credits: https://github.com/vishnubob/wait-for-it
|
4
|
+
|
5
|
+
WAITFORIT_cmdname=${0##*/}
|
6
|
+
|
7
|
+
echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
|
8
|
+
|
9
|
+
usage()
|
10
|
+
{
|
11
|
+
cat << USAGE >&2
|
12
|
+
Usage:
|
13
|
+
$WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
|
14
|
+
-h HOST | --host=HOST Host or IP under test
|
15
|
+
-p PORT | --port=PORT TCP port under test
|
16
|
+
Alternatively, you specify the host and port as host:port
|
17
|
+
-s | --strict Only execute subcommand if the test succeeds
|
18
|
+
-q | --quiet Don't output any status messages
|
19
|
+
-t TIMEOUT | --timeout=TIMEOUT
|
20
|
+
Timeout in seconds, zero for no timeout
|
21
|
+
-- COMMAND ARGS Execute command with args after the test finishes
|
22
|
+
USAGE
|
23
|
+
exit 1
|
24
|
+
}
|
25
|
+
|
26
|
+
wait_for()
|
27
|
+
{
|
28
|
+
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
|
29
|
+
echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
|
30
|
+
else
|
31
|
+
echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
|
32
|
+
fi
|
33
|
+
WAITFORIT_start_ts=$(date +%s)
|
34
|
+
while :
|
35
|
+
do
|
36
|
+
if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
|
37
|
+
nc -z $WAITFORIT_HOST $WAITFORIT_PORT
|
38
|
+
WAITFORIT_result=$?
|
39
|
+
else
|
40
|
+
(echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
|
41
|
+
WAITFORIT_result=$?
|
42
|
+
fi
|
43
|
+
if [[ $WAITFORIT_result -eq 0 ]]; then
|
44
|
+
WAITFORIT_end_ts=$(date +%s)
|
45
|
+
echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
|
46
|
+
break
|
47
|
+
fi
|
48
|
+
sleep 1
|
49
|
+
done
|
50
|
+
return $WAITFORIT_result
|
51
|
+
}
|
52
|
+
|
53
|
+
wait_for_wrapper()
|
54
|
+
{
|
55
|
+
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
|
56
|
+
if [[ $WAITFORIT_QUIET -eq 1 ]]; then
|
57
|
+
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
|
58
|
+
else
|
59
|
+
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
|
60
|
+
fi
|
61
|
+
WAITFORIT_PID=$!
|
62
|
+
trap "kill -INT -$WAITFORIT_PID" INT
|
63
|
+
wait $WAITFORIT_PID
|
64
|
+
WAITFORIT_RESULT=$?
|
65
|
+
if [[ $WAITFORIT_RESULT -ne 0 ]]; then
|
66
|
+
echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
|
67
|
+
fi
|
68
|
+
return $WAITFORIT_RESULT
|
69
|
+
}
|
70
|
+
|
71
|
+
# process arguments
|
72
|
+
while [[ $# -gt 0 ]]
|
73
|
+
do
|
74
|
+
case "$1" in
|
75
|
+
*:* )
|
76
|
+
WAITFORIT_hostport=(${1//:/ })
|
77
|
+
WAITFORIT_HOST=${WAITFORIT_hostport[0]}
|
78
|
+
WAITFORIT_PORT=${WAITFORIT_hostport[1]}
|
79
|
+
shift 1
|
80
|
+
;;
|
81
|
+
--child)
|
82
|
+
WAITFORIT_CHILD=1
|
83
|
+
shift 1
|
84
|
+
;;
|
85
|
+
-q | --quiet)
|
86
|
+
WAITFORIT_QUIET=1
|
87
|
+
shift 1
|
88
|
+
;;
|
89
|
+
-s | --strict)
|
90
|
+
WAITFORIT_STRICT=1
|
91
|
+
shift 1
|
92
|
+
;;
|
93
|
+
-h)
|
94
|
+
WAITFORIT_HOST="$2"
|
95
|
+
if [[ $WAITFORIT_HOST == "" ]]; then break; fi
|
96
|
+
shift 2
|
97
|
+
;;
|
98
|
+
--host=*)
|
99
|
+
WAITFORIT_HOST="${1#*=}"
|
100
|
+
shift 1
|
101
|
+
;;
|
102
|
+
-p)
|
103
|
+
WAITFORIT_PORT="$2"
|
104
|
+
if [[ $WAITFORIT_PORT == "" ]]; then break; fi
|
105
|
+
shift 2
|
106
|
+
;;
|
107
|
+
--port=*)
|
108
|
+
WAITFORIT_PORT="${1#*=}"
|
109
|
+
shift 1
|
110
|
+
;;
|
111
|
+
-t)
|
112
|
+
WAITFORIT_TIMEOUT="$2"
|
113
|
+
if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
|
114
|
+
shift 2
|
115
|
+
;;
|
116
|
+
--timeout=*)
|
117
|
+
WAITFORIT_TIMEOUT="${1#*=}"
|
118
|
+
shift 1
|
119
|
+
;;
|
120
|
+
--)
|
121
|
+
shift
|
122
|
+
WAITFORIT_CLI=("$@")
|
123
|
+
break
|
124
|
+
;;
|
125
|
+
--help)
|
126
|
+
usage
|
127
|
+
;;
|
128
|
+
*)
|
129
|
+
echoerr "Unknown argument: $1"
|
130
|
+
usage
|
131
|
+
;;
|
132
|
+
esac
|
133
|
+
done
|
134
|
+
|
135
|
+
if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
|
136
|
+
echoerr "Error: you need to provide a host and port to test."
|
137
|
+
usage
|
138
|
+
fi
|
139
|
+
|
140
|
+
WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
|
141
|
+
WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
|
142
|
+
WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
|
143
|
+
WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
|
144
|
+
|
145
|
+
# Check to see if timeout is from busybox?
|
146
|
+
WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
|
147
|
+
WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
|
148
|
+
|
149
|
+
WAITFORIT_BUSYTIMEFLAG=""
|
150
|
+
if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
|
151
|
+
WAITFORIT_ISBUSY=1
|
152
|
+
# Check if busybox timeout uses -t flag
|
153
|
+
# (recent Alpine versions don't support -t anymore)
|
154
|
+
if timeout &>/dev/stdout | grep -q -e '-t '; then
|
155
|
+
WAITFORIT_BUSYTIMEFLAG="-t"
|
156
|
+
fi
|
157
|
+
else
|
158
|
+
WAITFORIT_ISBUSY=0
|
159
|
+
fi
|
160
|
+
|
161
|
+
if [[ $WAITFORIT_CHILD -gt 0 ]]; then
|
162
|
+
wait_for
|
163
|
+
WAITFORIT_RESULT=$?
|
164
|
+
exit $WAITFORIT_RESULT
|
165
|
+
else
|
166
|
+
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
|
167
|
+
wait_for_wrapper
|
168
|
+
WAITFORIT_RESULT=$?
|
169
|
+
else
|
170
|
+
wait_for
|
171
|
+
WAITFORIT_RESULT=$?
|
172
|
+
fi
|
173
|
+
fi
|
174
|
+
|
175
|
+
if [[ $WAITFORIT_CLI != "" ]]; then
|
176
|
+
if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
|
177
|
+
echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
|
178
|
+
exit $WAITFORIT_RESULT
|
179
|
+
fi
|
180
|
+
exec "${WAITFORIT_CLI[@]}"
|
181
|
+
else
|
182
|
+
exit $WAITFORIT_RESULT
|
183
|
+
fi
|
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.11.
|
4
|
+
version: 0.11.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carlos Atkinson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-cli
|
@@ -236,10 +236,12 @@ files:
|
|
236
236
|
- lib/djin/entities/main_config.rb
|
237
237
|
- lib/djin/entities/task.rb
|
238
238
|
- lib/djin/entities/types.rb
|
239
|
+
- lib/djin/errors.rb
|
239
240
|
- lib/djin/executor.rb
|
240
241
|
- lib/djin/extensions/hash_extensions.rb
|
241
242
|
- lib/djin/extensions/object_extensions.rb
|
242
|
-
- lib/djin/
|
243
|
+
- lib/djin/include_config_loader.rb
|
244
|
+
- lib/djin/include_contract.rb
|
243
245
|
- lib/djin/interpreter.rb
|
244
246
|
- lib/djin/interpreter/base_command_builder.rb
|
245
247
|
- lib/djin/interpreter/docker_command_builder.rb
|
@@ -251,6 +253,7 @@ files:
|
|
251
253
|
- lib/djin/root_cli_parser.rb
|
252
254
|
- lib/djin/task_contract.rb
|
253
255
|
- lib/djin/version.rb
|
256
|
+
- wait-for-it.sh
|
254
257
|
homepage: https://github.com/catks/djin
|
255
258
|
licenses:
|
256
259
|
- MIT
|