From 433f830c54c49de9764e031734b00493032d7083 Mon Sep 17 00:00:00 2001 From: Thibault Jouan Date: Sat, 4 Apr 2015 04:41:25 +0000 Subject: [PATCH] Implement recipe arguments CLI will stop arguments processing after the special `--' argument, the rest will be saved in the env and accessible through a new task keyword: `recipe_argv'. --- features/steps/recipe_steps.rb | 5 +++++ features/task/recipe_argv.feature | 13 +++++++++++++ lib/producer/core/cli.rb | 12 ++++++++++++ lib/producer/core/env.rb | 2 +- lib/producer/core/task.rb | 1 + spec/producer/core/cli_spec.rb | 14 ++++++++++++++ spec/producer/core/task_spec.rb | 8 ++++++++ 7 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 features/task/recipe_argv.feature diff --git a/features/steps/recipe_steps.rb b/features/steps/recipe_steps.rb index 40b703b..a07d13a 100644 --- a/features/steps/recipe_steps.rb +++ b/features/steps/recipe_steps.rb @@ -51,6 +51,11 @@ When /^I successfully execute the recipe with option (-.+)$/ do |option| assert_exit_status 0 end +When /^I successfully execute the recipe with arguments "([^"]+)"$/ do |arguments| + run_simple "producer recipe.rb -- #{arguments}", false + assert_exit_status 0 +end + When /^I execute the recipe interactively$/ do run_interactive 'producer recipe.rb' end diff --git a/features/task/recipe_argv.feature b/features/task/recipe_argv.feature new file mode 100644 index 0000000..c1ce191 --- /dev/null +++ b/features/task/recipe_argv.feature @@ -0,0 +1,13 @@ +Feature: `recipe_argv' task keyword + + Background: + Given a recipe with: + """ + task :echo_arguments do + echo recipe_argv + end + """ + + Scenario: returns recipe arguments + When I successfully execute the recipe with arguments "foo bar" + Then the output must contain exactly "foo\nbar\n" diff --git a/lib/producer/core/cli.rb b/lib/producer/core/cli.rb index 6478323..4ff76a5 100644 --- a/lib/producer/core/cli.rb +++ b/lib/producer/core/cli.rb @@ -8,6 +8,8 @@ module Producer EX_USAGE = 64 EX_SOFTWARE = 70 + ARGUMENTS_SEPARATOR = '--'.freeze + class << self def run!(arguments, stdin: $stdin, stdout: $stdout, stderr: $stderr) cli = new(arguments, stdin: stdin, stdout: stdout, stderr: stderr) @@ -39,6 +41,9 @@ module Producer end def parse_arguments! + if @arguments.include? ARGUMENTS_SEPARATOR + @arguments, @env.recipe_argv = split_arguments_lists @arguments + end option_parser.parse!(@arguments) fail ArgumentError, option_parser if @arguments.empty? end @@ -60,6 +65,13 @@ module Producer Env.new(input: @stdin, output: @stdout, error_output: @stderr) end + def split_arguments_lists(arguments) + arguments + .chunk { |e| e == ARGUMENTS_SEPARATOR } + .reject { |b, a| b } + .map &:last + end + def option_parser OptionParser.new do |opts| opts.banner = USAGE diff --git a/lib/producer/core/env.rb b/lib/producer/core/env.rb index 261ca8e..dd2421d 100644 --- a/lib/producer/core/env.rb +++ b/lib/producer/core/env.rb @@ -5,7 +5,7 @@ module Producer def_delegators :@registry, :[]=, :key? attr_reader :input, :output, :error_output, :registry, :logger - attr_accessor :target, :verbose, :debug, :dry_run + attr_accessor :target, :verbose, :debug, :dry_run, :recipe_argv def initialize(input: $stdin, output: $stdout, error_output: $stderr, remote: nil, registry: {}) @verbose = @debug = @dry_run = false diff --git a/lib/producer/core/task.rb b/lib/producer/core/task.rb index 9bd646f..82b88c7 100644 --- a/lib/producer/core/task.rb +++ b/lib/producer/core/task.rb @@ -18,6 +18,7 @@ module Producer def_delegators :@env, :target def_delegator :@env, :[], :get def_delegator :@env, :key?, :set? + def_delegator :@env, :recipe_argv define_action :echo, Actions::Echo define_action :sh, Actions::ShellCommand diff --git a/spec/producer/core/cli_spec.rb b/spec/producer/core/cli_spec.rb index 20384e6..7b75366 100644 --- a/spec/producer/core/cli_spec.rb +++ b/spec/producer/core/cli_spec.rb @@ -130,6 +130,20 @@ module Producer::Core end end + context 'with recipe arguments' do + let(:arguments) { %w[recipe.rb -- foo] } + + it 'removes recipe arguments' do + cli.parse_arguments! + expect(cli.arguments).to eq %w[recipe.rb] + end + + it 'assigns env recipe arguments' do + cli.parse_arguments! + expect(cli.env.recipe_argv).to eq %w[foo] + end + end + context 'when no arguments remains after parsing' do let(:arguments) { [] } diff --git a/spec/producer/core/task_spec.rb b/spec/producer/core/task_spec.rb index 1220659..cbce7e7 100644 --- a/spec/producer/core/task_spec.rb +++ b/spec/producer/core/task_spec.rb @@ -179,5 +179,13 @@ module Producer::Core expect(task.target).to eq :some_target end end + + describe '#recipe_argv' do + before { env.recipe_argv = %w[foo bar] } + + it 'returns recipe arguments' do + expect(task.recipe_argv).to eq %w[foo bar] + end + end end end