From 10e03984443283d54e14ebf61fa20c9eb7906e09 Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Fri, 28 Apr 2017 19:23:03 +0900 Subject: [PATCH 1/2] Add a new option `unbundle` to ShellCommandAgent This addresses #1989. --- app/models/agents/shell_command_agent.rb | 13 ++++- .../models/agents/shell_command_agent_spec.rb | 50 +++++++++++++++++-- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/app/models/agents/shell_command_agent.rb b/app/models/agents/shell_command_agent.rb index fb055e5b..672dd9b4 100644 --- a/app/models/agents/shell_command_agent.rb +++ b/app/models/agents/shell_command_agent.rb @@ -22,6 +22,8 @@ module Agents The resulting event will contain the `command` which was executed, the `path` it was executed under, the `exit_status` of the command, the `errors`, and the actual `output`. ShellCommandAgent will not log an error if the result implies that something went wrong. + If `unbundle` is set to true, the command is run in a clean environment, outside of Huginn's bundler context. + If `suppress_on_failure` is set to true, no event is emitted when `exit_status` is not zero. If `suppress_on_empty_output` is set to true, no event is emitted when `output` is empty. @@ -47,6 +49,7 @@ module Agents { 'path' => "/", 'command' => "pwd", + 'unbundle' => false, 'suppress_on_failure' => false, 'suppress_on_empty_output' => false, 'expected_update_period_in_days' => 1 @@ -95,7 +98,7 @@ module Agents path = opts['path'] stdin = opts['stdin'] - result, errors, exit_status = run_command(path, command, stdin) + result, errors, exit_status = run_command(path, command, stdin, interpolated.slice(:unbundle).symbolize_keys) payload = { 'command' => command, @@ -115,7 +118,13 @@ module Agents end end - def run_command(path, command, stdin) + def run_command(path, command, stdin, unbundle: false) + if unbundle + return Bundler.with_original_env { + run_command(path, command, stdin) + } + end + begin rout, wout = IO.pipe rerr, werr = IO.pipe diff --git a/spec/models/agents/shell_command_agent_spec.rb b/spec/models/agents/shell_command_agent_spec.rb index ad31d6a7..0690204a 100644 --- a/spec/models/agents/shell_command_agent_spec.rb +++ b/spec/models/agents/shell_command_agent_spec.rb @@ -60,7 +60,7 @@ describe Agents::ShellCommandAgent do describe "#working?" do it "generating events as scheduled" do - stub(@checker).run_command(@valid_path, 'pwd', nil) { ["fake pwd output", "", 0] } + stub(@checker).run_command(@valid_path, 'pwd', nil, {}) { ["fake pwd output", "", 0] } expect(@checker).not_to be_working @checker.check @@ -73,9 +73,14 @@ describe Agents::ShellCommandAgent do describe "#check" do before do - stub(@checker).run_command(@valid_path, 'pwd', nil) { ["fake pwd output", "", 0] } - stub(@checker).run_command(@valid_path, 'empty_output', nil) { ["", "", 0] } - stub(@checker).run_command(@valid_path, 'failure', nil) { ["failed", "error message", 1] } + orig_run_command = @checker.method(:run_command) + stub(@checker).run_command(@valid_path, 'pwd', nil, {}) { ["fake pwd output", "", 0] } + stub(@checker).run_command(@valid_path, 'empty_output', nil, {}) { ["", "", 0] } + stub(@checker).run_command(@valid_path, 'failure', nil, {}) { ["failed", "error message", 1] } + stub(@checker).run_command(@valid_path, 'echo $BUNDLE_GEMFILE', nil, unbundle: true) { orig_run_command.(@valid_path, 'echo $BUNDLE_GEMFILE', nil, unbundle: true) } + [[], [{}], [{ unbundle: false }]].each do |rest| + stub(@checker).run_command(@valid_path, 'echo $BUNDLE_GEMFILE', nil, *rest) { [ENV['BUNDLE_GEMFILE'].to_s, "", 0] } + end end it "should create an event when checking" do @@ -125,11 +130,46 @@ describe Agents::ShellCommandAgent do stub(Agents::ShellCommandAgent).should_run? { false } expect { @checker.check }.not_to change { Event.count } end + + describe "with unbundle" do + before do + @checker.options[:command] = 'echo $BUNDLE_GEMFILE' + end + + context "unspecified" do + it "should be run inside of our bundler context" do + expect { @checker.check }.to change { Event.count }.by(1) + expect(Event.last.payload[:output].strip).to eq(ENV['BUNDLE_GEMFILE']) + end + end + + context "explicitly set to false" do + before do + @checker.options[:unbundle] = false + end + + it "should be run inside of our bundler context" do + expect { @checker.check }.to change { Event.count }.by(1) + expect(Event.last.payload[:output].strip).to eq(ENV['BUNDLE_GEMFILE']) + end + end + + context "set to true" do + before do + @checker.options[:unbundle] = true + end + + it "should be run outside of our bundler context" do + expect { @checker.check }.to change { Event.count }.by(1) + expect(Event.last.payload[:output].strip).to eq('') # not_to eq(ENV['BUNDLE_GEMFILE'] + end + end + end end describe "#receive" do before do - stub(@checker).run_command(@valid_path, @event.payload[:cmd], nil) { ["fake ls output", "", 0] } + stub(@checker).run_command(@valid_path, @event.payload[:cmd], nil, {}) { ["fake ls output", "", 0] } end it "creates events" do From 807c493efe933b1c3fbd2791add295438c6faf2e Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Fri, 28 Apr 2017 20:41:54 +0900 Subject: [PATCH 2/2] Add a tweak for Travis where BUNDLE_GEMFILE is preset --- spec/models/agents/shell_command_agent_spec.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/models/agents/shell_command_agent_spec.rb b/spec/models/agents/shell_command_agent_spec.rb index 0690204a..ff554eb1 100644 --- a/spec/models/agents/shell_command_agent_spec.rb +++ b/spec/models/agents/shell_command_agent_spec.rb @@ -134,6 +134,9 @@ describe Agents::ShellCommandAgent do describe "with unbundle" do before do @checker.options[:command] = 'echo $BUNDLE_GEMFILE' + if ENV['TRAVIS'] == 'true' + stub.proxy(Bundler).original_env { |env| env.except('BUNDLE_GEMFILE') } + end end context "unspecified" do