djin 0.11.3 → 0.11.4

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: 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