dip 3.8.3 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47956f8a76407c96fe354e73d11fb582d081736b6c83b4b1756e5b514d3f6e59
4
- data.tar.gz: e1b8a52c7fbcf29c407e562f12647e977429dd6661c41e11705eeee0d1f6e439
3
+ metadata.gz: 814f6f4b810a700663a169d6d34f535c010d7c9c9241a1343307f9657f50a9cd
4
+ data.tar.gz: 2d6b76d8e3459302accc2c264148083bb0b15d63fb365e9d4a12ed245820f843
5
5
  SHA512:
6
- metadata.gz: ac05cfd64e35d26919a9291af4dd9b94c30b5fc67c0e292ee2457c67c778c24d28fab485dd5cf8931c073560b302e06a3f4a7a8681ddf8b35ccc6c5cd2965211
7
- data.tar.gz: e43a7d567dd871f2fa4fc6d88571c9b07c929db2a177b1f2e8faa3c54f8ffb065fabe789bbc5ffde1dab180e07216ab92cb450b118d9204a7fc55ebbe6d0bfc4
6
+ metadata.gz: dc0e2299a4eed706c48868779fe655c7207e9b8d6353ed5bbb5887f318d1099e8c1db556f05af000b2869dc8e483b58ed874382062ebc2ea23d27def0481f705
7
+ data.tar.gz: f0a832bb6d9394b84a9e10b248ea9f1122d6cbed0fd8c973c679f9fc34faad066477b044bd8090cb8000b63d47f1d7329a67fd83e55a5d84e11c49379ec88d3e
data/README.md CHANGED
@@ -6,10 +6,7 @@
6
6
 
7
7
  Docker Interaction Process
8
8
 
9
- Command line utility that gives the "native" interaction with applications configured with Docker Compose. It is for the local development only. In practice, it creates the feeling that you work without containers.
10
-
11
- <a href="https://evilmartians.com/?utm_source=dip">
12
- <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
9
+ A command-line utility that gives the "native" interaction with applications configured with Docker Compose. It is for local development only. In practice, it creates the feeling that you work without containers.
13
10
 
14
11
  ## Presentations and examples
15
12
 
@@ -22,7 +19,7 @@ Command line utility that gives the "native" interaction with applications confi
22
19
 
23
20
  ## Integration with shell
24
21
 
25
- Dip can be injected into current shell (ZSH or Bash).
22
+ Dip can be injected into the current shell (ZSH or Bash).
26
23
 
27
24
  ```sh
28
25
  eval "$(dip console)"
@@ -38,9 +35,9 @@ down
38
35
  provision
39
36
  ```
40
37
 
41
- When we change the current directory, all shell aliases will be automatically removed. But when we will enter back to a directory with a dip.yml file, then shell aliases will be renewed.
38
+ When we change the current directory, all shell aliases will be automatically removed. But when we enter back into a directory with a `dip.yml` file, then shell aliases will be renewed.
42
39
 
43
- Also, in shell mode Dip is trying to determine passed manually environment variables. For example:
40
+ Also, in shell mode Dip is trying to determine manually passed environment variables. For example:
44
41
 
45
42
  ```sh
46
43
  VERSION=20180515103400 rails db:migrate:down
@@ -51,20 +48,34 @@ After that, it will be automatically applied when you open your preferred termin
51
48
 
52
49
  ## Installation
53
50
 
54
- You have two ways.
51
+ You have many ways.
52
+
53
+ ### Homebrew
54
+
55
55
 
56
- Install like a typical Ruby gem:
56
+ You can use [Homebrew](https://brew.sh) on macOS (or [Linux](https://docs.brew.sh/Homebrew-on-Linux)).
57
+
58
+ Today Homebrew tap for DIP is located at https://github.com/bibendi/homebrew-dip
59
+
60
+ ```sh
61
+ brew tap bibendi/dip
62
+ brew install dip
63
+ ```
64
+
65
+ ### Ruby Gem
57
66
 
58
67
  ```sh
59
68
  gem install dip
