sheller 0.0.2 → 0.0.3

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.
@@ -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: []