Skip to content

Commit

Permalink
feat: #execute now accepts an optional :env hash
Browse files Browse the repository at this point in the history
Closes #99
  • Loading branch information
flavorjones committed Apr 28, 2021
1 parent 0ae074f commit 1a0d778
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 13 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,10 @@

This release ends support for ruby < 2.3.0. If you're on 2.2.x or earlier, we strongly suggest that you find the time to upgrade, because [official support for Ruby 2.2 ended on 2018-03-31](https://www.ruby-lang.org/en/news/2018/06/20/support-of-ruby-2-2-has-ended/).

#### Enhancements

* `MiniPortile.execute` now takes an optional `:env` hash, which is merged into the environment variables for the subprocess. Likely this is only useful for specialized use cases. [#99]


### 2.5.0 / 2020-02-24

Expand Down
38 changes: 25 additions & 13 deletions lib/mini_portile2/mini_portile.rb
Expand Up @@ -380,29 +380,41 @@ def extract_file(file, target)
execute('extract', [tar_exe, "#{tar_compression_switch(filename)}xf", file, "-C", target], {:cd => Dir.pwd, :initial_message => false})
end

def execute(action, command, options={})
log_out = log_file(action)
# command could be an array of args, or one string containing a command passed to the shell. See
# Process.spawn for more information.
def execute(action, command, command_opts={})
opt_message = command_opts.fetch(:initial_message, true)
opt_debug = command_opts.fetch(:debug, false)
opt_cd = command_opts.fetch(:cd) { work_path }
opt_env = command_opts.fetch(:env) { Hash.new }

Dir.chdir (options.fetch(:cd){ work_path }) do
if options.fetch(:initial_message){ true }
message "Running '#{action}' for #{@name} #{@version}... "
end
log_out = log_file(action)

Dir.chdir(opt_cd) do
output "DEBUG: env is #{opt_env.inspect}" if opt_debug
output "DEBUG: command is #{command.inspect}" if opt_debug
message "Running '#{action}' for #{@name} #{@version}... " if opt_message

if Process.respond_to?(:spawn) && ! RbConfig.respond_to?(:java)
args = [command].flatten + [{[:out, :err]=>[log_out, "a"]}]
options = {[:out, :err]=>[log_out, "a"]}
output "DEBUG: options are #{options.inspect}" if opt_debug
args = [opt_env, command, options].flatten
pid = spawn(*args)
Process.wait(pid)
else
redirected = if command.kind_of?(Array)
%Q{#{command.map(&:shellescape).join(" ")} > #{log_out.shellescape} 2>&1}
else
%Q{#{command} > #{log_out.shellescape} 2>&1}
end
env_args = opt_env.map { |k,v| "#{k}=#{v}".shellescape }.join(" ")
c = if command.kind_of?(Array)
command.map(&:shellescape).join(" ")
else
command
end
redirected = %Q{env #{env_args} #{c} > #{log_out.shellescape} 2>&1}
output "DEBUG: final command is #{redirected.inspect}" if opt_debug
system redirected
end

if $?.success?
output "OK"
output "OK" if opt_message
return true
else
if File.exist? log_out
Expand Down
39 changes: 39 additions & 0 deletions test/test_execute.rb
@@ -0,0 +1,39 @@
require_relative "helper"

class TestExecute < TestCase
def setup
super
@env = {"TEST_ENV_VAR1" => "VAR1_VALUE", "TEST_ENV_VAR2" => "VAR2_VALUE"}
@recipe = MiniPortile.new("test_execute", "1.0.0")
@log_path = @recipe.send(:tmp_path)
FileUtils.mkdir_p File.join(@log_path, "subdir") # normally created by `download`
end

def test_execute_one_big_string_arg
class << @recipe
def execute_with_env(env)
execute("testenv1",
%Q(ruby -e "puts ENV['TEST_ENV_VAR1'].inspect ; exit 0"),
{:env => env, :initial_message => false, :debug => true})
end
end

@recipe.execute_with_env(@env)

assert_equal("VAR1_VALUE".inspect, IO.read(File.join(@log_path, "testenv1.log")).chomp)
end

def test_execute_array_args
class << @recipe
def execute_with_env(env)
execute("testenv2",
["ruby", "-e", "puts ENV['TEST_ENV_VAR2'].inspect"],
{:env => env, :initial_message => false, :debug => true})
end
end

@recipe.execute_with_env(@env)

assert_equal("VAR2_VALUE".inspect, IO.read(File.join(@log_path, "testenv2.log")).chomp)
end
end

0 comments on commit 1a0d778

Please sign in to comment.