Skip to content

Commit

Permalink
Merge pull request #6 from dkolb/enhance-output
Browse files Browse the repository at this point in the history
Enahncing the build call to stream output to the terminal.
  • Loading branch information
zl4bv authored Sep 30, 2017
2 parents 8a60269 + d3aaa7d commit ad33565
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 32 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ client.build('template.json').artifacts
# Get packer output
result = client.build('template.json')
puts result.stdout

# Or have output streamed directly to stdout
result = client.build('template.json', live_stream: $STDOUT)
```

### Fix: Fix template
Expand Down
22 changes: 17 additions & 5 deletions lib/packer/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class Client
# @option options [Hash] :vars variables for templates
# @option options [String] :var_file path to JSON file containing user
# variables
# @option options [IO] :live_stream an IO object to stream packer output to
# in addition to saving output in the output object.
# @return [Packer::Output::Build]
def build(template, options = {})
args = ['build', '-machine-readable']
Expand All @@ -40,14 +42,20 @@ def build(template, options = {})

args << template

Packer::Output::Build.new(command(args))
Packer::Output::Build.new(
command(args, options[:live_stream]))
end

# @api private
# @param [Array<String>] args to pass to Packer
def command(args)
# @param Boolean set to true to stream output to $stdout
def command(args, stream = nil)
cmd = [executable_path, args].join(' ')
so = Mixlib::ShellOut.new(cmd, timeout: execution_timeout)
options = {
timeout: execution_timeout,
live_stream: stream
}
so = Mixlib::ShellOut.new(cmd, options)
so.run_command
end

Expand Down Expand Up @@ -126,6 +134,8 @@ def inspect_template(template)
# @option options [Hash] :vars variables for templates
# @option options [String] :var_file path to JSON file containing user
# variables
# @option options [IO] :live_stream an IO object to stream packer output to
# in addition to saving output in the output object.
# @return [Packer::Output::Push]
def push(template, options = {})
args = ['push']
Expand All @@ -139,7 +149,7 @@ def push(template, options = {})

args << template

Packer::Output::Push.new(command(args))
Packer::Output::Push.new(command(args, options[:live_stream]))
end

# Executes +packer validate+
Expand All @@ -160,6 +170,8 @@ def push(template, options = {})
# @option options [Array<String>] :only validate only these builds
# @option options [Hash] :vars variables for templates
# @option options [String] :var_file path to JSON file containing user
# @option options [IO] :live_stream an IO object to stream packer output to
# in addition to saving output in the output object.
# variables
# @return [Packer::Output::Validate]
def validate(template, options = {})
Expand All @@ -174,7 +186,7 @@ def validate(template, options = {})

args << template

Packer::Output::Validate.new(command(args))
Packer::Output::Validate.new(command(args, options[:live_stream]))
end

# Executes +packer version+
Expand Down
2 changes: 1 addition & 1 deletion spec/integration/build_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ def mock_shellout(cmd, stdout)
shellout = double('Mixlib::Shellout')

allow(OS).to receive(:windows?).and_return(false)
allow(Mixlib::ShellOut).to receive(:new).with(cmd, timeout: 7200).and_return(shellout)
allow(Mixlib::ShellOut).to receive(:new).with(cmd, timeout: 7200, live_stream: nil).and_return(shellout)
allow(shellout).to receive(:run_command).and_return(shellout)
allow(shellout).to receive(:stdout).and_return(File.read(stdout))
end
Expand Down
92 changes: 66 additions & 26 deletions spec/unit/packer/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
context 'when no options given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['build', '-machine-readable', 'template.json'])
.with(['build', '-machine-readable', 'template.json'], nil)

subject.build('template.json')
end
Expand All @@ -14,7 +14,7 @@
context 'when force option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['build', '-machine-readable', '-force', 'template.json'])
.with(['build', '-machine-readable', '-force', 'template.json'], nil)

subject.build('template.json', force: true)
end
Expand All @@ -23,7 +23,7 @@
context 'when except option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['build', '-machine-readable', '-except=foo,bar', 'template.json'])
.with(['build', '-machine-readable', '-except=foo,bar', 'template.json'], nil)

subject.build('template.json', except: %w(foo bar))
end
Expand All @@ -32,7 +32,7 @@
context 'when only option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['build', '-machine-readable', '-only=foo,bar', 'template.json'])
.with(['build', '-machine-readable', '-only=foo,bar', 'template.json'], nil)

subject.build('template.json', only: %w(foo bar))
end
Expand All @@ -41,16 +41,15 @@
context 'when parallel option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['build', '-machine-readable', '-parallel=false', 'template.json'])

.with(['build', '-machine-readable', '-parallel=false', 'template.json'], nil)
subject.build('template.json', parallel: false)
end
end

context 'when var_file option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['build', '-machine-readable', '-var-file=vars.json', 'template.json'])
.with(['build', '-machine-readable', '-var-file=vars.json', 'template.json'], nil)

subject.build('template.json', var_file: 'vars.json')
end
Expand All @@ -59,11 +58,20 @@
context 'when vars option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['build', '-machine-readable', "-var 'foo=bar'", 'template.json'])
.with(['build', '-machine-readable', "-var 'foo=bar'", 'template.json'], nil)

subject.build('template.json', vars: { 'foo' => 'bar' })
end
end

context 'when stream_output options given' do
it 'executes the command with live streaming enabled' do
expect(subject).to receive(:command)
.with(['build', '-machine-readable', 'template.json'], "stdout_io")

subject.build('template.json', live_stream: "stdout_io")
end
end
end

describe '#command' do
Expand All @@ -73,13 +81,27 @@
allow(subject).to receive(:executable_path).and_return('exe')
end

it 'executes packer with the given args' do
expect(Mixlib::ShellOut).to receive(:new)
.with('exe cmd', timeout: 7200)
.and_return(shellout)
expect(shellout).to receive(:run_command)
context 'streaming is disabled' do
it 'executes packer with the given args' do
expect(Mixlib::ShellOut).to receive(:new)
.with('exe cmd', timeout: 7200, live_stream: nil)
.and_return(shellout)
expect(shellout).to receive(:run_command)

subject.command(['cmd'])
subject.command(['cmd'])
end
end

context 'streaming is enabled' do
it 'executes packer with given args and live_stream set' do
expect(Mixlib::ShellOut).to receive(:new)
.with('exe cmd', timeout: 7200, live_stream: "stdout_io")
.and_return(shellout)

expect(shellout).to receive(:run_command)

subject.command(['cmd'], "stdout_io")
end
end
end

Expand Down Expand Up @@ -153,7 +175,7 @@
context 'when no options given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['push', 'template.json'])
.with(['push', 'template.json'], nil)

subject.push('template.json')
end
Expand All @@ -162,7 +184,7 @@
context 'when message option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['push', '-message=foo', 'template.json'])
.with(['push', '-message=foo', 'template.json'], nil)

subject.push('template.json', message: 'foo')
end
Expand All @@ -171,7 +193,7 @@
context 'when name option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['push', '-name=foo/bar', 'template.json'])
.with(['push', '-name=foo/bar', 'template.json'], nil)

subject.push('template.json', name: 'foo/bar')
end
Expand All @@ -180,7 +202,7 @@
context 'when token option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['push', '-token=example', 'template.json'])
.with(['push', '-token=example', 'template.json'], nil)

subject.push('template.json', token: 'example')
end
Expand All @@ -189,7 +211,7 @@
context 'when var_file option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['push', '-var-file=vars.json', 'template.json'])
.with(['push', '-var-file=vars.json', 'template.json'], nil)

subject.push('template.json', var_file: 'vars.json')
end
Expand All @@ -198,18 +220,27 @@
context 'when vars option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['push', "-var 'foo=bar'", 'template.json'])
.with(['push', "-var 'foo=bar'", 'template.json'], nil)

subject.push('template.json', vars: { 'foo' => 'bar' })
end
end

context 'when live_stream option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['push', 'template.json'], 'stdout_io')

subject.push('template.json', live_stream: 'stdout_io')
end
end
end

describe '#validate' do
context 'when no options given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['validate', 'template.json'])
.with(['validate', 'template.json'], nil)

subject.validate('template.json')
end
Expand All @@ -218,7 +249,7 @@
context 'when syntax_only option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['validate', '-syntax-only', 'template.json'])
.with(['validate', '-syntax-only', 'template.json'], nil)

subject.validate('template.json', syntax_only: true)
end
Expand All @@ -227,7 +258,7 @@
context 'when except option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['validate', '-except=foo,bar', 'template.json'])
.with(['validate', '-except=foo,bar', 'template.json'], nil)

subject.validate('template.json', except: %w(foo bar))
end
Expand All @@ -236,7 +267,7 @@
context 'when only option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['validate', '-only=foo,bar', 'template.json'])
.with(['validate', '-only=foo,bar', 'template.json'], nil)

subject.validate('template.json', only: %w(foo bar))
end
Expand All @@ -245,7 +276,7 @@
context 'when var_file option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['validate', '-var-file=vars.json', 'template.json'])
.with(['validate', '-var-file=vars.json', 'template.json'], nil)

subject.validate('template.json', var_file: 'vars.json')
end
Expand All @@ -254,11 +285,20 @@
context 'when vars option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['validate', "-var 'foo=bar'", 'template.json'])
.with(['validate', "-var 'foo=bar'", 'template.json'], nil)

subject.validate('template.json', vars: { 'foo' => 'bar' })
end
end

context 'when live_stream option given' do
it 'executes Packer with correct arguments' do
expect(subject).to receive(:command)
.with(['validate', 'template.json'], 'stdout_io')

subject.validate('template.json', live_stream: 'stdout_io')
end
end
end

describe '#version' do
Expand Down

0 comments on commit ad33565

Please sign in to comment.