execute_shell 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +18 -0
- data/README +0 -0
- data/execute_shell.gemspec +26 -0
- data/gemfile +11 -0
- data/lib/execute_shell.rb +6 -0
- data/lib/execute_shell/execute_shell.rb +180 -0
- data/lib/execute_shell/script_env.rb +81 -0
- data/rakefile +121 -0
- data/test/execute_shell_test.rb +126 -0
- data/test/lib/test_case.rb +502 -0
- data/test/require.rb +13 -0
- metadata +150 -0
data/Gemfile.lock
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
Platform (0.4.0)
|
5
|
+
highline (1.6.1)
|
6
|
+
open4 (1.0.1)
|
7
|
+
rake (0.8.7)
|
8
|
+
win32-open3-19 (0.0.1)
|
9
|
+
|
10
|
+
PLATFORMS
|
11
|
+
ruby
|
12
|
+
|
13
|
+
DEPENDENCIES
|
14
|
+
Platform (~> 0.4.0)
|
15
|
+
highline (~> 1.6.1)
|
16
|
+
open4 (~> 1.0.1)
|
17
|
+
rake (= 0.8.7)
|
18
|
+
win32-open3-19 (~> 0.0.1)
|
data/README
ADDED
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
gem_spec = Gem::Specification.new do |s|
|
2
|
+
s.name = 'execute_shell'
|
3
|
+
s.version = '0.0.1'
|
4
|
+
|
5
|
+
s.summary = 'Executes shell commands.'
|
6
|
+
|
7
|
+
s.author = 'Travis Herrick'
|
8
|
+
s.email = 'tthetoad@gmail.com'
|
9
|
+
|
10
|
+
s.license = 'MIT'
|
11
|
+
|
12
|
+
s.extra_rdoc_files << 'README'
|
13
|
+
|
14
|
+
s.require_paths = ['lib']
|
15
|
+
s.files = Dir['lib/**/*.rb', '*']
|
16
|
+
s.test_files = Dir['test/**/*.rb']
|
17
|
+
|
18
|
+
s.add_dependency 'Platform', '~> 0.4.0'
|
19
|
+
s.add_dependency 'open4', '~> 1.0.1'
|
20
|
+
s.add_dependency 'win32-open3-19', '~> 0.0.1'
|
21
|
+
|
22
|
+
s.add_development_dependency 'rake', '0.8.7'
|
23
|
+
s.add_development_dependency 'highline', '~> 1.6.1'
|
24
|
+
|
25
|
+
s.has_rdoc = true
|
26
|
+
end
|
data/gemfile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem 'Platform', '~> 0.4.0', :group => [:rake, :test],
|
4
|
+
:require => 'platform'
|
5
|
+
gem 'open4', '~> 1.0.1', :group => [:rake, :test]
|
6
|
+
gem 'win32-open3-19', '~> 0.0.1', :group => [:rake, :test], :require => 'open3'
|
7
|
+
|
8
|
+
group :rake do
|
9
|
+
gem 'rake', '0.8.7'
|
10
|
+
gem 'highline', '~> 1.6.1', :require => 'highline/import'
|
11
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
# This file contains a module for returning output from console commands.
|
2
|
+
|
3
|
+
#--
|
4
|
+
################################################################################
|
5
|
+
# Copyright (C) 2011 Travis Herrick #
|
6
|
+
################################################################################
|
7
|
+
# #
|
8
|
+
# \v^V,^!v\^/ #
|
9
|
+
# ~% %~ #
|
10
|
+
# { _ _ } #
|
11
|
+
# ( * - ) #
|
12
|
+
# | / | #
|
13
|
+
# \ _, / #
|
14
|
+
# \__.__/ #
|
15
|
+
# #
|
16
|
+
################################################################################
|
17
|
+
# This program is free software: you can redistribute it #
|
18
|
+
# and/or modify it under the terms of the GNU General Public License #
|
19
|
+
# as published by the Free Software Foundation, #
|
20
|
+
# either version 3 of the License, or (at your option) any later version. #
|
21
|
+
# #
|
22
|
+
# Commercial licensing may be available for a fee under a different license. #
|
23
|
+
################################################################################
|
24
|
+
# This program is distributed in the hope that it will be useful, #
|
25
|
+
# but WITHOUT ANY WARRANTY; #
|
26
|
+
# without even the implied warranty of MERCHANTABILITY #
|
27
|
+
# or FITNESS FOR A PARTICULAR PURPOSE. #
|
28
|
+
# See the GNU General Public License for more details. #
|
29
|
+
# #
|
30
|
+
# You should have received a copy of the GNU General Public License #
|
31
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
32
|
+
################################################################################
|
33
|
+
#++
|
34
|
+
|
35
|
+
# Contains methods for returning output from console commands.
|
36
|
+
module ExecuteShell
|
37
|
+
|
38
|
+
# Returns output from a console command.
|
39
|
+
# ==== Input
|
40
|
+
# [command : String] The command to be run.
|
41
|
+
# [path : String : Dir.getwd] The path to use for the command.
|
42
|
+
# ==== Output
|
43
|
+
# [Boolean] Whether the shell execution was successful.
|
44
|
+
# [String]
|
45
|
+
def shell(command, path = Dir.getwd)
|
46
|
+
raise_not_implemented(__method__) unless
|
47
|
+
[:linux, :mingw].include?(Platform::IMPL)
|
48
|
+
|
49
|
+
out = ''
|
50
|
+
err = ''
|
51
|
+
success = nil
|
52
|
+
|
53
|
+
path ||= Dir.getwd
|
54
|
+
|
55
|
+
begin
|
56
|
+
STDOUT.puts command if ScriptEnv.development
|
57
|
+
|
58
|
+
block = case Platform::IMPL
|
59
|
+
when :mingw
|
60
|
+
lambda {
|
61
|
+
# Run the command and wait for it to execute.
|
62
|
+
result = Open3::popen3('cmd') do |std_in, std_out, std_err, thread|
|
63
|
+
# Set up the command.
|
64
|
+
std_in.puts command
|
65
|
+
|
66
|
+
# Run it.
|
67
|
+
std_in.close
|
68
|
+
|
69
|
+
# Get the output.
|
70
|
+
out = std_out.read.strip
|
71
|
+
err = std_err.read.strip
|
72
|
+
end
|
73
|
+
}
|
74
|
+
when :linux
|
75
|
+
lambda {
|
76
|
+
# Run the command and wait for it to execute.
|
77
|
+
result = Open4::popen4('bash') do |pid, std_in, std_out, std_err|
|
78
|
+
# Set up the command.
|
79
|
+
std_in.puts command
|
80
|
+
|
81
|
+
# Run it.
|
82
|
+
std_in.close
|
83
|
+
|
84
|
+
# Get the output.
|
85
|
+
out = std_out.read.strip
|
86
|
+
err = std_err.read.strip
|
87
|
+
end
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
wrap_success, wrap_out = wrap_path(path, block)
|
92
|
+
|
93
|
+
# Success is determined by lack of error text.
|
94
|
+
success = err.empty?
|
95
|
+
|
96
|
+
# Remove all the extra stuff that the cmd prompt adds.
|
97
|
+
if Platform::IMPL == :mingw
|
98
|
+
out.gsub!(/\n\n#{path.gsub(%r[/], '\\\\\\')}>\Z/, '')
|
99
|
+
|
100
|
+
# replace contains the command line prompt
|
101
|
+
# and the command up to the first space.
|
102
|
+
replace = path.gsub(%r[/], '\\\\\\')
|
103
|
+
replace += '>'
|
104
|
+
replace += command[0..(command.index(/ /) || 0) - 1]
|
105
|
+
|
106
|
+
# Remove the header portion of the text.
|
107
|
+
# This includes the Microsoft 'banner' text
|
108
|
+
# that consumes the first two lines.
|
109
|
+
out = out.gsub(/\A.+#{replace}.*?$/m, '').strip
|
110
|
+
end
|
111
|
+
|
112
|
+
# Set the error flag and notify the user if anything went wrong.
|
113
|
+
out = (out + "\n" + err).strip unless success
|
114
|
+
out += wrap_out.strip unless wrap_success
|
115
|
+
|
116
|
+
# Include the wrapper's success flag in the resulting success flag.
|
117
|
+
success = success && wrap_success
|
118
|
+
rescue Exception => exc
|
119
|
+
# Format exception messages.
|
120
|
+
success = false
|
121
|
+
out += format_error(exc)
|
122
|
+
end
|
123
|
+
|
124
|
+
return success, out
|
125
|
+
end
|
126
|
+
|
127
|
+
############################################################################
|
128
|
+
private
|
129
|
+
############################################################################
|
130
|
+
|
131
|
+
# Formats error messages.
|
132
|
+
# ==== Input
|
133
|
+
# [exception : Exception] The error that was raised.
|
134
|
+
# ==== Output
|
135
|
+
# [String] The error information in a readable format.
|
136
|
+
def format_error(exception)
|
137
|
+
error_format = '%s: %s%s'
|
138
|
+
error_format % [exception.class, exception.message,
|
139
|
+
ScriptEnv.development ? "\n#{exception.backtrace.join("\n")}" : '']
|
140
|
+
end
|
141
|
+
|
142
|
+
# Raises a NotImplementedError.
|
143
|
+
# ==== Input
|
144
|
+
# [method : String] The method that does not have
|
145
|
+
# an implementation for the current platform.
|
146
|
+
def raise_not_implemented(method)
|
147
|
+
raise NotImplementedError,
|
148
|
+
"#{method} " +
|
149
|
+
"has not been implemented for #{Platform::IMPL}."
|
150
|
+
end
|
151
|
+
|
152
|
+
# Runs a block of code by changing the path first.
|
153
|
+
# ==== Input
|
154
|
+
# [path : String] The path to change to prior to running the block.
|
155
|
+
# [block : Proc] The code block to execute.
|
156
|
+
# [*args : Array] Any other parameters
|
157
|
+
# that will be passed on to <tt>block</tt>.
|
158
|
+
# ==== Output
|
159
|
+
# [Boolean] Indicates whether the block was executed successfully.
|
160
|
+
# [String] Any error messages from trapped errors.
|
161
|
+
def wrap_path(path, block, *args)
|
162
|
+
path ||= File.expand_path(Dir.getwd)
|
163
|
+
original = File.expand_path(Dir.getwd)
|
164
|
+
out = nil
|
165
|
+
|
166
|
+
STDOUT.puts path if ScriptEnv.development
|
167
|
+
|
168
|
+
begin
|
169
|
+
Dir.chdir path unless path == original
|
170
|
+
block.call(*args)
|
171
|
+
rescue Exception => exc
|
172
|
+
# Format exception messages.
|
173
|
+
out = format_error(exc)
|
174
|
+
ensure
|
175
|
+
Dir.chdir original unless path == original
|
176
|
+
end
|
177
|
+
|
178
|
+
return out.nil?, out
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# This file contains a class to manage information about the environment.
|
2
|
+
|
3
|
+
#--
|
4
|
+
################################################################################
|
5
|
+
# Copyright (C) 2011 Travis Herrick #
|
6
|
+
################################################################################
|
7
|
+
# #
|
8
|
+
# \v^V,^!v\^/ #
|
9
|
+
# ~% %~ #
|
10
|
+
# { _ _ } #
|
11
|
+
# ( * - ) #
|
12
|
+
# | / | #
|
13
|
+
# \ _, / #
|
14
|
+
# \__.__/ #
|
15
|
+
# #
|
16
|
+
################################################################################
|
17
|
+
# This program is free software: you can redistribute it #
|
18
|
+
# and/or modify it under the terms of the GNU General Public License #
|
19
|
+
# as published by the Free Software Foundation, #
|
20
|
+
# either version 3 of the License, or (at your option) any later version. #
|
21
|
+
# #
|
22
|
+
# Commercial licensing may be available for a fee under a different license. #
|
23
|
+
################################################################################
|
24
|
+
# This program is distributed in the hope that it will be useful, #
|
25
|
+
# but WITHOUT ANY WARRANTY; #
|
26
|
+
# without even the implied warranty of MERCHANTABILITY #
|
27
|
+
# or FITNESS FOR A PARTICULAR PURPOSE. #
|
28
|
+
# See the GNU General Public License for more details. #
|
29
|
+
# #
|
30
|
+
# You should have received a copy of the GNU General Public License #
|
31
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
32
|
+
################################################################################
|
33
|
+
#++
|
34
|
+
|
35
|
+
# This class manages environment information.
|
36
|
+
class ScriptEnv
|
37
|
+
# Contains valid environments for the script.
|
38
|
+
STATES = {
|
39
|
+
:development => :development,
|
40
|
+
:test => :testing,
|
41
|
+
:production => :production,
|
42
|
+
}
|
43
|
+
|
44
|
+
# Indicates the current environment of the script.
|
45
|
+
@@env = nil
|
46
|
+
|
47
|
+
class << self
|
48
|
+
# Retrieves the current environment setting.
|
49
|
+
def env
|
50
|
+
if @@env.nil? && File.expand_path(Dir.getwd) ==
|
51
|
+
File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
52
|
+
return STATES[:development]
|
53
|
+
else
|
54
|
+
return STATES[@@env] || STATES[:production]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Black magic.
|
59
|
+
#
|
60
|
+
# Allows the getting and setting of the 'state' of the script.
|
61
|
+
# Only one environment can be active at a time.
|
62
|
+
# Setting one environment to true means the others are false.
|
63
|
+
# ==== Input
|
64
|
+
# [method : Symbol] The method that was called.
|
65
|
+
# [*args : Array] Any arguments that were passed in.
|
66
|
+
# [&block : Block] A block, if specified.
|
67
|
+
def method_missing(method, *args, &block)
|
68
|
+
if STATES.keys.include?(method.to_s.sub(/=$/, '').to_sym)
|
69
|
+
if method.to_s.match(/=$/) # Setter method.
|
70
|
+
value = args && args.shift || nil
|
71
|
+
@@env = method.to_s[0..-2].to_sym if value == true
|
72
|
+
else # ------------------- # Getter method.
|
73
|
+
states = STATES.select { |k, v| v == env }
|
74
|
+
return !states[method].nil?
|
75
|
+
end
|
76
|
+
else
|
77
|
+
super
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/rakefile
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
root_path = File.expand_path(File.dirname(__FILE__))
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.require :rake
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
require 'rake/clean'
|
7
|
+
require_relative 'lib/execute_shell'
|
8
|
+
|
9
|
+
include ExecuteShell
|
10
|
+
|
11
|
+
task :default => [:tests]
|
12
|
+
|
13
|
+
# Include any ruby files in the tasks folder.
|
14
|
+
task_files = Dir[
|
15
|
+
File.join(File.expand_path(File.dirname(__FILE__)), 'tasks', '*.rb')]
|
16
|
+
|
17
|
+
task_files.each do |rake_file|
|
18
|
+
require rake_file
|
19
|
+
end
|
20
|
+
|
21
|
+
# Add a task to run all tests.
|
22
|
+
Rake::TestTask.new('tests') do |task|
|
23
|
+
task.pattern = 'test/*_test.rb'
|
24
|
+
task.verbose = true
|
25
|
+
task.warning = true
|
26
|
+
end
|
27
|
+
Rake::Task[:tests].comment = 'Run all tests'
|
28
|
+
|
29
|
+
################################################################################
|
30
|
+
namespace :test do
|
31
|
+
################################################################################
|
32
|
+
file_list = Dir['test/*_test.rb']
|
33
|
+
|
34
|
+
# Add a distinct test task for each test file.
|
35
|
+
file_list.each do |item|
|
36
|
+
# Get the name to use for the task by removing '_test.rb' from the name.
|
37
|
+
task_name = File.basename(item, '.rb').gsub(/_test$/, '')
|
38
|
+
|
39
|
+
# Add each test.
|
40
|
+
Rake::TestTask.new(task_name) do |task|
|
41
|
+
task.pattern = item
|
42
|
+
task.verbose = true
|
43
|
+
task.warning = true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
################################################################################
|
47
|
+
end # :test
|
48
|
+
################################################################################
|
49
|
+
|
50
|
+
################################################################################
|
51
|
+
namespace :rdoc do
|
52
|
+
################################################################################
|
53
|
+
|
54
|
+
# Set the paths used by each of the rdoc options.
|
55
|
+
RDOC_FILES = {
|
56
|
+
:all => ['**/*.rb'],
|
57
|
+
:test => ['test/lib/**/*.rb'],
|
58
|
+
:app => [
|
59
|
+
'*.rb',
|
60
|
+
'lib/**/*.rb',
|
61
|
+
],
|
62
|
+
}
|
63
|
+
|
64
|
+
# Loop through the typs of rdoc files to generate an rdoc task for each one.
|
65
|
+
RDOC_FILES.keys.each do |rdoc_task|
|
66
|
+
Rake::RDocTask.new(
|
67
|
+
:rdoc => rdoc_task,
|
68
|
+
:clobber_rdoc => "#{rdoc_task}:clobber",
|
69
|
+
:rerdoc => "#{rdoc_task}:force") do |rdtask|
|
70
|
+
rdtask.rdoc_dir = "help/#{rdoc_task}"
|
71
|
+
rdtask.options << '--charset' << 'utf8'
|
72
|
+
rdtask.rdoc_files.include(RDOC_FILES[rdoc_task])
|
73
|
+
end
|
74
|
+
|
75
|
+
Rake::Task[rdoc_task].comment =
|
76
|
+
"Generate #{rdoc_task} RDoc documentation."
|
77
|
+
end
|
78
|
+
################################################################################
|
79
|
+
end # :rdoc
|
80
|
+
################################################################################
|
81
|
+
|
82
|
+
desc 'Search for a string in all files using a case insensitive search.'
|
83
|
+
task :grep, [:text] do |task, args|
|
84
|
+
# Set default search text to t-o-d-o.
|
85
|
+
# It is done this way to prevent coming up in the search itself.
|
86
|
+
args.with_defaults(:text => 't' + 'o' + 'd' + 'o')
|
87
|
+
|
88
|
+
# Use the sample color scheme, since it provides us with bold red via :error.
|
89
|
+
HighLine.color_scheme = HighLine::SampleColorScheme.new
|
90
|
+
COLOR = "<%%= color('%s', :error) %%>"
|
91
|
+
|
92
|
+
notification = "\nSearching for '%s':\n\n"
|
93
|
+
|
94
|
+
# Output the text that is being searched for.
|
95
|
+
case Platform::IMPL
|
96
|
+
when :linux
|
97
|
+
notification = notification % [COLOR % args[:text]]
|
98
|
+
when :mingw
|
99
|
+
notification = notification % args[:text]
|
100
|
+
else
|
101
|
+
raise_not_implemented('grep')
|
102
|
+
end
|
103
|
+
|
104
|
+
say notification
|
105
|
+
|
106
|
+
command = "grep #{args[:text]} * -ri"
|
107
|
+
success, output = shell(command)
|
108
|
+
|
109
|
+
# Send the results to the console.
|
110
|
+
case Platform::IMPL
|
111
|
+
when :linux
|
112
|
+
output = output.gsub(/(#{args[:text]})/i, COLOR % '\1')
|
113
|
+
when :mingw
|
114
|
+
else
|
115
|
+
raise_not_implemented('grep')
|
116
|
+
end
|
117
|
+
|
118
|
+
say output
|
119
|
+
end
|
120
|
+
|
121
|
+
CLOBBER.include('help')
|
@@ -0,0 +1,126 @@
|
|
1
|
+
#--
|
2
|
+
################################################################################
|
3
|
+
# Copyright (C) 2011 Travis Herrick #
|
4
|
+
################################################################################
|
5
|
+
# #
|
6
|
+
# \v^V,^!v\^/ #
|
7
|
+
# ~% %~ #
|
8
|
+
# { _ _ } #
|
9
|
+
# ( * - ) #
|
10
|
+
# | / | #
|
11
|
+
# \ _, / #
|
12
|
+
# \__.__/ #
|
13
|
+
# #
|
14
|
+
################################################################################
|
15
|
+
# This program is free software: you can redistribute it #
|
16
|
+
# and/or modify it under the terms of the GNU General Public License #
|
17
|
+
# as published by the Free Software Foundation, #
|
18
|
+
# either version 3 of the License, or (at your option) any later version. #
|
19
|
+
# #
|
20
|
+
# Commercial licensing may be available for a fee under a different license. #
|
21
|
+
################################################################################
|
22
|
+
# This program is distributed in the hope that it will be useful, #
|
23
|
+
# but WITHOUT ANY WARRANTY; #
|
24
|
+
# without even the implied warranty of MERCHANTABILITY #
|
25
|
+
# or FITNESS FOR A PARTICULAR PURPOSE. #
|
26
|
+
# See the GNU General Public License for more details. #
|
27
|
+
# #
|
28
|
+
# You should have received a copy of the GNU General Public License #
|
29
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
30
|
+
################################################################################
|
31
|
+
#++
|
32
|
+
|
33
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), 'require')
|
34
|
+
|
35
|
+
class ExecuteShellTest < Test::Unit::TestCase
|
36
|
+
def setup
|
37
|
+
@obj = Object.new
|
38
|
+
@obj.extend(@class)
|
39
|
+
|
40
|
+
@working_path = Dir.getwd
|
41
|
+
@home_path = File.expand_path(File.join('~', '..'))
|
42
|
+
@user = File.basename(File.expand_path('~'))
|
43
|
+
|
44
|
+
Dir.chdir @home_path
|
45
|
+
|
46
|
+
# Setting $stderr to STDERR does not work due to the way
|
47
|
+
# STDERR was being redirected (or something).
|
48
|
+
@stdout_inspect = $stdout.inspect
|
49
|
+
@stderr_inspect = $stderr.inspect
|
50
|
+
end
|
51
|
+
|
52
|
+
def teardown
|
53
|
+
Dir.chdir @working_path
|
54
|
+
assert_equal(@stdout_inspect, $stdout.inspect)
|
55
|
+
assert_equal(@stderr_inspect, $stderr.inspect)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_stdout
|
59
|
+
command = nil
|
60
|
+
|
61
|
+
case Platform::IMPL
|
62
|
+
when :linux
|
63
|
+
command = "ls #{@home_path}"
|
64
|
+
when :mingw
|
65
|
+
command = "dir #{convert_to_backslash(@home_path)}"
|
66
|
+
else
|
67
|
+
raise_not_implemented
|
68
|
+
end
|
69
|
+
|
70
|
+
success, output = @obj.shell(command)
|
71
|
+
|
72
|
+
assert output.index(@user),
|
73
|
+
"'#{command}' does not appear to include " +
|
74
|
+
"the current user's folder (#{@user})."
|
75
|
+
assert_true success, "#{command} was not successful"
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_stderr
|
79
|
+
command = nil
|
80
|
+
result = nil
|
81
|
+
|
82
|
+
folder = 'giggidygiggidy'
|
83
|
+
|
84
|
+
test_path = File.join(@home_path, folder)
|
85
|
+
|
86
|
+
case Platform::IMPL
|
87
|
+
when :linux
|
88
|
+
command = "ls #{test_path}"
|
89
|
+
result = "ls: cannot access #{test_path}: No such file or directory"
|
90
|
+
when :mingw
|
91
|
+
command = "dir #{convert_to_backslash(test_path)}"
|
92
|
+
result = 'File Not Found'
|
93
|
+
else
|
94
|
+
raise_not_implemented
|
95
|
+
end
|
96
|
+
|
97
|
+
success, output = @obj.shell(command)
|
98
|
+
|
99
|
+
assert_equal result, output if Platform::IMPL == :linux
|
100
|
+
|
101
|
+
assert output.index(result)
|
102
|
+
assert_false success
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_grep
|
106
|
+
Dir.chdir @working_path
|
107
|
+
command = 'grep jabberwocky' + 'riseagain * -ri'
|
108
|
+
result = nil
|
109
|
+
|
110
|
+
assert_equal [true, ''], @obj.shell(command)
|
111
|
+
end
|
112
|
+
|
113
|
+
############################################################################
|
114
|
+
private
|
115
|
+
############################################################################
|
116
|
+
|
117
|
+
def convert_to_backslash(text)
|
118
|
+
text.gsub(%r[/], "\\")
|
119
|
+
end
|
120
|
+
|
121
|
+
def raise_not_implemented(method)
|
122
|
+
raise NotImplementedError,
|
123
|
+
"#{method} " +
|
124
|
+
"has not been implemented for #{Platform::IMPL}."
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,502 @@
|
|
1
|
+
# This file contains a monkey patch of Test::Unit::TestCase.
|
2
|
+
|
3
|
+
#--
|
4
|
+
################################################################################
|
5
|
+
# Copyright (C) 2011 Travis Herrick #
|
6
|
+
################################################################################
|
7
|
+
# #
|
8
|
+
# \v^V,^!v\^/ #
|
9
|
+
# ~% %~ #
|
10
|
+
# { _ _ } #
|
11
|
+
# ( * - ) #
|
12
|
+
# | / | #
|
13
|
+
# \ _, / #
|
14
|
+
# \__.__/ #
|
15
|
+
# #
|
16
|
+
################################################################################
|
17
|
+
# This program is free software: you can redistribute it #
|
18
|
+
# and/or modify it under the terms of the GNU General Public License #
|
19
|
+
# as published by the Free Software Foundation, #
|
20
|
+
# either version 3 of the License, or (at your option) any later version. #
|
21
|
+
# #
|
22
|
+
# Commercial licensing may be available for a fee under a different license. #
|
23
|
+
################################################################################
|
24
|
+
# This program is distributed in the hope that it will be useful, #
|
25
|
+
# but WITHOUT ANY WARRANTY; #
|
26
|
+
# without even the implied warranty of MERCHANTABILITY #
|
27
|
+
# or FITNESS FOR A PARTICULAR PURPOSE. #
|
28
|
+
# See the GNU General Public License for more details. #
|
29
|
+
# #
|
30
|
+
# You should have received a copy of the GNU General Public License #
|
31
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
32
|
+
################################################################################
|
33
|
+
#++
|
34
|
+
|
35
|
+
# Monkey patch Test::Unit::TestCase to make it do cool stuff.
|
36
|
+
Test::Unit::TestCase.class_eval do
|
37
|
+
# Since this is in a class_eval, instance methods need to be wrapped up
|
38
|
+
# in class_variable_set or ruby will throw warnings.
|
39
|
+
|
40
|
+
# Indicates whether the class has already been initialized.
|
41
|
+
# This combined with @@class_name prevents duplicate patching.
|
42
|
+
class_variable_set(:@@initialized, false)
|
43
|
+
|
44
|
+
# Keeps track of the class that has most recently been initialized.
|
45
|
+
# This combined with @@initialized prevents duplicate patching.
|
46
|
+
class_variable_set(:@@class_name, '')
|
47
|
+
|
48
|
+
# Initializes the class
|
49
|
+
# and exposes private methods and variables of the class that is being tested.
|
50
|
+
def initialize(*args)
|
51
|
+
# Call initialize on the superclass.
|
52
|
+
super
|
53
|
+
|
54
|
+
@obj = nil
|
55
|
+
|
56
|
+
reset_io
|
57
|
+
reset_trace
|
58
|
+
|
59
|
+
# This block ensures that tests still work if there is not a class that
|
60
|
+
# corresponds with the test file/class.
|
61
|
+
@class = nil
|
62
|
+
begin
|
63
|
+
# Get the class that is being tested.
|
64
|
+
# Assume that the name of the class is found by removing 'Test'
|
65
|
+
# from the test class.
|
66
|
+
@class = Kernel.const_get(self.class.name.gsub(/Test$/, ''))
|
67
|
+
@@initialized = ((@class.name == @@class_name) && @@initialized)
|
68
|
+
@@class_name = @class.name
|
69
|
+
rescue
|
70
|
+
@@initialized = true
|
71
|
+
@@class_name = ''
|
72
|
+
end
|
73
|
+
|
74
|
+
# Only patch if this code has not yet been run.
|
75
|
+
if !@@initialized and @class.class.name != 'Module'
|
76
|
+
set_instance_method_wrappers
|
77
|
+
|
78
|
+
# Expose private class methods.
|
79
|
+
# We will only expose the methods we are responsible for creating.
|
80
|
+
# (i.e. subtracting the superclass's private methods)
|
81
|
+
expose_private_methods(:class,
|
82
|
+
@class.private_methods -
|
83
|
+
@class.superclass.private_methods)
|
84
|
+
|
85
|
+
# Expose private instance methods.
|
86
|
+
# We will only expose the methods we are responsible for creating.
|
87
|
+
# (i.e. subtracting the superclass's private methods)
|
88
|
+
expose_private_methods(:instance,
|
89
|
+
@class.private_instance_methods -
|
90
|
+
@class.superclass.private_instance_methods)
|
91
|
+
|
92
|
+
# Expose variables.
|
93
|
+
# Requires that variables are assigned to in the constructor.
|
94
|
+
wrap_output {
|
95
|
+
expose_variables(@class.class_variables +
|
96
|
+
@class.new([]).instance_variables)
|
97
|
+
}
|
98
|
+
|
99
|
+
# Indicate that this code has been run.
|
100
|
+
@@initialized = true
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Sets up functionality for all tests.
|
105
|
+
#
|
106
|
+
# Tracing is set up here so that it is only running during tests.
|
107
|
+
#
|
108
|
+
# If you want to disable tracing, simply override the setup method
|
109
|
+
# without calling super. (It would be good form to also override teardown).
|
110
|
+
def setup
|
111
|
+
set_trace_func proc { |event, file, line, id, binding, class_name|
|
112
|
+
if class_name == @class and
|
113
|
+
@stack_trace.last != {:class => class_name.name, :method => id}
|
114
|
+
@stack_trace << {
|
115
|
+
:class => class_name.name,
|
116
|
+
:method => id,
|
117
|
+
}
|
118
|
+
end
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
# Clean up after each test.
|
123
|
+
#
|
124
|
+
# If you disable tracing, it would be good form to override this method
|
125
|
+
# as well without calling super.
|
126
|
+
def teardown
|
127
|
+
set_trace_func nil
|
128
|
+
end
|
129
|
+
|
130
|
+
############################################################################
|
131
|
+
private
|
132
|
+
############################################################################
|
133
|
+
|
134
|
+
############################################################################
|
135
|
+
# Monkey patching methods for the class being tested.
|
136
|
+
############################################################################
|
137
|
+
|
138
|
+
# Monkey patch the class's initializer to enable tracing
|
139
|
+
# with parameters and results.
|
140
|
+
def set_initializer
|
141
|
+
@class.class_eval do
|
142
|
+
attr_accessor :trace
|
143
|
+
|
144
|
+
alias :test_case_initialize :initialize
|
145
|
+
def initialize(*args)
|
146
|
+
@trace = []
|
147
|
+
result = test_case_initialize(*args)
|
148
|
+
return result
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Loop through the instance methods, calling set_instance_methods for each.
|
154
|
+
def set_instance_method_wrappers
|
155
|
+
[
|
156
|
+
:public_instance_methods,
|
157
|
+
:protected_instance_methods,
|
158
|
+
:private_instance_methods
|
159
|
+
].each do |method_id|
|
160
|
+
|
161
|
+
scope = method_id.to_s.gsub(/_.*/, '')
|
162
|
+
|
163
|
+
set_instance_methods(@class.send(method_id) -
|
164
|
+
@class.superclass.send(method_id), scope)
|
165
|
+
end
|
166
|
+
|
167
|
+
# If this is not at the end, the loop will attempt to do it's thing
|
168
|
+
# with the constructor created in this method, which is not necessary.
|
169
|
+
set_initializer
|
170
|
+
end
|
171
|
+
|
172
|
+
# Loop through the list of methods that are passed in,
|
173
|
+
# creating a wrapper method that enables tracing.
|
174
|
+
#
|
175
|
+
# Tracing data includes method name, parameters, and result.
|
176
|
+
# ==== Input
|
177
|
+
# [method_list : Array] A list of methods that will have wrapping functions
|
178
|
+
# created to enable tracing.
|
179
|
+
# [scope : String] The scope of the original function.
|
180
|
+
def set_instance_methods(method_list, scope)
|
181
|
+
method_list.each do |method_id|
|
182
|
+
# Setters and methods that accept blocks do not appear to work.
|
183
|
+
next if method_id =~ /=/ or method_id =~ /wrap_output/
|
184
|
+
|
185
|
+
# Build the method.
|
186
|
+
new_method = <<-DOC
|
187
|
+
alias :test_case_#{method_id} :#{method_id}
|
188
|
+
def #{method_id}(*args)
|
189
|
+
result = test_case_#{method_id}(*args)
|
190
|
+
@trace << {
|
191
|
+
:method => '#{method_id}',
|
192
|
+
:args => args,
|
193
|
+
:result => result
|
194
|
+
}
|
195
|
+
return result
|
196
|
+
end
|
197
|
+
#{scope} :#{method_id}
|
198
|
+
DOC
|
199
|
+
|
200
|
+
# Add the method to the class.
|
201
|
+
@class.class_eval do
|
202
|
+
eval(new_method)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
# Expose the private methods that are passed in. New methods will be created
|
208
|
+
# with the old method name followed by '_public_test'. If the original
|
209
|
+
# method contained a '?', it will be removed in the new method.
|
210
|
+
# ==== Input
|
211
|
+
# [type : Symbol] Indicates whether to handle instance or class methods.
|
212
|
+
#
|
213
|
+
# Only :class and :instance are supported.
|
214
|
+
# [methods : Array] An array of the methods to expose.
|
215
|
+
def expose_private_methods(type, methods)
|
216
|
+
# Get the text that the method should be wrapped in.
|
217
|
+
method_wrapper = wrapper(type)
|
218
|
+
|
219
|
+
# Loop through the methods.
|
220
|
+
methods.each do |method|
|
221
|
+
# Remove ?s.
|
222
|
+
new_method = method.to_s.gsub(/\?/, '')
|
223
|
+
|
224
|
+
# This is the new method.
|
225
|
+
new_method = <<-DOC
|
226
|
+
def #{new_method}_public_test(*args)
|
227
|
+
#{method}(*args)
|
228
|
+
end
|
229
|
+
DOC
|
230
|
+
|
231
|
+
# Add the wrapping text.
|
232
|
+
new_method = method_wrapper % [new_method]
|
233
|
+
|
234
|
+
# Add the method to the class.
|
235
|
+
@class.class_eval do
|
236
|
+
eval(new_method)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
# Expose the variables.
|
242
|
+
#
|
243
|
+
# New methods will be created (a getter and a setter) for each variable.
|
244
|
+
#
|
245
|
+
# Regardless of the type of variable, these methods are only available
|
246
|
+
# via an instance.
|
247
|
+
# ==== Input
|
248
|
+
# [variables : Array] An array of variables to expose.
|
249
|
+
def expose_variables(variables)
|
250
|
+
# Get the text that the methods should be wrapped in.
|
251
|
+
var_wrapper = wrapper(:instance)
|
252
|
+
|
253
|
+
# Loop through the variables
|
254
|
+
variables.each do |var|
|
255
|
+
# Remove any @s.
|
256
|
+
new_method = var.to_s.gsub(/@/, '')
|
257
|
+
|
258
|
+
# These are the new getter and setters.
|
259
|
+
new_method = <<-DOC
|
260
|
+
def #{new_method}_variable_method
|
261
|
+
#{var}
|
262
|
+
end
|
263
|
+
|
264
|
+
def #{new_method}_variable_method=(value)
|
265
|
+
#{var} = value
|
266
|
+
end
|
267
|
+
DOC
|
268
|
+
|
269
|
+
# Add the wrapping text.
|
270
|
+
new_method = var_wrapper % [new_method]
|
271
|
+
|
272
|
+
# Add the methods to the class.
|
273
|
+
@class.class_eval do
|
274
|
+
eval(new_method)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
# Returns the wrapping text for the specified type of method.
|
280
|
+
# ==== Input
|
281
|
+
# [type : Symbol] Indicates whether to handle instance or class methods.
|
282
|
+
#
|
283
|
+
# Only :class & :instance are supported.
|
284
|
+
# ==== Output
|
285
|
+
# [String] The text that the specified type of method should be wrapped in.
|
286
|
+
def wrapper(type)
|
287
|
+
case type
|
288
|
+
when :class then 'class << self;%s;end'
|
289
|
+
when :instance then '%s'
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
############################################################################
|
294
|
+
# I/O support methods.
|
295
|
+
############################################################################
|
296
|
+
|
297
|
+
# Return the actual output to stdout and stderr.
|
298
|
+
# ==== Output
|
299
|
+
# [Array] Two element array of strings.
|
300
|
+
#
|
301
|
+
# The first element is from stdout.
|
302
|
+
#
|
303
|
+
# The second element is from stderr.
|
304
|
+
def real_finis
|
305
|
+
return out, err
|
306
|
+
end
|
307
|
+
|
308
|
+
# Wrap a block to capture the output to stdout and stderr.
|
309
|
+
# ==== Input
|
310
|
+
# [&block : Block] The block of code that will have stdout and stderr trapped.
|
311
|
+
def wrap_output(&block)
|
312
|
+
begin
|
313
|
+
$stdout = @out
|
314
|
+
$stderr = @err
|
315
|
+
yield
|
316
|
+
ensure
|
317
|
+
$stdout = STDOUT
|
318
|
+
$stderr = STDERR
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
# Returns the output from stdout as a string.
|
323
|
+
# ==== Output
|
324
|
+
# [String] The output from stdout.
|
325
|
+
#
|
326
|
+
# All trailing line feeds are removed.
|
327
|
+
def out
|
328
|
+
@out.respond_to?(:string) ? @out.string.gsub(/\n*\z/, '') : ''
|
329
|
+
end
|
330
|
+
|
331
|
+
# Returns the output from stderr as a string.
|
332
|
+
# ==== Output
|
333
|
+
# [String] The output from stderr.
|
334
|
+
#
|
335
|
+
# All trailing line feeds are removed.
|
336
|
+
def err
|
337
|
+
@err.respond_to?(:string) ? @err.string.gsub(/\n*\z/, '') : ''
|
338
|
+
end
|
339
|
+
|
340
|
+
# Reset the stdout and stderr stream variables.
|
341
|
+
def reset_io
|
342
|
+
@out = StringIO.new
|
343
|
+
@err = StringIO.new
|
344
|
+
end
|
345
|
+
|
346
|
+
############################################################################
|
347
|
+
# Support methods.
|
348
|
+
############################################################################
|
349
|
+
|
350
|
+
# Indicates whether the specified method has been called on a given class.
|
351
|
+
# ==== Input
|
352
|
+
# [method_name : String] The name of the method.
|
353
|
+
#
|
354
|
+
# This value may be a string or a symbol.
|
355
|
+
# [class_name : String : @class.name] The name of the class that the method
|
356
|
+
# should have been invoked from.
|
357
|
+
def method_called?(method_name, class_name = @class.name)
|
358
|
+
!@stack_trace.index(
|
359
|
+
{:method => method_name.to_sym, :class => class_name}).nil?
|
360
|
+
end
|
361
|
+
|
362
|
+
# Resets the trace arrays.
|
363
|
+
#
|
364
|
+
# This is intended for use in cases where code may be called multiple
|
365
|
+
# times in a single test.
|
366
|
+
def reset_trace
|
367
|
+
@stack_trace = []
|
368
|
+
@obj.trace = [] if @obj.respond_to?(:trace=)
|
369
|
+
end
|
370
|
+
|
371
|
+
# Shows the trace history as it stands, if the object supports it.
|
372
|
+
def show_trace
|
373
|
+
return unless defined? @obj
|
374
|
+
puts @obj.trace.join("\n" + '-' * 80 + "\n") if @obj.respond_to?(:trace)
|
375
|
+
end
|
376
|
+
|
377
|
+
############################################################################
|
378
|
+
# Assertions.
|
379
|
+
############################################################################
|
380
|
+
|
381
|
+
# Asserts that a value is equal to false.
|
382
|
+
# ==== Input
|
383
|
+
# [value : Any] The value to check for equality against false.
|
384
|
+
# [message : String : nil] The message to display if the value is not false.
|
385
|
+
def assert_false(value, message = nil)
|
386
|
+
assert_equal false, value, message
|
387
|
+
end
|
388
|
+
|
389
|
+
# Asserts that a value is equal to true.
|
390
|
+
# ==== Input
|
391
|
+
# [value : Any] The value to check for equality against true.
|
392
|
+
# [message : String : nil] The message to display if the value is not true.
|
393
|
+
def assert_true(value, message = nil)
|
394
|
+
assert_equal true, value, message
|
395
|
+
end
|
396
|
+
|
397
|
+
# Asserts that the negation of a value is true.
|
398
|
+
# ==== Input
|
399
|
+
# [value : Any] The value which will be negated and then asserted.
|
400
|
+
# [message : String : nil] The message to display if the assertion fails.
|
401
|
+
def assert_not(value, message = nil)
|
402
|
+
assert !value, message
|
403
|
+
end
|
404
|
+
|
405
|
+
# Assert that an array has a specified number of elements.
|
406
|
+
# ==== Input
|
407
|
+
# [array : Array] The array that will have it's length checked.
|
408
|
+
# [length : Fixnum] The length that the array should be.
|
409
|
+
# [message : String : nil] The message to display if the assertion fails.
|
410
|
+
def assert_array_count(array, length, message = nil)
|
411
|
+
if message.nil?
|
412
|
+
message = "#{array} has #{array.length} item(s), " +
|
413
|
+
"but was expected to have #{length}."
|
414
|
+
end
|
415
|
+
|
416
|
+
assert array.length == length, message
|
417
|
+
end
|
418
|
+
|
419
|
+
############################################################################
|
420
|
+
# Assertions - Stack trace.
|
421
|
+
############################################################################
|
422
|
+
|
423
|
+
# Asserts that a method was called on a class.
|
424
|
+
# ==== Input
|
425
|
+
# [method_name : String] The name of the method to check for.
|
426
|
+
# [class_name : String : @class.name] The name of the class
|
427
|
+
# on which <tt>method_name</tt>
|
428
|
+
# should have been invoked.
|
429
|
+
def assert_method(method_name, class_name = @class.name)
|
430
|
+
assert method_called?(method_name.to_sym, class_name),
|
431
|
+
"#{class_name}.#{method_name} has not been called."
|
432
|
+
end
|
433
|
+
|
434
|
+
# Asserts that a method was not called on a class.
|
435
|
+
# ==== Input
|
436
|
+
# [method_name : String] The name of the method to check for.
|
437
|
+
# [class_name : String : @class.name] The name of the class
|
438
|
+
# on which <tt>method_name</tt>
|
439
|
+
# should not have been invoked.
|
440
|
+
def assert_not_method(method_name, class_name = @class.name)
|
441
|
+
assert !method_called?(method_name.to_sym, class_name),
|
442
|
+
"#{class_name}.#{method_name} should not be called."
|
443
|
+
end
|
444
|
+
|
445
|
+
# Asserts that a method was called with the specified parameters.
|
446
|
+
# ==== Input
|
447
|
+
# [method_name : String] The name of the method to check.
|
448
|
+
# [*args : Array] The parameters that were passed in to the method.
|
449
|
+
def assert_trace_args(method_name, *args)
|
450
|
+
match = false
|
451
|
+
|
452
|
+
list = []
|
453
|
+
|
454
|
+
# Loop through the stack trace to see if the method was called
|
455
|
+
# with the specified arguments.
|
456
|
+
@obj.trace.each do |trace|
|
457
|
+
if trace[:method] == method_name and trace[:args] == args
|
458
|
+
match = true
|
459
|
+
break
|
460
|
+
elsif trace[:method] == method_name
|
461
|
+
list << trace[:args]
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
assert match,
|
466
|
+
"#{method_name} was not called with the following parameters:\n" +
|
467
|
+
"#{args.join("\n" + '-' * 80 + "\n")}\n" +
|
468
|
+
'*' * 80 + "\n" +
|
469
|
+
"#{method_name} was recorded as follows:\n" +
|
470
|
+
"#{list.join("\n" + '-' * 80 + "\n")}"
|
471
|
+
end
|
472
|
+
|
473
|
+
# Asserts that a method was called with the specified parameters
|
474
|
+
# and returned the specified result.
|
475
|
+
# ==== Input
|
476
|
+
# [method_name : String] The name of the method to check.
|
477
|
+
# [result : Any] The expected result of the method call.
|
478
|
+
# [*args : Array] The parameters that were passed in to the method.
|
479
|
+
def assert_trace_info(method_name, result, *args)
|
480
|
+
match = (@obj.trace.index(
|
481
|
+
{:methd => method_name, :args => args, :result => result}))
|
482
|
+
|
483
|
+
list = []
|
484
|
+
|
485
|
+
# Only get a list of possible results if a match was not found.
|
486
|
+
unless match
|
487
|
+
@obj.trace.each do |trace|
|
488
|
+
if trace[:method] == method_name
|
489
|
+
list << {:args => trace[:args], :result => trace[:result]}
|
490
|
+
end
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
assert match,
|
495
|
+
"#{method_name} was not called with the following parameters:\n" +
|
496
|
+
"#{args}\n" +
|
497
|
+
"or did not return the following result:\n" +
|
498
|
+
"#{result}\n" +
|
499
|
+
"#{method_name} was recorded as follows:\n" +
|
500
|
+
"#{list.join("\n" + '-' * 80 + "\n")}"
|
501
|
+
end
|
502
|
+
end
|
data/test/require.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
root_path = File.join(File.dirname(File.expand_path(__FILE__)), '..')
|
2
|
+
root_path = File.expand_path(root_path)
|
3
|
+
|
4
|
+
Bundler.require :test
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
|
8
|
+
require_relative '../lib/execute_shell'
|
9
|
+
|
10
|
+
file_list = Dir[File.join(root_path, 'test', 'lib', '*.rb')]
|
11
|
+
file_list.each do |file|
|
12
|
+
require file
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: execute_shell
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Travis Herrick
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-07-28 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: Platform
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
- 4
|
31
|
+
- 0
|
32
|
+
version: 0.4.0
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: open4
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 1
|
45
|
+
- 0
|
46
|
+
- 1
|
47
|
+
version: 1.0.1
|
48
|
+
type: :runtime
|
49
|
+
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: win32-open3-19
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ~>
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
- 0
|
61
|
+
- 1
|
62
|
+
version: 0.0.1
|
63
|
+
type: :runtime
|
64
|
+
version_requirements: *id003
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: rake
|
67
|
+
prerelease: false
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - "="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
- 8
|
76
|
+
- 7
|
77
|
+
version: 0.8.7
|
78
|
+
type: :development
|
79
|
+
version_requirements: *id004
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: highline
|
82
|
+
prerelease: false
|
83
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ~>
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
segments:
|
89
|
+
- 1
|
90
|
+
- 6
|
91
|
+
- 1
|
92
|
+
version: 1.6.1
|
93
|
+
type: :development
|
94
|
+
version_requirements: *id005
|
95
|
+
description:
|
96
|
+
email: tthetoad@gmail.com
|
97
|
+
executables: []
|
98
|
+
|
99
|
+
extensions: []
|
100
|
+
|
101
|
+
extra_rdoc_files:
|
102
|
+
- README
|
103
|
+
files:
|
104
|
+
- lib/execute_shell/execute_shell.rb
|
105
|
+
- lib/execute_shell/script_env.rb
|
106
|
+
- lib/execute_shell.rb
|
107
|
+
- Gemfile.lock
|
108
|
+
- README
|
109
|
+
- gemfile
|
110
|
+
- rakefile
|
111
|
+
- execute_shell.gemspec
|
112
|
+
- test/require.rb
|
113
|
+
- test/lib/test_case.rb
|
114
|
+
- test/execute_shell_test.rb
|
115
|
+
has_rdoc: true
|
116
|
+
homepage:
|
117
|
+
licenses:
|
118
|
+
- MIT
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
segments:
|
130
|
+
- 0
|
131
|
+
version: "0"
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
none: false
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
segments:
|
138
|
+
- 0
|
139
|
+
version: "0"
|
140
|
+
requirements: []
|
141
|
+
|
142
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 1.3.7
|
144
|
+
signing_key:
|
145
|
+
specification_version: 3
|
146
|
+
summary: Executes shell commands.
|
147
|
+
test_files:
|
148
|
+
- test/require.rb
|
149
|
+
- test/lib/test_case.rb
|
150
|
+
- test/execute_shell_test.rb
|