Skip to content

Commit

Permalink
Return non-zero exit codes when something goes wrong
Browse files Browse the repository at this point in the history
  • Loading branch information
Flavio Auciello committed Apr 27, 2017
1 parent c0b2ce3 commit ab34606
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 4 deletions.
1 change: 1 addition & 0 deletions lib/pulsar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module Pulsar
require 'fileutils'

require 'pulsar/context_error'
require 'pulsar/executor'
require 'pulsar/validator'
require 'pulsar/interactors/cleanup'
require 'pulsar/interactors/create_run_dirs'
Expand Down
8 changes: 8 additions & 0 deletions lib/pulsar/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

module Pulsar
class CLI < Thor
def self.exit_on_failure?; true; end
map %w[--version -v] => :__print_version

desc 'install [DIRECTORY]', 'Install initial repository in DIRECTORY'
Expand All @@ -20,9 +21,11 @@ def install(directory = './pulsar-conf')

if result.success?
puts 'Successfully created intial repo!'
exit 0
else
puts 'Failed to create intial repo.'
puts result.error
exit result.error.exit_code
end
end

Expand All @@ -40,9 +43,11 @@ def list
result.applications.each do |app, stages|
puts "#{app}: #{stages.join(', ')}"
end
exit 0
else
puts 'Failed to list application and environments.'
puts result.error
exit result.error.exit_code
end
end

Expand All @@ -62,15 +67,18 @@ def deploy(application, environment)

if result.success?
puts "Deployed #{application} on #{environment}!"
exit 0
else
puts "Failed to deploy #{application} on #{environment}."
puts result.error
exit result.error.exit_code
end
end

desc "--version, -v", "print the version"
def __print_version
puts Pulsar::VERSION
exit 0
end

private
Expand Down
5 changes: 5 additions & 0 deletions lib/pulsar/context_error.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
module Pulsar
class ContextError < StandardError
attr_reader :exit_code
def initialize(obj, exit_code)
super obj
@exit_code = exit_code
end
def to_s
backtrace ? backtrace.unshift(super).join("\n") : super
end
Expand Down
17 changes: 17 additions & 0 deletions lib/pulsar/executor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require 'open3'

module Pulsar
module Executor
def self.sh(cmd)
stdin, stdout, stderr, wait_thr = Open3.popen3(cmd)
output = stdout.gets(nil)
stdout.close
stderr.gets(nil)
stderr.close
stdin.close
exit_code = wait_thr.value
yield exit_code, output if block_given?
[exit_code, output]
end
end
end
2 changes: 1 addition & 1 deletion lib/pulsar/validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def validate_context!
end

def context_fail!(msg)
context.fail! error: Pulsar::ContextError.new(msg)
context.fail! error: Pulsar::ContextError.new(msg, 1)
end

def validable_properties
Expand Down
18 changes: 17 additions & 1 deletion spec/features/deploy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
let(:command) do
`DRY_RUN=true #{RSpec.configuration.pulsar_command} deploy #{options} #{arguments}`
end

let(:exit_status) do
Pulsar::Executor.sh("DRY_RUN=true #{RSpec.configuration.pulsar_command} deploy #{options} #{arguments}")[0].exitstatus
end
let(:repo) { RSpec.configuration.pulsar_conf_path }
let(:options) { "--conf-repo #{repo}" }
let(:app) { 'blog' }
Expand All @@ -17,6 +19,7 @@
let(:error) { /Could not find command/ }

it { is_expected.not_to output(error).to_stderr_from_any_process }
it { expect(exit_status).to eq(0) }
end

context 'requires a --conf-repo option' do
Expand All @@ -29,12 +32,14 @@
let(:options) { "-c #{repo}" }

it { is_expected.not_to output(error).to_stderr_from_any_process }
it { expect(exit_status).to eq(0) }
end

context 'can be specified via the environment variable PULSAR_CONF_REPO' do
before { ENV['PULSAR_CONF_REPO'] = repo }

