docker-compose 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.github/workflows/publish.yml +42 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +38 -0
- data/.ruby-version +1 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +32 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +16 -0
- data/LICENSE.txt +21 -0
- data/README.md +170 -0
- data/Rakefile +7 -0
- data/bin/console +18 -0
- data/bin/setup +7 -0
- data/docker-compose.gemspec +29 -0
- data/docker-compose.yml +11 -0
- data/lib/docker/compose/collection.rb +13 -0
- data/lib/docker/compose/container.rb +80 -0
- data/lib/docker/compose/error.rb +26 -0
- data/lib/docker/compose/mapper.rb +159 -0
- data/lib/docker/compose/net_info.rb +89 -0
- data/lib/docker/compose/rake_tasks.rb +171 -0
- data/lib/docker/compose/session.rb +354 -0
- data/lib/docker/compose/shell_printer/fish.rb +17 -0
- data/lib/docker/compose/shell_printer/posix.rb +33 -0
- data/lib/docker/compose/shell_printer.rb +26 -0
- data/lib/docker/compose/version.rb +6 -0
- data/lib/docker/compose.rb +19 -0
- metadata +132 -0
@@ -0,0 +1,354 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'backticks'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Docker::Compose
|
6
|
+
# A Ruby OOP interface to a docker-compose session. A session is bound to
|
7
|
+
# a particular directory and docker-compose file (which are set at initialize
|
8
|
+
# time) and invokes whichever docker-compose command is resident in $PATH.
|
9
|
+
#
|
10
|
+
# Run docker-compose commands by calling instance methods of this class and
|
11
|
+
# passing kwargs that are equivalent to the CLI options you would pass to
|
12
|
+
# the command-line tool.
|
13
|
+
#
|
14
|
+
# Note that the Ruby command methods usually expose a _subset_ of the options
|
15
|
+
# allowed by the docker-compose CLI, and that options are sometimes renamed
|
16
|
+
# for clarity, e.g. the "-d" flag always becomes the "detached:" kwarg.
|
17
|
+
class Session
|
18
|
+
# A Regex that matches all ANSI escape sequences.
|
19
|
+
ANSI = /\033\[([0-9];?)+[a-z]/
|
20
|
+
|
21
|
+
# Working directory (determines compose project name); default is Dir.pwd
|
22
|
+
attr_reader :dir
|
23
|
+
|
24
|
+
# Project name; default is not to pass a custom name
|
25
|
+
attr_reader :project_name
|
26
|
+
|
27
|
+
# Project file; default is 'docker-compose.yml'
|
28
|
+
attr_reader :file
|
29
|
+
|
30
|
+
# Reference to the last executed command.
|
31
|
+
attr_reader :last_command
|
32
|
+
|
33
|
+
def initialize(shell = Backticks::Runner.new(buffered: [:stderr], interactive: true),
|
34
|
+
dir: Dir.pwd, project_name: nil, file: 'docker-compose.yml')
|
35
|
+
@shell = shell
|
36
|
+
@project_name = project_name
|
37
|
+
@dir = dir
|
38
|
+
@file = file
|
39
|
+
@last_command = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
# Validate docker-compose file and return it as Hash
|
43
|
+
# @return [Hash] the docker-compose config file
|
44
|
+
# @raise [Error] if command fails
|
45
|
+
def config(*args)
|
46
|
+
config = strip_ansi(run!('config', *args))
|
47
|
+
YAML.load(config)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Monitor the logs of one or more containers.
|
51
|
+
# @param [Array] services list of String service names to show logs for
|
52
|
+
# @return [true] always returns true
|
53
|
+
# @raise [Error] if command fails
|
54
|
+
def logs(*services)
|
55
|
+
run!('logs', services)
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
def ps(*services)
|
60
|
+
inter = @shell.interactive
|
61
|
+
@shell.interactive = false
|
62
|
+
|
63
|
+
lines = strip_ansi(run!('ps', {q: true}, services)).split(/[\r\n]+/)
|
64
|
+
containers = Collection.new
|
65
|
+
|
66
|
+
lines.each do |id|
|
67
|
+
containers << docker_ps(strip_ansi(id))
|
68
|
+
end
|
69
|
+
|
70
|
+
containers
|
71
|
+
ensure
|
72
|
+
@shell.interactive = inter
|
73
|
+
end
|
74
|
+
|
75
|
+
# Idempotently up the given services in the project.
|
76
|
+
# @param [Array] services list of String service names to run
|
77
|
+
# @param [Boolean] detached if true, to start services in the background;
|
78
|
+
# otherwise, monitor logs in the foreground and shutdown on Ctrl+C
|
79
|
+
# @param [Integer] timeout how long to wait for each service to start
|
80
|
+
# @param [Boolean] build if true, build images before starting containers
|
81
|
+
# @param [Boolean] no_build if true, don't build images, even if they're
|
82
|
+
# missing
|
83
|
+
# @param [Boolean] no_deps if true, just run specified services without
|
84
|
+
# running the services that they depend on
|
85
|
+
# @return [true] always returns true
|
86
|
+
# @raise [Error] if command fails
|
87
|
+
def up(*services,
|
88
|
+
abort_on_container_exit: false,
|
89
|
+
detached: false, timeout: 10, build: false,
|
90
|
+
exit_code_from: nil,
|
91
|
+
no_build: false, no_deps: false, no_start: false)
|
92
|
+
o = opts(
|
93
|
+
abort_on_container_exit: [abort_on_container_exit, false],
|
94
|
+
d: [detached, false],
|
95
|
+
timeout: [timeout, 10],
|
96
|
+
build: [build, false],
|
97
|
+
exit_code_from: [exit_code_from, nil],
|
98
|
+
no_build: [no_build, false],
|
99
|
+
no_deps: [no_deps, false],
|
100
|
+
no_start: [no_start, false]
|
101
|
+
)
|
102
|
+
run!('up', o, services)
|
103
|
+
true
|
104
|
+
end
|
105
|
+
|
106
|
+
# Idempotently scales the number of containers for given services in the project.
|
107
|
+
# @param [Hash] container_count per service, e.g. {web: 2, worker: 3}
|
108
|
+
# @param [Integer] timeout how long to wait for each service to scale
|
109
|
+
def scale(container_count, timeout: 10)
|
110
|
+
args = container_count.map {|service, count| "#{service}=#{count}"}
|
111
|
+
o = opts(timeout: [timeout, 10])
|
112
|
+
run!('scale', o, *args)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Take the stack down
|
116
|
+
def down(remove_volumes: false)
|
117
|
+
run!('down', opts(v: [!!remove_volumes, false]))
|
118
|
+
end
|
119
|
+
|
120
|
+
# Pull images of services
|
121
|
+
# @param [Array] services list of String service names to pull
|
122
|
+
def pull(*services)
|
123
|
+
run!('pull', *services)
|
124
|
+
end
|
125
|
+
|
126
|
+
def rm(*services, force: false, volumes: false)
|
127
|
+
o = opts(f: [force, false], v: [volumes, false])
|
128
|
+
run!('rm', o, services)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Idempotently run an arbitrary command with a service container.
|
132
|
+
# @param [String] service name to run
|
133
|
+
# @param [String] cmd command statement to run
|
134
|
+
# @param [Boolean] detached if true, to start services in the background;
|
135
|
+
# otherwise, monitor logs in the foreground and shutdown on Ctrl+C
|
136
|
+
# @param [Boolean] no_deps if true, just run specified services without
|
137
|
+
# running the services that they depend on
|
138
|
+
# @param [Array] env a list of environment variables (see: -e flag)
|
139
|
+
# @param [Array] volumes a list of volumes to bind mount (see: -v flag)
|
140
|
+
# @param [Boolean] rm remove the container when done
|
141
|
+
# @param [Boolean] no_tty disable pseudo-tty allocation (see: -T flag)
|
142
|
+
# @param [String] user run as specified username or uid (see: -u flag)
|
143
|
+
# @raise [Error] if command fails
|
144
|
+
def run(service, *cmd, detached: false, no_deps: false, volumes: [], env: [], rm: false, no_tty: false, user: nil, service_ports: false)
|
145
|
+
o = opts(d: [detached, false], no_deps: [no_deps, false], rm: [rm, false], T: [no_tty, false], u: [user, nil], service_ports: [service_ports, false])
|
146
|
+
env_params = env.map { |v| { e: v } }
|
147
|
+
volume_params = volumes.map { |v| { v: v } }
|
148
|
+
run!('run', o, *env_params, *volume_params, service, cmd)
|
149
|
+
end
|
150
|
+
|
151
|
+
def restart(*services, timeout:10)
|
152
|
+
o = opts(timeout: [timeout, 10])
|
153
|
+
run!('restart', o, *services)
|
154
|
+
end
|
155
|
+
|
156
|
+
# Pause running services.
|
157
|
+
# @param [Array] services list of String service names to run
|
158
|
+
def pause(*services)
|
159
|
+
run!('pause', *services)
|
160
|
+
end
|
161
|
+
|
162
|
+
# Unpause running services.
|
163
|
+
# @param [Array] services list of String service names to run
|
164
|
+
def unpause(*services)
|
165
|
+
run!('unpause', *services)
|
166
|
+
end
|
167
|
+
|
168
|
+
# Stop running services.
|
169
|
+
# @param [Array] services list of String service names to stop
|
170
|
+
# @param [Integer] timeout how long to wait for each service to stop
|
171
|
+
# @raise [Error] if command fails
|
172
|
+
def stop(*services, timeout: 10)
|
173
|
+
o = opts(timeout: [timeout, 10])
|
174
|
+
run!('stop', o, services)
|
175
|
+
end
|
176
|
+
|
177
|
+
# Forcibly stop running services.
|
178
|
+
# @param [Array] services list of String service names to stop
|
179
|
+
# @param [String] name of murderous signal to use, default is 'KILL'
|
180
|
+
# @see Signal.list for a list of acceptable signal names
|
181
|
+
def kill(*services, signal: 'KILL')
|
182
|
+
o = opts(signal: [signal, 'KILL'])
|
183
|
+
run!('kill', o, services)
|
184
|
+
end
|
185
|
+
|
186
|
+
# Figure out which interface(s) and port a given service port has been published to.
|
187
|
+
#
|
188
|
+
# **NOTE**: if Docker Compose is communicating with a remote Docker host, this method
|
189
|
+
# returns IP addresses from the point of view of *that* host and its interfaces. If
|
190
|
+
# you need to know the address as reachable from localhost, you probably want to use
|
191
|
+
# `Mapper`.
|
192
|
+
#
|
193
|
+
# @see Docker::Compose::Mapper
|
194
|
+
#
|
195
|
+
# @param [String] service name of service from docker-compose.yml
|
196
|
+
# @param [Integer] port number of port
|
197
|
+
# @param [String] protocol 'tcp' or 'udp'
|
198
|
+
# @param [Integer] index of container (if multiple instances running)
|
199
|
+
# @return [String,nil] an ip:port pair such as "0.0.0.0:32176" or nil if the service is not running
|
200
|
+
# @raise [Error] if command fails
|
201
|
+
def port(service, port, protocol: 'tcp', index: 1)
|
202
|
+
inter = @shell.interactive
|
203
|
+
@shell.interactive = false
|
204
|
+
|
205
|
+
o = opts(protocol: [protocol, 'tcp'], index: [index, 1])
|
206
|
+
s = strip_ansi(run!('port', o, service, port).strip)
|
207
|
+
(!s.empty? && s) || nil
|
208
|
+
rescue Error => e
|
209
|
+
# Deal with docker-compose v1.11+
|
210
|
+
if e.detail =~ /No container found/i
|
211
|
+
nil
|
212
|
+
else
|
213
|
+
raise
|
214
|
+
end
|
215
|
+
ensure
|
216
|
+
@shell.interactive = inter
|
217
|
+
end
|
218
|
+
|
219
|
+
# Determine the installed version of docker-compose.
|
220
|
+
# @param [Boolean] short whether to return terse version information
|
221
|
+
# @return [String, Hash] if short==true, returns a version string;
|
222
|
+
# otherwise, returns a Hash of component-name strings to version strings
|
223
|
+
# @raise [Error] if command fails
|
224
|
+
def version(short: false)
|
225
|
+
o = opts(short: [short, false])
|
226
|
+
result = run!('version', o, file: false, dir: false)
|
227
|
+
|
228
|
+
if short
|
229
|
+
result.strip
|
230
|
+
else
|
231
|
+
lines = result.split(/[\r\n]+/)
|
232
|
+
lines.inject({}) do |h, line|
|
233
|
+
kv = line.split(/: +/, 2)
|
234
|
+
h[kv.first] = kv.last
|
235
|
+
h
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def build(*services, force_rm: false, no_cache: false, pull: false)
|
241
|
+
o = opts(force_rm: [force_rm, false],
|
242
|
+
no_cache: [no_cache, false],
|
243
|
+
pull: [pull, false])
|
244
|
+
result = run!('build', o, services)
|
245
|
+
end
|
246
|
+
|
247
|
+
# Run a docker-compose command without validating that the CLI parameters
|
248
|
+
# make sense. Prepend project and file options if suitable.
|
249
|
+
#
|
250
|
+
# @see Docker::Compose::Shell#command
|
251
|
+
#
|
252
|
+
# @param [Array] args command-line arguments in the format accepted by
|
253
|
+
# Backticks::Runner#command
|
254
|
+
# @return [String] output of the command
|
255
|
+
# @raise [Error] if command fails
|
256
|
+
def run!(*args)
|
257
|
+
project_name_args = if @project_name
|
258
|
+
[{ project_name: @project_name }]
|
259
|
+
else
|
260
|
+
[]
|
261
|
+
end
|
262
|
+
file_args = case @file
|
263
|
+
when 'docker-compose.yml'
|
264
|
+
[]
|
265
|
+
when Array
|
266
|
+
# backticks sugar can't handle array values; build a list of hashes
|
267
|
+
# IMPORTANT: preserve the order of the files so overrides work correctly
|
268
|
+
file_args = @file.map { |filepath| { :file => filepath } }
|
269
|
+
else
|
270
|
+
# a single String (or Pathname, etc); use normal sugar to add it
|
271
|
+
[{ file: @file.to_s }]
|
272
|
+
end
|
273
|
+
|
274
|
+
@shell.chdir = dir
|
275
|
+
@last_command = @shell.run('docker-compose', *project_name_args, *file_args, *args).join
|
276
|
+
status = @last_command.status
|
277
|
+
out = @last_command.captured_output
|
278
|
+
err = @last_command.captured_error
|
279
|
+
status.success? || fail(Error.new(args.first, status, out+err))
|
280
|
+
out
|
281
|
+
end
|
282
|
+
|
283
|
+
private
|
284
|
+
|
285
|
+
def docker_ps(id)
|
286
|
+
cmd = @shell.run('docker', 'ps', a: true, f: "id=#{id}", no_trunc: true, format: Container::PS_FMT).join
|
287
|
+
status, out, err = cmd.status, cmd.captured_output, cmd.captured_error
|
288
|
+
raise Error.new('docker ps', status, out+err) unless status.success?
|
289
|
+
lines = out.split(/[\r\n]+/)
|
290
|
+
return nil if lines.empty?
|
291
|
+
l = strip_ansi(lines.shift)
|
292
|
+
m = parse(l)
|
293
|
+
raise Error.new('docker ps', status, "Cannot parse output: '#{l}'") unless m
|
294
|
+
raise Error.new('docker ps', status, "Cannot parse output: '#{l}'") unless m.size == 7
|
295
|
+
return Container.new(*m)
|
296
|
+
end
|
297
|
+
|
298
|
+
# strip default-valued options. the value of each kw should be a pair:
|
299
|
+
# [0] is present value
|
300
|
+
# [1] is default value
|
301
|
+
def opts(**kws)
|
302
|
+
res = {}
|
303
|
+
kws.each_pair do |kw, v|
|
304
|
+
res[kw] = v[0] unless v[0] == v[1]
|
305
|
+
end
|
306
|
+
res
|
307
|
+
end
|
308
|
+
|
309
|
+
# strip all ANSI escape sequences from str
|
310
|
+
def strip_ansi(str)
|
311
|
+
str.gsub(ANSI, '')
|
312
|
+
end
|
313
|
+
|
314
|
+
# Parse a string that consists of a sequence of values enclosed within parentheses.
|
315
|
+
# Ignore any bytes that are outside of parentheses. Values may include nested parentheses.
|
316
|
+
#
|
317
|
+
# @param [String] str e.g. "(foo) ((bar)) ... (baz)"
|
318
|
+
# @return [Array] e.g. ["foo", "bar", "baz"]
|
319
|
+
def parse(str)
|
320
|
+
fields = []
|
321
|
+
nest = 0
|
322
|
+
field = ''
|
323
|
+
str.each_char do |ch|
|
324
|
+
got = false
|
325
|
+
if nest == 0
|
326
|
+
if ch == '('
|
327
|
+
nest += 1
|
328
|
+
end
|
329
|
+
else
|
330
|
+
if ch == '('
|
331
|
+
nest += 1
|
332
|
+
field << ch
|
333
|
+
elsif ch == ')'
|
334
|
+
nest -= 1
|
335
|
+
if nest == 0
|
336
|
+
got = true
|
337
|
+
else
|
338
|
+
field << ch
|
339
|
+
end
|
340
|
+
else
|
341
|
+
field << ch
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
if got
|
346
|
+
fields << field
|
347
|
+
field = ''
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
fields
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Docker::Compose::ShellPrinter
|
3
|
+
# Printer that works with the Friendly Interactive Shell (fish).
|
4
|
+
class Fish < Posix
|
5
|
+
def eval_output(command)
|
6
|
+
format('eval (%s)', command)
|
7
|
+
end
|
8
|
+
|
9
|
+
def export(name, value)
|
10
|
+
format('set -gx %s %s; ', name, single_quoted_escaped(value))
|
11
|
+
end
|
12
|
+
|
13
|
+
def unset(name)
|
14
|
+
format('set -ex %s; ', name)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Docker::Compose::ShellPrinter
|
3
|
+
# Printer that works with any POSIX-compliant shell e.g. sh, bash, zsh
|
4
|
+
class Posix
|
5
|
+
def comment(value)
|
6
|
+
format('# %s', value)
|
7
|
+
end
|
8
|
+
|
9
|
+
def eval_output(command)
|
10
|
+
format('eval "$(%s)"', command)
|
11
|
+
end
|
12
|
+
|
13
|
+
def export(name, value)
|
14
|
+
format('export %s=%s', name, single_quoted_escaped(value))
|
15
|
+
end
|
16
|
+
|
17
|
+
def unset(name)
|
18
|
+
format('unset %s', name)
|
19
|
+
end
|
20
|
+
|
21
|
+
protected def single_quoted_escaped(value)
|
22
|
+
# "escape" any occurrences of ' in value by closing the single-quoted
|
23
|
+
# string, concatenating a single backslash-escaped ' character, and reopening
|
24
|
+
# the single-quoted string.
|
25
|
+
#
|
26
|
+
# This relies on the shell's willingness to concatenate adjacent string
|
27
|
+
# literals. Tested under sh, bash and zsh; should work elsewhere.
|
28
|
+
escaped = value.gsub("'") { "'\\''" }
|
29
|
+
|
30
|
+
"'#{escaped}'"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'etc'
|
3
|
+
|
4
|
+
module Docker::Compose
|
5
|
+
module ShellPrinter
|
6
|
+
def self.new
|
7
|
+
shell = Etc.getpwuid(Process.uid).shell
|
8
|
+
basename = File.basename(shell)
|
9
|
+
|
10
|
+
# Crappy titleize (bash -> Bash)
|
11
|
+
basename[0] = basename[0].upcase
|
12
|
+
|
13
|
+
# Find adapter class named after shell; default to posix if nothing found
|
14
|
+
klass = begin
|
15
|
+
const_get(basename.to_sym)
|
16
|
+
rescue
|
17
|
+
Posix
|
18
|
+
end
|
19
|
+
|
20
|
+
klass.new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
require_relative 'shell_printer/posix'
|
26
|
+
require_relative 'shell_printer/fish'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
require_relative 'compose/version'
|
5
|
+
require_relative 'compose/error'
|
6
|
+
require_relative 'compose/container'
|
7
|
+
require_relative 'compose/collection'
|
8
|
+
require_relative 'compose/session'
|
9
|
+
require_relative 'compose/net_info'
|
10
|
+
require_relative 'compose/mapper'
|
11
|
+
|
12
|
+
module Docker
|
13
|
+
module Compose
|
14
|
+
# Create a new session with default options.
|
15
|
+
def self.new
|
16
|
+
Session.new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: docker-compose
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tony Spataro
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-05-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: backticks
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Provides an OOP interface to docker-compose and facilitates container-to-host
|
70
|
+
and host-to-container networking.
|
71
|
+
email:
|
72
|
+
- xeger@xeger.net
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".coveralls.yml"
|
78
|
+
- ".github/workflows/publish.yml"
|
79
|
+
- ".gitignore"
|
80
|
+
- ".rspec"
|
81
|
+
- ".rubocop.yml"
|
82
|
+
- ".ruby-version"
|
83
|
+
- ".travis.yml"
|
84
|
+
- CHANGELOG.md
|
85
|
+
- CODE_OF_CONDUCT.md
|
86
|
+
- Gemfile
|
87
|
+
- LICENSE.txt
|
88
|
+
- README.md
|
89
|
+
- Rakefile
|
90
|
+
- bin/console
|
91
|
+
- bin/setup
|
92
|
+
- docker-compose.gemspec
|
93
|
+
- docker-compose.yml
|
94
|
+
- lib/docker/compose.rb
|
95
|
+
- lib/docker/compose/collection.rb
|
96
|
+
- lib/docker/compose/container.rb
|
97
|
+
- lib/docker/compose/error.rb
|
98
|
+
- lib/docker/compose/mapper.rb
|
99
|
+
- lib/docker/compose/net_info.rb
|
100
|
+
- lib/docker/compose/rake_tasks.rb
|
101
|
+
- lib/docker/compose/session.rb
|
102
|
+
- lib/docker/compose/shell_printer.rb
|
103
|
+
- lib/docker/compose/shell_printer/fish.rb
|
104
|
+
- lib/docker/compose/shell_printer/posix.rb
|
105
|
+
- lib/docker/compose/version.rb
|
106
|
+
homepage: https://github.com/xeger/docker-compose
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '2.0'
|
119
|
+
- - "<"
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '4.0'
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
requirements: []
|
128
|
+
rubygems_version: 3.2.3
|
129
|
+
signing_key:
|
130
|
+
specification_version: 4
|
131
|
+
summary: Wrapper docker-compose with added Rake smarts.
|
132
|
+
test_files: []
|