sheller 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,4 @@
1
+ Cork
2
+ Dublin
3
+ Louth
4
+ Letterkenny
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $stderr.puts "frog"
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $stdout.puts "puma1"
4
+ $stderr.puts "puma2"
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $stdout.puts "turtle"
@@ -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
@@ -0,0 +1,6 @@
1
+ require 'test/unit'
2
+ require 'fileutils'
3
+
4
+ $: << File.expand_path(File.join(File.dirname(__FILE__), '../lib'))
5
+
6
+ require 'sheller'
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: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
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: []