summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom May <thom@may.lt>2016-10-07 12:38:51 +0100
committerGitHub <noreply@github.com>2016-10-07 12:38:51 +0100
commit7f33f2b2f47f95beb485123f01469dbe2034d35b (patch)
treeac16d9c20bb63ff10217505961b9b6c5cea6de16
parentc452a2159d92009fd1d17b82b682be54d5dd745c (diff)
parent5b42bca5f16ded4df1b7f736e08284ae90ce30ac (diff)
downloadmixlib-shellout-7f33f2b2f47f95beb485123f01469dbe2034d35b.tar.gz
Merge pull request #130 from chef/ruby22
Require Ruby 2.2 and use chefstyle
-rw-r--r--.rubocop.yml8
-rw-r--r--.travis.yml11
-rw-r--r--Gemfile12
-rw-r--r--README.md6
-rw-r--r--Rakefile15
-rw-r--r--appveyor.yml4
-rw-r--r--lib/mixlib/shellout.rb56
-rw-r--r--lib/mixlib/shellout/unix.rb14
-rw-r--r--lib/mixlib/shellout/windows.rb60
-rw-r--r--lib/mixlib/shellout/windows/core_ext.rb128
-rw-r--r--mixlib-shellout-windows.gemspec2
-rw-r--r--mixlib-shellout.gemspec15
-rw-r--r--spec/mixlib/shellout/windows_spec.rb144
-rw-r--r--spec/mixlib/shellout_spec.rb606
-rw-r--r--spec/spec_helper.rb11
15 files changed, 554 insertions, 538 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
new file mode 100644
index 0000000..4343509
--- /dev/null
+++ b/.rubocop.yml
@@ -0,0 +1,8 @@
+Lint/UnderscorePrefixedVariableName:
+ Exclude:
+ - 'spec/mixlib/shellout/windows_spec.rb'
+
+# Configuration parameters: ContextCreatingMethods.
+Lint/UselessAccessModifier:
+ Exclude:
+ - 'lib/mixlib/shellout/windows/core_ext.rb'
diff --git a/.travis.yml b/.travis.yml
index ea98a8b..c5340d5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,18 +1,13 @@
language: ruby
cache: bundler
-
sudo: false
-
rvm:
- - 2.1.9
- 2.2.5
- 2.3.1
-
-before_install:
- - gem update bundler
-
branches:
only:
- master
+before_install:
+ - gem update bundler
-script: bundle exec rspec --color --format progress
+script: bundle exec rake
diff --git a/Gemfile b/Gemfile
index 1f468d9..420bfae 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,15 +1,15 @@
-source 'https://rubygems.org'
+source "https://rubygems.org"
gemspec :name => "mixlib-shellout"
group(:test) do
gem "rspec_junit_formatter"
- gem 'rake'
+ gem "rake"
end
group(:development) do
- gem 'pry'
- gem 'pry-byebug'
- gem 'pry-stack_explorer'
- gem 'rb-readline'
+ gem "pry"
+ gem "pry-byebug"
+ gem "pry-stack_explorer"
+ gem "rb-readline"
end
diff --git a/README.md b/README.md
index 85146d8..909dd5e 100644
--- a/README.md
+++ b/README.md
@@ -65,9 +65,13 @@ Invoke "whoami.exe" to demonstrate running a command as another user:
Mixlib::ShellOut does a standard fork/exec on Unix, and uses the Win32 API on Windows. There is not currently support for JRuby.
## See Also
-- `Process.spawn` in Ruby 1.9
+- `Process.spawn` in Ruby 1.9+
- [https://github.com/rtomayko/posix-spawn](https://github.com/rtomayko/posix-spawn)
+## Contributing
+
+For information on contributing to this project see <https://github.com/chef/chef/blob/master/CONTRIBUTING.md>
+
## License
- Copyright:: Copyright (c) 2011-2016 Chef Software, Inc.
- License:: Apache License, Version 2.0
diff --git a/Rakefile b/Rakefile
index e4c694e..03c1c26 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,11 +1,16 @@
-require 'bundler'
-require 'rspec/core/rake_task'
+require "bundler"
+require "rspec/core/rake_task"
-Bundler::GemHelper.install_tasks
+Bundler::GemHelper.install_tasks name: "mixlib-shellout"
+
+require "chefstyle"
+require "rubocop/rake_task"
+desc "Run Ruby style checks"
+RuboCop::RakeTask.new(:style)
desc "Run all specs in spec directory"
RSpec::Core::RakeTask.new(:spec) do |t|
- t.pattern = FileList['spec/**/*_spec.rb']
+ t.pattern = FileList["spec/**/*_spec.rb"]
end
-task default: :spec
+task default: [:style, :spec]
diff --git a/appveyor.yml b/appveyor.yml
index 0ea6535..e49c59e 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -6,7 +6,9 @@ platform:
environment:
matrix:
- - ruby_version: "21"
+ - ruby_version: "22"
+ - ruby_version: "23"
+ - ruby_version: "23-x64"
clone_folder: c:\projects\mixlib-shellout
clone_depth: 1
diff --git a/lib/mixlib/shellout.rb b/lib/mixlib/shellout.rb
index 2fdbcfd..d15b645 100644
--- a/lib/mixlib/shellout.rb
+++ b/lib/mixlib/shellout.rb
@@ -16,10 +16,10 @@
# limitations under the License.
#
-require 'etc'
-require 'tmpdir'
-require 'fcntl'
-require 'mixlib/shellout/exceptions'
+require "etc"
+require "tmpdir"
+require "fcntl"
+require "mixlib/shellout/exceptions"
module Mixlib
@@ -29,10 +29,10 @@ module Mixlib
DEFAULT_READ_TIMEOUT = 600
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
- require 'mixlib/shellout/windows'
+ require "mixlib/shellout/windows"
include ShellOut::Windows
else
- require 'mixlib/shellout/unix'
+ require "mixlib/shellout/unix"
include ShellOut::Unix
end
@@ -162,7 +162,7 @@ module Mixlib
# cmd = Mixlib::ShellOut.new("apachectl", "start", :user => 'www', :env => nil, :cwd => '/tmp')
# cmd.run_command # etc.
def initialize(*command_args)
- @stdout, @stderr, @process_status = '', '', ''
+ @stdout, @stderr, @process_status = "", "", ""
@live_stdout = @live_stderr = nil
@input = nil
@log_level = :debug
@@ -284,15 +284,15 @@ module Mixlib
# is highly encouraged.
# === Raises
# ShellCommandFailed always
- def invalid!(msg=nil)
+ def invalid!(msg = nil)
msg ||= "Command produced unexpected results"
raise ShellCommandFailed, msg + "\n" + format_for_exception
end
def inspect
"<#{self.class.name}##{object_id}: command: '#@command' process_status: #{@status.inspect} " +
- "stdout: '#{stdout.strip}' stderr: '#{stderr.strip}' child_pid: #{@child_pid.inspect} " +
- "environment: #{@environment.inspect} timeout: #{timeout} user: #@user group: #@group working_dir: #@cwd >"
+ "stdout: '#{stdout.strip}' stderr: '#{stderr.strip}' child_pid: #{@child_pid.inspect} " +
+ "environment: #{@environment.inspect} timeout: #{timeout} user: #@user group: #@group working_dir: #@cwd >"
end
private
@@ -300,44 +300,44 @@ module Mixlib
def parse_options(opts)
opts.each do |option, setting|
case option.to_s
- when 'cwd'
+ when "cwd"
self.cwd = setting
- when 'domain'
+ when "domain"
self.domain = setting
- when 'password'
+ when "password"
self.password = setting
- when 'user'
+ when "user"
self.user = setting
self.with_logon = setting
- when 'group'
+ when "group"
self.group = setting
- when 'umask'
+ when "umask"
self.umask = setting
- when 'timeout'
+ when "timeout"
self.timeout = setting
- when 'returns'
+ when "returns"
self.valid_exit_codes = Array(setting)
- when 'live_stream'
+ when "live_stream"
self.live_stdout = self.live_stderr = setting
- when 'live_stdout'
+ when "live_stdout"
self.live_stdout = setting
- when 'live_stderr'
+ when "live_stderr"
self.live_stderr = setting
- when 'input'
+ when "input"
self.input = setting
- when 'logger'
+ when "logger"
self.logger = setting
- when 'log_level'
+ when "log_level"
self.log_level = setting
- when 'log_tag'
+ when "log_tag"
self.log_tag = setting
- when 'environment', 'env'
+ when "environment", "env"
if setting
- self.environment = Hash[setting.map{|(k,v)| [k.to_s,v]}]
+ self.environment = Hash[setting.map { |(k, v)| [k.to_s, v] }]
else
self.environment = {}
end
- when 'login'
+ when "login"
self.login = setting
else
raise InvalidCommandOption, "option '#{option.inspect}' is not a valid option for #{self.class.name}"
diff --git a/lib/mixlib/shellout/unix.rb b/lib/mixlib/shellout/unix.rb
index 734a597..238273c 100644
--- a/lib/mixlib/shellout/unix.rb
+++ b/lib/mixlib/shellout/unix.rb
@@ -39,7 +39,7 @@ module Mixlib
def all_seconderies
ret = []
Etc.endgrent
- while ( g = Etc.getgrent ) do
+ while ( g = Etc.getgrent )
ret << g
end
Etc.endgrent
@@ -52,7 +52,7 @@ module Mixlib
def sgids
return nil unless using_login?
user_name = Etc.getpwuid(uid).name
- all_seconderies.select{|g| g.mem.include?(user_name)}.map{|g|g.gid}
+ all_seconderies.select { |g| g.mem.include?(user_name) }.map { |g| g.gid }
end
# The environment variables that are deduced from simulating logon
@@ -63,7 +63,7 @@ module Mixlib
# According to `man su`, the set fields are:
# $HOME, $SHELL, $USER, $LOGNAME, $PATH, and $IFS
# Values are copied from "shadow" package in Ubuntu 14.10
- {'HOME'=>entry.dir, 'SHELL'=>entry.shell, 'USER'=>entry.name, 'LOGNAME'=>entry.name, 'PATH'=>'/sbin:/bin:/usr/sbin:/usr/bin', 'IFS'=>"\t\n"}
+ { "HOME" => entry.dir, "SHELL" => entry.shell, "USER" => entry.name, "LOGNAME" => entry.name, "PATH" => "/sbin:/bin:/usr/sbin:/usr/bin", "IFS" => "\t\n" }
end
# Merges the two environments for the process
@@ -170,7 +170,7 @@ module Mixlib
def set_environment
# user-set variables should override the login ones
- process_environment.each do |env_var,value|
+ process_environment.each do |env_var, value|
ENV[env_var] = value
end
end
@@ -335,14 +335,14 @@ module Mixlib
set_cwd
begin
- command.kind_of?(Array) ? exec(*command, :close_others=>true) : exec(command, :close_others=>true)
+ command.kind_of?(Array) ? exec(*command, :close_others => true) : exec(command, :close_others => true)
- raise 'forty-two' # Should never get here
+ raise "forty-two" # Should never get here
rescue Exception => e
Marshal.dump(e, process_status_pipe.last)
process_status_pipe.last.flush
end
- process_status_pipe.last.close unless (process_status_pipe.last.closed?)
+ process_status_pipe.last.close unless process_status_pipe.last.closed?
exit!
end
end
diff --git a/lib/mixlib/shellout/windows.rb b/lib/mixlib/shellout/windows.rb
index 5b13dad..0c66c2e 100644
--- a/lib/mixlib/shellout/windows.rb
+++ b/lib/mixlib/shellout/windows.rb
@@ -18,8 +18,8 @@
# limitations under the License.
#
-require 'win32/process'
-require 'mixlib/shellout/windows/core_ext'
+require "win32/process"
+require "mixlib/shellout/windows/core_ext"
module Mixlib
class ShellOut
@@ -63,10 +63,10 @@ module Mixlib
:startup_info => {
:stdout => stdout_write,
:stderr => stderr_write,
- :stdin => stdin_read
+ :stdin => stdin_read,
},
- :environment => inherit_environment.map { |k,v| "#{k}=#{v}" },
- :close_handles => false
+ :environment => inherit_environment.map { |k, v| "#{k}=#{v}" },
+ :close_handles => false,
}
create_process_args[:cwd] = cwd if cwd
# default to local account database if domain is not specified
@@ -90,24 +90,24 @@ module Mixlib
# Wait for the process to finish, consuming output as we go
#
start_wait = Time.now
- while true
+ loop do
wait_status = WaitForSingleObject(process.process_handle, 0)
case wait_status
when WAIT_OBJECT_0
# Get process exit code
- exit_code = [0].pack('l')
+ exit_code = [0].pack("l")
unless GetExitCodeProcess(process.process_handle, exit_code)
raise get_last_error
end
@status = ThingThatLooksSortOfLikeAProcessStatus.new
- @status.exitstatus = exit_code.unpack('l').first
+ @status.exitstatus = exit_code.unpack("l").first
return self
when WAIT_TIMEOUT
# Kill the process
if (Time.now - start_wait) > timeout
begin
- require 'wmi-lite/wmi'
+ require "wmi-lite/wmi"
wmi = WmiLite::Wmi.new
Utils.kill_process_tree(process.process_id, wmi, logger)
Process.kill(:KILL, process.process_id)
@@ -118,13 +118,13 @@ module Mixlib
raise Mixlib::ShellOut::CommandTimeout, [
"command timed out:",
format_for_exception,
- Utils.format_process(process, app_name, command_line, timeout)
+ Utils.format_process(process, app_name, command_line, timeout),
].join("\n")
end
consume_output(open_streams, stdout_read, stderr_read)
else
- raise "Unknown response from WaitForSingleObject(#{process.process_handle}, #{timeout*1000}): #{wait_status}"
+ raise "Unknown response from WaitForSingleObject(#{process.process_handle}, #{timeout * 1000}): #{wait_status}"
end
end
@@ -212,7 +212,7 @@ module Mixlib
# https://github.com/opscode/mixlib-shellout/pull/2#issuecomment-4837859
# http://ss64.com/nt/syntax-esc.html
def _run_under_cmd(command)
- [ ENV['COMSPEC'], "cmd /c \"#{command}\"" ]
+ [ ENV["COMSPEC"], "cmd /c \"#{command}\"" ]
end
def _run_directly(command, exe)
@@ -220,7 +220,7 @@ module Mixlib
end
def unquoted_executable_path(command)
- command[0,command.index(/\s/) || command.length]
+ command[0, command.index(/\s/) || command.length]
end
def candidate_executable_for_command(command)
@@ -235,11 +235,11 @@ module Mixlib
def inherit_environment
result = {}
- ENV.each_pair do |k,v|
+ ENV.each_pair do |k, v|
result[k] = v
end
- environment.each_pair do |k,v|
+ environment.each_pair do |k, v|
if v == nil
result.delete(k)
else
@@ -266,15 +266,15 @@ module Mixlib
command.dup.each_char do |c|
case c
when "'", '"'
- if (!quote)
+ if !quote
quote = c
elsif quote == c
quote = nil
end
next
- when '>', '<', '|', '&', "\n"
+ when ">", "<", "|", "&", "\n"
return true unless quote
- when '%'
+ when "%"
return true if env
env = env_first_char = true
next
@@ -282,7 +282,7 @@ module Mixlib
next unless env
if env_first_char
env_first_char = false
- env = false and next if c !~ /[A-Za-z_]/
+ (env = false) && next if c !~ /[A-Za-z_]/
end
env = false if c !~ /[A-Za-z1-9_]/
end
@@ -291,13 +291,13 @@ module Mixlib
end
def self.pathext
- @pathext ||= ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') + [''] : ['']
+ @pathext ||= ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") + [""] : [""]
end
# which() mimicks the Unix which command
# FIXME: it is not working
def self.which(cmd)
- ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
+ ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
exe = find_executable("#{path}/#{cmd}")
return exe if exe
end
@@ -323,13 +323,13 @@ module Mixlib
def self.system_required_processes
[
- 'System Idle Process',
- 'System',
- 'spoolsv.exe',
- 'lsass.exe',
- 'csrss.exe',
- 'smss.exe',
- 'svchost.exe'
+ "System Idle Process",
+ "System",
+ "spoolsv.exe",
+ "lsass.exe",
+ "csrss.exe",
+ "smss.exe",
+ "svchost.exe",
]
end
@@ -358,13 +358,13 @@ module Mixlib
child_pid = instance.wmi_ole_object.processid
logger.debug([
"killing child process #{child_pid}::",
- "#{instance.wmi_ole_object.Name} of parent #{pid}"
+ "#{instance.wmi_ole_object.Name} of parent #{pid}",
].join) if logger
Process.kill(:KILL, instance.wmi_ole_object.processid)
rescue Errno::EIO, SystemCallError
logger.debug([
"Failed to kill child process #{child_pid}::",
- "#{instance.wmi_ole_object.Name} of parent #{pid}"
+ "#{instance.wmi_ole_object.Name} of parent #{pid}",
].join) if logger
end
diff --git a/lib/mixlib/shellout/windows/core_ext.rb b/lib/mixlib/shellout/windows/core_ext.rb
index 2fe2bf2..17faff2 100644
--- a/lib/mixlib/shellout/windows/core_ext.rb
+++ b/lib/mixlib/shellout/windows/core_ext.rb
@@ -17,7 +17,7 @@
# limitations under the License.
#
-require 'win32/process'
+require "win32/process"
# Add new constants for Logon
module Process::Constants
@@ -65,78 +65,78 @@ module Process
class << self
def create(args)
unless args.kind_of?(Hash)
- raise TypeError, 'hash keyword arguments expected'
+ raise TypeError, "hash keyword arguments expected"
end
- valid_keys = %w[
+ valid_keys = %w{
app_name command_line inherit creation_flags cwd environment
startup_info thread_inherit process_inherit close_handles with_logon
domain password
- ]
+ }
- valid_si_keys = %w[
+ valid_si_keys = %w{
startf_flags desktop title x y x_size y_size x_count_chars
y_count_chars fill_attribute sw_flags stdin stdout stderr
- ]
+ }
# Set default values
hash = {
- 'app_name' => nil,
- 'creation_flags' => 0,
- 'close_handles' => true
+ "app_name" => nil,
+ "creation_flags" => 0,
+ "close_handles" => true,
}
# Validate the keys, and convert symbols and case to lowercase strings.
- args.each{ |key, val|
+ args.each do |key, val|
key = key.to_s.downcase
unless valid_keys.include?(key)
raise ArgumentError, "invalid key '#{key}'"
end
hash[key] = val
- }
+ end
si_hash = {}
# If the startup_info key is present, validate its subkeys
- if hash['startup_info']
- hash['startup_info'].each{ |key, val|
+ 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
- }
+ end
end
# The +command_line+ key is mandatory unless the +app_name+ key
# is specified.
- unless hash['command_line']
- if hash['app_name']
- hash['command_line'] = hash['app_name']
- hash['app_name'] = nil
+ unless hash["command_line"]
+ if hash["app_name"]
+ hash["command_line"] = hash["app_name"]
+ hash["app_name"] = nil
else
- raise ArgumentError, 'command_line or app_name must be specified'
+ raise ArgumentError, "command_line or app_name must be specified"
end
end
env = nil
# The env string should be passed as a string of ';' separated paths.
- if hash['environment']
- env = hash['environment']
+ if hash["environment"]
+ env = hash["environment"]
unless env.respond_to?(:join)
- env = hash['environment'].split(File::PATH_SEPARATOR)
+ env = hash["environment"].split(File::PATH_SEPARATOR)
end
- env = env.map{ |e| e + 0.chr }.join('') + 0.chr
- env.to_wide_string! if hash['with_logon']
+ env = env.map { |e| e + 0.chr }.join("") + 0.chr
+ env.to_wide_string! if hash["with_logon"]
end
# Process SECURITY_ATTRIBUTE structure
process_security = nil
- if hash['process_inherit']
+ if hash["process_inherit"]
process_security = SECURITY_ATTRIBUTES.new
process_security[:nLength] = 12
process_security[:bInheritHandle] = 1
@@ -145,7 +145,7 @@ module Process
# Thread SECURITY_ATTRIBUTE structure
thread_security = nil
- if hash['thread_inherit']
+ if hash["thread_inherit"]
thread_security = SECURITY_ATTRIBUTES.new
thread_security[:nLength] = 12
thread_security[:bInheritHandle] = 1
@@ -156,7 +156,7 @@ module Process
# will not work on JRuby because of the way it handles internal file
# descriptors.
#
- ['stdin', 'stdout', 'stderr'].each{ |io|
+ %w{stdin stdout stderr}.each do |io|
if si_hash[io]
if si_hash[io].respond_to?(:fileno)
handle = get_osfhandle(si_hash[io].fileno)
@@ -187,66 +187,66 @@ module Process
raise SystemCallError.new("SetHandleInformation", FFI.errno) unless bool
si_hash[io] = handle
- si_hash['startf_flags'] ||= 0
- si_hash['startf_flags'] |= STARTF_USESTDHANDLES
- hash['inherit'] = true
+ si_hash["startf_flags"] ||= 0
+ si_hash["startf_flags"] |= STARTF_USESTDHANDLES
+ hash["inherit"] = true
end
- }
+ end
procinfo = PROCESS_INFORMATION.new
startinfo = STARTUPINFO.new
unless si_hash.empty?
startinfo[:cb] = startinfo.size
- startinfo[:lpDesktop] = si_hash['desktop'] if si_hash['desktop']
- startinfo[:lpTitle] = si_hash['title'] if si_hash['title']
- startinfo[:dwX] = si_hash['x'] if si_hash['x']
- startinfo[:dwY] = si_hash['y'] if si_hash['y']
- startinfo[:dwXSize] = si_hash['x_size'] if si_hash['x_size']
- startinfo[:dwYSize] = si_hash['y_size'] if si_hash['y_size']
- startinfo[:dwXCountChars] = si_hash['x_count_chars'] if si_hash['x_count_chars']
- startinfo[:dwYCountChars] = si_hash['y_count_chars'] if si_hash['y_count_chars']
- startinfo[:dwFillAttribute] = si_hash['fill_attribute'] if si_hash['fill_attribute']
- startinfo[:dwFlags] = si_hash['startf_flags'] if si_hash['startf_flags']
- startinfo[:wShowWindow] = si_hash['sw_flags'] if si_hash['sw_flags']
+ startinfo[:lpDesktop] = si_hash["desktop"] if si_hash["desktop"]
+ startinfo[:lpTitle] = si_hash["title"] if si_hash["title"]
+ startinfo[:dwX] = si_hash["x"] if si_hash["x"]
+ startinfo[:dwY] = si_hash["y"] if si_hash["y"]
+ startinfo[:dwXSize] = si_hash["x_size"] if si_hash["x_size"]
+ startinfo[:dwYSize] = si_hash["y_size"] if si_hash["y_size"]
+ startinfo[:dwXCountChars] = si_hash["x_count_chars"] if si_hash["x_count_chars"]
+ startinfo[:dwYCountChars] = si_hash["y_count_chars"] if si_hash["y_count_chars"]
+ startinfo[:dwFillAttribute] = si_hash["fill_attribute"] if si_hash["fill_attribute"]
+ startinfo[:dwFlags] = si_hash["startf_flags"] if si_hash["startf_flags"]
+ startinfo[:wShowWindow] = si_hash["sw_flags"] if si_hash["sw_flags"]
startinfo[:cbReserved2] = 0
- startinfo[:hStdInput] = si_hash['stdin'] if si_hash['stdin']
- startinfo[:hStdOutput] = si_hash['stdout'] if si_hash['stdout']
- startinfo[:hStdError] = si_hash['stderr'] if si_hash['stderr']
+ startinfo[:hStdInput] = si_hash["stdin"] if si_hash["stdin"]
+ startinfo[:hStdOutput] = si_hash["stdout"] if si_hash["stdout"]
+ startinfo[:hStdError] = si_hash["stderr"] if si_hash["stderr"]
end
app = nil
cmd = nil
# Convert strings to wide character strings if present
- if hash['app_name']
- app = hash['app_name'].to_wide_string
+ if hash["app_name"]
+ app = hash["app_name"].to_wide_string
end
- if hash['command_line']
- cmd = hash['command_line'].to_wide_string
+ if hash["command_line"]
+ cmd = hash["command_line"].to_wide_string
end
- if hash['cwd']
- cwd = hash['cwd'].to_wide_string
+ if hash["cwd"]
+ cwd = hash["cwd"].to_wide_string
end
- inherit = hash['inherit'] ? 1 : 0
+ inherit = hash["inherit"] ? 1 : 0
- if hash['with_logon']
- logon = hash['with_logon'].to_wide_string
+ if hash["with_logon"]
+ logon = hash["with_logon"].to_wide_string
- if hash['password']
- passwd = hash['password'].to_wide_string
+ if hash["password"]
+ passwd = hash["password"].to_wide_string
else
- raise ArgumentError, 'password must be specified if with_logon is used'
+ raise ArgumentError, "password must be specified if with_logon is used"
end
- if hash['domain']
- domain = hash['domain'].to_wide_string
+ if hash["domain"]
+ domain = hash["domain"].to_wide_string
end
- hash['creation_flags'] |= CREATE_UNICODE_ENVIRONMENT
+ hash["creation_flags"] |= CREATE_UNICODE_ENVIRONMENT
winsta_name = FFI::MemoryPointer.new(:char, 256)
return_size = FFI::MemoryPointer.new(:ulong)
@@ -297,7 +297,7 @@ module Process
process_security, # Process attributes
thread_security, # Thread attributes
inherit, # Inherit handles
- hash['creation_flags'], # Creation Flags
+ hash["creation_flags"], # Creation Flags
env, # Environment
cwd, # Working directory
startinfo, # Startup Info
@@ -318,7 +318,7 @@ module Process
LOGON_WITH_PROFILE, # Logon flags
app, # App name
cmd, # Command line
- hash['creation_flags'], # Creation flags
+ hash["creation_flags"], # Creation flags
env, # Environment
cwd, # Working directory
startinfo, # Startup Info
@@ -336,7 +336,7 @@ module Process
process_security, # Process attributes
thread_security, # Thread attributes
inherit, # Inherit handles?
- hash['creation_flags'], # Creation flags
+ hash["creation_flags"], # Creation flags
env, # Environment
cwd, # Working directory
startinfo, # Startup Info
@@ -350,7 +350,7 @@ module Process
# Automatically close the process and thread handles in the
# PROCESS_INFORMATION struct unless explicitly told not to.
- if hash['close_handles']
+ if hash["close_handles"]
CloseHandle(procinfo[:hProcess])
CloseHandle(procinfo[:hThread])
# Clear these fields so callers don't attempt to close the handle
diff --git a/mixlib-shellout-windows.gemspec b/mixlib-shellout-windows.gemspec
index f051dc6..bd3c21d 100644
--- a/mixlib-shellout-windows.gemspec
+++ b/mixlib-shellout-windows.gemspec
@@ -1,6 +1,6 @@
gemspec = eval(File.read(File.expand_path("../mixlib-shellout.gemspec", __FILE__)))
-gemspec.platform = Gem::Platform.new(["universal", "mingw32"])
+gemspec.platform = Gem::Platform.new(%w{universal mingw32})
gemspec.add_dependency "win32-process", "~> 0.8.2"
gemspec.add_dependency "wmi-lite", "~> 1.0"
diff --git a/mixlib-shellout.gemspec b/mixlib-shellout.gemspec
index 4aa568f..bbbe0df 100644
--- a/mixlib-shellout.gemspec
+++ b/mixlib-shellout.gemspec
@@ -1,8 +1,8 @@
-$:.unshift(File.dirname(__FILE__) + '/lib')
-require 'mixlib/shellout/version'
+$:.unshift(File.dirname(__FILE__) + "/lib")
+require "mixlib/shellout/version"
Gem::Specification.new do |s|
- s.name = 'mixlib-shellout'
+ s.name = "mixlib-shellout"
s.version = Mixlib::ShellOut::VERSION
s.platform = Gem::Platform::RUBY
s.extra_rdoc_files = ["README.md", "LICENSE" ]
@@ -12,13 +12,14 @@ Gem::Specification.new do |s|
s.email = "info@chef.io"
s.homepage = "https://www.chef.io/"
- s.required_ruby_version = ">= 2.1"
+ s.required_ruby_version = ">= 2.2"
s.add_development_dependency "rspec", "~> 3.0"
+ s.add_development_dependency "chefstyle"
s.bindir = "bin"
s.executables = []
- s.require_path = 'lib'
- s.files = %w(Gemfile Rakefile LICENSE README.md) + Dir.glob("*.gemspec") +
- Dir.glob("lib/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
+ s.require_path = "lib"
+ s.files = %w{Gemfile Rakefile LICENSE README.md} + Dir.glob("*.gemspec") +
+ Dir.glob("lib/**/*", File::FNM_DOTMATCH).reject { |f| File.directory?(f) }
end
diff --git a/spec/mixlib/shellout/windows_spec.rb b/spec/mixlib/shellout/windows_spec.rb
index 8b40fde..fe511eb 100644
--- a/spec/mixlib/shellout/windows_spec.rb
+++ b/spec/mixlib/shellout/windows_spec.rb
@@ -1,9 +1,9 @@
-require 'spec_helper'
+require "spec_helper"
-describe 'Mixlib::ShellOut::Windows', :windows_only do
+describe "Mixlib::ShellOut::Windows", :windows_only do
- describe 'Utils' do
- describe '.should_run_under_cmd?' do
+ describe "Utils" do
+ describe ".should_run_under_cmd?" do
subject { Mixlib::ShellOut::Windows::Utils.should_run_under_cmd?(command) }
def self.with_command(_command, &example)
@@ -13,7 +13,7 @@ describe 'Mixlib::ShellOut::Windows', :windows_only do
end
end
- context 'when unquoted' do
+ context "when unquoted" do
with_command(%q{ruby -e 'prints "foobar"'}) { is_expected.not_to be_truthy }
# https://github.com/opscode/mixlib-shellout/pull/2#issuecomment-4825574
@@ -38,7 +38,7 @@ describe 'Mixlib::ShellOut::Windows', :windows_only do
with_command(%q{run.exe %A B% %PATH1%}) { is_expected.to be_truthy }
with_command(%q{run.exe %A B% %_PATH1%}) { is_expected.to be_truthy }
- context 'when outside quotes' do
+ context "when outside quotes" do
with_command(%q{ruby -e "exit 1" | ruby -e "exit 0"}) { is_expected.to be_truthy }
with_command(%q{ruby -e "exit 1" > out.txt}) { is_expected.to be_truthy }
with_command(%q{ruby -e "exit 1" > out.txt 2>&1}) { is_expected.to be_truthy }
@@ -47,7 +47,7 @@ describe 'Mixlib::ShellOut::Windows', :windows_only do
with_command(%q{ruby -e "exit 1" && ruby -e "exit 0"}) { is_expected.to be_truthy }
with_command(%q{@echo "TRUE"}) { is_expected.to be_truthy }
- context 'with unclosed quote' do
+ context "with unclosed quote" do
with_command(%q{ruby -e "exit 1" | ruby -e "exit 0}) { is_expected.to be_truthy }
with_command(%q{ruby -e "exit 1" > "out.txt}) { is_expected.to be_truthy }
with_command(%q{ruby -e "exit 1" > "out.txt 2>&1}) { is_expected.to be_truthy }
@@ -70,7 +70,7 @@ describe 'Mixlib::ShellOut::Windows', :windows_only do
end
end
- context 'when quoted' do
+ context "when quoted" do
with_command(%q{run.exe "ruby -e 'exit 1' || ruby -e 'exit 0'"}) { is_expected.to be_falsey }
with_command(%q{run.exe "ruby -e 'exit 1' > out.txt"}) { is_expected.to be_falsey }
with_command(%q{run.exe "ruby -e 'exit 1' > out.txt 2>&1"}) { is_expected.to be_falsey }
@@ -88,7 +88,7 @@ describe 'Mixlib::ShellOut::Windows', :windows_only do
with_command(%q{run.exe "%A B% %PATH1%"}) { is_expected.to be_truthy }
with_command(%q{run.exe "%A B% %_PATH1%"}) { is_expected.to be_truthy }
- context 'with unclosed quote' do
+ context "with unclosed quote" do
with_command(%q{run.exe "ruby -e 'exit 1' || ruby -e 'exit 0'}) { is_expected.to be_falsey }
with_command(%q{run.exe "ruby -e 'exit 1' > out.txt}) { is_expected.to be_falsey }
with_command(%q{run.exe "ruby -e 'exit 1' > out.txt 2>&1}) { is_expected.to be_falsey }
@@ -109,7 +109,7 @@ describe 'Mixlib::ShellOut::Windows', :windows_only do
end
end
- describe '.kill_process_tree' do
+ describe ".kill_process_tree" do
let(:utils) { Mixlib::ShellOut::Windows::Utils }
let(:wmi) { Object.new }
let(:wmi_ole_object) { Object.new }
@@ -122,25 +122,25 @@ describe 'Mixlib::ShellOut::Windows', :windows_only do
allow(logger).to receive(:debug)
end
- context 'with a protected system process in the process tree' do
+ context "with a protected system process in the process tree" do
before do
- allow(wmi_ole_object).to receive(:name).and_return('csrss.exe')
+ allow(wmi_ole_object).to receive(:name).and_return("csrss.exe")
allow(wmi_ole_object).to receive(:processid).and_return(100)
end
- it 'does not attempt to kill csrss.exe' do
+ it "does not attempt to kill csrss.exe" do
expect(utils).to_not receive(:kill_process)
utils.kill_process_tree(200, wmi, logger)
end
end
- context 'with a non-system-critical process in the process tree' do
+ context "with a non-system-critical process in the process tree" do
before do
- allow(wmi_ole_object).to receive(:name).and_return('blah.exe')
+ allow(wmi_ole_object).to receive(:name).and_return("blah.exe")
allow(wmi_ole_object).to receive(:processid).and_return(300)
end
- it 'does attempt to kill blah.exe' do
+ it "does attempt to kill blah.exe" do
expect(utils).to receive(:kill_process).with(wmi_process, logger)
expect(utils).to receive(:kill_process_tree).with(200, wmi, logger).and_call_original
expect(utils).to receive(:kill_process_tree).with(300, wmi, logger)
@@ -152,9 +152,9 @@ describe 'Mixlib::ShellOut::Windows', :windows_only do
# Caveat: Private API methods are subject to change without notice.
# Monkeypatch at your own risk.
- context 'for private API methods' do
+ context "for private API methods" do
- describe '::IS_BATCH_FILE' do
+ describe "::IS_BATCH_FILE" do
subject { candidate =~ Mixlib::ShellOut::Windows::IS_BATCH_FILE }
def self.with_candidate(_context, _options = {}, &example)
@@ -164,130 +164,130 @@ describe 'Mixlib::ShellOut::Windows', :windows_only do
end
end
- with_candidate('valid .bat file', :candidate => 'autoexec.bat') { is_expected.to be_truthy }
- with_candidate('valid .cmd file', :candidate => 'autoexec.cmd') { is_expected.to be_truthy }
- with_candidate('valid quoted .bat file', :candidate => '"C:\Program Files\autoexec.bat"') { is_expected.to be_truthy }
- with_candidate('valid quoted .cmd file', :candidate => '"C:\Program Files\autoexec.cmd"') { is_expected.to be_truthy }
+ with_candidate("valid .bat file", :candidate => "autoexec.bat") { is_expected.to be_truthy }
+ with_candidate("valid .cmd file", :candidate => "autoexec.cmd") { is_expected.to be_truthy }
+ with_candidate("valid quoted .bat file", :candidate => '"C:\Program Files\autoexec.bat"') { is_expected.to be_truthy }
+ with_candidate("valid quoted .cmd file", :candidate => '"C:\Program Files\autoexec.cmd"') { is_expected.to be_truthy }
- with_candidate('invalid .bat file', :candidate => 'autoexecbat') { is_expected.not_to be_truthy }
- with_candidate('invalid .cmd file', :candidate => 'autoexeccmd') { is_expected.not_to be_truthy }
- with_candidate('bat in filename', :candidate => 'abattoir.exe') { is_expected.not_to be_truthy }
- with_candidate('cmd in filename', :candidate => 'parse_cmd.exe') { is_expected.not_to be_truthy }
+ with_candidate("invalid .bat file", :candidate => "autoexecbat") { is_expected.not_to be_truthy }
+ with_candidate("invalid .cmd file", :candidate => "autoexeccmd") { is_expected.not_to be_truthy }
+ with_candidate("bat in filename", :candidate => "abattoir.exe") { is_expected.not_to be_truthy }
+ with_candidate("cmd in filename", :candidate => "parse_cmd.exe") { is_expected.not_to be_truthy }
- with_candidate('invalid quoted .bat file', :candidate => '"C:\Program Files\autoexecbat"') { is_expected.not_to be_truthy }
- with_candidate('invalid quoted .cmd file', :candidate => '"C:\Program Files\autoexeccmd"') { is_expected.not_to be_truthy }
- with_candidate('quoted bat in filename', :candidate => '"C:\Program Files\abattoir.exe"') { is_expected.not_to be_truthy }
- with_candidate('quoted cmd in filename', :candidate => '"C:\Program Files\parse_cmd.exe"') { is_expected.not_to be_truthy }
+ with_candidate("invalid quoted .bat file", :candidate => '"C:\Program Files\autoexecbat"') { is_expected.not_to be_truthy }
+ with_candidate("invalid quoted .cmd file", :candidate => '"C:\Program Files\autoexeccmd"') { is_expected.not_to be_truthy }
+ with_candidate("quoted bat in filename", :candidate => '"C:\Program Files\abattoir.exe"') { is_expected.not_to be_truthy }
+ with_candidate("quoted cmd in filename", :candidate => '"C:\Program Files\parse_cmd.exe"') { is_expected.not_to be_truthy }
end
- describe '#command_to_run' do
+ describe "#command_to_run" do
subject { stubbed_shell_out.send(:command_to_run, cmd) }
- let(:stubbed_shell_out) { fail NotImplemented, 'Must declare let(:stubbed_shell_out)' }
+ let(:stubbed_shell_out) { raise NotImplemented, "Must declare let(:stubbed_shell_out)" }
let(:shell_out) { Mixlib::ShellOut.new(cmd) }
let(:utils) { Mixlib::ShellOut::Windows::Utils }
let(:with_valid_exe_at_location) { lambda { |s| allow(utils).to receive(:find_executable).and_return(executable_path) } }
let(:with_invalid_exe_at_location) { lambda { |s| allow(utils).to receive(:find_executable).and_return(nil) } }
- context 'with empty command' do
+ context "with empty command" do
let(:stubbed_shell_out) { shell_out }
- let(:cmd) { ' ' }
+ let(:cmd) { " " }
- it 'should return with a nil executable' do
+ it "should return with a nil executable" do
is_expected.to eql([nil, cmd])
end
end
- context 'with extensionless executable' do
+ context "with extensionless executable" do
let(:stubbed_shell_out) { shell_out }
let(:executable_path) { 'C:\Windows\system32/ping.EXE' }
- let(:cmd) { 'ping' }
+ let(:cmd) { "ping" }
before do
- allow(ENV).to receive(:[]).with('PATH').and_return('C:\Windows\system32')
- allow(ENV).to receive(:[]).with('PATHEXT').and_return('.EXE')
- allow(ENV).to receive(:[]).with('COMSPEC').and_return('C:\Windows\system32\cmd.exe')
+ allow(ENV).to receive(:[]).with("PATH").and_return('C:\Windows\system32')
+ allow(ENV).to receive(:[]).with("PATHEXT").and_return(".EXE")
+ allow(ENV).to receive(:[]).with("COMSPEC").and_return('C:\Windows\system32\cmd.exe')
allow(File).to receive(:executable?).and_return(false)
allow(File).to receive(:executable?).with(executable_path).and_return(true)
allow(File).to receive(:directory?).and_return(false)
end
- it 'should return with full path with extension' do
+ it "should return with full path with extension" do
is_expected.to eql([executable_path, cmd])
end
- context 'there is a directory named after command' do
+ context "there is a directory named after command" do
before do
# File.executable? returns true for directories
allow(File).to receive(:executable?).with(cmd).and_return(true)
allow(File).to receive(:directory?).with(cmd).and_return(true)
end
- it 'should return with full path with extension' do
+ it "should return with full path with extension" do
is_expected.to eql([executable_path, cmd])
end
end
end
- context 'with batch files' do
+ context "with batch files" do
let(:stubbed_shell_out) { shell_out.tap(&with_valid_exe_at_location) }
let(:cmd_invocation) { "cmd /c \"#{cmd}\"" }
let(:cmd_exe) { "C:\\Windows\\system32\\cmd.exe" }
let(:cmd) { "#{executable_path}" }
- before { ENV['ComSpec'] = 'C:\Windows\system32\cmd.exe' }
+ before { ENV["ComSpec"] = 'C:\Windows\system32\cmd.exe' }
- context 'with .bat file' do
+ context "with .bat file" do
let(:executable_path) { '"C:\Program Files\Application\Start.bat"' }
# Examples taken from: https://github.com/opscode/mixlib-shellout/pull/2#issuecomment-4825574
- context 'with executable path enclosed in double quotes' do
+ context "with executable path enclosed in double quotes" do
- it 'should use specified batch file' do
+ it "should use specified batch file" do
is_expected.to eql([cmd_exe, cmd_invocation])
end
- context 'with arguments' do
+ context "with arguments" do
let(:cmd) { "#{executable_path} arguments" }
- it 'should use specified executable' do
+ it "should use specified executable" do
is_expected.to eql([cmd_exe, cmd_invocation])
end
end
- context 'with quoted arguments' do
+ context "with quoted arguments" do
let(:cmd) { "#{executable_path} /i \"C:\Program Files (x86)\NUnit 2.6\bin\framework\nunit.framework.dll\"" }
- it 'should use specified executable' do
+ it "should use specified executable" do
is_expected.to eql([cmd_exe, cmd_invocation])
end
end
end
end
- context 'with .cmd file' do
+ context "with .cmd file" do
let(:executable_path) { '"C:\Program Files\Application\Start.cmd"' }
# Examples taken from: https://github.com/opscode/mixlib-shellout/pull/2#issuecomment-4825574
- context 'with executable path enclosed in double quotes' do
+ context "with executable path enclosed in double quotes" do
- it 'should use specified batch file' do
+ it "should use specified batch file" do
is_expected.to eql([cmd_exe, cmd_invocation])
end
- context 'with arguments' do
+ context "with arguments" do
let(:cmd) { "#{executable_path} arguments" }
- it 'should use specified executable' do
+ it "should use specified executable" do
is_expected.to eql([cmd_exe, cmd_invocation])
end
end
- context 'with quoted arguments' do
+ context "with quoted arguments" do
let(:cmd) { "#{executable_path} /i \"C:\Program Files (x86)\NUnit 2.6\bin\framework\nunit.framework.dll\"" }
- it 'should use specified executable' do
+ it "should use specified executable" do
is_expected.to eql([cmd_exe, cmd_invocation])
end
end
@@ -296,55 +296,55 @@ describe 'Mixlib::ShellOut::Windows', :windows_only do
end
end
- context 'with valid executable at location' do
+ context "with valid executable at location" do
let(:stubbed_shell_out) { shell_out.tap(&with_valid_exe_at_location) }
- context 'with executable path' do
+ context "with executable path" do
let(:cmd) { "#{executable_path}" }
let(:executable_path) { 'C:\RUBY192\bin\ruby.exe' }
- it 'should use specified executable' do
+ it "should use specified executable" do
is_expected.to eql([executable_path, cmd])
end
- context 'with arguments' do
+ context "with arguments" do
let(:cmd) { "#{executable_path} arguments" }
- it 'should use specified executable' do
+ it "should use specified executable" do
is_expected.to eql([executable_path, cmd])
end
end
- context 'with quoted arguments' do
+ context "with quoted arguments" do
let(:cmd) { "#{executable_path} -e \"print 'fee fie foe fum'\"" }
- it 'should use specified executable' do
+ it "should use specified executable" do
is_expected.to eql([executable_path, cmd])
end
end
end
# Examples taken from: https://github.com/opscode/mixlib-shellout/pull/2#issuecomment-4825574
- context 'with executable path enclosed in double quotes' do
+ context "with executable path enclosed in double quotes" do
let(:cmd) { "#{executable_path}" }
let(:executable_path) { '"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\gacutil.exe"' }
- it 'should use specified executable' do
+ it "should use specified executable" do
is_expected.to eql([executable_path, cmd])
end
- context 'with arguments' do
+ context "with arguments" do
let(:cmd) { "#{executable_path} arguments" }
- it 'should use specified executable' do
+ it "should use specified executable" do
is_expected.to eql([executable_path, cmd])
end
end
- context 'with quoted arguments' do
+ context "with quoted arguments" do
let(:cmd) { "#{executable_path} /i \"C:\Program Files (x86)\NUnit 2.6\bin\framework\nunit.framework.dll\"" }
- it 'should use specified executable' do
+ it "should use specified executable" do
is_expected.to eql([executable_path, cmd])
end
end
diff --git a/spec/mixlib/shellout_spec.rb b/spec/mixlib/shellout_spec.rb
index 38915f3..b5df5dd 100644
--- a/spec/mixlib/shellout_spec.rb
+++ b/spec/mixlib/shellout_spec.rb
@@ -1,6 +1,6 @@
-require 'spec_helper'
-require 'logger'
-require 'timeout'
+require "spec_helper"
+require "logger"
+require "timeout"
describe Mixlib::ShellOut do
let(:shell_cmd) { options ? shell_cmd_with_options : shell_cmd_without_options }
@@ -14,76 +14,76 @@ describe Mixlib::ShellOut do
let(:shell_cmd_without_options) { Mixlib::ShellOut.new(cmd) }
let(:shell_cmd_with_options) { Mixlib::ShellOut.new(cmd, options) }
let(:cmd) { ruby_eval.call(ruby_code) }
- let(:ruby_code) { raise 'define let(:ruby_code)' }
+ let(:ruby_code) { raise "define let(:ruby_code)" }
let(:options) { nil }
let(:ruby_eval) { lambda { |code| "ruby -e '#{code}'" } }
- context 'when instantiating' do
+ context "when instantiating" do
subject { shell_cmd }
- let(:cmd) { 'apt-get install chef' }
+ let(:cmd) { "apt-get install chef" }
it "should set the command" do
expect(subject.command).to eql(cmd)
end
- context 'with default settings' do
- describe '#cwd' do
+ context "with default settings" do
+ describe "#cwd" do
subject { super().cwd }
it { is_expected.to be_nil }
end
- describe '#user' do
+ describe "#user" do
subject { super().user }
it { is_expected.to be_nil }
end
- describe '#with_logon' do
+ describe "#with_logon" do
subject { super().with_logon }
it { is_expected.to be_nil }
end
- describe '#login' do
+ describe "#login" do
subject { super().login }
it { is_expected.to be_nil }
end
- describe '#domain' do
+ describe "#domain" do
subject { super().domain }
it { is_expected.to be_nil }
end
- describe '#password' do
+ describe "#password" do
subject { super().password }
it { is_expected.to be_nil }
end
- describe '#group' do
+ describe "#group" do
subject { super().group }
it { is_expected.to be_nil }
end
- describe '#umask' do
+ describe "#umask" do
subject { super().umask }
it { is_expected.to be_nil }
end
- describe '#timeout' do
+ describe "#timeout" do
subject { super().timeout }
it { is_expected.to eql(600) }
end
- describe '#valid_exit_codes' do
+ describe "#valid_exit_codes" do
subject { super().valid_exit_codes }
it { is_expected.to eql([0]) }
end
- describe '#live_stream' do
+ describe "#live_stream" do
subject { super().live_stream }
it { is_expected.to be_nil }
end
- describe '#input' do
+ describe "#input" do
subject { super().input }
it { is_expected.to be_nil }
end
@@ -93,23 +93,23 @@ describe Mixlib::ShellOut do
end
end
- context 'when setting accessors' do
+ context "when setting accessors" do
subject { shell_cmd.send(accessor) }
let(:shell_cmd) { blank_shell_cmd.tap(&with_overrides) }
- let(:blank_shell_cmd) { Mixlib::ShellOut.new('apt-get install chef') }
+ let(:blank_shell_cmd) { Mixlib::ShellOut.new("apt-get install chef") }
let(:with_overrides) { lambda { |shell_cmd| shell_cmd.send("#{accessor}=", value) } }
- context 'when setting user' do
+ context "when setting user" do
let(:accessor) { :user }
- let(:value) { 'root' }
+ let(:value) { "root" }
it "should set the user" do
is_expected.to eql(value)
end
# TODO add :unix_only
- context 'with an integer value for user' do
+ context "with an integer value for user" do
let(:value) { 0 }
it "should use the user-supplied uid" do
expect(shell_cmd.uid).to eql(value)
@@ -117,7 +117,7 @@ describe Mixlib::ShellOut do
end
# TODO add :unix_only
- context 'with string value for user' do
+ context "with string value for user" do
let(:value) { username }
let(:username) { user_info.name }
@@ -130,16 +130,16 @@ describe Mixlib::ShellOut do
end
end
- context 'when setting with_logon' do
+ context "when setting with_logon" do
let(:accessor) { :with_logon }
- let(:value) { 'root' }
+ let(:value) { "root" }
it "should set the with_logon" do
is_expected.to eql(value)
end
end
- context 'when setting login' do
+ context "when setting login" do
let(:accessor) { :login }
let(:value) { true }
@@ -148,41 +148,41 @@ describe Mixlib::ShellOut do
end
end
- context 'when setting domain' do
+ context "when setting domain" do
let(:accessor) { :domain }
- let(:value) { 'localhost' }
+ let(:value) { "localhost" }
it "should set the domain" do
is_expected.to eql(value)
end
end
- context 'when setting password' do
+ context "when setting password" do
let(:accessor) { :password }
- let(:value) { 'vagrant' }
+ let(:value) { "vagrant" }
it "should set the password" do
is_expected.to eql(value)
end
end
- context 'when setting group' do
+ context "when setting group" do
let(:accessor) { :group }
- let(:value) { 'wheel' }
+ let(:value) { "wheel" }
it "should set the group" do
is_expected.to eql(value)
end
# TODO add :unix_only
- context 'with integer value for group' do
+ context "with integer value for group" do
let(:value) { 0 }
it "should use the user-supplied gid" do
expect(shell_cmd.gid).to eql(value)
end
end
- context 'with string value for group' do
+ context "with string value for group" do
let(:value) { groupname }
let(:groupname) { group_info.name }
let(:expected_gid) { group_info.gid }
@@ -194,44 +194,44 @@ describe Mixlib::ShellOut do
end
end
- context 'when setting the umask' do
+ context "when setting the umask" do
let(:accessor) { :umask }
- context 'with octal integer' do
- let(:value) { 007555}
+ context "with octal integer" do
+ let(:value) { 007555 }
- it 'should set the umask' do
+ it "should set the umask" do
is_expected.to eql(value)
end
end
- context 'with decimal integer' do
+ context "with decimal integer" do
let(:value) { 2925 }
- it 'should sets the umask' do
+ it "should sets the umask" do
is_expected.to eql(005555)
end
end
- context 'with string' do
- let(:value) { '7777' }
+ context "with string" do
+ let(:value) { "7777" }
- it 'should sets the umask' do
+ it "should sets the umask" do
is_expected.to eql(007777)
end
end
end
- context 'when setting read timeout' do
+ context "when setting read timeout" do
let(:accessor) { :timeout }
let(:value) { 10 }
- it 'should set the read timeout' do
+ it "should set the read timeout" do
is_expected.to eql(value)
end
end
- context 'when setting valid exit codes' do
+ context "when setting valid exit codes" do
let(:accessor) { :valid_exit_codes }
let(:value) { [0, 23, 42] }
@@ -240,7 +240,7 @@ describe Mixlib::ShellOut do
end
end
- context 'when setting a live stream' do
+ context "when setting a live stream" do
let(:accessor) { :live_stream }
let(:value) { stream }
let(:stream) { StringIO.new }
@@ -262,7 +262,7 @@ describe Mixlib::ShellOut do
end
end
- context 'when setting the live stdout and live stderr streams separately' do
+ context "when setting the live stdout and live stderr streams separately" do
let(:accessor) { :live_stream }
let(:stream) { StringIO.new }
let(:value) { stream }
@@ -287,7 +287,7 @@ describe Mixlib::ShellOut do
end
end
- context 'when setting a live stream and then overriding the live stderr' do
+ context "when setting a live stream and then overriding the live stderr" do
let(:accessor) { :live_stream }
let(:value) { stream }
let(:stream) { StringIO.new }
@@ -310,7 +310,7 @@ describe Mixlib::ShellOut do
end
end
- context 'when setting an input' do
+ context "when setting an input" do
let(:accessor) { :input }
let(:value) { "Random content #{rand(1000000)}" }
@@ -320,107 +320,108 @@ describe Mixlib::ShellOut do
end
end
- context 'testing login', :unix_only do
- subject {shell_cmd}
- let (:uid) {1005}
- let (:gid) {1002}
- let (:shell) {'/bin/money'}
- let (:dir) {'/home/castle'}
- let (:path) {'/sbin:/bin:/usr/sbin:/usr/bin'}
+ context "testing login", :unix_only do
+ subject { shell_cmd }
+ let (:uid) { 1005 }
+ let (:gid) { 1002 }
+ let (:shell) { "/bin/money" }
+ let (:dir) { "/home/castle" }
+ let (:path) { "/sbin:/bin:/usr/sbin:/usr/bin" }
before :each do
- shell_cmd.login=true
- catbert_user=double("Etc::Passwd", :name=>'catbert', :passwd=>'x', :uid=>1005, :gid=>1002, :gecos=>"Catbert,,,", :dir=>'/home/castle', :shell=>'/bin/money')
- group_double=[
- double("Etc::Group", :name=>'catbert', :passwd=>'x', :gid=>1002, :mem=>[]),
- double("Etc::Group", :name=>'sudo', :passwd=>'x', :gid=>52, :mem=>['catbert']),
- double("Etc::Group", :name=>'rats', :passwd=>'x', :gid=>43, :mem=>['ratbert']),
- double("Etc::Group", :name=>'dilbertpets', :passwd=>'x', :gid=>700, :mem=>['catbert', 'ratbert']),
+ shell_cmd.login = true
+ catbert_user = double("Etc::Passwd", :name => "catbert", :passwd => "x", :uid => 1005, :gid => 1002, :gecos => "Catbert,,,", :dir => "/home/castle", :shell => "/bin/money")
+ group_double = [
+ double("Etc::Group", :name => "catbert", :passwd => "x", :gid => 1002, :mem => []),
+ double("Etc::Group", :name => "sudo", :passwd => "x", :gid => 52, :mem => ["catbert"]),
+ double("Etc::Group", :name => "rats", :passwd => "x", :gid => 43, :mem => ["ratbert"]),
+ double("Etc::Group", :name => "dilbertpets", :passwd => "x", :gid => 700, :mem => %w{catbert ratbert}),
]
- allow(Etc).to receive(:getpwuid).with(1005) {catbert_user}
- allow(Etc).to receive(:getpwnam).with('catbert') {catbert_user}
- allow(shell_cmd).to receive(:all_seconderies) {group_double}
+ allow(Etc).to receive(:getpwuid).with(1005) { catbert_user }
+ allow(Etc).to receive(:getpwnam).with("catbert") { catbert_user }
+ allow(shell_cmd).to receive(:all_seconderies) { group_double }
end
# Setting the user by name should change the uid
- context 'when setting user by name' do
- before(:each){ shell_cmd.user='catbert' }
- describe '#uid' do
- subject { super().uid }
- it { is_expected.to eq(uid) }
- end
+ context "when setting user by name" do
+ before(:each) { shell_cmd.user = "catbert" }
+ describe "#uid" do
+ subject { super().uid }
+ it { is_expected.to eq(uid) }
+ end
end
- context 'when setting user by id' do
- before(:each){shell_cmd.user=uid}
+ context "when setting user by id" do
+ before(:each) { shell_cmd.user = uid }
# Setting the user by uid should change the uid
#it 'should set the uid' do
- describe '#uid' do
+ describe "#uid" do
subject { super().uid }
it { is_expected.to eq(uid) }
end
#end
# Setting the user without a different gid should change the gid to 1002
- describe '#gid' do
+ describe "#gid" do
subject { super().gid }
it { is_expected.to eq(gid) }
end
# Setting the user and the group (to 43) should change the gid to 43
- context 'when setting the group manually' do
- before(:each){shell_cmd.group=43}
+ context "when setting the group manually" do
+ before(:each) { shell_cmd.group = 43 }
- describe '#gid' do
+ describe "#gid" do
subject { super().gid }
- it {is_expected.to eq(43)}
+ it { is_expected.to eq(43) }
end
end
# Setting the user should set the env variables
- describe '#process_environment' do
- subject { super().process_environment }
- it { is_expected.to eq ({'HOME'=>dir, 'SHELL'=>shell, 'USER'=>'catbert', 'LOGNAME'=>'catbert', 'PATH'=>path, 'IFS'=>"\t\n"}) }
- end
+ describe "#process_environment" do
+ subject { super().process_environment }
+ it { is_expected.to eq ({ "HOME" => dir, "SHELL" => shell, "USER" => "catbert", "LOGNAME" => "catbert", "PATH" => path, "IFS" => "\t\n" }) }
+ end
# Setting the user with overriding env variables should override
- context 'when adding environment variables' do
- before(:each){shell_cmd.environment={'PATH'=>'/lord:/of/the/dance', 'CUSTOM'=>'costume'}}
- it 'should preserve custom variables' do
- expect(shell_cmd.process_environment['PATH']).to eq('/lord:/of/the/dance')
- end
- # Setting the user with additional env variables should have both
- it 'should allow new variables' do
- expect(shell_cmd.process_environment['CUSTOM']).to eq('costume')
- end
- end
+ context "when adding environment variables" do
+ before(:each) { shell_cmd.environment = { "PATH" => "/lord:/of/the/dance", "CUSTOM" => "costume" } }
+ it "should preserve custom variables" do
+ expect(shell_cmd.process_environment["PATH"]).to eq("/lord:/of/the/dance")
+ end
+ # Setting the user with additional env variables should have both
+ it "should allow new variables" do
+ expect(shell_cmd.process_environment["CUSTOM"]).to eq("costume")
+ end
+ end
# Setting the user should set secondary groups
- describe '#sgids' do
- subject { super().sgids }
- it { is_expected.to match_array([52,700]) }
- end
+ describe "#sgids" do
+ subject { super().sgids }
+ it { is_expected.to match_array([52, 700]) }
+ end
end
# Setting login with user should throw errors
- context 'when not setting a user id' do
- it 'should fail showing an error' do
- expect { Mixlib::ShellOut.new('hostname', {login:true}) }.to raise_error(Mixlib::ShellOut::InvalidCommandOption)
+ context "when not setting a user id" do
+ it "should fail showing an error" do
+ expect { Mixlib::ShellOut.new("hostname", { login: true }) }.to raise_error(Mixlib::ShellOut::InvalidCommandOption)
end
end
end
context "with options hash" do
- let(:cmd) { 'brew install couchdb' }
- let(:options) { { :cwd => cwd, :user => user, :login => true, :domain => domain, :password => password, :group => group,
- :umask => umask, :timeout => timeout, :environment => environment, :returns => valid_exit_codes,
- :live_stream => stream, :input => input } }
-
- let(:cwd) { '/tmp' }
- let(:user) { 'toor' }
+ let(:cmd) { "brew install couchdb" }
+ let(:options) do
+ { :cwd => cwd, :user => user, :login => true, :domain => domain, :password => password, :group => group,
+ :umask => umask, :timeout => timeout, :environment => environment, :returns => valid_exit_codes,
+ :live_stream => stream, :input => input } end
+
+ let(:cwd) { "/tmp" }
+ let(:user) { "toor" }
let(:with_logon) { user }
let(:login) { true }
- let(:domain) { 'localhost' }
- let(:password) { 'vagrant' }
- let(:group) { 'wheel' }
- let(:umask) { '2222' }
+ let(:domain) { "localhost" }
+ let(:password) { "vagrant" }
+ let(:group) { "wheel" }
+ let(:umask) { "2222" }
let(:timeout) { 5 }
- let(:environment) { { 'RUBY_OPTS' => '-w' } }
+ let(:environment) { { "RUBY_OPTS" => "-w" } }
let(:valid_exit_codes) { [ 0, 1, 42 ] }
let(:stream) { StringIO.new }
let(:input) { 1.upto(10).map { "Data #{rand(100000)}" }.join("\n") }
@@ -462,27 +463,27 @@ describe Mixlib::ShellOut do
end
it "should add environment settings to the default" do
- expect(shell_cmd.environment).to eql({'RUBY_OPTS' => '-w'})
+ expect(shell_cmd.environment).to eql({ "RUBY_OPTS" => "-w" })
end
- context 'when setting custom environments' do
- context 'when setting the :env option' do
+ context "when setting custom environments" do
+ context "when setting the :env option" do
let(:options) { { :env => environment } }
it "should also set the enviroment" do
- expect(shell_cmd.environment).to eql({'RUBY_OPTS' => '-w'})
+ expect(shell_cmd.environment).to eql({ "RUBY_OPTS" => "-w" })
end
end
- context 'when setting environments with symbols' do
- let(:options) { { :environment => { SYMBOL: 'cymbal' } } }
+ context "when setting environments with symbols" do
+ let(:options) { { :environment => { SYMBOL: "cymbal" } } }
it "should also set the enviroment" do
- expect(shell_cmd.environment).to eql({'SYMBOL' => 'cymbal'})
+ expect(shell_cmd.environment).to eql({ "SYMBOL" => "cymbal" })
end
end
- context 'when :environment is set to nil' do
+ context "when :environment is set to nil" do
let(:options) { { :environment => nil } }
it "should not set any environment" do
@@ -490,7 +491,7 @@ describe Mixlib::ShellOut do
end
end
- context 'when :env is set to nil' do
+ context "when :env is set to nil" do
let(:options) { { :env => nil } }
it "should not set any environment" do
@@ -511,7 +512,7 @@ describe Mixlib::ShellOut do
expect(shell_cmd.input).to eql(input)
end
- context 'with an invalid option' do
+ context "with an invalid option" do
let(:options) { { :frab => :job } }
let(:invalid_option_exception) { Mixlib::ShellOut::InvalidCommandOption }
let(:exception_message) { "option ':frab' is not a valid option for Mixlib::ShellOut" }
@@ -523,9 +524,9 @@ describe Mixlib::ShellOut do
end
context "with array of command and args" do
- let(:cmd) { [ 'ruby', '-e', %q{'puts "hello"'} ] }
+ let(:cmd) { [ "ruby", "-e", %q{'puts "hello"'} ] }
- context 'without options' do
+ context "without options" do
let(:options) { nil }
it "should set the command to the array of command and args" do
@@ -533,46 +534,46 @@ describe Mixlib::ShellOut do
end
end
- context 'with options' do
- let(:options) { {:cwd => '/tmp', :user => 'nobody', :password => "something"} }
+ context "with options" do
+ let(:options) { { :cwd => "/tmp", :user => "nobody", :password => "something" } }
it "should set the command to the array of command and args" do
expect(shell_cmd.command).to eql(cmd)
end
it "should evaluate the options" do
- expect(shell_cmd.cwd).to eql('/tmp')
- expect(shell_cmd.user).to eql('nobody')
- expect(shell_cmd.password).to eql('something')
+ expect(shell_cmd.cwd).to eql("/tmp")
+ expect(shell_cmd.user).to eql("nobody")
+ expect(shell_cmd.password).to eql("something")
end
end
end
end
- context 'when executing the command' do
+ context "when executing the command" do
let(:dir) { Dir.mktmpdir }
let(:dump_file) { "#{dir}/out.txt" }
let(:dump_file_content) { stdout; IO.read(dump_file) }
- context 'with a current working directory' do
+ context "with a current working directory" do
subject { File.expand_path(chomped_stdout) }
let(:fully_qualified_cwd) { File.expand_path(cwd) }
let(:options) { { :cwd => cwd } }
- context 'when running under Unix', :unix_only do
+ context "when running under Unix", :unix_only do
# Use /bin for tests only if it is not a symlink. Some
# distributions (e.g. Fedora) symlink it to /usr/bin
- let(:cwd) { File.symlink?('/bin') ? '/tmp' : '/bin' }
- let(:cmd) { 'pwd' }
+ let(:cwd) { File.symlink?("/bin") ? "/tmp" : "/bin" }
+ let(:cmd) { "pwd" }
it "should chdir to the working directory" do
is_expected.to eql(fully_qualified_cwd)
end
end
- context 'when running under Windows', :windows_only do
+ context "when running under Windows", :windows_only do
let(:cwd) { Dir.tmpdir }
- let(:cmd) { 'echo %cd%' }
+ let(:cmd) { "echo %cd%" }
it "should chdir to the working directory" do
is_expected.to eql(fully_qualified_cwd)
@@ -580,53 +581,53 @@ describe Mixlib::ShellOut do
end
end
- context 'when handling locale' do
+ context "when handling locale" do
before do
- @original_lc_all = ENV['LC_ALL']
- ENV['LC_ALL'] = "en_US.UTF-8"
+ @original_lc_all = ENV["LC_ALL"]
+ ENV["LC_ALL"] = "en_US.UTF-8"
end
after do
- ENV['LC_ALL'] = @original_lc_all
+ ENV["LC_ALL"] = @original_lc_all
end
subject { stripped_stdout }
let(:cmd) { ECHO_LC_ALL }
- let(:options) { { :environment => { 'LC_ALL' => locale } } }
+ let(:options) { { :environment => { "LC_ALL" => locale } } }
- context 'without specifying environment' do
+ context "without specifying environment" do
let(:options) { nil }
it "should no longer use the C locale by default" do
is_expected.to eql("en_US.UTF-8")
end
end
- context 'with locale' do
- let(:locale) { 'es' }
+ context "with locale" do
+ let(:locale) { "es" }
it "should use the requested locale" do
is_expected.to eql(locale)
end
end
- context 'with LC_ALL set to nil' do
+ context "with LC_ALL set to nil" do
let(:locale) { nil }
- context 'when running under Unix', :unix_only do
+ context "when running under Unix", :unix_only do
it "should unset the process's locale" do
is_expected.to eql("")
end
end
- context 'when running under Windows', :windows_only do
+ context "when running under Windows", :windows_only do
it "should unset process's locale" do
- is_expected.to eql('%LC_ALL%')
+ is_expected.to eql("%LC_ALL%")
end
end
end
end
context "when running under Windows", :windows_only do
- let(:cmd) { '%windir%/system32/whoami.exe' }
+ let(:cmd) { "%windir%/system32/whoami.exe" }
let(:running_user) { shell_cmd.run_command.stdout.strip.downcase }
context "when no user is set" do
@@ -647,8 +648,8 @@ describe Mixlib::ShellOut do
expect(system("net user #{user} /delete")).to eq(true)
end
- let(:user) { 'testuser' }
- let(:password) { 'testpass1!' }
+ let(:user) { "testuser" }
+ let(:password) { "testpass1!" }
let(:options) { { :user => user, :password => password } }
it "should run as specified user" do
@@ -702,8 +703,8 @@ describe Mixlib::ShellOut do
context "with an input" do
subject { stdout }
- let(:input) { 'hello' }
- let(:ruby_code) { 'STDIN.sync = true; STDOUT.sync = true; puts gets' }
+ let(:input) { "hello" }
+ let(:ruby_code) { "STDIN.sync = true; STDOUT.sync = true; puts gets" }
let(:options) { { :input => input } }
it "should copy the input to the child's stdin" do
@@ -716,41 +717,41 @@ describe Mixlib::ShellOut do
let(:file_name) { "#{dir}/Setup Script.cmd" }
let(:script_name) { "\"#{script.path}\"" }
- let(:open_file) { File.open(file_name, 'w') }
+ let(:open_file) { File.open(file_name, "w") }
let(:write_file) { lambda { |f| f.write(script_content) } }
let(:make_executable) { lambda { |f| File.chmod(0755, f.path) } }
- context 'with spaces in the path' do
+ context "with spaces in the path" do
subject { chomped_stdout }
let(:cmd) { script_name }
- context 'when running under Unix', :unix_only do
- let(:script_content) { 'echo blah' }
+ context "when running under Unix", :unix_only do
+ let(:script_content) { "echo blah" }
- it 'should execute' do
- is_expected.to eql('blah')
+ it "should execute" do
+ is_expected.to eql("blah")
end
end
- context 'when running under Windows', :windows_only do
+ context "when running under Windows", :windows_only do
let(:cmd) { "#{script_name} #{argument}" }
- let(:script_content) { '@echo %1' }
+ let(:script_content) { "@echo %1" }
let(:argument) { rand(10000).to_s }
- it 'should execute' do
+ it "should execute" do
is_expected.to eql(argument)
end
- context 'with multiple quotes in the command and args' do
- context 'when using a batch file' do
+ context "with multiple quotes in the command and args" do
+ context "when using a batch file" do
let(:argument) { "\"Random #{rand(10000)}\"" }
- it 'should execute' do
+ it "should execute" do
is_expected.to eql(argument)
end
end
- context 'when not using a batch file' do
+ context "when not using a batch file" do
let(:cmd) { "#{executable_file_name} #{script_name}" }
let(:executable_file_name) { "\"#{dir}/Ruby Parser.exe\"".tap(&make_executable!) }
@@ -758,10 +759,10 @@ describe Mixlib::ShellOut do
let(:script_content) { "print \"#{expected_output}\"" }
let(:expected_output) { "Random #{rand(10000)}" }
- let(:full_path_to_ruby) { ENV['PATH'].split(';').map(&try_ruby).reject(&:nil?).first }
+ let(:full_path_to_ruby) { ENV["PATH"].split(";").map(&try_ruby).reject(&:nil?).first }
let(:try_ruby) { lambda { |path| "#{path}\\ruby.exe" if File.executable? "#{path}\\ruby.exe" } }
- it 'should execute' do
+ it "should execute" do
is_expected.to eql(expected_output)
end
end
@@ -769,72 +770,72 @@ describe Mixlib::ShellOut do
end
end
- context 'with lots of long arguments' do
+ context "with lots of long arguments" do
subject { chomped_stdout }
# This number was chosen because it seems to be an actual maximum
# in Windows--somewhere around 6-7K of command line
- let(:echotext) { 10000.upto(11340).map(&:to_s).join(' ') }
+ let(:echotext) { 10000.upto(11340).map(&:to_s).join(" ") }
let(:cmd) { "echo #{echotext}" }
- it 'should execute' do
+ it "should execute" do
is_expected.to eql(echotext)
end
end
- context 'with special characters' do
+ context "with special characters" do
subject { stdout }
- let(:special_characters) { '<>&|&&||;' }
+ let(:special_characters) { "<>&|&&||;" }
let(:ruby_code) { "print \"#{special_characters}\"" }
- it 'should execute' do
+ it "should execute" do
is_expected.to eql(special_characters)
end
end
- context 'with backslashes' do
+ context "with backslashes" do
subject { stdout }
let(:backslashes) { %q{\\"\\\\} }
let(:cmd) { ruby_eval.call("print \"#{backslashes}\"") }
- it 'should execute' do
+ it "should execute" do
is_expected.to eql("\"\\")
end
end
- context 'with pipes' do
+ context "with pipes" do
let(:input_script) { "STDOUT.sync = true; STDERR.sync = true; print true; STDERR.print false" }
let(:output_script) { "print STDIN.read.length" }
let(:cmd) { ruby_eval.call(input_script) + " | " + ruby_eval.call(output_script) }
- it 'should execute' do
- expect(stdout).to eql('4')
+ it "should execute" do
+ expect(stdout).to eql("4")
end
- it 'should handle stderr' do
- expect(stderr).to eql('false')
+ it "should handle stderr" do
+ expect(stderr).to eql("false")
end
end
- context 'with stdout and stderr file pipes' do
+ context "with stdout and stderr file pipes" do
let(:code) { "STDOUT.sync = true; STDERR.sync = true; print true; STDERR.print false" }
let(:cmd) { ruby_eval.call(code) + " > #{dump_file}" }
- it 'should execute' do
- expect(stdout).to eql('')
+ it "should execute" do
+ expect(stdout).to eql("")
end
- it 'should handle stderr' do
- expect(stderr).to eql('false')
+ it "should handle stderr" do
+ expect(stderr).to eql("false")
end
- it 'should write to file pipe' do
- expect(dump_file_content).to eql('true')
+ it "should write to file pipe" do
+ expect(dump_file_content).to eql("true")
end
end
- context 'with stdin file pipe' do
+ context "with stdin file pipe" do
let(:code) { "STDIN.sync = true; STDOUT.sync = true; STDERR.sync = true; print gets; STDERR.print false" }
let(:cmd) { ruby_eval.call(code) + " < #{dump_file_path}" }
let(:file_content) { "Random content #{rand(100000)}" }
@@ -843,48 +844,48 @@ describe Mixlib::ShellOut do
let(:dump_file) { open_file.tap(&write_file).tap(&:close) }
let(:file_name) { "#{dir}/input" }
- let(:open_file) { File.open(file_name, 'w') }
+ let(:open_file) { File.open(file_name, "w") }
let(:write_file) { lambda { |f| f.write(file_content) } }
- it 'should execute' do
+ it "should execute" do
expect(stdout).to eql(file_content)
end
- it 'should handle stderr' do
- expect(stderr).to eql('false')
+ it "should handle stderr" do
+ expect(stderr).to eql("false")
end
end
- context 'with stdout and stderr file pipes' do
+ context "with stdout and stderr file pipes" do
let(:code) { "STDOUT.sync = true; STDERR.sync = true; print true; STDERR.print false" }
let(:cmd) { ruby_eval.call(code) + " > #{dump_file} 2>&1" }
- it 'should execute' do
- expect(stdout).to eql('')
+ it "should execute" do
+ expect(stdout).to eql("")
end
- it 'should write to file pipe' do
- expect(dump_file_content).to eql('truefalse')
+ it "should write to file pipe" do
+ expect(dump_file_content).to eql("truefalse")
end
end
- context 'with &&' do
+ context "with &&" do
subject { stdout }
- let(:cmd) { ruby_eval.call('print "foo"') + ' && ' + ruby_eval.call('print "bar"') }
+ let(:cmd) { ruby_eval.call('print "foo"') + " && " + ruby_eval.call('print "bar"') }
- it 'should execute' do
- is_expected.to eql('foobar')
+ it "should execute" do
+ is_expected.to eql("foobar")
end
end
- context 'with ||' do
- let(:cmd) { ruby_eval.call('print "foo"; exit 1') + ' || ' + ruby_eval.call('print "bar"') }
+ context "with ||" do
+ let(:cmd) { ruby_eval.call('print "foo"; exit 1') + " || " + ruby_eval.call('print "bar"') }
- it 'should execute' do
- expect(stdout).to eql('foobar')
+ it "should execute" do
+ expect(stdout).to eql("foobar")
end
- it 'should exit with code 0' do
+ it "should exit with code 0" do
expect(exit_status).to eql(0)
end
end
@@ -893,7 +894,7 @@ describe Mixlib::ShellOut do
context "when handling process exit codes" do
let(:cmd) { ruby_eval.call("exit #{exit_code}") }
- context 'with normal exit status' do
+ context "with normal exit status" do
let(:exit_code) { 0 }
it "should not raise error" do
@@ -905,7 +906,7 @@ describe Mixlib::ShellOut do
end
end
- context 'with nonzero exit status' do
+ context "with nonzero exit status" do
let(:exit_code) { 2 }
let(:exception_message_format) { Regexp.escape(executed_cmd.format_for_exception) }
@@ -926,11 +927,11 @@ describe Mixlib::ShellOut do
end
end
- context 'with valid exit codes' do
+ context "with valid exit codes" do
let(:cmd) { ruby_eval.call("exit #{exit_code}" ) }
let(:options) { { :returns => valid_exit_codes } }
- context 'when exiting with valid code' do
+ context "when exiting with valid code" do
let(:valid_exit_codes) { 42 }
let(:exit_code) { 42 }
@@ -943,7 +944,7 @@ describe Mixlib::ShellOut do
end
end
- context 'when exiting with invalid code' do
+ context "when exiting with invalid code" do
let(:valid_exit_codes) { [ 0, 1, 42 ] }
let(:exit_code) { 2 }
@@ -955,7 +956,7 @@ describe Mixlib::ShellOut do
expect(exit_status).to eql(exit_code)
end
- context 'with input data' do
+ context "with input data" do
let(:options) { { :returns => valid_exit_codes, :input => input } }
let(:input) { "Random data #{rand(1000000)}" }
@@ -969,7 +970,7 @@ describe Mixlib::ShellOut do
end
end
- context 'when exiting with invalid code 0' do
+ context "when exiting with invalid code 0" do
let(:valid_exit_codes) { 42 }
let(:exit_code) { 0 }
@@ -992,7 +993,7 @@ describe Mixlib::ShellOut do
end
describe "#error?" do
- context 'when exiting with invalid code' do
+ context "when exiting with invalid code" do
let(:exit_code) { 2 }
it "should return true" do
@@ -1000,7 +1001,7 @@ describe Mixlib::ShellOut do
end
end
- context 'when exiting with valid code' do
+ context "when exiting with valid code" do
let(:exit_code) { 0 }
it "should return false" do
@@ -1011,8 +1012,8 @@ describe Mixlib::ShellOut do
end
context "when handling the subprocess" do
- context 'with STDOUT and STDERR' do
- let(:ruby_code) { 'STDERR.puts :hello; STDOUT.puts :world' }
+ context "with STDOUT and STDERR" do
+ let(:ruby_code) { "STDERR.puts :hello; STDOUT.puts :world" }
# We could separate this into two examples, but we want to make
# sure that stderr and stdout gets collected without stepping
@@ -1023,7 +1024,7 @@ describe Mixlib::ShellOut do
end
end
- context 'with forking subprocess that does not close stdout and stderr' do
+ context "with forking subprocess that does not close stdout and stderr" do
let(:ruby_code) { "exit if fork; 10.times { sleep 1 }" }
it "should not hang" do
@@ -1066,9 +1067,9 @@ describe Mixlib::ShellOut do
end
end
- context 'with open files for parent process' do
+ context "with open files for parent process" do
before do
- @test_file = Tempfile.new('fd_test')
+ @test_file = Tempfile.new("fd_test")
@test_file.write("hello")
@test_file.flush
end
@@ -1095,7 +1096,7 @@ describe Mixlib::ShellOut do
end
context "when the child process dies immediately" do
- let(:cmd) { [ 'exit' ] }
+ let(:cmd) { [ "exit" ] }
it "handles ESRCH from getpgid of a zombie", :unix_only do
allow(Process).to receive(:setsid) { exit!(4) }
@@ -1113,22 +1114,22 @@ describe Mixlib::ShellOut do
end
- context 'with subprocess that takes longer than timeout' do
+ context "with subprocess that takes longer than timeout" do
let(:options) { { :timeout => 1 } }
- context 'on windows', :windows_only do
+ context "on windows", :windows_only do
let(:cmd) do
'cmd /c powershell -c "sleep 10"'
end
it "should raise CommandTimeout" do
- Timeout::timeout(5) do
+ Timeout.timeout(5) do
expect { executed_cmd }.to raise_error(Mixlib::ShellOut::CommandTimeout)
end
end
- context 'and child processes should be killed' do
- it 'kills the child processes' do
+ context "and child processes should be killed" do
+ it "kills the child processes" do
expect(Mixlib::ShellOut::Windows::Utils).to receive(:kill_process) do |instance|
expect(instance.wmi_ole_object.Name).to match(/powershell/)
Process.kill(:KILL, instance.wmi_ole_object.processid)
@@ -1138,9 +1139,9 @@ describe Mixlib::ShellOut do
end
end
- context 'on unix', :unix_only do
+ context "on unix", :unix_only do
def ruby_wo_shell(code)
- parts = %w[ruby]
+ parts = %w{ruby}
parts << "-e"
parts << code
end
@@ -1177,7 +1178,7 @@ describe Mixlib::ShellOut do
it "should KILL the wayward child" do
# note: let blocks don't correctly memoize if an exception is raised,
# so can't use executed_cmd
- expect { shell_cmd.run_command}.to raise_error(Mixlib::ShellOut::CommandTimeout)
+ expect { shell_cmd.run_command }.to raise_error(Mixlib::ShellOut::CommandTimeout)
expect(shell_cmd.stdout).to include("nanana cant hear you")
expect(shell_cmd.status.termsig).to eq(9)
end
@@ -1185,12 +1186,12 @@ describe Mixlib::ShellOut do
context "and a logger is configured" do
let(:log_output) { StringIO.new }
let(:logger) { Logger.new(log_output) }
- let(:options) { {:timeout => 1, :logger => logger} }
+ let(:options) { { :timeout => 1, :logger => logger } }
it "should log messages about killing the child process" do
# note: let blocks don't correctly memoize if an exception is raised,
# so can't use executed_cmd
- expect { shell_cmd.run_command}.to raise_error(Mixlib::ShellOut::CommandTimeout)
+ expect { shell_cmd.run_command }.to raise_error(Mixlib::ShellOut::CommandTimeout)
expect(shell_cmd.stdout).to include("nanana cant hear you")
expect(shell_cmd.status.termsig).to eq(9)
@@ -1217,7 +1218,7 @@ describe Mixlib::ShellOut do
it "should TERM the wayward child and grandchild" do
# note: let blocks don't correctly memoize if an exception is raised,
# so can't use executed_cmd
- expect { shell_cmd.run_command}.to raise_error(Mixlib::ShellOut::CommandTimeout)
+ expect { shell_cmd.run_command }.to raise_error(Mixlib::ShellOut::CommandTimeout)
expect(shell_cmd.stdout).to include("got term in child")
expect(shell_cmd.stdout).to include("got term in grandchild")
end
@@ -1240,7 +1241,7 @@ describe Mixlib::ShellOut do
it "should TERM the wayward child and grandchild, then KILL whoever is left" do
# note: let blocks don't correctly memoize if an exception is raised,
# so can't use executed_cmd
- expect { shell_cmd.run_command}.to raise_error(Mixlib::ShellOut::CommandTimeout)
+ expect { shell_cmd.run_command }.to raise_error(Mixlib::ShellOut::CommandTimeout)
begin
@@ -1257,7 +1258,7 @@ describe Mixlib::ShellOut do
kill_return_val = Process.kill(:INT, child_pgid) # should raise ESRCH
# AIX - kill returns code > 0 for error, where as other platforms return -1. Ruby code signal.c treats < 0 as error and raises exception and hence fails on AIX. So we check the return code for assertions since ruby wont raise an error here.
- if(kill_return_val == 0)
+ if kill_return_val == 0
# Debug the failure:
puts "child pgid=#{child_pgid.inspect}"
Process.wait
@@ -1276,7 +1277,7 @@ describe Mixlib::ShellOut do
end
end
- context 'with subprocess that exceeds buffersize' do
+ context "with subprocess that exceeds buffersize" do
let(:ruby_code) { 'print("X" * 16 * 1024); print("." * 1024)' }
it "should still reads all of the output" do
@@ -1284,39 +1285,39 @@ describe Mixlib::ShellOut do
end
end
- context 'with subprocess that returns nothing' do
- let(:ruby_code) { 'exit 0' }
+ context "with subprocess that returns nothing" do
+ let(:ruby_code) { "exit 0" }
- it 'should return an empty string for stdout' do
- expect(stdout).to eql('')
+ it "should return an empty string for stdout" do
+ expect(stdout).to eql("")
end
- it 'should return an empty string for stderr' do
- expect(stderr).to eql('')
+ it "should return an empty string for stderr" do
+ expect(stderr).to eql("")
end
end
- context 'with subprocess that closes stdin and continues writing to stdout' do
+ context "with subprocess that closes stdin and continues writing to stdout" do
let(:ruby_code) { "STDIN.close; sleep 0.5; STDOUT.puts :win" }
let(:options) { { :input => "Random data #{rand(100000)}" } }
- it 'should not hang or lose output' do
+ it "should not hang or lose output" do
expect(stdout).to eql("win#{LINE_ENDING}")
end
end
- context 'with subprocess that closes stdout and continues writing to stderr' do
+ context "with subprocess that closes stdout and continues writing to stderr" do
let(:ruby_code) { "STDOUT.close; sleep 0.5; STDERR.puts :win" }
- it 'should not hang or lose output' do
+ it "should not hang or lose output" do
expect(stderr).to eql("win#{LINE_ENDING}")
end
end
- context 'with subprocess that closes stderr and continues writing to stdout' do
+ context "with subprocess that closes stderr and continues writing to stdout" do
let(:ruby_code) { "STDERR.close; sleep 0.5; STDOUT.puts :win" }
- it 'should not hang or lose output' do
+ it "should not hang or lose output" do
expect(stdout).to eql("win#{LINE_ENDING}")
end
end
@@ -1333,54 +1334,54 @@ describe Mixlib::ShellOut do
# Otherwise, we will attempt to read from the closed STDOUT pipe over and
# over again and generate lots of garbage, which will not be collected
# since we have to turn GC off to avoid segv.
- context 'with subprocess that closes STDOUT before closing STDERR' do
- let(:ruby_code) { %q{STDOUT.puts "F" * 4096; STDOUT.close; sleep 0.1; STDERR.puts "foo"; STDERR.close; sleep 0.1; exit} }
+ context "with subprocess that closes STDOUT before closing STDERR" do
+ let(:ruby_code) { %q{STDOUT.puts "F" * 4096; STDOUT.close; sleep 0.1; STDERR.puts "foo"; STDERR.close; sleep 0.1; exit} }
let(:unclosed_pipes) { executed_cmd.send(:open_pipes) }
- it 'should not hang' do
+ it "should not hang" do
expect(stdout).not_to be_empty
end
- it 'should close all pipes', :unix_only do
+ it "should close all pipes", :unix_only do
expect(unclosed_pipes).to be_empty
end
end
- context 'with subprocess reading lots of data from stdin' do
+ context "with subprocess reading lots of data from stdin" do
subject { stdout.to_i }
- let(:ruby_code) { 'STDOUT.print gets.size' }
+ let(:ruby_code) { "STDOUT.print gets.size" }
let(:options) { { :input => input } }
- let(:input) { 'f' * 20_000 }
+ let(:input) { "f" * 20_000 }
let(:input_size) { input.size }
- it 'should not hang' do
+ it "should not hang" do
is_expected.to eql(input_size)
end
end
- context 'with subprocess writing lots of data to both stdout and stderr' do
+ context "with subprocess writing lots of data to both stdout and stderr" do
let(:expected_output_with) { lambda { |chr| (chr * 20_000) + "#{LINE_ENDING}" + (chr * 20_000) + "#{LINE_ENDING}" } }
- context 'when writing to STDOUT first' do
+ context "when writing to STDOUT first" do
let(:ruby_code) { %q{puts "f" * 20_000; STDERR.puts "u" * 20_000; puts "f" * 20_000; STDERR.puts "u" * 20_000} }
it "should not deadlock" do
- expect(stdout).to eql(expected_output_with.call('f'))
- expect(stderr).to eql(expected_output_with.call('u'))
+ expect(stdout).to eql(expected_output_with.call("f"))
+ expect(stderr).to eql(expected_output_with.call("u"))
end
end
- context 'when writing to STDERR first' do
+ context "when writing to STDERR first" do
let(:ruby_code) { %q{STDERR.puts "u" * 20_000; puts "f" * 20_000; STDERR.puts "u" * 20_000; puts "f" * 20_000} }
it "should not deadlock" do
- expect(stdout).to eql(expected_output_with.call('f'))
- expect(stderr).to eql(expected_output_with.call('u'))
+ expect(stdout).to eql(expected_output_with.call("f"))
+ expect(stderr).to eql(expected_output_with.call("u"))
end
end
end
- context 'with subprocess piping lots of data through stdin, stdout, and stderr' do
+ context "with subprocess piping lots of data through stdin, stdout, and stderr" do
let(:multiplier) { 20 }
let(:expected_output_with) { lambda { |chr| (chr * multiplier) + (chr * multiplier) } }
@@ -1389,78 +1390,78 @@ describe Mixlib::ShellOut do
let(:options) { { :input => input } }
- context 'when writing to STDOUT first' do
- let(:input) { [ 'f' * multiplier, 'u' * multiplier, 'f' * multiplier, 'u' * multiplier ].join(LINE_ENDING) }
+ context "when writing to STDOUT first" do
+ let(:input) { [ "f" * multiplier, "u" * multiplier, "f" * multiplier, "u" * multiplier ].join(LINE_ENDING) }
it "should not deadlock" do
- expect(stdout).to eql(expected_output_with.call('f'))
- expect(stderr).to eql(expected_output_with.call('u'))
+ expect(stdout).to eql(expected_output_with.call("f"))
+ expect(stderr).to eql(expected_output_with.call("u"))
end
end
- context 'when writing to STDERR first' do
- let(:input) { [ 'u' * multiplier, 'f' * multiplier, 'u' * multiplier, 'f' * multiplier ].join(LINE_ENDING) }
+ context "when writing to STDERR first" do
+ let(:input) { [ "u" * multiplier, "f" * multiplier, "u" * multiplier, "f" * multiplier ].join(LINE_ENDING) }
it "should not deadlock" do
- expect(stdout).to eql(expected_output_with.call('f'))
- expect(stderr).to eql(expected_output_with.call('u'))
+ expect(stdout).to eql(expected_output_with.call("f"))
+ expect(stderr).to eql(expected_output_with.call("u"))
end
end
end
- context 'when subprocess closes prematurely', :unix_only do
- context 'with input data' do
- let(:ruby_code) { 'bad_ruby { [ } ]' }
+ context "when subprocess closes prematurely", :unix_only do
+ context "with input data" do
+ let(:ruby_code) { "bad_ruby { [ } ]" }
let(:options) { { :input => input } }
- let(:input) { [ 'f' * 20_000, 'u' * 20_000, 'f' * 20_000, 'u' * 20_000 ].join(LINE_ENDING) }
+ let(:input) { [ "f" * 20_000, "u" * 20_000, "f" * 20_000, "u" * 20_000 ].join(LINE_ENDING) }
# Should the exception be handled?
- it 'should raise error' do
+ it "should raise error" do
expect { executed_cmd }.to raise_error(Errno::EPIPE)
end
end
end
- context 'when subprocess writes, pauses, then continues writing' do
+ context "when subprocess writes, pauses, then continues writing" do
subject { stdout }
let(:ruby_code) { %q{puts "before"; sleep 0.5; puts "after"} }
- it 'should not hang or lose output' do
+ it "should not hang or lose output" do
is_expected.to eql("before#{LINE_ENDING}after#{LINE_ENDING}")
end
end
- context 'when subprocess pauses before writing' do
+ context "when subprocess pauses before writing" do
subject { stdout }
let(:ruby_code) { 'sleep 0.5; puts "missed_the_bus"' }
- it 'should not hang or lose output' do
+ it "should not hang or lose output" do
is_expected.to eql("missed_the_bus#{LINE_ENDING}")
end
end
- context 'when subprocess pauses before reading from stdin' do
+ context "when subprocess pauses before reading from stdin" do
subject { stdout.to_i }
- let(:ruby_code) { 'sleep 0.5; print gets.size ' }
- let(:input) { 'c' * 1024 }
+ let(:ruby_code) { "sleep 0.5; print gets.size " }
+ let(:input) { "c" * 1024 }
let(:input_size) { input.size }
let(:options) { { :input => input } }
- it 'should not hang or lose output' do
+ it "should not hang or lose output" do
is_expected.to eql(input_size)
end
end
- context 'when execution fails' do
+ context "when execution fails" do
let(:cmd) { "fuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu" }
- context 'when running under Unix', :unix_only do
+ context "when running under Unix", :unix_only do
it "should recover the error message" do
expect { executed_cmd }.to raise_error(Errno::ENOENT)
end
- context 'with input' do
- let(:options) { {:input => input } }
+ context "with input" do
+ let(:options) { { :input => input } }
let(:input) { "Random input #{rand(1000000)}" }
it "should recover the error message" do
@@ -1469,16 +1470,16 @@ describe Mixlib::ShellOut do
end
end
- skip 'when running under Windows', :windows_only
+ skip "when running under Windows", :windows_only
end
- context 'without input data' do
- context 'with subprocess that expects stdin' do
+ context "without input data" do
+ context "with subprocess that expects stdin" do
let(:ruby_code) { %q{print STDIN.eof?.to_s} }
# If we don't have anything to send to the subprocess, we need to close
# stdin so that the subprocess won't wait for input.
- it 'should close stdin' do
+ it "should close stdin" do
expect(stdout).to eql("true")
end
end
@@ -1488,13 +1489,14 @@ describe Mixlib::ShellOut do
describe "#format_for_exception" do
let(:ruby_code) { %q{STDERR.puts "msg_in_stderr"; puts "msg_in_stdout"} }
let(:exception_output) { executed_cmd.format_for_exception.split("\n") }
- let(:expected_output) { [
+ let(:expected_output) do
+ [
"---- Begin output of #{cmd} ----",
%q{STDOUT: msg_in_stdout},
%q{STDERR: msg_in_stderr},
"---- End output of #{cmd} ----",
- "Ran #{cmd} returned 0"
- ] }
+ "Ran #{cmd} returned 0",
+ ] end
it "should format exception messages" do
exception_output.each_with_index do |output_line, i|
@@ -1505,7 +1507,7 @@ describe Mixlib::ShellOut do
end
context "when running under *nix", :requires_root, :unix_only do
- let(:cmd) { 'whoami' }
+ let(:cmd) { "whoami" }
let(:running_user) { shell_cmd.run_command.stdout.chomp }
context "when no user is set" do
@@ -1515,7 +1517,7 @@ describe Mixlib::ShellOut do
end
context "when user is specified" do
- let(:user) { 'nobody' }
+ let(:user) { "nobody" }
let(:options) { { :user => user } }
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index b84b302..e1d530d 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,15 +1,14 @@
$:.unshift File.expand_path("../../lib", __FILE__)
$:.unshift File.expand_path("../..", __FILE__)
-require 'mixlib/shellout'
-
-require 'tmpdir'
-require 'tempfile'
-require 'timeout'
+require "mixlib/shellout"
+require "tmpdir"
+require "tempfile"
+require "timeout"
# Load everything from spec/support
# Do not change the gsub.
-Dir["spec/support/**/*.rb"].map { |f| f.gsub(%r{.rb$}, '') }.each { |f| require f }
+Dir["spec/support/**/*.rb"].map { |f| f.gsub(%r{.rb$}, "") }.each { |f| require f }
RSpec.configure do |config|
config.mock_with :rspec