60
69
  ```
61
70
 
62
- If you don't have installed Ruby then you could copy a precompiled binary to your system.
71
+ ### Precompiled binary
72
+
73
+ If you don't have installed Ruby, then you could copy a precompiled binary to your system.
63
74
  It can be found at [releases page](https://github.com/bibendi/dip/releases)
64
75
  or type bellow into your terminal:
65
76
 
66
77
  ```sh
67
- curl -L https://github.com/bibendi/dip/releases/download/3.8.3/dip-`uname -s`-`uname -m` > /usr/local/bin/dip
78
+ curl -L https://github.com/bibendi/dip/releases/download/4.0.0/dip-`uname -s`-`uname -m` > /usr/local/bin/dip
68
79
  chmod +x /usr/local/bin/dip
69
80
  ```
70
81
 
@@ -86,13 +97,13 @@ The configuration file `dip.yml` should be placed in a project root directory.
86
97
  Also, in some cases, you may want to change the default config path by providing an environment variable `DIP_FILE`.
87
98
  If nearby places `dip.override.yml` file it would be merged into the main config.
88
99
 
89
- Below is an example of real config.
100
+ Below is an example of a real config.
90
101
  `dip.yml` reference will be written soon.
91
- Also, you can check out examples in the top.
92
-
102
+ Also, you can check out examples in the top.
93
103
 
94
104
  ```yml
95
- version: '2'
105
+ # Required minimum dip version
106
+ version: '4'
96
107
 
97
108
  environment:
98
109
  COMPOSE_EXT: development
@@ -106,32 +117,48 @@ compose:
106
117
 
107
118
  interaction:
108
119
  bash:
120
+ description: Open the Bash shell in app's container
109
121
  service: app
110
- compose_run_options: [no-deps]
122
+ compose:
123
+ run_options: [no-deps]
111
124
 
112
125
  bundle:
126
+ description: Run Bundler commands
113
127
  service: app
114
128
  command: bundle
115
129
 
116
130
  rake:
131
+ description: Run Rake commands
117
132
  service: app
118
133
  command: bundle exec rake
119
134
 
120
135
  rspec:
136
+ description: Run Rspec commands
121
137
  service: app
122
138
  environment:
123
139
  RAILS_ENV: test
124
140
  command: bundle exec rspec
125
141
 
126
142
  rails:
143
+ description: Run Rails commands
127
144
  service: app
128
145
  command: bundle exec rails
129
146
  subcommands:
130
147
  s:
148
+ description: Run Rails server at http://localhost:3000
131
149
  service: web
132
- compose_run_options: [service-ports]
150
+ compose:
151
+ run_options: [service-ports]
152
+
153
+ sidekiq:
154
+ description: Run sidekiq in background
155
+ service: worker
156
+ compose:
157
+ method: up
158
+ run_options: [detach]
133
159
 
134
160
  psql:
161
+ description: Run Postgres psql console
135
162
  service: app
136
163
  command: psql -h pg -U postgres
137
164
 
@@ -143,27 +170,39 @@ provision:
143
170
 
144
171
  ### dip run
145
172
 
146
- Run commands defined within `interaction` section of dip.yml
173
+ Run commands defined within the `interaction` section of dip.yml
147
174
 
148
175
  ```sh
149
176
  dip run rails c
150
177
  dip run rake db:migrate
151
178
  ```
152
179
 
153
- `run` argument can be ommited
180
+ `run` argument can be omitted
154
181
 
155
182
  ```sh
156
183
  dip rake db:migrate
157
184
  dip VERSION=12352452 rake db:rollback
158
185
  ```
159
186
 
187
+ ### dip ls
188
+
189
+ List al available run commands.
190
+
191
+ ```sh
192
+ dip ls
193
+
194
+ bash # Open the Bash shell in app's container
195
+ rails # Run Rails command
196
+ rails s # Run Rails server at http://localhost:3000
197
+ ```
198
+
160
199
  ### dip provision
161
200
 
162
201
  Run commands each by each from `provision` section of dip.yml
163
202
 
164
203
  ### dip compose
165
204
 
166
- Run docker-compose commands that are configured according with application dip.yml
205
+ Run docker-compose commands that are configured according to the application's dip.yml :
167
206
 
