From 638f8320bcf9061a3e99eaabd9247d02ccbac3c4 Mon Sep 17 00:00:00 2001 From: Thibault Jouan Date: Wed, 24 Sep 2014 22:26:22 +0000 Subject: [PATCH] Implement nested tasks --- features/task_nested_tasks.feature | 15 +++++++++++++++ lib/producer/core/task.rb | 4 ++++ lib/producer/core/worker.rb | 8 ++++++-- spec/producer/core/task_spec.rb | 9 +++++++++ spec/producer/core/worker_spec.rb | 18 ++++++++++++++---- 5 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 features/task_nested_tasks.feature diff --git a/features/task_nested_tasks.feature b/features/task_nested_tasks.feature new file mode 100644 index 0000000..cf9c850 --- /dev/null +++ b/features/task_nested_tasks.feature @@ -0,0 +1,15 @@ +Feature: nested tasks + + Background: + Given a recipe with: + """ + task :outer_task do + task :inner_task do + echo 'OK' + end + end + """ + + Scenario: applies nested tasks + When I successfully execute the recipe + Then the output must match /\AOK/ diff --git a/lib/producer/core/task.rb b/lib/producer/core/task.rb index c5e2dcc..3ea952d 100644 --- a/lib/producer/core/task.rb +++ b/lib/producer/core/task.rb @@ -43,6 +43,10 @@ module Producer @condition end + def task(name, *args, &block) + @actions << self.class.evaluate(@env, name, *args, &block) + end + def ask(question, choices, prompter: Prompter.new(@env.input, @env.output)) prompter.prompt(question, choices) end diff --git a/lib/producer/core/worker.rb b/lib/producer/core/worker.rb index 453ea52..8d4cc70 100644 --- a/lib/producer/core/worker.rb +++ b/lib/producer/core/worker.rb @@ -18,8 +18,12 @@ module Producer if task.condition_met? @env.log "Task: `#{task}' applying..." task.actions.each do |e| - @env.log " action: #{e}" - e.apply unless @env.dry_run? + case e + when Task then process_task e + else + @env.log " action: #{e}" + e.apply unless @env.dry_run? + end end else @env.log "Task: `#{task}' skipped" diff --git a/spec/producer/core/task_spec.rb b/spec/producer/core/task_spec.rb index fbffa53..5b2e877 100644 --- a/spec/producer/core/task_spec.rb +++ b/spec/producer/core/task_spec.rb @@ -126,6 +126,15 @@ module Producer::Core end end + describe '#task' do + before { described_class.define_action(:some_action, SomeAction) } + + it 'registers a nested task as an action' do + task.task(:nested_task) { some_action } + expect(task.actions).to match [an_instance_of(Task)] + end + end + describe '#ask' do let(:question) { 'Which letter?' } let(:choices) { [[:a, ?A], [:b, ?B]] } diff --git a/spec/producer/core/worker_spec.rb b/spec/producer/core/worker_spec.rb index 8ba1c0d..76526bc 100644 --- a/spec/producer/core/worker_spec.rb +++ b/spec/producer/core/worker_spec.rb @@ -25,9 +25,9 @@ module Producer::Core end describe '#process_task' do - let(:env) { instance_spy Env, dry_run?: false } - let(:action) { double('action', to_s: 'echo').as_null_object } - let(:task) { Task.new(env, :some_task, [action]) } + let(:env) { instance_spy Env, dry_run?: false } + let(:action) { double('action', to_s: 'echo').as_null_object } + let(:task) { Task.new(env, :some_task, [action]) } it 'logs task info' do expect(env).to receive(:log).with /\ATask: `some_task'/ @@ -68,11 +68,21 @@ module Producer::Core worker.process_task task end - it 'logs the task as beeing skipped' do + it 'logs the task as being skipped' do expect(env).to receive(:log).with /some_task.+skipped\z/ worker.process_task task end end + + context 'when a task contains nested tasks' do + let(:inner_task) { Task.new(env, :inner, [action]) } + let(:outer_task) { Task.new(env, :outer, [inner_task]) } + + it 'processes nested tasks' do + expect(action).to receive :apply + worker.process [outer_task] + end + end end end end