docker-compose 0.2.2 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d0fd6f058df23b81e91fb41201f8e8f6c0b46a1f
4
- data.tar.gz: 2b4fa470ffa68b8ede08591129e0135d548effe8
3
+ metadata.gz: 39373275b82cf434210606a3f6f11d69677db295
4
+ data.tar.gz: b504d7029a2a6150eb5a4e5994d87bf48fa1a03d
5
5
  SHA512:
6
- metadata.gz: 708ea8165969cf7b7e6b91b8707ff4b89ba1af98101a6d7bfb43e8d3f6dbbf85607159e1b20f29a4af9615ea90409292d0df830c7915b4de2dbfd011ce69eb47
7
- data.tar.gz: 17793d4f5899fbc76c238965f5990609b12cad7fb5a7866d6ac8c8d402dd43c61cc245642f3eb39b5894634450b0156c388fc131075a1fbc3354d9cdcd813153
6
+ metadata.gz: 652113dd63815d7e8261b02e5029d81fc49e6fb0edfd65ffd1f70aa03c3a3f068be1b4d8b361cbb048f7ffff2dd1018ce98ce20d5c82ce15b69df3dd65873f3c
7
+ data.tar.gz: 734de8b8783c44a666e6485b5bce36d5d81a9158d421f2721f27a165ed5fb6d7cf53de0027b1223960a2b7dc475a91fe2b1c9d7ae5d3defa4b4d258474d51df9
@@ -1,5 +1,3 @@
1
- require 'docker/compose/future/session'
2
-
3
1
  module Docker::Compose
4
2
  # A Ruby OOP interface to a docker-compose session. A session is bound to
5
3
  # a particular directory and docker-compose file (which are set at initialize
@@ -107,8 +105,5 @@ module Docker::Compose
107
105
  output
108
106
  end
109
107
  end
110
-
111
- # Simulate behaviors from Docker 1.5
112
- include Docker::Compose::Future::Session
113
108
  end
114
109
  end
@@ -1,4 +1,5 @@
1
1
  require 'open3'
2
+ require 'pty'
2
3
 
3
4
  module Docker::Compose
4
5
  # An easy-to-use interface for invoking commands and capturing their output.
@@ -16,8 +17,6 @@ module Docker::Compose
16
17
  # actual program, and bytes sent to stdin may not arrive until you send
17
18
  # a lot of them!
18
19
  #
19
- # TODO: solve pipe buffering issues, perhaps with a pty...
20
- #
21
20
  # @return [Boolean]
22
21
  attr_accessor :interactive
23
22
 
@@ -101,15 +100,65 @@ module Docker::Compose
101
100
  run(argv)
102
101
  end
103
102
 
104
- # Run a shell command. Perform no translation or substitution. Return
105
- # the program's exit status and stdout.
103
+ # Run a simple command.
104
+ #
105
+ # @param [Array] argv list of command words
106
+ # @return [Array] triple of integer exitstatus, string stdout, and stderr
107
+ private def run(argv)
108
+ if self.interactive
109
+ run_interactive(argv)
110
+ else
111
+ run_noninteractive(argv)
112
+ end
113
+ end
114
+
115
+ # Run a shell command. Use a pty to capture the unbuffered output.
116
+ #
117
+ # @param [Array] argv command to run; argv[0] is program name and the
118
+ # remaining elements are parameters and flags
119
+ # @return [Array] an (Integer,String,String) triple of exitstatus, stdout and (empty) stderr
120
+ private def run_interactive(argv)
121
+ stdout, stdout_w = PTY.open
122
+ stdin_r, stdin = IO.pipe
123
+ stderr, stderr_w = IO.pipe
124
+ pid = spawn(*argv, in: stdin_r, out: stdout_w, err: stderr_w)
125
+ stdin_r.close
126
+ stdout_w.close
127
+ stderr_w.close
128
+
129
+ output, error = run_inner(stdin, stdout, stderr)
130
+
131
+ Process.waitpid(pid)
132
+
133
+ [$?.exitstatus, output, error]
134
+ end
135
+
136
+ # Run a shell command. Perform no translation or substitution. Use a pipe
137
+ # to read the output, which may be buffered by the OS. Return the program's
138
+ # exit status and stdout.
139
+ #
140
+ # TODO eliminate interactive path (it can't happen anymore) and move flourishes to run_interactive
106
141
  #
107
142
  # @param [Array] argv command to run; argv[0] is program name and the
108
143
  # remaining elements are parameters and flags
109
144
  # @return [Array] an (Integer,String,String) triple of exitstatus, stdout and stderr
110
- private def run(argv)
145
+ private def run_noninteractive(argv)
111
146
  stdin, stdout, stderr, thr = Open3.popen3(*argv)
112
147
 