168
207
  ```sh
169
208
  dip compose COMMAND [OPTIONS]
@@ -199,7 +238,7 @@ volumes:
199
238
 
200
239
  ### dip nginx
201
240
 
202
- Runs Nginx server container based on [bibendi/nginx-proxy](https://github.com/bibendi/nginx-proxy) image. An application's docker-compose.yml should contains environment variable `VIRTUAL_HOST` and `VIRTUAL_PATH` and connects to external network `frontend`.
241
+ Runs Nginx server container based on [bibendi/nginx-proxy](https://github.com/bibendi/nginx-proxy) image. An application's docker-compose.yml should contain environment variable `VIRTUAL_HOST` and `VIRTUAL_PATH` and connects to external network `frontend`.
203
242
 
204
243
  foo-project/docker-compose.yml
205
244
 
@@ -255,7 +294,7 @@ curl www.bar-app.docker/api/v1/baz_service/qzz
255
294
 
256
295
  ### dip dns
257
296
 
258
- Runs DNS server container based on https://github.com/aacebedo/dnsdock It used for container to container requests through nginx. An application's docker-compose.yml should define `dns` configuration with environment variable `$DIP_DNS` and connect to external network `frontend`. `$DIP_DNS` will be automatically assigned by dip.
297
+ Runs a DNS server container based on https://github.com/aacebedo/dnsdock. It is used for container to container requests through Nginx. An application's docker-compose.yml should define `dns` configuration with environment variable `$DIP_DNS` and connect to external network `frontend`. `$DIP_DNS` will be automatically assigned by dip.
259
298
 
260
299
  ```sh
261
300
  dip dns up
data/lib/dip.rb CHANGED
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "dip/errors"
3
4
  require "dip/config"
4
5
  require "dip/environment"
5
6
 
6
7
  module Dip
7
- Error = Class.new(StandardError)
8
-
9
8
  class << self
10
9
  def config
11
10
  @config ||= Dip::Config.new
@@ -39,6 +39,12 @@ module Dip
39
39
  end
40
40
  map %w(--version -v) => :version
41
41
 
42
+ desc 'ls', 'List available run commands'
43
+ def ls
44
+ require_relative 'commands/list'
45
+ Dip::Commands::List.new.execute
46
+ end
47
+
42
48
  desc 'compose CMD [OPTIONS]', 'Run docker-compose commands'
43
49
  def compose(*argv)
44
50
  require_relative 'commands/compose'
@@ -22,7 +22,6 @@ module Dip
22
22
  desc: 'Docker image name'
23
23
  method_option :domain, aliases: '-d', type: :string, default: "docker",
24
24
  desc: 'Top level domain'
25
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
26
25
  def up
27
26
  if options[:help]
28
27
  invoke :help, ['up']
@@ -37,7 +36,6 @@ module Dip
37
36
  ).execute
38
37
  end
39
38
  end
40
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
41
39
 
42
40
  desc "down", "Stop dnsdock container"
43
41
  method_option :help, aliases: '-h', type: :boolean,
@@ -22,7 +22,6 @@ module Dip
22
22
  desc: 'Docker image name'
23
23
  method_option :domain, aliases: '-d', type: :string, default: "docker",
24
24
  desc: 'Top level domain'
25
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
26
25
  def up
27
26
  if options[:help]
28
27
  invoke :help, ['up']
@@ -37,7 +36,6 @@ module Dip
37
36
  ).execute
38
37
  end
39
38
  end
40
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
41
39
 
42
40
  desc "down", "Stop nginx container"
43
41
  method_option :help, aliases: '-h', type: :boolean,
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../command'
4
+ require_relative '../interaction_tree'
5
+
6
+ module Dip
7
+ module Commands
8
+ class List < Dip::Command
9
+ def execute
10
+ tree = InteractionTree.new(Dip.config.interaction).list
11
+
12
+ longest_name = tree.keys.map(&:size).max
13
+
14
+ tree.each do |name, command|
15
+ puts "#{name.ljust(longest_name)} ##{command[:description] ? ' ' + command[:description] : ''}"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -2,58 +2,47 @@
2
2
 
