sheller 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/sheller.rb +65 -0
- data/test/fixtures/cities.txt +4 -0
- data/test/fixtures/stderr_frog +3 -0
- data/test/fixtures/stdout_stderr_puma +4 -0
- data/test/fixtures/stdout_turtle +3 -0
- data/test/sheller_test.rb +92 -0
- data/test/test_helper.rb +6 -0
- metadata +11 -5
data/lib/sheller.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'POpen4'
|
2
|
+
|
3
|
+
module Sheller
|
4
|
+
VERSION = '0.0.3'
|
5
|
+
|
6
|
+
INESCAPABLE = {}
|
7
|
+
|
8
|
+
{
|
9
|
+
'STDOUT_TO_FILE' => :>,
|
10
|
+
'STDOUT_TO_PIPE' => :|,
|
11
|
+
'STDOUT_APPEND_TO_FILE' => :>>,
|
12
|
+
'STDOUT_TO_STDERR' => :'1>&2',
|
13
|
+
'STDERR_TO_FILE' => :'2>',
|
14
|
+
'STDERR_TO_STDOUT' => :'2>&1',
|
15
|
+
'STDERR_APPEND_TO_FILE' => :'2>>',
|
16
|
+
'STDOUT_AND_STDERR_TO_FILE' => :'&>',
|
17
|
+
'STDIN_FROM_FILE' => :<
|
18
|
+
}.each do |c, s|
|
19
|
+
const_set(c, s)
|
20
|
+
INESCAPABLE[s] = s.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
SHELL_SAFE = /\A[0-9A-Za-z+,.\/:=@_-]+\z/
|
24
|
+
ARG_SCAN = /('+)|[^']+/
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def command(*args)
|
28
|
+
args.map { |a| arg_to_cmd(a) }.join(' ')
|
29
|
+
end
|
30
|
+
|
31
|
+
def execute(*args)
|
32
|
+
stdout, stderr = nil
|
33
|
+
status = POpen4.popen4(command(*args)) do |_stdout, _stderr, _stdin, _pid|
|
34
|
+
stdout = _stdout.read
|
35
|
+
stderr = _stderr.read
|
36
|
+
end
|
37
|
+
ShellerResult.new(stdout, stderr, status)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
def arg_to_cmd(arg)
|
42
|
+
if INESCAPABLE[arg]
|
43
|
+
arg.to_s
|
44
|
+
elsif arg.empty? || SHELL_SAFE =~ arg
|
45
|
+
"'%s'" % arg
|
46
|
+
else
|
47
|
+
result = ''
|
48
|
+
arg.scan(ARG_SCAN) do
|
49
|
+
result << ($1 ? "\\'" * $1.length : "'#{$&}'")
|
50
|
+
end
|
51
|
+
result
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class ShellerResult
|
57
|
+
attr_reader 'stdout', 'stderr', 'exit_status'
|
58
|
+
|
59
|
+
def initialize(stdout, stderr, exit_status)
|
60
|
+
@stdout = stdout
|
61
|
+
@stderr = stderr
|
62
|
+
@exit_status = exit_status
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class ShellerTest < Test::Unit::TestCase
|
4
|
+
TEST_DIR = File.expand_path(File.join(File.dirname(__FILE__)))
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@original_dir = Dir.pwd
|
8
|
+
Dir.chdir(TEST_DIR)
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
Dir.chdir(TEST_DIR) do
|
13
|
+
FileUtils.rm('output.txt', :force => true)
|
14
|
+
end
|
15
|
+
Dir.chdir(@original_dir)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_command_no_arguments
|
19
|
+
assert_equal "turtle\n", Sheller.execute('./fixtures/stdout_turtle').stdout
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_command_one_argument
|
23
|
+
assert_equal "frog\n", Sheller.execute('echo', 'frog').stdout
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_command_one_argument_with_quotes
|
27
|
+
assert_equal "\"toad\"\n", Sheller.execute('echo', '"toad"').stdout
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_command_one_argument_with_redirect
|
31
|
+
assert_equal "toad > newt\n", Sheller.execute('echo', 'toad > newt').stdout
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_echo_to_stderr
|
35
|
+
assert_equal "frog\n", Sheller.execute('./fixtures/stderr_frog').stderr
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_successful_exit_status_code
|
39
|
+
assert_equal 0, Sheller.execute('echo').exit_status
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_unsuccessful_exit_status_code
|
43
|
+
assert_not_equal 0, Sheller.execute('false').exit_status
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_stdout_to_file
|
47
|
+
result = Sheller.execute('./fixtures/stdout_stderr_puma', Sheller::STDOUT_TO_FILE, 'output.txt')
|
48
|
+
assert_equal "puma1\n", File.read('output.txt')
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_stdout_to_pipe
|
52
|
+
result = Sheller.execute('./fixtures/stdout_stderr_puma', Sheller::STDOUT_TO_PIPE, 'grep', 'puma')
|
53
|
+
assert_equal "puma1\n", result.stdout
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_stdout_append_to_file
|
57
|
+
File.open('output.txt', 'w') { |f| f.puts "jungle" }
|
58
|
+
Sheller.execute('./fixtures/stdout_stderr_puma', Sheller::STDOUT_APPEND_TO_FILE, 'output.txt')
|
59
|
+
assert_equal "jungle\npuma1\n", File.read('output.txt')
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_stdout_to_stderr
|
63
|
+
result = Sheller.execute('./fixtures/stdout_stderr_puma', Sheller::STDOUT_TO_STDERR)
|
64
|
+
assert_equal "puma2\npuma1\n", result.stderr
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_stderr_to_file
|
68
|
+
Sheller.execute('./fixtures/stdout_stderr_puma', Sheller::STDERR_TO_FILE, 'output.txt')
|
69
|
+
assert_equal "puma2\n", File.read('output.txt')
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_stderr_to_stdout
|
73
|
+
result = Sheller.execute('./fixtures/stdout_stderr_puma', Sheller::STDERR_TO_STDOUT)
|
74
|
+
assert_equal "puma2\npuma1\n", result.stdout
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_stderr_append_to_file
|
78
|
+
File.open('output.txt', 'w') { |f| f.puts "jungle" }
|
79
|
+
Sheller.execute('./fixtures/stdout_stderr_puma', Sheller::STDERR_APPEND_TO_FILE, 'output.txt')
|
80
|
+
assert_equal "jungle\npuma2\n", File.read('output.txt')
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_stdout_and_stderr_to_file
|
84
|
+
Sheller.execute('./fixtures/stdout_stderr_puma', Sheller::STDOUT_AND_STDERR_TO_FILE, 'output.txt')
|
85
|
+
assert_equal "puma2\npuma1\n", File.read('output.txt')
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_stdin_from_file
|
89
|
+
result = Sheller.execute('grep', 'Dublin', Sheller::STDIN_FROM_FILE, './fixtures/cities.txt')
|
90
|
+
assert_equal "Dublin\n", result.stdout
|
91
|
+
end
|
92
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sheller
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Duncan Beevers
|
@@ -42,8 +42,14 @@ extensions: []
|
|
42
42
|
|
43
43
|
extra_rdoc_files: []
|
44
44
|
|
45
|
-
files:
|
46
|
-
|
45
|
+
files:
|
46
|
+
- lib/sheller.rb
|
47
|
+
- test/fixtures/cities.txt
|
48
|
+
- test/fixtures/stderr_frog
|
49
|
+
- test/fixtures/stdout_stderr_puma
|
50
|
+
- test/fixtures/stdout_turtle
|
51
|
+
- test/sheller_test.rb
|
52
|
+
- test/test_helper.rb
|
47
53
|
has_rdoc: true
|
48
54
|
homepage: http://github.com/duncanbeevers/sheller
|
49
55
|
licenses: []
|