diff --git a/features/cli_debug.feature b/features/cli_debug.feature new file mode 100644 index 0000000..74bdb46 --- /dev/null +++ b/features/cli_debug.feature @@ -0,0 +1,11 @@ +Feature: CLI debug option + + Background: + Given a recipe with: + """ + task(:trigger_error) { fail 'some error' } + """ + + Scenario: reports recipe errors + When I execute the recipe with option -d + Then the output must match /\ARuntimeError:.*\n\ncause:\nRuntimeError:/ diff --git a/features/cli_usage.feature b/features/cli_usage.feature index a7329e0..9791061 100644 --- a/features/cli_usage.feature +++ b/features/cli_usage.feature @@ -10,6 +10,7 @@ Feature: CLI usage options: -v, --verbose enable verbose mode + -d, --debug enable debug mode -n, --dry-run enable dry run mode -t, --target HOST target host """ diff --git a/features/steps/recipe_steps.rb b/features/steps/recipe_steps.rb index 66f55ba..1255925 100644 --- a/features/steps/recipe_steps.rb +++ b/features/steps/recipe_steps.rb @@ -24,6 +24,10 @@ When /^I successfully execute the recipe on remote target$/ do assert_exit_status 0 end +When /^I execute the recipe with option (-.+)$/ do |option| + run_simple "producer #{option} recipe.rb", false +end + When /^I successfully execute the recipe with option (-.+)$/ do |option| run_simple "producer #{option} recipe.rb", false assert_exit_status 0 diff --git a/lib/producer/core/cli.rb b/lib/producer/core/cli.rb index d2c2daa..503663e 100644 --- a/lib/producer/core/cli.rb +++ b/lib/producer/core/cli.rb @@ -18,7 +18,10 @@ module Producer stderr.puts e.message exit EX_USAGE rescue Exception => e - ef = ErrorFormatter.new(force_cause: [RecipeEvaluationError]) + ef = ErrorFormatter.new( + debug: cli.env.debug?, + force_cause: [RecipeEvaluationError] + ) stderr.puts ef.format e exit EX_SOFTWARE end @@ -66,6 +69,10 @@ module Producer env.verbose = true end + opts.on '-d', '--debug', 'enable debug mode' do |e| + env.debug = true + end + opts.on '-n', '--dry-run', 'enable dry run mode' do |e| env.dry_run = true end diff --git a/lib/producer/core/env.rb b/lib/producer/core/env.rb index 6530760..e5602ca 100644 --- a/lib/producer/core/env.rb +++ b/lib/producer/core/env.rb @@ -2,10 +2,10 @@ module Producer module Core class Env attr_reader :input, :output, :error_output, :registry, :logger - attr_accessor :target, :verbose, :dry_run + attr_accessor :target, :verbose, :debug, :dry_run def initialize(input: $stdin, output: $stdout, error_output: $stderr, remote: nil, registry: {}) - @verbose = @dry_run = false + @verbose = @debug = @dry_run = false @input = input @output = output @error_output = error_output @@ -45,6 +45,10 @@ module Producer @verbose end + def debug? + @debug + end + def dry_run? @dry_run end diff --git a/spec/producer/core/cli_spec.rb b/spec/producer/core/cli_spec.rb index a3fd902..dbde3c3 100644 --- a/spec/producer/core/cli_spec.rb +++ b/spec/producer/core/cli_spec.rb @@ -112,6 +112,15 @@ module Producer::Core end end + context 'with debug option' do + let(:options) { %w[-d] } + + it 'assigns the given target to the env' do + cli.parse_arguments! + expect(cli.env).to be_debug + end + end + context 'with combined options' do let(:options) { %w[-vn]} diff --git a/spec/producer/core/env_spec.rb b/spec/producer/core/env_spec.rb index d595013..44db8cd 100644 --- a/spec/producer/core/env_spec.rb +++ b/spec/producer/core/env_spec.rb @@ -26,6 +26,10 @@ module Producer::Core expect(env.verbose).to be false end + it 'assigns debug as false' do + expect(env.debug).to be false + end + it 'assigns dry run as false' do expect(env.dry_run).to be false end @@ -168,6 +172,13 @@ module Producer::Core end end + describe '#debug?' do + it 'returns true when debug is enabled' do + env.debug = true + expect(env).to be_debug + end + end + describe '#dry_run?' do it 'returns true when dry run is enabled' do env.dry_run = true diff --git a/spec/producer/core/error_formatter_spec.rb b/spec/producer/core/error_formatter_spec.rb index fd4bc86..e833c30 100644 --- a/spec/producer/core/error_formatter_spec.rb +++ b/spec/producer/core/error_formatter_spec.rb @@ -23,14 +23,15 @@ module Producer end describe '#format' do - let(:message) { 'some exception' } - let(:exception) { Exception.new(message) } - - before { exception.set_backtrace %w[back trace] } + def exception + begin fail 'original exception' rescue fail 'some exception' end + rescue + $!.tap { |o| o.set_backtrace %w[back trace] } + end it 'formats the message' do expect(formatter.format exception) - .to match /^Exception: some exception$/ + .to match /^RuntimeError: some exception$/ end it 'indents the backtrace' do @@ -43,6 +44,14 @@ module Producer it 'excludes producer code from the backtrace' do expect(formatter.format exception).not_to include 'producer-core' end + + context 'when debug is enabled' do + let(:debug) { true } + + it 'does not exclude producer code from the backtrace' do + expect(formatter.format exception).to include 'producer-core' + end + end end end end