3
3
  require 'shellwords'
4
4
  require_relative '../command'
5
+ require_relative '../interaction_tree'
5
6
  require_relative 'compose'
6
7
 
7
8
  module Dip
8
9
  module Commands
9
10
  class Run < Dip::Command
10
- def initialize(cmd, subcmd = nil, *argv)
11
- @cmd = cmd.to_sym
12
- @subcmd = subcmd.to_sym if subcmd
13
- @argv = argv
14
- @config = ::Dip.config.interaction
11
+ def initialize(cmd, *argv)
12
+ @command, @argv = InteractionTree.
13
+ new(Dip.config.interaction).
14
+ find(cmd, *argv)&.
15
+ values_at(:command, :argv)
16
+
17
+ raise Dip::Error, "Command `#{[cmd, *argv].join(' ')}` not recognized!" unless command
18
+
19
+ Dip.env.merge(command[:environment])
15
20
  end
16
21
 
17
- # TODO: Refactor
18
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
19
22
  def execute
20
- command = @config.fetch(@cmd)
21
- command[:subcommands] ||= {}
22
-
23
- if (subcommand = command[:subcommands].fetch(@subcmd, {})).any?
24
- subcommand[:command] ||= nil
25
- command.merge!(subcommand)
26
- elsif @subcmd
27
- @argv.unshift(@subcmd.to_s)
28
- end
23
+ Dip::Commands::Compose.new(
24
+ command[:compose][:method],
25
+ *compose_arguments
26
+ ).execute
27
+ end
29
28
 
30
- Dip.env.merge(command[:environment]) if command[:environment]
29
+ private
31
30
 
32
- compose_method = command.fetch(:compose_method, "run").to_s
31
+ attr_reader :command, :argv
33
32
 
34
- compose_argv = []
35
- compose_argv.concat(prepare_compose_run_options(command[:compose_run_options]))
33
+ def compose_arguments
34
+ compose_argv = command[:compose][:run_options].dup
36
35
 
37
- if compose_method == "run"
36
+ if command[:compose][:method] == "run"
38
37
  compose_argv.concat(run_vars)
39
38
  compose_argv << "--rm"
40
39
  end
41
40
 
42
- compose_argv << command.fetch(:service).to_s
43
- compose_argv += command[:command].to_s.shellsplit
44
- compose_argv.concat(@argv)
45
-
46
- Dip::Commands::Compose.new(compose_method, *compose_argv).execute
47
- end
48
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
49
-
50
- def prepare_compose_run_options(value)
51
- return [] unless value
41
+ compose_argv << command.fetch(:service)
42
+ compose_argv.concat(command[:command].to_s.shellsplit)
43
+ compose_argv.concat(argv)
52
44
 
53
- value.map do |o|
54
- o = o.start_with?("-") ? o : "--#{o}"
55
- o.shellsplit
56
- end.flatten
45
+ compose_argv
57
46
  end
58
47
 
59
48
  def run_vars
@@ -3,6 +3,7 @@
3
3
  require "yaml"
4
4
  require "erb"
5
5
 
6
+ require "dip/version"
6
7
  require "dip/ext/hash"
7
8
 
8
9
  using ActiveSupportHashHelpers
@@ -52,6 +53,13 @@ module Dip
52
53
  raise ArgumentError, "Dip config not found at path '#{self.class.path}'" unless self.class.exist?
53
54
 
54
55
  config = self.class.load_yaml
56
+
57
+ unless Gem::Version.new(Dip::VERSION) >= Gem::Version.new(config.fetch(:version))
58
+ raise VersionMismatchError, "Your dip version is `#{Dip::VERSION}`, " \
59
+ "but config requires minimum version `#{config[:version]}`. " \
60
+ "Please upgrade your dip!"
61
+ end
62
+
55
63
  config.deep_merge!(self.class.load_yaml(self.class.override_path))
56
64
 