it { is_expected.not_to output(error).to_stderr_from_any_process }
it { expect(exit_status).to eq(0) }
end
end

Expand All @@ -44,6 +49,7 @@
let(:error) { /Usage: "pulsar deploy APPLICATION ENVIRONMENT"/ }

it { is_expected.to output(error).to_stderr_from_any_process }
it { expect(exit_status).to eq(1) }
end

context 'when succeeds' do
Expand All @@ -60,6 +66,7 @@
end

it { is_expected.to match(output) }
it { expect(exit_status).to eq(0) }

context 'leaves the tmp folder empty' do
subject { Dir.glob("#{Pulsar::PULSAR_TMP}/*") }
Expand All @@ -77,6 +84,7 @@
let(:output) { "Deployed your_app on staging!\n" }

it { is_expected.to match(output) }
it { expect(exit_status).to eq(0) }

context 'leaves the tmp folder empty' do
subject { Dir.glob("#{Pulsar::PULSAR_TMP}/*") }
Expand All @@ -94,6 +102,7 @@
let(:output) { "Deployed your_app on staging!\n" }

it { is_expected.to match(output) }
it { expect(exit_status).to eq(0) }

context 'leaves the tmp folder empty' do
subject { Dir.glob("#{Pulsar::PULSAR_TMP}/*") }
Expand All @@ -113,25 +122,29 @@
let(:repo) { './some-wrong-directory' }

it { is_expected.to match("Failed to deploy blog on production.\n") }
it { expect(exit_status).to eq(1) }
end

context 'because of empty directory' do
let(:repo) { RSpec.configuration.pulsar_empty_conf_path }

it { is_expected.to match("Failed to deploy blog on production.\n") }
it { is_expected.to match "No application found on repository #{RSpec.configuration.pulsar_empty_conf_path}\n" }
it { expect(exit_status).to eq(1) }
end

context 'because Bundler failed' do
let(:repo) { RSpec.configuration.pulsar_wrong_bundle_conf_path }

it { is_expected.to match("Failed to deploy blog on production.\n") }
it { expect(exit_status).to eq(1) }
end

context 'because Capistrano failed' do
let(:repo) { RSpec.configuration.pulsar_wrong_cap_conf_path }

it { is_expected.to match("Failed to deploy blog on production.\n") }
it { expect(exit_status).to eq(1) }
end

context 'because the application does not exists in the repository' do
Expand All @@ -140,6 +153,7 @@
let(:environment) { 'staging' }

it { is_expected.to match("The application foobuzz does not exist in your repository") }
it { expect(exit_status).to eq(1) }
end

context 'because the environment does not exists for the application' do
Expand All @@ -148,11 +162,13 @@
let(:environment) { 'foobuzz' }

it { is_expected.to match("The application blog does not have an environment called foobuzz") }
it { expect(exit_status).to eq(1) }

context 'but \'no application error\' message takes precedence' do
let(:app) { 'foobuzz' }

it { is_expected.to match("The application foobuzz does not exist in your repository") }
it { expect(exit_status).to eq(1) }
end
end
end
Expand Down
7 changes: 7 additions & 0 deletions spec/features/install_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
let(:command) do
`#{RSpec.configuration.pulsar_command} install #{arguments}`
end
let(:exit_status) do
Pulsar::Executor.sh("#{RSpec.configuration.pulsar_command} install #{arguments}")[0].exitstatus
end

let(:arguments) { nil }

Expand All @@ -15,6 +18,7 @@
let(:error) { /Could not find command/ }

it { is_expected.not_to output(error).to_stderr_from_any_process }
it { expect(exit_status).to eq(0) }
end

context 'when succeeds' do
Expand All @@ -23,6 +27,8 @@
context 'creates a directory' do
subject { -> { command } }

it { expect(exit_status).to eq(0) }

