shellshot 0.2.0 → 0.3.0
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/.gitignore +1 -0
- data/VERSION +1 -1
- data/lib/shellshot.rb +68 -9
- data/shellshot.gemspec +6 -5
- data/spec/shellshot_spec.rb +6 -2
- metadata +3 -3
data/.gitignore
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/lib/shellshot.rb
CHANGED
@@ -1,18 +1,26 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'tempfile'
|
2
3
|
require 'system_timer'
|
3
4
|
|
4
5
|
module Shellshot
|
5
|
-
|
6
|
+
|
7
|
+
class CommandError < RuntimeError; end
|
8
|
+
|
6
9
|
class Command
|
7
10
|
|
8
11
|
alias_method :system_exec, :exec
|
9
12
|
|
10
13
|
DEFAULT_TIMEOUT = 60 * 60 # 1 hour
|
11
14
|
|
12
|
-
attr_accessor :pid, :status
|
15
|
+
attr_accessor :pid, :status, :options
|
13
16
|
|
14
17
|
def exec(command, options = {})
|
18
|
+
|
19
|
+
self.options = options
|
20
|
+
|
21
|
+
prepare_pipes if no_stderr?
|
15
22
|
self.pid = fork do
|
23
|
+
close_reading_pipe if no_stderr?
|
16
24
|
redefine_stds(options)
|
17
25
|
system_exec(command)
|
18
26
|
end
|
@@ -29,28 +37,79 @@ module Shellshot
|
|
29
37
|
|
30
38
|
def wait_for(seconds)
|
31
39
|
SystemTimer.timeout(seconds) do
|
32
|
-
Process.wait(pid)
|
40
|
+
Process.wait(pid)
|
33
41
|
self.status = $?
|
42
|
+
unless self.status.success?
|
43
|
+
raise CommandError, stderr_contents
|
44
|
+
end
|
34
45
|
end
|
35
46
|
end
|
36
47
|
|
48
|
+
def close_stderr
|
49
|
+
error_tempfile.close
|
50
|
+
end
|
51
|
+
|
37
52
|
def terminate_child_process
|
38
|
-
if pid
|
53
|
+
if pid
|
39
54
|
Process.kill("KILL", pid)
|
40
55
|
Process.wait(pid) # reaping zombie processes. Not sure if correct.
|
41
56
|
end
|
42
57
|
end
|
43
58
|
|
44
59
|
def redefine_stds(options)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
if options[:stdall]
|
49
|
-
combined = File.open(options[:stdall], "w+")
|
60
|
+
if stdall_location
|
61
|
+
combined = File.open(stdall_location, "w+")
|
50
62
|
$stdout.reopen(combined)
|
51
63
|
$stderr.reopen(combined)
|
64
|
+
else
|
65
|
+
$stdout.reopen(File.open(stdout_location, "w+")) if stdout_location
|
66
|
+
if no_stderr?
|
67
|
+
$stderr.reopen(@wr)
|
68
|
+
else
|
69
|
+
$stderr.reopen(File.open(stderr_location, "w+"))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def stderr_location
|
75
|
+
stdall_location || options[:stderr]
|
76
|
+
end
|
77
|
+
|
78
|
+
def no_stderr?
|
79
|
+
!stderr_location
|
80
|
+
end
|
81
|
+
|
82
|
+
def stdout_location
|
83
|
+
stdall_location || options[:stdout]
|
84
|
+
end
|
85
|
+
|
86
|
+
def stdall_location
|
87
|
+
options[:stdall]
|
88
|
+
end
|
89
|
+
|
90
|
+
def close_reading_pipe
|
91
|
+
@rd.close
|
92
|
+
end
|
93
|
+
|
94
|
+
def stderr_contents
|
95
|
+
if no_stderr?
|
96
|
+
@wr.close
|
97
|
+
contents = @rd.read
|
98
|
+
@rd.close
|
99
|
+
contents
|
100
|
+
else
|
101
|
+
File.read(stderr_location)
|
52
102
|
end
|
53
103
|
end
|
104
|
+
|
105
|
+
def prepare_pipes
|
106
|
+
@rd, @wr = IO.pipe
|
107
|
+
end
|
108
|
+
|
109
|
+
def close_pipes
|
110
|
+
@rd.close
|
111
|
+
@wr.close
|
112
|
+
end
|
54
113
|
end
|
55
114
|
|
56
115
|
def self.exec(command, options = {})
|
data/shellshot.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{shellshot}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Petyo Ivanov"]
|
12
|
-
s.date = %q{2009-
|
12
|
+
s.date = %q{2009-11-24}
|
13
13
|
s.description = %q{
|
14
14
|
A small library dealing with the obscurities of shell commands, piping and timeouts.
|
15
15
|
Most of the stuff comes from bad experience in http://beanstalkapp.com.
|
@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.homepage = %q{http://github.com/underlog/shellshot}
|
35
35
|
s.rdoc_options = ["--charset=UTF-8"]
|
36
36
|
s.require_paths = ["lib"]
|
37
|
-
s.rubygems_version = %q{1.3.
|
37
|
+
s.rubygems_version = %q{1.3.5}
|
38
38
|
s.summary = %q{ruby proxy handling the complexities of system invocations}
|
39
39
|
s.test_files = [
|
40
40
|
"spec/shellshot_spec.rb",
|
@@ -57,3 +57,4 @@ Gem::Specification.new do |s|
|
|
57
57
|
s.add_dependency(%q<SystemTimer>, [">= 0"])
|
58
58
|
end
|
59
59
|
end
|
60
|
+
|
data/spec/shellshot_spec.rb
CHANGED
@@ -8,12 +8,12 @@ describe Shellshot do
|
|
8
8
|
"file".should be_a_file
|
9
9
|
end
|
10
10
|
|
11
|
-
it "should pipe the out to the right file" do
|
11
|
+
it "should pipe the out to the right file" do
|
12
12
|
Shellshot.exec(%q[ruby -e 'puts "Hello World"'], :stdout => "file")
|
13
13
|
"file".should contain("Hello World")
|
14
14
|
end
|
15
15
|
|
16
|
-
it "should pipe the err to the right file" do
|
16
|
+
it "should pipe the err to the right file" do
|
17
17
|
Shellshot.exec(%q[ruby -e '$stderr << "error"'], :stderr => "file")
|
18
18
|
"file".should contain("error")
|
19
19
|
end
|
@@ -27,6 +27,10 @@ describe Shellshot do
|
|
27
27
|
lambda { Shellshot.exec %q[ruby -e 'sleep 10000'], :timeout => 1 }.should raise_error(Timeout::Error)
|
28
28
|
end
|
29
29
|
|
30
|
+
it "should raise error if command returned something else." do
|
31
|
+
lambda { Shellshot.exec %q[ruby -e '$stderr << "problem"; exit 1;'] }.should raise_error(Shellshot::CommandError, "problem")
|
32
|
+
end
|
33
|
+
|
30
34
|
end
|
31
35
|
|
32
36
|
# EOF
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shellshot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Petyo Ivanov
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-11-24 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -76,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
76
|
requirements: []
|
77
77
|
|
78
78
|
rubyforge_project:
|
79
|
-
rubygems_version: 1.3.
|
79
|
+
rubygems_version: 1.3.5
|
80
80
|
signing_key:
|
81
81
|
specification_version: 3
|
82
82
|
summary: ruby proxy handling the complexities of system invocations
|