57
65
  @config = config
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dip
4
+ Error = Class.new(StandardError)
5
+
6
+ class VersionMismatchError < Dip::Error
7
+ end
8
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "shellwords"
4
+ require "dip/ext/hash"
5
+
6
+ using ActiveSupportHashHelpers
7
+
8
+ module Dip
9
+ class InteractionTree
10
+ def initialize(entries)
11
+ @entries = entries
12
+ end
13
+
14
+ def find(name, *argv)
15
+ entry = entries[name.to_sym]
16
+ return unless entry
17
+
18
+ commands = expand(name, entry)
19
+
20
+ keys = [name, *argv]
21
+ rest = []
22
+
23
+ keys.size.times do
24
+ if (command = commands[keys.join(" ")])
25
+ return {command: command, argv: rest.reverse!}
26
+ else
27
+ rest << keys.pop
28
+ end
29
+ end
30
+ end
31
+
32
+ def list
33
+ entries.each_with_object({}) do |(name, entry), memo|
34
+ expand(name.to_s, entry, tree: memo)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :entries
41
+
42
+ def expand(name, entry, tree: {})
43
+ cmd = build_command(entry)
44
+
45
+ tree[name] = cmd
46
+
47
+ entry[:subcommands]&.each do |sub_name, sub_entry|
48
+ sub_command_defaults!(sub_entry)
49
+
50
+ expand("#{name} #{sub_name}", entry.deep_merge(sub_entry), tree: tree)
51
+ end
52
+
53
+ tree
54
+ end
55
+
56
+ def build_command(entry)
57
+ {
58
+ description: entry[:description],
59
+ service: entry.fetch(:service),
60
+ command: entry[:command],
61
+ environment: entry[:environment] || {},
62
+ compose: {
63
+ method: entry.dig(:compose, :method) || entry[:compose_method] || "run",
64
+ run_options: compose_run_options(entry.dig(:compose, :run_options) || entry[:compose_run_options])
65
+ }
66
+ }
67
+ end
68
+
69
+ def sub_command_defaults!(entry)
70
+ entry[:command] ||= nil
71
+ entry[:subcommands] ||= nil
72
+ entry[:description] ||= nil
73
+ end
74
+
75
+ def compose_run_options(value)
76
+ return [] unless value
77
+
78
+ value.map do |o|
79
+ o = o.start_with?("-") ? o : "--#{o}"
80
+ o.shellsplit
81
+ end.flatten
82
+ end
83
+ end
84
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dip
4
- VERSION = "3.8.3"
4
+ VERSION = "4.0.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dip
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.8.3
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - bibendi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-24 00:00:00.000000000 Z
11
+ date: 2019-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '12.3'
61
+ version: '13.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '12.3'
68
+ version: '13.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -144,13 +144,16 @@ files:
144
144
  - lib/dip/commands/compose.rb
145
145
  - lib/dip/commands/console.rb
146
146
  - lib/dip/commands/dns.rb
147
+ - lib/dip/commands/list.rb
147
148
  - lib/dip/commands/nginx.rb
148
149
  - lib/dip/commands/provision.rb
149
150
  - lib/dip/commands/run.rb
150
151
  - lib/dip/commands/ssh.rb
151
152
  - lib/dip/config.rb
152
153
  - lib/dip/environment.rb
154
+ - lib/dip/errors.rb
153
155
  - lib/dip/ext/hash.rb
156
+ - lib/dip/interaction_tree.rb
154
157
  - lib/dip/run_vars.rb
155
158
  - lib/dip/version.rb
156
159
  homepage: https://github.com/bibendi/dip
@@ -166,14 +169,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
166
169
  requirements:
167
170
  - - ">="
168
171
  - !ruby/object:Gem::Version
169
- version: '0'
172
+ version: '2.3'
170
173
  required_rubygems_version: !ruby/object:Gem::Requirement
171
174
  requirements:
172
175
  - - ">="
173
176
  - !ruby/object:Gem::Version
174
177
  version: '0'
175
178
  requirements: []
176
- rubygems_version: 3.0.4
179
+ rubyforge_project:
180
+ rubygems_version: 2.7.7
177
181
  signing_key:
178
182
  specification_version: 4
179
183
  summary: Ruby gem CLI tool for better interacting docker-compose files.