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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 626c84b6931a23c78952835ba8fe34b9c33a9cb37b174539804b32f052e2af21
4
- data.tar.gz: 4dd41c1ced7edc3b662edd8eb0c53c32866c686e156744f78e93b723260ebbbe
3
+ metadata.gz: 20d3e4379f1a66394b34708a76c8c362b4ce996bea8fba4a449856260533c288
4
+ data.tar.gz: e6d6713bc9a6a81f7bdc34ae56a75fc962a6c0c76719747c044e9557f8ff6f42
5
5
  SHA512:
6
- metadata.gz: 241a5cc08af93622125bfe228384b3920221e24da7f74b13d404d7a74b3b2c5b7b2fb435a3e3803f61e9d5d10166bef7629f70b40553d5059916d9fdd30abf53
7
- data.tar.gz: 6e7253e6bdf3a1c85b8b29163d28db67031dff8bd31dac2b6f0d8d10b8e9de3a94e1b9a3669598549a77bb59171b471327a3ea294dd98916878fb756b95df8cc
6
+ metadata.gz: 2e809bb84de4f96ad4054e07020460502b6fded297074356d2255b649298986c06881f1719946e7fd3731bccf6d6f23cb2b6c0597a9255a629837028e9866eb1
7
+ data.tar.gz: ddb2334bfa660b5114bf8dd5eb83c3aebcedd32087bf880f616e5630e6259c34ad2e9c264cc0c8e2ce04fd9d3b05ad5d89b89c212059cc71ce40007837a47838
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 0.11.4 - 12/02/2021
2
+ * [PATCH] Include Config Validations
3
+
1
4
  ## 0.11.3 - 29/01/2021
2
5
  * [FIX] --version, -v
3
6
 
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/verto/docker-entrypoint.sh"]
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.3)
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.0)
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.3'
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.3'
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.3'
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.3'
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.3'
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.3'
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.3'
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.3'
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.3'
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.3'
275
+ djin_version: '0.11.4'
276
276
 
277
277
  include:
278
278
  - git: 'https://github.com/catks/djin.git'
data/djin.yml CHANGED
@@ -1,4 +1,4 @@
1
- djin_version: '0.11.3'
1
+ djin_version: '0.11.4'
2
2
 
3
3
  _default_run_options: &default_run_options
4
4
  options: "--rm --entrypoint=''"
data/docker-entrypoint.sh CHANGED
@@ -4,4 +4,6 @@ set -e
4
4
 
5
5
  bundle check || bundle install
6
6
 
7
+ ./wait-for-it.sh gitserver:80 -t 10
8
+
7
9
  exec bundle exec "$@"
data/examples/djin.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- djin_version: '0.11.3'
2
+ djin_version: '0.11.4'
3
3
 
4
4
  include:
5
5
  - file: 'djin_lib/test.yml'
@@ -1,4 +1,4 @@
1
- djin_version: '0.11.3'
1
+ djin_version: '0.11.4'
2
2
 
3
3
  _default_run_options: &default_run_options
4
4
  options: "--rm --entrypoint=''"
@@ -1,4 +1,4 @@
1
- djin_version: '0.11.3'
1
+ djin_version: '0.11.4'
2
2
 
3
3
  include:
4
4
  - file: '.djin/server_tasks.yml'
@@ -1,4 +1,4 @@
1
- djin_version: '0.11.3'
1
+ djin_version: '0.11.4'
2
2
 
3
3
  include:
4
4
  - git: 'https://gitserver/myrepo.git'
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/include_resolver'
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::Interpreter::InvalidConfigurationError => e
56
+ rescue Djin::InvalidConfigurationError => e
55
57
  error_name = e.class.name.split('::').last
56
58
  abort("[#{error_name}] #{e.message}")
57
59
  end
@@ -1,36 +1,33 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Djin
4
- # TODO: Refactor this class to be the Interpreter
5
- # class and use the current interpreter as
6
- # a TaskLoader
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
- # Change Base Error
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, runtime_config: runtime_config, base_directory: base_directory)
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, runtime_config: {}, base_directory: '.')
23
- new(template_file_path, runtime_config: runtime_config, base_directory: base_directory).load!
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, runtime_config: {}, base_directory: '.')
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
- @runtime_config = runtime_config
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
- runtime_config: present_include.context)
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 ||= begin
126
- # TODO: Rename the resolved variables
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(@runtime_config)
138
+ @raw_djin_config ||= yaml_load(@template_file_content).deep_merge(@context_config)
151
139
  rescue Psych::SyntaxError => e
152
- raise Interpreter::InvalidConfigFileError, "File: #{@template_file.realpath}\n #{e.message}"
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(@runtime_config)
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 Interpreter::MissingVersionError, 'Missing djin_version' unless version
160
+ raise MissingVersionError, 'Missing djin_version' unless version
173
161
 
174
162
  return if file_config.version_supported?
175
163
 
176
- raise Interpreter::VersionNotSupportedError, "Version #{version} is not supported, use #{Djin::VERSION} or higher"
164
+ raise VersionNotSupportedError, "Version #{version} is not supported, use #{Djin::VERSION} or higher"
177
165
  end
178
166
 
179
167
  def validate_missing_config!
@@ -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 IncludeResolver
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 call(params)
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
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Djin
4
- VERSION = '0.11.3'
4
+ VERSION = '0.11.4'
5
5
  end
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.3
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-01-30 00:00:00.000000000 Z
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/include_resolver.rb
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