module Mixlib::ShellOut::Helper
Public Instance Methods
These APIs are considered public for use in ohai and chef (by cookbooks and plugins, etc) but are considered private/experimental for now for the direct users of mixlib-shellout.
You can see an example of how to handle the “dependency injection” in the rspec unit test. That backend API is left deliberately undocumented for now and may not follow SemVer and may break at any time (at least for the rest of 2020).
# File lib/mixlib/shellout/helper.rb, line 38 def shell_out(*args, **options) options = options.dup options = __maybe_add_timeout(self, options) if options.empty? shell_out_compacted(*__clean_array(*args)) else shell_out_compacted(*__clean_array(*args), **options) end end
# File lib/mixlib/shellout/helper.rb, line 48 def shell_out!(*args, **options) options = options.dup options = __maybe_add_timeout(self, options) if options.empty? shell_out_compacted!(*__clean_array(*args)) else shell_out_compacted!(*__clean_array(*args), **options) end end
Private Instance Methods
helper function to mangle options when ‘default_env` is true
@api private
# File lib/mixlib/shellout/helper.rb, line 81 def __apply_default_env(options) options = options.dup default_env = options.delete(:default_env) default_env = true if default_env.nil? if default_env env_key = options.key?(:env) ? :env : :environment options[env_key] = { "LC_ALL" => __config[:internal_locale], "LANGUAGE" => __config[:internal_locale], "LANG" => __config[:internal_locale], __env_path_name => default_paths, }.update(options[env_key] || {}) end options end
Helper
for subclasses to reject nil out of an array. It allows using the array form of shell_out
(which avoids the need to surround arguments with quote marks to deal with shells).
@param args [String] variable number of string arguments @return [Array] array of strings with nil and null string rejection
# File lib/mixlib/shellout/helper.rb, line 140 def __clean_array(*args) args.flatten.compact.map(&:to_s) end
# File lib/mixlib/shellout/helper.rb, line 167 def __env_path_name if ChefUtils.windows? "Path" else "PATH" end end
# File lib/mixlib/shellout/helper.rb, line 159 def __io_for_live_stream if !STDOUT.closed? && __log.trace? STDOUT else nil end end
helper sugar for resources that support passing timeouts to shell_out
module method to not pollute namespaces, but that means we need self injected as an arg @api private
# File lib/mixlib/shellout/helper.rb, line 64 def __maybe_add_timeout(obj, options) options = options.dup # historically resources have not properly declared defaults on their timeouts, so a default default of 900s was enforced here default_val = 900 return options if options.key?(:timeout) # FIXME: need to nuke descendent tracker out of Chef::Provider so we can just define that class here without requiring the # world, and then just use symbol lookup if obj.class.ancestors.map(&:name).include?("Chef::Provider") && obj.respond_to?(:new_resource) && obj.new_resource.respond_to?(:timeout) && !options.key?(:timeout) options[:timeout] = obj.new_resource.timeout ? obj.new_resource.timeout.to_f : default_val end options end
# File lib/mixlib/shellout/helper.rb, line 144 def __shell_out_command(*args, **options) if __transport_connection FakeShellOut.new(args, options, __transport_connection.run_command(args.join(" "))) # FIXME: train should accept run_command(*args) else cmd = if options.empty? Mixlib::ShellOut.new(*args) else Mixlib::ShellOut.new(*args, **options) end cmd.live_stream ||= __io_for_live_stream cmd.run_command cmd end end
The shell_out_compacted/shell_out_compacted! APIs are private but are intended for use in rspec tests. They should always be used in rspec tests instead of shell_out
to allow for less brittle rspec tests.
This expectation:
allow(provider).to receive(:shell_out_compacted!).with(“foo”, “bar”, “baz”)
Is met by many different possible calling conventions that mean the same thing:
provider.shell_out!(“foo”, [ “bar”, nil, “baz”]) provider.shell_out!([“foo”, nil, “bar” ], [“baz”])
Note that when setting ‘default_env: false` that you should just setup an expectation on :shell_out_compacted for `default_env: false`, rather than the expanded env settings so that the default_env implementation can change without breaking unit tests.
# File lib/mixlib/shellout/helper.rb, line 114 def shell_out_compacted(*args, **options) options = __apply_default_env(options) if options.empty? __shell_out_command(*args) else __shell_out_command(*args, **options) end end
# File lib/mixlib/shellout/helper.rb, line 123 def shell_out_compacted!(*args, **options) options = __apply_default_env(options) cmd = if options.empty? __shell_out_command(*args) else __shell_out_command(*args, **options) end cmd.error! cmd end