diff --git a/features/actions/sh.feature b/features/actions/sh.feature new file mode 100644 index 0000000..2ff5343 --- /dev/null +++ b/features/actions/sh.feature @@ -0,0 +1,26 @@ +@sshd +Feature: sh task action + + Scenario: executes command + Given a recipe with: + """ + target 'some_host.test' + + task :some_task do + sh '\true' + end + """ + When I execute the recipe + Then the exit status must be 0 + + Scenario: forwards standard ouput + Given a recipe with: + """ + target 'some_host.test' + + task :some_task do + sh '\echo from remote' + end + """ + When I execute the recipe + Then the output must contain "from remote" diff --git a/lib/producer/core.rb b/lib/producer/core.rb index 4ebe692..144118d 100644 --- a/lib/producer/core.rb +++ b/lib/producer/core.rb @@ -1,4 +1,5 @@ require 'producer/core/action' +require 'producer/core/actions/shell_command' require 'producer/core/cli' require 'producer/core/env' require 'producer/core/errors' diff --git a/lib/producer/core/actions/shell_command.rb b/lib/producer/core/actions/shell_command.rb new file mode 100644 index 0000000..6836878 --- /dev/null +++ b/lib/producer/core/actions/shell_command.rb @@ -0,0 +1,11 @@ +module Producer + module Core + module Actions + class ShellCommand < Action + def apply + env.output env.remote.execute(arguments.first) + end + end + end + end +end diff --git a/lib/producer/core/task/dsl.rb b/lib/producer/core/task/dsl.rb index 43e964a..bc84580 100644 --- a/lib/producer/core/task/dsl.rb +++ b/lib/producer/core/task/dsl.rb @@ -10,6 +10,8 @@ module Producer end end + define_action :sh, Actions::ShellCommand + attr_accessor :actions def initialize(&block) diff --git a/spec/producer/core/actions/shell_command_spec.rb b/spec/producer/core/actions/shell_command_spec.rb new file mode 100644 index 0000000..956fef4 --- /dev/null +++ b/spec/producer/core/actions/shell_command_spec.rb @@ -0,0 +1,27 @@ +require 'spec_helper' + +module Producer::Core + describe Actions::ShellCommand do + let(:env) { Env.new } + let(:command_args) { 'hello from remote host'} + let(:command) { "echo #{command_args}" } + subject(:sh) { Actions::ShellCommand.new(env, command) } + + describe '#apply' do + before do + env.output = StringIO.new + end + + it 'delegates the call to env.remote.execute method' do + expect(env.remote).to receive(:execute).with(command) + sh.apply + end + + it 'forwards the returned output to env.output' do + allow(env.remote).to receive(:execute) { command_args } + expect(env).to receive(:output).with(command_args) + sh.apply + end + end + end +end diff --git a/spec/producer/core/task/dsl_spec.rb b/spec/producer/core/task/dsl_spec.rb index 92f7df6..4b66aba 100644 --- a/spec/producer/core/task/dsl_spec.rb +++ b/spec/producer/core/task/dsl_spec.rb @@ -6,6 +6,12 @@ module Producer::Core let(:env) { double('env') } subject(:dsl) { Task::DSL.new &block } + %w[sh].each do |action| + it "has `#{action}' action defined" do + expect(dsl).to respond_to action.to_sym + end + end + describe '.define_action' do it 'defines a new action keyword' do Task::DSL.define_action(:some_action, Object)