148
+ output, error = run_inner(stdin, stdout, stderr)
149
+
150
+ # This blocks until the process exits (which probably already happened,
151
+ # given that we have received EOF on its output streams).
152
+ status = thr.value.exitstatus
153
+
154
+ [status, output, error]
155
+ rescue Interrupt
156
+ # Proxy Ctrl+C to our child process
157
+ Process.kill('INT', thr.pid) rescue nil
158
+ raise
159
+ end
160
+
161
+ private def run_inner(stdin, stdout, stderr)
113
162
  streams = [stdout, stderr]
114
163
 
115
164
  if @interactive
@@ -155,15 +204,7 @@ module Docker::Compose
155
204
  end
156
205
  end
157
206
 
158
- # This blocks until the process exits (which probably already happened,
159
- # given that we have received EOF on its output streams).
160
- status = thr.value.exitstatus
161
-
162
- [status, output, error]
163
- rescue Interrupt
164
- # Proxy Ctrl+C to our child process
165
- Process.kill('INT', thr.pid) rescue nil
166
- raise
207
+ [output, error]
167
208
  end
168
209
  end
169
210
  end
@@ -1,5 +1,5 @@
1
1
  module Docker
2
2
  module Compose
3
- VERSION = "0.2.2"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docker-compose
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tony Spataro
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-12-08 00:00:00.000000000 Z
11
+ date: 2015-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -74,7 +74,6 @@ files:
74
74
  - docker-compose.gemspec
75
75
  - lib/docker/compose.rb
76
76
  - lib/docker/compose/error.rb
77
- - lib/docker/compose/future/session.rb
78
77
  - lib/docker/compose/mapper.rb
79
78
  - lib/docker/compose/net_info.rb
80
79
  - lib/docker/compose/rake_tasks.rb
@@ -1,90 +0,0 @@
1
- require 'yaml'
2
-
3
- module Docker::Compose::Future
4
- module Session
5
- # Pattern that matches an environment substitution in a docker-compose YML
6
- # file.
7
- # @see #substitute
8
- SUBSTITUTION = /\$\{([A-Z0-9:_-]+)\}/
9
-
10
- # Hook in env-var substitution by aliasing a method chain for run!
11
- def self.included(host)
12
- done = host.instance_methods.include?(:run_without_substitution!)
13
- host.instance_eval do
14
- alias_method :run_without_substitution!, :run!
15
- alias_method :run!, :run_with_substitution!
16
- end unless done
17
- end
18
-
19
- # Read docker-compose YML; perform environment variable substitution;
20
- # write a temp file; invoke run! with the new file; delete the temp
21
- # file afterward.
22
- #
23
- # This is a complete reimplementation of run! and we only alias the original
24
- # to be good citizens.
25
- def run_with_substitution!(*cmd)
26
- temp = nil
27
- project = File.basename(@dir)
28
-
29
- # Find and purge the 'file' flag if it exists; otherwise assume we will
30
- # substitute our default (session) file.
31
- fn = nil
32
- cmd.each do |item|
33
- fn ||= item.delete(:file) if item.is_a?(Hash)
34
- end
35
- fn ||= @file
36
-
37
- # Rewrite YML if the file exists and the file:false "flag" wasn't
38
- # explicitly passed to us.
39
- Dir.chdir(@dir) do
40
- yml = YAML.load(File.read(fn))
41
- yml = substitute(yml)
42
- temp = Tempfile.new(fn, @dir)
43
- temp.write(YAML.dump(yml))
44
- temp.close
45
-
46
- project_opts = {
47
- file: temp.path,
48
- project: File.basename(@dir)
49
- }
50
-
51
- result, output, error =
52
- @shell.command('docker-compose', project_opts, *cmd)
53
- (result == 0) ||
54
- raise(Docker::Compose::Error.new(cmd.first, result, error))
55
- output
56
- end
57
- ensure
58
- temp.unlink if temp
59
- end
60
-
61
- # Simulate the behavior of docker-compose 1.5: replace "${VAR}" sequences
62
- # with the values of environment variables. Perform this recursively if
63
- # data is a Hash or Array.
64
- #
65
- #
66
- # @param [Hash,Array,String,Object] data
67
- # @return [Hash,Array,String,Object] data with all ${ENV} references substituted
68
- private def substitute(data)
69
- case data
70
- when Hash
71
- result = {}
72
- data.each_pair { |k, v| result[k] = substitute(v) }
73
- when Array
74
- result = []
75
- data.each { |v| result << substitute(v) }
76
- when String
77
- result = data
78
- while (match = SUBSTITUTION.match(result))
79
- var = match[1]
80
- repl = format("${%s}", var)
81
- result.gsub!(repl, ENV[var])
82
- end
83
- else
84
- result = data
85
- end
86
-
87
- result
88
- end
89
- end
90
- end