dip 6.1.0 → 7.0.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/README.md +11 -33
- data/exe/dip +6 -6
- data/lib/dip.rb +1 -1
- data/lib/dip/cli.rb +28 -23
- data/lib/dip/cli/console.rb +7 -7
- data/lib/dip/cli/dns.rb +31 -31
- data/lib/dip/cli/nginx.rb +25 -25
- data/lib/dip/cli/ssh.rb +23 -23
- data/lib/dip/command.rb +8 -7
- data/lib/dip/commands/compose.rb +7 -7
- data/lib/dip/commands/console.rb +5 -5
- data/lib/dip/commands/dns.rb +7 -7
- data/lib/dip/commands/list.rb +3 -3
- data/lib/dip/commands/nginx.rb +4 -4
- data/lib/dip/commands/provision.rb +1 -1
- data/lib/dip/commands/run.rb +31 -18
- data/lib/dip/commands/ssh.rb +3 -3
- data/lib/dip/config.rb +5 -5
- data/lib/dip/environment.rb +6 -6
- data/lib/dip/ext/hash.rb +1 -1
- data/lib/dip/interaction_tree.rb +3 -16
- data/lib/dip/version.rb +1 -1
- metadata +35 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5df0e0954a241e561cfe313fc0f6a8000644e8ebe102a954ba721e81752046a6
|
4
|
+
data.tar.gz: 89c96af17e4dc28d2d0953deb411075e662eb7815193517634b08242d9a31761
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6730c668a3850de7625f819045787dd901546868df56ecde7264796736b567e66a3ef96a7db7b7855585f6b6a47ba0b241e0ce7b07177692cf0df783a35bc313
|
7
|
+
data.tar.gz: d32638715384461a37cb62ed6f2f0f41b6b3ea3618e9b7dd006d3d57b88325f3c37ac9faa5e82727fda56297473153b59736c97f162d326e8ffb3d1020519d45
|
data/README.md
CHANGED
@@ -19,6 +19,8 @@ A command-line utility that gives the "native" interaction with applications con
|
|
19
19
|
- Dockerized Ruby on Rails applications: [one](https://github.com/lewagon/rails-k8s-demo), [two](https://github.com/bibendi/dip-example-rails), [three](https://github.com/evilmartians/evil_chat)
|
20
20
|
- Dockerized Node.js application: [one](https://github.com/bibendi/twinkle.js), [two](https://github.com/bibendi/yt-graphql-react-event-booking-api)
|
21
21
|
- [Dockerized Ruby gem](https://github.com/bibendi/schked)
|
22
|
+
- [Dockerizing Ruby and Rails development](https://evilmartians.com/chronicles/ruby-on-whales-docker-for-ruby-rails-development)
|
23
|
+
- [Reusable development containers with Docker Compose and Dip](https://evilmartians.com/chronicles/reusable-development-containers-with-docker-compose-and-dip)
|
22
24
|
|
23
25
|
[](https://asciinema.org/a/210236)
|
24
26
|
|
@@ -36,6 +38,7 @@ After that we can type commands without `dip` prefix. For example:
|
|
36
38
|
<run-command> *any-args
|
37
39
|
compose *any-compose-arg
|
38
40
|
up <service>
|
41
|
+
build
|
39
42
|
down
|
40
43
|
provision
|
41
44
|
```
|
@@ -53,41 +56,11 @@ After that, it will be automatically applied when you open your preferred termin
|
|
53
56
|
|
54
57
|
## Installation
|
55
58
|
|
56
|
-
You have many ways.
|
57
|
-
|
58
|
-
### Homebrew
|
59
|
-
|
60
|
-
|
61
|
-
You can use [Homebrew](https://brew.sh) on macOS (or [Linux](https://docs.brew.sh/Homebrew-on-Linux)).
|
62
|
-
|
63
|
-
Today Homebrew tap for DIP is located at https://github.com/bibendi/homebrew-dip
|
64
|
-
|
65
|
-
```sh
|
66
|
-
brew tap bibendi/dip
|
67
|
-
brew install dip
|
68
|
-
```
|
69
|
-
|
70
|
-
### Ruby Gem
|
71
|
-
|
72
59
|
```sh
|
73
60
|
gem install dip
|
74
61
|
```
|
75
62
|
|
76
|
-
|
77
|
-
|
78
|
-
If you don't have installed Ruby, then you could copy a precompiled binary to your system.
|
79
|
-
It can be found at [releases page](https://github.com/bibendi/dip/releases)
|
80
|
-
or type bellow into your terminal:
|
81
|
-
|
82
|
-
```sh
|
83
|
-
curl -L https://github.com/bibendi/dip/releases/download/v6.1.0/dip-`uname -s`-`uname -m` > /usr/local/bin/dip
|
84
|
-
chmod +x /usr/local/bin/dip
|
85
|
-
```
|
86
|
-
|
87
|
-
## Docker installation
|
88
|
-
|
89
|
-
- [Ubuntu](docs/docker-ubuntu-install.md)
|
90
|
-
- [Mac OS](docs/docker-for-mac-install.md)
|
63
|
+
The compiled binary is no more provided since version 7, because of new version of [Ruby Packer](https://github.com/pmq20/ruby-packer) not released for a long time with recent Ruby version. Also there was a lot of work to prepare each release of Dip for MacOS version.
|
91
64
|
|
92
65
|
## Usage
|
93
66
|
|
@@ -108,7 +81,7 @@ Also, you can check out examples at the top.
|
|
108
81
|
|
109
82
|
```yml
|
110
83
|
# Required minimum dip version
|
111
|
-
version: '
|
84
|
+
version: '7.0'
|
112
85
|
|
113
86
|
environment:
|
114
87
|
COMPOSE_EXT: development
|
@@ -121,7 +94,7 @@ compose:
|
|
121
94
|
project_name: bear
|
122
95
|
|
123
96
|
interaction:
|
124
|
-
|
97
|
+
shell:
|
125
98
|
description: Open the Bash shell in app's container
|
126
99
|
service: app
|
127
100
|
command: bash
|
@@ -169,8 +142,13 @@ interaction:
|
|
169
142
|
default_args: db_dev
|
170
143
|
command: psql -h pg -U postgres
|
171
144
|
|
145
|
+
clean_cache:
|
146
|
+
description: Delete cache files on the host machine
|
147
|
+
command: rm -rf $(pwd)/tmp/cache/*
|
148
|
+
|
172
149
|
provision:
|
173
150
|
- dip compose down --volumes
|
151
|
+
- dip clean_cache
|
174
152
|
- dip compose up -d pg redis
|
175
153
|
- dip bash -c ./bin/setup
|
176
154
|
```
|
data/exe/dip
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
lib_path = File.expand_path(
|
4
|
+
lib_path = File.expand_path("../lib", __dir__)
|
5
5
|
$LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
|
6
6
|
|
7
7
|
begin
|
8
|
-
require
|
8
|
+
require "pry-byebug" if ENV["DIP_ENV"] == "debug"
|
9
9
|
rescue LoadError
|
10
10
|
# do nothing
|
11
11
|
end
|
12
12
|
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
13
|
+
require "dip"
|
14
|
+
require "dip/cli"
|
15
|
+
require "dip/run_vars"
|
16
16
|
|
17
|
-
Signal.trap(
|
17
|
+
Signal.trap("INT") do
|
18
18
|
warn("\n#{caller.join("\n")}: interrupted")
|
19
19
|
exit(1)
|
20
20
|
end
|
data/lib/dip.rb
CHANGED
data/lib/dip/cli.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "thor"
|
4
|
+
require "dip/run_vars"
|
5
5
|
|
6
6
|
module Dip
|
7
7
|
class CLI < Thor
|
@@ -34,25 +34,30 @@ module Dip
|
|
34
34
|
|
35
35
|
stop_on_unknown_option! :run
|
36
36
|
|
37
|
-
desc
|
37
|
+
desc "version", "dip version"
|
38
38
|
def version
|
39
|
-
require_relative
|
39
|
+
require_relative "version"
|
40
40
|
puts Dip::VERSION
|
41
41
|
end
|
42
|
-
map %w
|
42
|
+
map %w[--version -v] => :version
|
43
43
|
|
44
|
-
desc
|
44
|
+
desc "ls", "List available run commands"
|
45
45
|
def ls
|
46
|
-
require_relative
|
46
|
+
require_relative "commands/list"
|
47
47
|
Dip::Commands::List.new.execute
|
48
48
|
end
|
49
49
|
|
50
|
-
desc
|
50
|
+
desc "compose CMD [OPTIONS]", "Run docker-compose commands"
|
51
51
|
def compose(*argv)
|
52
|
-
require_relative
|
52
|
+
require_relative "commands/compose"
|
53
53
|
Dip::Commands::Compose.new(*argv).execute
|
54
54
|
end
|
55
55
|
|
56
|
+
desc "build [OPTIONS] SERVICE", "Run `docker-compose build` command"
|
57
|
+
def build(*argv)
|
58
|
+
compose("build", *argv)
|
59
|
+
end
|
60
|
+
|
56
61
|
desc "up [OPTIONS] SERVICE", "Run `docker-compose up` command"
|
57
62
|
def up(*argv)
|
58
63
|
compose("up", *argv)
|
@@ -63,49 +68,49 @@ module Dip
|
|
63
68
|
compose("stop", *argv)
|
64
69
|
end
|
65
70
|
|
66
|
-
desc "down
|
71
|
+
desc "down [OPTIONS]", "Run `docker-compose down` command"
|
67
72
|
def down(*argv)
|
68
73
|
compose("down", *argv)
|
69
74
|
end
|
70
75
|
|
71
|
-
desc
|
72
|
-
method_option :publish, aliases:
|
76
|
+
desc "run [OPTIONS] CMD [ARGS]", "Run configured command in a docker-compose service. `run` prefix may be omitted"
|
77
|
+
method_option :publish, aliases: "-p", type: :string, repeatable: true,
|
73
78
|
desc: "Publish a container's port(s) to the host"
|
74
|
-
method_option :help, aliases:
|
79
|
+
method_option :help, aliases: "-h", type: :boolean, desc: "Display usage information"
|
75
80
|
def run(*argv)
|
76
81
|
if argv.empty? || options[:help]
|
77
|
-
invoke :help, [
|
82
|
+
invoke :help, ["run"]
|
78
83
|
else
|
79
|
-
require_relative
|
84
|
+
require_relative "commands/run"
|
80
85
|
Dip::Commands::Run.new(*argv, publish: options[:publish]).execute
|
81
86
|
end
|
82
87
|
end
|
83
88
|
|
84
89
|
desc "provision", "Execute commands within provision section"
|
85
|
-
method_option :help, aliases:
|
86
|
-
desc:
|
90
|
+
method_option :help, aliases: "-h", type: :boolean,
|
91
|
+
desc: "Display usage information"
|
87
92
|
def provision
|
88
93
|
if options[:help]
|
89
|
-
invoke :help, [
|
94
|
+
invoke :help, ["provision"]
|
90
95
|
else
|
91
|
-
require_relative
|
96
|
+
require_relative "commands/provision"
|
92
97
|
Dip::Commands::Provision.new.execute
|
93
98
|
end
|
94
99
|
end
|
95
100
|
|
96
|
-
require_relative
|
101
|
+
require_relative "cli/ssh"
|
97
102
|
desc "ssh", "ssh-agent container commands"
|
98
103
|
subcommand :ssh, Dip::CLI::SSH
|
99
104
|
|
100
|
-
require_relative
|
105
|
+
require_relative "cli/dns"
|
101
106
|
desc "dns", "DNS server for automatic docker container discovery"
|
102
107
|
subcommand :dns, Dip::CLI::DNS
|
103
108
|
|
104
|
-
require_relative
|
109
|
+
require_relative "cli/nginx"
|
105
110
|
desc "nginx", "Nginx reverse proxy server"
|
106
111
|
subcommand :nginx, Dip::CLI::Nginx
|
107
112
|
|
108
|
-
require_relative
|
113
|
+
require_relative "cli/console"
|
109
114
|
desc "console", "Integrate Dip commands into shell (only ZSH and Bash is supported)"
|
110
115
|
subcommand :console, Dip::CLI::Console
|
111
116
|
end
|
data/lib/dip/cli/console.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "thor"
|
4
4
|
require_relative "./base"
|
5
5
|
require_relative "../commands/console"
|
6
6
|
|
@@ -8,11 +8,11 @@ module Dip
|
|
8
8
|
class CLI
|
9
9
|
class Console < Base
|
10
10
|
desc "start", "Integrate Dip into current shell"
|
11
|
-
method_option :help, aliases:
|
12
|
-
desc:
|
11
|
+
method_option :help, aliases: "-h", type: :boolean,
|
12
|
+
desc: "Display usage information"
|
13
13
|
def start
|
14
14
|
if options[:help]
|
15
|
-
invoke :help, [
|
15
|
+
invoke :help, ["start"]
|
16
16
|
else
|
17
17
|
Dip::Commands::Console::Start.new.execute
|
18
18
|
end
|
@@ -21,11 +21,11 @@ module Dip
|
|
21
21
|
default_task :start
|
22
22
|
|
23
23
|
desc "inject", "Inject aliases"
|
24
|
-
method_option :help, aliases:
|
25
|
-
desc:
|
24
|
+
method_option :help, aliases: "-h", type: :boolean,
|
25
|
+
desc: "Display usage information"
|
26
26
|
def inject
|
27
27
|
if options[:help]
|
28
|
-
invoke :help, [
|
28
|
+
invoke :help, ["inject"]
|
29
29
|
else
|
30
30
|
Dip::Commands::Console::Inject.new.execute
|
31
31
|
end
|
data/lib/dip/cli/dns.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "thor"
|
4
4
|
require_relative "./base"
|
5
5
|
require_relative "../commands/dns"
|
6
6
|
|
@@ -9,23 +9,23 @@ module Dip
|
|
9
9
|
# See more https://github.com/aacebedo/dnsdock
|
10
10
|
class DNS < Base
|
11
11
|
desc "up", "Run dnsdock container"
|
12
|
-
method_option :help, aliases:
|
13
|
-
desc:
|
14
|
-
method_option :name, aliases:
|
15
|
-
desc:
|
16
|
-
method_option :socket, aliases:
|
17
|
-
desc:
|
18
|
-
method_option :net, aliases:
|
19
|
-
desc:
|
20
|
-
method_option :publish, aliases:
|
21
|
-
desc:
|
22
|
-
method_option :image, aliases:
|
23
|
-
desc:
|
24
|
-
method_option :domain, aliases:
|
25
|
-
desc:
|
12
|
+
method_option :help, aliases: "-h", type: :boolean,
|
13
|
+
desc: "Display usage information"
|
14
|
+
method_option :name, aliases: "-n", type: :string, default: "dnsdock",
|
15
|
+
desc: "Container name"
|
16
|
+
method_option :socket, aliases: "-s", type: :string, default: "/var/run/docker.sock",
|
17
|
+
desc: "Path to docker socket"
|
18
|
+
method_option :net, aliases: "-t", type: :string, default: "frontend",
|
19
|
+
desc: "Container network name"
|
20
|
+
method_option :publish, aliases: "-p", type: :string, default: "53/udp",
|
21
|
+
desc: "Container port"
|
22
|
+
method_option :image, aliases: "-i", type: :string, default: "aacebedo/dnsdock:latest-amd64",
|
23
|
+
desc: "Docker image name"
|
24
|
+
method_option :domain, aliases: "-d", type: :string, default: "docker",
|
25
|
+
desc: "Top level domain"
|
26
26
|
def up
|
27
27
|
if options[:help]
|
28
|
-
invoke :help, [
|
28
|
+
invoke :help, ["up"]
|
29
29
|
else
|
30
30
|
Dip::Commands::DNS::Up.new(
|
31
31
|
name: options.fetch(:name),
|
@@ -39,13 +39,13 @@ module Dip
|
|
39
39
|
end
|
40
40
|
|
41
41
|
desc "down", "Stop dnsdock container"
|
42
|
-
method_option :help, aliases:
|
43
|
-
desc:
|
44
|
-
method_option :name, aliases:
|
45
|
-
desc:
|
42
|
+
method_option :help, aliases: "-h", type: :boolean,
|
43
|
+
desc: "Display usage information"
|
44
|
+
method_option :name, aliases: "-n", type: :string, default: "dnsdock",
|
45
|
+
desc: "Container name"
|
46
46
|
def down
|
47
47
|
if options[:help]
|
48
|
-
invoke :help, [
|
48
|
+
invoke :help, ["down"]
|
49
49
|
else
|
50
50
|
Dip::Commands::DNS::Down.new(
|
51
51
|
name: options.fetch(:name)
|
@@ -54,11 +54,11 @@ module Dip
|
|
54
54
|
end
|
55
55
|
|
56
56
|
desc "restart", "Stop and start dnsdock container"
|
57
|
-
method_option :help, aliases:
|
58
|
-
desc:
|
57
|
+
method_option :help, aliases: "-h", type: :boolean,
|
58
|
+
desc: "Display usage information"
|
59
59
|
def restart(*args)
|
60
60
|
if options[:help]
|
61
|
-
invoke :help, [
|
61
|
+
invoke :help, ["restart"]
|
62
62
|
else
|
63
63
|
Dip::CLI::DNS.start(["down"] + args)
|
64
64
|
sleep 1
|
@@ -67,15 +67,15 @@ module Dip
|
|
67
67
|
end
|
68
68
|
|
69
69
|
desc "ip", "Get ip address of dnsdock container"
|
70
|
-
method_option :help, aliases:
|
71
|
-
desc:
|
72
|
-
method_option :name, aliases:
|
73
|
-
desc:
|
74
|
-
method_option :net, aliases:
|
75
|
-
desc:
|
70
|
+
method_option :help, aliases: "-h", type: :boolean,
|
71
|
+
desc: "Display usage information"
|
72
|
+
method_option :name, aliases: "-n", type: :string, default: "dnsdock",
|
73
|
+
desc: "Container name"
|
74
|
+
method_option :net, aliases: "-t", type: :string, default: "frontend",
|
75
|
+
desc: "Container network name"
|
76
76
|
def ip
|
77
77
|
if options[:help]
|
78
|
-
invoke :help, [
|
78
|
+
invoke :help, ["status"]
|
79
79
|
else
|
80
80
|
Dip::Commands::DNS::IP.new(
|
81
81
|
name: options.fetch(:name),
|
data/lib/dip/cli/nginx.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "thor"
|
4
4
|
require_relative "./base"
|
5
5
|
require_relative "../commands/nginx"
|
6
6
|
|
@@ -9,24 +9,24 @@ module Dip
|
|
9
9
|
# See more https://github.com/bibendi/nginx-proxy
|
10
10
|
class Nginx < Base
|
11
11
|
desc "up", "Run nginx container"
|
12
|
-
method_option :help, aliases:
|
13
|
-
desc:
|
14
|
-
method_option :name, aliases:
|
15
|
-
desc:
|
16
|
-
method_option :socket, aliases:
|
17
|
-
desc:
|
18
|
-
method_option :net, aliases:
|
19
|
-
desc:
|
20
|
-
method_option :publish, aliases:
|
21
|
-
desc:
|
22
|
-
method_option :image, aliases:
|
23
|
-
desc:
|
24
|
-
method_option :domain, aliases:
|
25
|
-
desc:
|
26
|
-
method_option :certs, aliases:
|
12
|
+
method_option :help, aliases: "-h", type: :boolean,
|
13
|
+
desc: "Display usage information"
|
14
|
+
method_option :name, aliases: "-n", type: :string, default: "nginx",
|
15
|
+
desc: "Container name"
|
16
|
+
method_option :socket, aliases: "-s", type: :string, default: "/var/run/docker.sock",
|
17
|
+
desc: "Path to docker socket"
|
18
|
+
method_option :net, aliases: "-t", type: :string, default: "frontend",
|
19
|
+
desc: "Container network name"
|
20
|
+
method_option :publish, aliases: "-p", type: :array, default: ["80:80"],
|
21
|
+
desc: "Container port(s). For more than one port, separate them by a space"
|
22
|
+
method_option :image, aliases: "-i", type: :string, default: "bibendi/nginx-proxy:latest",
|
23
|
+
desc: "Docker image name"
|
24
|
+
method_option :domain, aliases: "-d", type: :string, default: "docker",
|
25
|
+
desc: "Top level domain"
|
26
|
+
method_option :certs, aliases: "-c", type: :string, desc: "Path to ssl certificates"
|
27
27
|
def up
|
28
28
|
if options[:help]
|
29
|
-
invoke :help, [
|
29
|
+
invoke :help, ["up"]
|
30
30
|
else
|
31
31
|
Dip::Commands::Nginx::Up.new(
|
32
32
|
name: options.fetch(:name),
|
@@ -41,13 +41,13 @@ module Dip
|
|
41
41
|
end
|
42
42
|
|
43
43
|
desc "down", "Stop nginx container"
|
44
|
-
method_option :help, aliases:
|
45
|
-
desc:
|
46
|
-
method_option :name, aliases:
|
47
|
-
desc:
|
44
|
+
method_option :help, aliases: "-h", type: :boolean,
|
45
|
+
desc: "Display usage information"
|
46
|
+
method_option :name, aliases: "-n", type: :string, default: "nginx",
|
47
|
+
desc: "Container name"
|
48
48
|
def down
|
49
49
|
if options[:help]
|
50
|
-
invoke :help, [
|
50
|
+
invoke :help, ["down"]
|
51
51
|
else
|
52
52
|
Dip::Commands::Nginx::Down.new(
|
53
53
|
name: options.fetch(:name)
|
@@ -56,11 +56,11 @@ module Dip
|
|
56
56
|
end
|
57
57
|
|
58
58
|
desc "restart", "Stop and start nginx container"
|
59
|
-
method_option :help, aliases:
|
60
|
-
desc:
|
59
|
+
method_option :help, aliases: "-h", type: :boolean,
|
60
|
+
desc: "Display usage information"
|
61
61
|
def restart(*args)
|
62
62
|
if options[:help]
|
63
|
-
invoke :help, [
|
63
|
+
invoke :help, ["restart"]
|
64
64
|
else
|
65
65
|
Dip::CLI::Nginx.start(["down"] + args)
|
66
66
|
sleep 1
|
data/lib/dip/cli/ssh.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "thor"
|
4
4
|
require_relative "./base"
|
5
5
|
require_relative "../commands/ssh"
|
6
6
|
|
@@ -8,22 +8,22 @@ module Dip
|
|
8
8
|
class CLI
|
9
9
|
class SSH < Base
|
10
10
|
desc "up", "Run ssh-agent container"
|
11
|
-
method_option :help, aliases:
|
12
|
-
desc:
|
13
|
-
method_option :key, aliases:
|
14
|
-
desc:
|
15
|
-
method_option :volume, aliases:
|
16
|
-
desc:
|
17
|
-
method_option :interactive, aliases:
|
18
|
-
desc:
|
19
|
-
method_option :user, aliases:
|
20
|
-
desc:
|
11
|
+
method_option :help, aliases: "-h", type: :boolean,
|
12
|
+
desc: "Display usage information"
|
13
|
+
method_option :key, aliases: "-k", type: :string, default: "$HOME/.ssh/id_rsa",
|
14
|
+
desc: "Path to ssh key"
|
15
|
+
method_option :volume, aliases: "-v", type: :string, default: "$HOME",
|
16
|
+
desc: "Mounted docker volume"
|
17
|
+
method_option :interactive, aliases: "-t", type: :boolean, default: true,
|
18
|
+
desc: "Run in interactive mode"
|
19
|
+
method_option :user, aliases: "-u", type: :string,
|
20
|
+
desc: "UID for ssh-agent container"
|
21
21
|
# Backward compatibility
|
22
|
-
method_option :nonteractive, aliases:
|
23
|
-
desc:
|
22
|
+
method_option :nonteractive, aliases: "-T", type: :boolean,
|
23
|
+
desc: "Run in noninteractive mode"
|
24
24
|
def up
|
25
25
|
if options[:help]
|
26
|
-
invoke :help, [
|
26
|
+
invoke :help, ["up"]
|
27
27
|
else
|
28
28
|
Dip::Commands::SSH::Up.new(
|
29
29
|
key: options.fetch(:key),
|
@@ -37,22 +37,22 @@ module Dip
|
|
37
37
|
map add: :up
|
38
38
|
|
39
39
|
desc "down", "Stop ssh-agent container"
|
40
|
-
method_option :help, aliases:
|
41
|
-
desc:
|
40
|
+
method_option :help, aliases: "-h", type: :boolean,
|
41
|
+
desc: "Display usage information"
|
42
42
|
def down
|
43
43
|
if options[:help]
|
44
|
-
invoke :help, [
|
44
|
+
invoke :help, ["down"]
|
45
45
|
else
|
46
46
|
Dip::Commands::SSH::Down.new.execute
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
50
|
desc "restart", "Stop and start ssh-agent container"
|
51
|
-
method_option :help, aliases:
|
52
|
-
desc:
|
51
|
+
method_option :help, aliases: "-h", type: :boolean,
|
52
|
+
desc: "Display usage information"
|
53
53
|
def restart(*args)
|
54
54
|
if options[:help]
|
55
|
-
invoke :help, [
|
55
|
+
invoke :help, ["restart"]
|
56
56
|
else
|
57
57
|
Dip::CLI::SSH.start(["down"] + args)
|
58
58
|
sleep 1
|
@@ -61,11 +61,11 @@ module Dip
|
|
61
61
|
end
|
62
62
|
|
63
63
|
desc "status", "Show status of ssh-agent container"
|
64
|
-
method_option :help, aliases:
|
65
|
-
desc:
|
64
|
+
method_option :help, aliases: "-h", type: :boolean,
|
65
|
+
desc: "Display usage information"
|
66
66
|
def status
|
67
67
|
if options[:help]
|
68
|
-
invoke :help, [
|
68
|
+
invoke :help, ["status"]
|
69
69
|
else
|
70
70
|
Dip::Commands::SSH::Status.new.execute
|
71
71
|
end
|
data/lib/dip/command.rb
CHANGED
@@ -9,15 +9,15 @@ module Dip
|
|
9
9
|
def_delegators self, :shell, :subshell
|
10
10
|
|
11
11
|
class ExecRunner
|
12
|
-
def self.call(
|
13
|
-
::Process.exec(env,
|
12
|
+
def self.call(cmdline, env: {}, **options)
|
13
|
+
::Process.exec(env, cmdline, options)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
class SubshellRunner
|
18
|
-
def self.call(
|
19
|
-
return if ::Kernel.system(env,
|
20
|
-
raise Dip::Error, "Command '#{
|
18
|
+
def self.call(cmdline, env: {}, panic: true, **options)
|
19
|
+
return if ::Kernel.system(env, cmdline, options)
|
20
|
+
raise Dip::Error, "Command '#{cmdline}' executed with error." if panic
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -25,11 +25,12 @@ module Dip
|
|
25
25
|
def shell(cmd, argv = [], subshell: false, **options)
|
26
26
|
cmd = Dip.env.interpolate(cmd)
|
27
27
|
argv = argv.map { |arg| Dip.env.interpolate(arg) }
|
28
|
+
cmdline = [cmd, *argv].compact.join(" ")
|
28
29
|
|
29
|
-
puts [Dip.env.vars,
|
30
|
+
puts [Dip.env.vars, cmdline].inspect if Dip.debug?
|
30
31
|
|
31
32
|
runner = subshell ? SubshellRunner : ExecRunner
|
32
|
-
runner.call(
|
33
|
+
runner.call(cmdline, env: Dip.env.vars, **options)
|
33
34
|
end
|
34
35
|
|
35
36
|
def subshell(*args, **kwargs)
|
data/lib/dip/commands/compose.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "pathname"
|
4
4
|
|
5
|
-
require_relative
|
6
|
-
require_relative
|
5
|
+
require_relative "../command"
|
6
|
+
require_relative "dns"
|
7
7
|
|
8
8
|
module Dip
|
9
9
|
module Commands
|
@@ -49,7 +49,7 @@ module Dip
|
|
49
49
|
next unless value.is_a?(String)
|
50
50
|
|
51
51
|
value = ::Dip.env.interpolate(value)
|
52
|
-
["--#{name.to_s.
|
52
|
+
["--#{name.to_s.tr("_", "-")}", value]
|
53
53
|
end.compact
|
54
54
|
end
|
55
55
|
|
@@ -58,9 +58,9 @@ module Dip
|
|
58
58
|
net = Dip.env["FRONTEND_NETWORK"] || "frontend"
|
59
59
|
|
60
60
|
IO.pipe do |r, w|
|
61
|
-
Dip::Commands::DNS::IP
|
62
|
-
new(name: name, net: net)
|
63
|
-
execute(out: w, err: File::NULL, panic: false)
|
61
|
+
Dip::Commands::DNS::IP
|
62
|
+
.new(name: name, net: net)
|
63
|
+
.execute(out: w, err: File::NULL, panic: false)
|
64
64
|
|
65
65
|
w.close_write
|
66
66
|
ip = r.readlines[0].to_s.strip
|
data/lib/dip/commands/console.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "../command"
|
4
4
|
|
5
5
|
module Dip
|
6
6
|
module Commands
|
@@ -13,9 +13,9 @@ module Dip
|
|
13
13
|
private
|
14
14
|
|
15
15
|
def script
|
16
|
-
<<-SH.gsub(/^
|
16
|
+
<<-SH.gsub(/^ {12}/, "")
|
17
17
|
export DIP_SHELL=1
|
18
|
-
export DIP_EARLY_ENVS=#{ENV.keys.join(
|
18
|
+
export DIP_EARLY_ENVS=#{ENV.keys.join(",")}
|
19
19
|
export DIP_PROMPT_TEXT="ⅆ"
|
20
20
|
|
21
21
|
function dip_clear() {
|
@@ -88,7 +88,7 @@ module Dip
|
|
88
88
|
def execute
|
89
89
|
if Dip.config.exist?
|
90
90
|
add_aliases(*Dip.config.interaction.keys) if Dip.config.interaction
|
91
|
-
add_aliases("compose", "up", "stop", "down", "provision")
|
91
|
+
add_aliases("compose", "up", "stop", "down", "provision", "build")
|
92
92
|
end
|
93
93
|
|
94
94
|
clear_aliases
|
@@ -107,7 +107,7 @@ module Dip
|
|
107
107
|
|
108
108
|
def clear_aliases
|
109
109
|
out << "function dip_clear() { \n" \
|
110
|
-
"#{aliases.any? ? aliases.map { |a| " unset -f #{a}" }.join("\n") :
|
110
|
+
"#{aliases.any? ? aliases.map { |a| " unset -f #{a}" }.join("\n") : "true"} " \
|
111
111
|
"\n}"
|
112
112
|
end
|
113
113
|
end
|
data/lib/dip/commands/dns.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "shellwords"
|
4
|
-
require_relative
|
4
|
+
require_relative "../command"
|
5
5
|
|
6
6
|
module Dip
|
7
7
|
module Commands
|
@@ -24,13 +24,13 @@ module Dip
|
|
24
24
|
private
|
25
25
|
|
26
26
|
def container_args
|
27
|
-
result = %w
|
27
|
+
result = %w[--detach]
|
28
28
|
result << "--volume #{@socket}:/var/run/docker.sock:ro"
|
29
29
|
result << "--restart always"
|
30
30
|
result << "--publish #{@publish}"
|
31
31
|
result << "--net #{@net}"
|
32
32
|
result << "--name #{@name}"
|
33
|
-
result.join(
|
33
|
+
result.join(" ")
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -53,10 +53,10 @@ module Dip
|
|
53
53
|
|
54
54
|
def execute(**options)
|
55
55
|
subshell("docker",
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
"inspect " \
|
57
|
+
"--format '{{ .NetworkSettings.Networks.#{@net}.IPAddress }}' " \
|
58
|
+
"#{@name}".shellsplit,
|
59
|
+
**options)
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
data/lib/dip/commands/list.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
4
|
-
require_relative
|
3
|
+
require_relative "../command"
|
4
|
+
require_relative "../interaction_tree"
|
5
5
|
|
6
6
|
module Dip
|
7
7
|
module Commands
|
@@ -12,7 +12,7 @@ module Dip
|
|
12
12
|
longest_name = tree.keys.map(&:size).max
|
13
13
|
|
14
14
|
tree.each do |name, command|
|
15
|
-
puts "#{name.ljust(longest_name)} ##{command[:description] ?
|
15
|
+
puts "#{name.ljust(longest_name)} ##{command[:description] ? " #{command[:description]}" : ""}"
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
data/lib/dip/commands/nginx.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "shellwords"
|
4
|
-
require_relative
|
4
|
+
require_relative "../command"
|
5
5
|
|
6
6
|
module Dip
|
7
7
|
module Commands
|
@@ -25,15 +25,15 @@ module Dip
|
|
25
25
|
private
|
26
26
|
|
27
27
|
def container_args
|
28
|
-
result = %w
|
28
|
+
result = %w[--detach]
|
29
29
|
result << "--volume #{@socket}:/tmp/docker.sock:ro"
|
30
30
|
result << "--volume #{@certs}:/etc/nginx/certs" unless @certs.to_s.empty?
|
31
31
|
result << "--restart always"
|
32
|
-
result << Array(@publish).map { |p| "--publish #{p}" }.join(
|
32
|
+
result << Array(@publish).map { |p| "--publish #{p}" }.join(" ")
|
33
33
|
result << "--net #{@net}"
|
34
34
|
result << "--name #{@name}"
|
35
35
|
result << "--label com.dnsdock.alias=#{@domain}"
|
36
|
-
result.join(
|
36
|
+
result.join(" ")
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
data/lib/dip/commands/run.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require_relative
|
5
|
-
require_relative
|
6
|
-
require_relative
|
7
|
-
require_relative
|
3
|
+
require "shellwords"
|
4
|
+
require_relative "../../../lib/dip/run_vars"
|
5
|
+
require_relative "../command"
|
6
|
+
require_relative "../interaction_tree"
|
7
|
+
require_relative "compose"
|
8
8
|
|
9
9
|
module Dip
|
10
10
|
module Commands
|
@@ -12,21 +12,24 @@ module Dip
|
|
12
12
|
def initialize(cmd, *argv, publish: nil)
|
13
13
|
@publish = publish
|
14
14
|
|
15
|
-
@command, @argv = InteractionTree
|
16
|
-
|
17
|
-
|
18
|
-
values_at(:command, :argv)
|
15
|
+
@command, @argv = InteractionTree
|
16
|
+
.new(Dip.config.interaction)
|
17
|
+
.find(cmd, *argv)&.values_at(:command, :argv)
|
19
18
|
|
20
|
-
raise Dip::Error, "Command `#{[cmd, *argv].join(
|
19
|
+
raise Dip::Error, "Command `#{[cmd, *argv].join(" ")}` not recognized!" unless command
|
21
20
|
|
22
21
|
Dip.env.merge(command[:environment])
|
23
22
|
end
|
24
23
|
|
25
24
|
def execute
|
26
|
-
|
27
|
-
command[:
|
28
|
-
|
29
|
-
|
25
|
+
if command[:service].nil?
|
26
|
+
shell(command[:command], get_args)
|
27
|
+
else
|
28
|
+
Dip::Commands::Compose.new(
|
29
|
+
command[:compose][:method],
|
30
|
+
*compose_arguments
|
31
|
+
).execute
|
32
|
+
end
|
30
33
|
end
|
31
34
|
|
32
35
|
private
|
@@ -44,11 +47,11 @@ module Dip
|
|
44
47
|
|
45
48
|
compose_argv << command.fetch(:service)
|
46
49
|
|
47
|
-
unless (cmd = command[:command]
|
48
|
-
compose_argv
|
50
|
+
unless (cmd = command[:command]).empty?
|
51
|
+
compose_argv << cmd
|
49
52
|
end
|
50
53
|
|
51
|
-
compose_argv.concat(
|
54
|
+
compose_argv.concat(get_args)
|
52
55
|
|
53
56
|
compose_argv
|
54
57
|
end
|
@@ -57,7 +60,7 @@ module Dip
|
|
57
60
|
run_vars = Dip::RunVars.env
|
58
61
|
return [] unless run_vars
|
59
62
|
|
60
|
-
run_vars.map { |k, v| ["-e", "#{k}=#{v}"] }.flatten
|
63
|
+
run_vars.map { |k, v| ["-e", "#{k}=#{Shellwords.escape(v)}"] }.flatten
|
61
64
|
end
|
62
65
|
|
63
66
|
def published_ports
|
@@ -67,6 +70,16 @@ module Dip
|
|
67
70
|
[]
|
68
71
|
end
|
69
72
|
end
|
73
|
+
|
74
|
+
def get_args
|
75
|
+
if argv.any?
|
76
|
+
argv
|
77
|
+
elsif !(default_args = command[:default_args]).empty?
|
78
|
+
Array(default_args)
|
79
|
+
else
|
80
|
+
[]
|
81
|
+
end
|
82
|
+
end
|
70
83
|
end
|
71
84
|
end
|
72
85
|
end
|
data/lib/dip/commands/ssh.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "shellwords"
|
4
|
-
require_relative
|
4
|
+
require_relative "../command"
|
5
5
|
|
6
6
|
module Dip
|
7
7
|
module Commands
|
@@ -33,12 +33,12 @@ module Dip
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def container_args
|
36
|
-
result = %w
|
36
|
+
result = %w[--rm]
|
37
37
|
volume = Dip.env.interpolate(@volume)
|
38
38
|
result << "--volume ssh_data:/ssh"
|
39
39
|
result << "--volume #{volume}:#{volume}"
|
40
40
|
result << "--interactive --tty" if @interactive
|
41
|
-
result.join(
|
41
|
+
result.join(" ")
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
data/lib/dip/config.rb
CHANGED
@@ -29,10 +29,10 @@ module Dip
|
|
29
29
|
@override = override
|
30
30
|
|
31
31
|
@file_path = if ENV["DIP_FILE"]
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
Pathname.new(prepared_name(ENV["DIP_FILE"]))
|
33
|
+
else
|
34
|
+
find(Pathname.new(work_dir))
|
35
|
+
end
|
36
36
|
end
|
37
37
|
|
38
38
|
def exist?
|
@@ -119,7 +119,7 @@ module Dip
|
|
119
119
|
end
|
120
120
|
|
121
121
|
def config_missing_error(config_key)
|
122
|
-
msg =
|
122
|
+
msg = "config for %<key>s is not defined in %<path>s" % {key: config_key, path: finder.file_path}
|
123
123
|
ConfigKeyMissingError.new(msg)
|
124
124
|
end
|
125
125
|
end
|
data/lib/dip/environment.rb
CHANGED
@@ -4,7 +4,7 @@ require "pathname"
|
|
4
4
|
|
5
5
|
module Dip
|
6
6
|
class Environment
|
7
|
-
VAR_REGEX =
|
7
|
+
VAR_REGEX = /\$\{?(?<var_name>[a-zA-Z_][a-zA-Z0-9_]*)\}?/.freeze
|
8
8
|
SPECIAL_VARS = %i[os work_dir_rel_path].freeze
|
9
9
|
|
10
10
|
attr_reader :vars
|
@@ -26,8 +26,8 @@ module Dip
|
|
26
26
|
vars.fetch(name) { ENV[name] }
|
27
27
|
end
|
28
28
|
|
29
|
-
def fetch(name)
|
30
|
-
vars.fetch(name) { ENV.fetch(name)
|
29
|
+
def fetch(name, &block)
|
30
|
+
vars.fetch(name) { ENV.fetch(name, &block) }
|
31
31
|
end
|
32
32
|
|
33
33
|
def []=(key, value)
|
@@ -35,18 +35,18 @@ module Dip
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def interpolate(value)
|
38
|
-
value.gsub(VAR_REGEX) do
|
38
|
+
value.gsub(VAR_REGEX) do |match|
|
39
39
|
var_name = Regexp.last_match[:var_name]
|
40
40
|
|
41
41
|
if special_vars.key?(var_name)
|
42
42
|
fetch(var_name) { send(special_vars[var_name]) }
|
43
43
|
else
|
44
|
-
|
44
|
+
fetch(var_name) { match }
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
|
49
|
+
alias_method :replace, :interpolate
|
50
50
|
|
51
51
|
private
|
52
52
|
|
data/lib/dip/ext/hash.rb
CHANGED
@@ -24,7 +24,7 @@ module ActiveSupportHashHelpers
|
|
24
24
|
merge!(other_hash) do |key, this_val, other_val|
|
25
25
|
if this_val.is_a?(Hash) && other_val.is_a?(Hash)
|
26
26
|
this_val.deep_merge(other_val, &block)
|
27
|
-
elsif
|
27
|
+
elsif block
|
28
28
|
block.call(key, this_val, other_val)
|
29
29
|
else
|
30
30
|
other_val
|
data/lib/dip/interaction_tree.rb
CHANGED
@@ -58,9 +58,9 @@ module Dip
|
|
58
58
|
def build_command(entry)
|
59
59
|
{
|
60
60
|
description: entry[:description],
|
61
|
-
service: entry
|
62
|
-
command: entry[:command],
|
63
|
-
default_args:
|
61
|
+
service: entry[:service],
|
62
|
+
command: entry[:command].to_s.strip,
|
63
|
+
default_args: entry[:default_args].to_s.strip,
|
64
64
|
environment: entry[:environment] || {},
|
65
65
|
compose: {
|
66
66
|
method: entry.dig(:compose, :method) || entry[:compose_method] || "run",
|
@@ -76,19 +76,6 @@ module Dip
|
|
76
76
|
entry[:description] ||= nil
|
77
77
|
end
|
78
78
|
|
79
|
-
def prepare_default_args(args)
|
80
|
-
return [] if args.nil?
|
81
|
-
|
82
|
-
case args
|
83
|
-
when Array
|
84
|
-
args
|
85
|
-
when String
|
86
|
-
args.shellsplit
|
87
|
-
else
|
88
|
-
raise ArgumentError, "Unknown type for default_args: #{args.inspect}"
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
79
|
def compose_run_options(value)
|
93
80
|
return [] unless value
|
94
81
|
|
data/lib/dip/version.rb
CHANGED
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:
|
4
|
+
version: 7.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:
|
11
|
+
date: 2021-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -87,19 +87,47 @@ dependencies:
|
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '3.0'
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
|
-
name:
|
90
|
+
name: standard
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
93
|
- - "~>"
|
94
94
|
- !ruby/object:Gem::Version
|
95
|
-
version: '0
|
95
|
+
version: '1.0'
|
96
96
|
type: :development
|
97
97
|
prerelease: false
|
98
98
|
version_requirements: !ruby/object:Gem::Requirement
|
99
99
|
requirements:
|
100
100
|
- - "~>"
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version: '0
|
102
|
+
version: '1.0'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: rubocop-rake
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0.5'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0.5'
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: rubocop-rspec
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - "~>"
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '2.2'
|
124
|
+
type: :development
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - "~>"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '2.2'
|
103
131
|
- !ruby/object:Gem::Dependency
|
104
132
|
name: simplecov
|
105
133
|
requirement: !ruby/object:Gem::Requirement
|
@@ -176,14 +204,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
176
204
|
requirements:
|
177
205
|
- - ">="
|
178
206
|
- !ruby/object:Gem::Version
|
179
|
-
version: '2.
|
207
|
+
version: '2.5'
|
180
208
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
181
209
|
requirements:
|
182
210
|
- - ">="
|
183
211
|
- !ruby/object:Gem::Version
|
184
212
|
version: '0'
|
185
213
|
requirements: []
|
186
|
-
rubygems_version: 3.
|
214
|
+
rubygems_version: 3.1.2
|
187
215
|
signing_key:
|
188
216
|
specification_version: 4
|
189
217
|
summary: Ruby gem CLI tool for better interacting docker-compose files.
|