context 'with the basic configuration' do
subject(:initial_pulsar_repo) do
Dir.entries('./../../../lib/pulsar/generators/initial_repo/')
Expand Down Expand Up @@ -61,6 +67,7 @@
subject { -> { command } }

it { is_expected.not_to change { File.exist?('./my-dir') }.from(false) }
it { expect(exit_status).to eq(1) }
end
end
end
13 changes: 12 additions & 1 deletion spec/features/list_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,38 @@
let(:command) do
`#{RSpec.configuration.pulsar_command} list #{arguments}`
end

let(:exit_status) do
Pulsar::Executor.sh("#{RSpec.configuration.pulsar_command} list #{arguments}")[0].exitstatus
end
let(:repo) { RSpec.configuration.pulsar_conf_path }
let(:arguments) { "--conf-repo #{repo}" }

context 'via a subcommand named list' do
let(:error) { /Could not find command/ }

it { is_expected.not_to output(error).to_stderr_from_any_process }
it { expect(exit_status).to eq(0) }
end

context 'requires a --conf-repo option' do
let(:arguments) { nil }
let(:error) { /No value provided for required options '--conf-repo'/ }

it { is_expected.to output(error).to_stderr_from_any_process }
it { expect(exit_status).to eq(1) }

context 'can be specified via the alias -c' do
let(:arguments) { "-c #{repo}" }

it { is_expected.not_to output(error).to_stderr_from_any_process }
it { expect(exit_status).to eq(0) }
end

context 'can be specified via the environment variable PULSAR_CONF_REPO' do
before { ENV['PULSAR_CONF_REPO'] = repo }

it { is_expected.not_to output(error).to_stderr_from_any_process }
it { expect(exit_status).to eq(0) }
end
end

Expand All @@ -49,6 +55,7 @@
end

it { is_expected.to eql(output) }
it { expect(exit_status).to eq(0) }

context 'leaves the tmp folder empty' do
subject { Dir.glob("#{Pulsar::PULSAR_TMP}/*") }
Expand All @@ -64,6 +71,7 @@
let(:output) { "your_app: production, staging\n" }

it { is_expected.to eql output }
it { expect(exit_status).to eq(0) }

context 'leaves the tmp folder empty' do
subject { Dir.glob("#{Pulsar::PULSAR_TMP}/*") }
Expand All @@ -79,6 +87,7 @@
let(:output) { "your_app: production, staging\n" }

it { is_expected.to eql output }
it { expect(exit_status).to eq(0) }

context 'leaves the tmp folder empty' do
subject { Dir.glob("#{Pulsar::PULSAR_TMP}/*") }
Expand All @@ -98,13 +107,15 @@
let(:repo) { './some-wrong-directory' }

it { is_expected.to match "Failed to list application and environments.\n" }
it { expect(exit_status).to eq(1) }
end

context 'because of empty directory' do
let(:repo) { RSpec.configuration.pulsar_empty_conf_path }

it { is_expected.to match "Failed to list application and environments.\n" }
it { is_expected.to match "No application found on repository #{RSpec.configuration.pulsar_empty_conf_path}\n" }
it { expect(exit_status).to eq(1) }
end
end
end
5 changes: 4 additions & 1 deletion spec/features/version_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
let(:command) do
`#{RSpec.configuration.pulsar_command} #{arguments}`
end

let(:exit_status) do
Pulsar::Executor.sh("#{RSpec.configuration.pulsar_command} #{arguments}")[0].exitstatus
end
let(:arguments) { "--version" }

context 'via a --version flag' do
let(:version) { "#{Pulsar::VERSION}\n" }

it { is_expected.to eql version }
it { expect(exit_status).to eq(0) }
end
end
4 changes: 4 additions & 0 deletions spec/support/dummies/conf/dir/apps/ecommerce/staging.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Staging config

server 'staging.ecommerce.com', user: 'deploy', roles: %w{web app db}, primary: true
set :stage, :staging

0 comments on commit ab34606

Please sign in to comment.