Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package rubygem-mixlib-shellout for
openSUSE:Factory checked in at 2021-01-21 21:55:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-mixlib-shellout (Old)
and /work/SRC/openSUSE:Factory/.rubygem-mixlib-shellout.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-mixlib-shellout"
Thu Jan 21 21:55:55 2021 rev:23 rq:865207 version:3.2.2
Changes:
--------
---
/work/SRC/openSUSE:Factory/rubygem-mixlib-shellout/rubygem-mixlib-shellout.changes
2020-03-07 21:39:00.616303414 +0100
+++
/work/SRC/openSUSE:Factory/.rubygem-mixlib-shellout.new.28504/rubygem-mixlib-shellout.changes
2021-01-21 21:55:57.117818863 +0100
@@ -1,0 +2,12 @@
+Wed Jan 20 12:55:40 UTC 2021 - Stephan Kulow <[email protected]>
+
+updated to version 3.2.2
+ no changelog found
+
+-------------------------------------------------------------------
+Fri Sep 25 14:19:18 UTC 2020 - Stephan Kulow <[email protected]>
+
+updated to version 3.1.6
+ no changelog found
+
+-------------------------------------------------------------------
Old:
----
mixlib-shellout-3.0.9.gem
New:
----
mixlib-shellout-3.2.2.gem
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ rubygem-mixlib-shellout.spec ++++++
--- /var/tmp/diff_new_pack.YSZil1/_old 2021-01-21 21:55:57.805819342 +0100
+++ /var/tmp/diff_new_pack.YSZil1/_new 2021-01-21 21:55:57.809819345 +0100
@@ -1,7 +1,7 @@
#
# spec file for package rubygem-mixlib-shellout
#
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -24,12 +24,12 @@
#
Name: rubygem-mixlib-shellout
-Version: 3.0.9
+Version: 3.2.2
Release: 0
%define mod_name mixlib-shellout
%define mod_full_name %{mod_name}-%{version}
BuildRoot: %{_tmppath}/%{name}-%{version}-build
-BuildRequires: %{ruby >= 2.2}
+BuildRequires: %{ruby >= 2.4}
BuildRequires: %{rubygem gem2rpm}
BuildRequires: ruby-macros >= 5
URL: https://github.com/chef/mixlib-shellout
++++++ mixlib-shellout-3.0.9.gem -> mixlib-shellout-3.2.2.gem ++++++
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/mixlib/shellout/helper.rb
new/lib/mixlib/shellout/helper.rb
--- old/lib/mixlib/shellout/helper.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/lib/mixlib/shellout/helper.rb 2020-11-16 20:51:59.000000000 +0100
@@ -0,0 +1,197 @@
+#--
+# Author:: Daniel DeLeo (<[email protected]>)
+# Copyright:: Copyright (c) Chef Software Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require_relative "../shellout"
+require "chef-utils" unless defined?(ChefUtils)
+require "chef-utils/dsl/default_paths"
+require "chef-utils/internal"
+
+module Mixlib
+ class ShellOut
+ module Helper
+ include ChefUtils::Internal
+ include ChefUtils::DSL::DefaultPaths
+
+ #
+ # 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).
+ #
+
+ 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
+
+ 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
+
+ # 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
+ 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
+
+ # helper function to mangle options when `default_env` is true
+ #
+ # @api private
+ 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
+
+ # 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.
+ #
+ 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
+
+ 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
+
+ # 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
+ #
+ def __clean_array(*args)
+ args.flatten.compact.map(&:to_s)
+ end
+
+ 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
+
+ def __io_for_live_stream
+ if !STDOUT.closed? && __log.trace?
+ STDOUT
+ else
+ nil
+ end
+ end
+
+ def __env_path_name
+ if ChefUtils.windows?
+ "Path"
+ else
+ "PATH"
+ end
+ end
+
+ class FakeShellOut
+ attr_reader :stdout, :stderr, :exitstatus, :status
+
+ def initialize(args, options, result)
+ @args = args
+ @options = options
+ @stdout = result.stdout
+ @stderr = result.stderr
+ @exitstatus = result.exit_status
+ @status = OpenStruct.new(success?: ( exitstatus == 0 ))
+ end
+
+ def error?
+ exitstatus != 0
+ end
+
+ def error!
+ raise Mixlib::ShellOut::ShellCommandFailed, "Unexpected exit status
of #{exitstatus} running #{@args}" if error?
+ end
+ end
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/mixlib/shellout/unix.rb
new/lib/mixlib/shellout/unix.rb
--- old/lib/mixlib/shellout/unix.rb 2019-12-30 03:41:46.000000000 +0100
+++ new/lib/mixlib/shellout/unix.rb 2020-11-16 20:51:59.000000000 +0100
@@ -1,6 +1,6 @@
#
# Author:: Daniel DeLeo (<[email protected]>)
-# Copyright:: Copyright (c) 2010-2016 Chef Software, Inc.
+# Copyright:: Copyright (c) Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -370,11 +370,11 @@
return if attempt_reap
@terminate_reason = "Command exceeded allowed execution time, process
terminated"
- logger.error("Command exceeded allowed execution time, sending TERM")
if logger
+ logger&.error("Command exceeded allowed execution time, sending TERM")
Process.kill(:TERM, child_pgid)
sleep 3
attempt_reap
- logger.error("Command exceeded allowed execution time, sending KILL")
if logger
+ logger&.error("Command exceeded allowed execution time, sending KILL")
Process.kill(:KILL, child_pgid)
reap
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/mixlib/shellout/version.rb
new/lib/mixlib/shellout/version.rb
--- old/lib/mixlib/shellout/version.rb 2019-12-30 03:41:46.000000000 +0100
+++ new/lib/mixlib/shellout/version.rb 2020-11-16 20:51:59.000000000 +0100
@@ -1,5 +1,5 @@
module Mixlib
class ShellOut
- VERSION = "3.0.9".freeze
+ VERSION = "3.2.2".freeze
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/mixlib/shellout/windows/core_ext.rb
new/lib/mixlib/shellout/windows/core_ext.rb
--- old/lib/mixlib/shellout/windows/core_ext.rb 2019-12-30 03:41:46.000000000
+0100
+++ new/lib/mixlib/shellout/windows/core_ext.rb 2020-11-16 20:51:59.000000000
+0100
@@ -1,7 +1,7 @@
-#--
+#
# Author:: Daniel DeLeo (<[email protected]>)
# Author:: John Keiser (<[email protected]>)
-# Copyright:: Copyright (c) 2011-2016 Chef Software, Inc.
+# Copyright:: Copyright (c) Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,10 +18,10 @@
#
require "win32/process"
+require "ffi/win32/extensions"
# Add new constants for Logon
module Process::Constants
- private
LOGON32_LOGON_INTERACTIVE = 0x00000002
LOGON32_LOGON_BATCH = 0x00000004
@@ -45,6 +45,8 @@
WIN32_PROFILETYPE_PT_MANDATORY = 0x04
WIN32_PROFILETYPE_PT_ROAMING_PREEXISTING = 0x08
+ # The environment block list ends with two nulls (\0\0).
+ ENVIRONMENT_BLOCK_ENDS = "\0\0".freeze
end
# Structs required for data handling
@@ -78,6 +80,12 @@
attach_pfunc :UnloadUserProfile,
%i{handle handle}, :bool
+ attach_pfunc :CreateEnvironmentBlock,
+ %i{pointer ulong bool}, :bool
+
+ attach_pfunc :DestroyEnvironmentBlock,
+ %i{pointer}, :bool
+
ffi_lib :advapi32
attach_pfunc :LogonUserW,
@@ -148,15 +156,13 @@
si_hash = {}
# If the startup_info key is present, validate its subkeys
- if hash["startup_info"]
- hash["startup_info"].each do |key, val|
- key = key.to_s.downcase
- unless valid_si_keys.include?(key)
- raise ArgumentError, "invalid startup_info key '#{key}'"
- end
-
- si_hash[key] = val
+ hash["startup_info"]&.each do |key, val|
+ key = key.to_s.downcase
+ unless valid_si_keys.include?(key)
+ raise ArgumentError, "invalid startup_info key '#{key}'"
end
+
+ si_hash[key] = val
end
# The +command_line+ key is mandatory unless the +app_name+ key
@@ -172,9 +178,25 @@
env = nil
+ # Retrieve the environment variables for the specified user.
+ if hash["with_logon"]
+ logon, passwd, domain = format_creds_from_hash(hash)
+ logon_type = hash["elevated"] ? LOGON32_LOGON_BATCH :
LOGON32_LOGON_INTERACTIVE
+ token = logon_user(logon, domain, passwd, logon_type)
+ logon_ptr = FFI::MemoryPointer.from_string(logon)
+ profile = PROFILEINFO.new.tap do |dat|
+ dat[:dwSize] = dat.size
+ dat[:dwFlags] = 1
+ dat[:lpUserName] = logon_ptr
+ end
+
+ load_user_profile(token, profile.pointer)
+ env_list = retrieve_environment_variables(token)
+ end
+
# The env string should be passed as a string of ';' separated paths.
if hash["environment"]
- env = hash["environment"]
+ env = env_list.nil? ? hash["environment"] :
merge_env_variables(env_list, hash["environment"])
unless env.respond_to?(:join)
env = hash["environment"].split(File::PATH_SEPARATOR)
@@ -396,6 +418,33 @@
true
end
+ # Retrieves the environment variables for the specified user.
+ #
+ # @param env_pointer [Pointer] The environment block is an array of
null-terminated Unicode strings.
+ # @param token [Integer] User token handle.
+ # @return [Boolean] true if successfully retrieves the environment
variables for the specified user.
+ #
+ def create_environment_block(env_pointer, token)
+ unless CreateEnvironmentBlock(env_pointer, token, false)
+ raise SystemCallError.new("CreateEnvironmentBlock", FFI.errno)
+ end
+
+ true
+ end
+
+ # Frees environment variables created by the CreateEnvironmentBlock
function.
+ #
+ # @param env_pointer [Pointer] The environment block is an array of
null-terminated Unicode strings.
+ # @return [Boolean] true if successfully frees environment variables
created by the CreateEnvironmentBlock function.
+ #
+ def destroy_environment_block(env_pointer)
+ unless DestroyEnvironmentBlock(env_pointer)
+ raise SystemCallError.new("DestroyEnvironmentBlock", FFI.errno)
+ end
+
+ true
+ end
+
def create_process_as_user(token, app, cmd, process_security,
thread_security, inherit, creation_flags, env, cwd, startinfo, procinfo)
@@ -530,5 +579,51 @@
[ logon, passwd, domain ]
end
+ # Retrieves the environment variables for the specified user.
+ #
+ # @param token [Integer] User token handle.
+ # @return env_list [Array<String>] Environment variables of specified user.
+ #
+ def retrieve_environment_variables(token)
+ env_list = []
+ env_pointer = FFI::MemoryPointer.new(:pointer)
+ create_environment_block(env_pointer, token)
+ str_ptr = env_pointer.read_pointer
+ offset = 0
+ loop do
+ new_str_pointer = str_ptr + offset
+ break if new_str_pointer.read_string(2) == ENVIRONMENT_BLOCK_ENDS
+
+ environment = new_str_pointer.read_wstring
+ env_list << environment
+ offset = offset + environment.length * 2 + 2
+ end
+
+ # To free the buffer when we have finished with the environment block
+ destroy_environment_block(str_ptr)
+ env_list
+ end
+
+ # Merge environment variables of specified user and current environment
variables.
+ #
+ # @param fetched_env [Array<String>] environment variables of specified
user.
+ # @param current_env [Array<String>] current environment variables.
+ # @return [Array<String>] Merged environment variables.
+ #
+ def merge_env_variables(fetched_env, current_env)
+ env_hash_1 = environment_list_to_hash(fetched_env)
+ env_hash_2 = environment_list_to_hash(current_env)
+ merged_env = env_hash_2.merge(env_hash_1)
+ merged_env.map { |k, v| "#{k}=#{v}" }
+ end
+
+ # Convert an array to a hash.
+ #
+ # @param env_var [Array<String>] Environment variables.
+ # @return [Hash] Converted an array to hash.
+ #
+ def environment_list_to_hash(env_var)
+ Hash[ env_var.map { |pair| pair.split("=", 2) } ]
+ end
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/mixlib/shellout/windows.rb
new/lib/mixlib/shellout/windows.rb
--- old/lib/mixlib/shellout/windows.rb 2019-12-30 03:41:46.000000000 +0100
+++ new/lib/mixlib/shellout/windows.rb 2020-11-16 20:51:59.000000000 +0100
@@ -2,7 +2,7 @@
# Author:: Daniel DeLeo (<[email protected]>)
# Author:: John Keiser (<[email protected]>)
# Author:: Ho-Sheng Hsiao (<[email protected]>)
-# Copyright:: Copyright (c) 2011-2019, Chef Software Inc.
+# Copyright:: Copyright (c) Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -89,7 +89,7 @@
# Start the process
#
process, profile, token = Process.create3(create_process_args)
- logger.debug(format_process(process, app_name, command_line,
timeout)) if logger
+ logger&.debug(format_process(process, app_name, command_line,
timeout))
begin
# Start pushing data into input
stdin_write << input if input
@@ -124,7 +124,7 @@
kill_process_tree(process.process_id, wmi, logger)
Process.kill(:KILL, process.process_id)
rescue SystemCallError
- logger.warn("Failed to kill timed out process
#{process.process_id}") if logger
+ logger&.warn("Failed to kill timed out process
#{process.process_id}")
end
raise Mixlib::ShellOut::CommandTimeout, [
@@ -208,7 +208,7 @@
# 4. if the argument must be quoted by #1 and terminates in a sequence
of backslashes then all the backlashes must themselves
# be backslash excaped (double the backslashes).
# 5. if an interior quote that must be escaped by #2 has a sequence of
backslashes before it then all the backslashes must
- # themselves be backslash excaped along with the backslash ecape of
the interior quote (double plus one backslashes).
+ # themselves be backslash excaped along with the backslash escape of
the interior quote (double plus one backslashes).
#
# And to restate. We are constructing a string which will be parsed by
the windows parser into arguments, and we want those
# arguments to match the *args array we are passed here. So call the
windows parser operation A then we need to apply A^-1 to
@@ -398,20 +398,16 @@
def kill_process(instance, logger)
child_pid = instance.wmi_ole_object.processid
- if logger
- logger.debug([
+ logger&.debug([
"killing child process #{child_pid}::",
"#{instance.wmi_ole_object.Name} of parent #{pid}",
].join)
- end
Process.kill(:KILL, instance.wmi_ole_object.processid)
rescue SystemCallError
- if logger
- logger.debug([
+ logger&.debug([
"Failed to kill child process #{child_pid}::",
"#{instance.wmi_ole_object.Name} of parent #{pid}",
].join)
- end
end
def format_process(process, app_name, command_line, timeout)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/mixlib/shellout.rb new/lib/mixlib/shellout.rb
--- old/lib/mixlib/shellout.rb 2019-12-30 03:41:46.000000000 +0100
+++ new/lib/mixlib/shellout.rb 2020-11-16 20:51:59.000000000 +0100
@@ -1,6 +1,6 @@
#--
# Author:: Daniel DeLeo (<[email protected]>)
-# Copyright:: Copyright (c) 2010-2016 Chef Software, Inc.
+# Copyright:: Copyright (c) Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,8 +16,8 @@
# limitations under the License.
#
-require "etc"
-require "tmpdir"
+require "etc" unless defined?(Etc)
+require "tmpdir" unless defined?(Dir.mktmpdir)
require "fcntl"
require_relative "shellout/exceptions"
@@ -65,7 +65,7 @@
# as the subprocess is running.
attr_accessor :live_stderr
- # ShellOut will push data from :input down the stdin of the subprocss.
+ # ShellOut will push data from :input down the stdin of the subprocess.
# Normally set via options passed to new.
# Default: nil
attr_accessor :input
@@ -122,7 +122,7 @@
# === Options:
# If the last argument is a Hash, it is removed from the list of args
passed
# to exec and used as an options hash. The following options are available:
- # * +user+: the user the commmand should run as. if an integer is given,
it is
+ # * +user+: the user the command should run as. if an integer is given, it
is
# used as a uid. A string is treated as a username and resolved to a uid
# with Etc.getpwnam
# * +group+: the group the command should run as. works similarly to +user+
@@ -248,7 +248,7 @@
# running or died without setting an exit status (e.g., terminated by
# `kill -9`).
def exitstatus
- @status && @status.exitstatus
+ @status&.exitstatus
end
# Run the command, writing the command's standard out and standard error
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata 2019-12-30 03:41:46.000000000 +0100
+++ new/metadata 2020-11-16 20:51:59.000000000 +0100
@@ -1,15 +1,29 @@
--- !ruby/object:Gem::Specification
name: mixlib-shellout
version: !ruby/object:Gem::Version
- version: 3.0.9
+ version: 3.2.2
platform: ruby
authors:
- Chef Software Inc.
autorequire:
bindir: bin
cert_chain: []
-date: 2019-12-30 00:00:00.000000000 Z
-dependencies: []
+date: 2020-11-16 00:00:00.000000000 Z
+dependencies:
+- !ruby/object:Gem::Dependency
+ name: chef-utils
+ requirement: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: '0'
+ type: :runtime
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: '0'
description: Run external commands on Unix or Windows
email: [email protected]
executables: []
@@ -19,6 +33,7 @@
- LICENSE
- lib/mixlib/shellout.rb
- lib/mixlib/shellout/exceptions.rb
+- lib/mixlib/shellout/helper.rb
- lib/mixlib/shellout/unix.rb
- lib/mixlib/shellout/version.rb
- lib/mixlib/shellout/windows.rb
@@ -34,7 +49,7 @@
requirements:
- - ">="
- !ruby/object:Gem::Version
- version: '2.2'
+ version: '2.4'
required_rubygems_version: !ruby/object:Gem::Requirement
requirements:
- - ">="