system_run 1.0.1 → 1.0.2
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.
- checksums.yaml +4 -4
- data/README.md +77 -2
- data/spec/system_run_spec.rb +118 -0
- data/system_run.gemspec +3 -2
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd6598275fe6de6a8b62779ad1ad194634552787
|
4
|
+
data.tar.gz: 6323869c240f230dc367ca83183c74fc6e10e283
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7476d1f83a81b930acf77623d1b0c523fa5f1b009dfc1d8262779ae06acc2a19d570f6fcdbb1e1e6f11d70e083766058714c3c3ce12bfb23e6ef14af28faea1f
|
7
|
+
data.tar.gz: 72740f36a260b1cea5a683d85fab6468c3d8da0e2d104e276f7e3b1a276af344898fdc747af98f3567acbe0b799af5ef89b5275717fbcede002d4af3aacaa4a6
|
data/README.md
CHANGED
@@ -1,3 +1,78 @@
|
|
1
1
|
# system_run
|
2
|
-
Tiny wrapper for running commands.
|
3
|
-
|
2
|
+
Tiny wrapper for running commands. Inspired by systemu.
|
3
|
+
|
4
|
+
System.run is a wrapper for making subprocess-spawning more ergonomic. It uses
|
5
|
+
Ruby's `Kernel.spawn` internally and supports setting a timeout, environment
|
6
|
+
variables, a working directory, files for redirecting, a custom action for when
|
7
|
+
a timeout occurs and other options that are forwarded to `spawn` as-is.
|
8
|
+
|
9
|
+
## Examples
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
# capture both stderr and stdout, but separately.
|
13
|
+
program = %q{ruby -e "STDOUT.print 'hello'; STDERR.print 'world'"}
|
14
|
+
System.run program
|
15
|
+
# => [#<Process::Status: pid 20407 exit 0>, "hello", "world"]
|
16
|
+
|
17
|
+
# only capture stdout.
|
18
|
+
System.run program, capture: :out
|
19
|
+
# => [#<Process::Status: pid 20421 exit 0>, "hello"]
|
20
|
+
|
21
|
+
# only capture stderr.
|
22
|
+
System.run program, capture: :err
|
23
|
+
# => [#<Process::Status: pid 20458 exit 0>, "world"]
|
24
|
+
|
25
|
+
# capture both stdout and stderr into the same string.
|
26
|
+
# stdout is buffered, stderr is not!
|
27
|
+
System.run program, capture: :both
|
28
|
+
# => [#<Process::Status: pid 20464 exit 0>, "worldhello"]
|
29
|
+
|
30
|
+
# kill (send signal 9) process after the specified time.
|
31
|
+
program = %q{ruby -e "STDERR.print 'this can only end badly'; loop { sleep 1 }"}
|
32
|
+
System.run program, timeout: 2, capture: :both
|
33
|
+
# ...
|
34
|
+
# => [#<Process::Status: pid 20507 SIGKILL (signal 9)>, "this can only end badly"]
|
35
|
+
|
36
|
+
# override default action with sending SIGTERM and setting a control variable.
|
37
|
+
state = :everything_is_great
|
38
|
+
System.run program, timeout: 2, capture: :both, on_timeout: ->(pid) do
|
39
|
+
state = :oh_no
|
40
|
+
Process.kill 15, pid
|
41
|
+
end
|
42
|
+
# ...
|
43
|
+
# => [#<Process::Status: pid 20519 SIGTERM (signal 15)>, "this can only end badly"]
|
44
|
+
|
45
|
+
# set some environment variable.
|
46
|
+
program = %{ruby -e "STDERR.print ENV['hello']; STDOUT.print Dir.pwd"}
|
47
|
+
System.run program, capture: :err, env: {'hello' => 2}
|
48
|
+
# => [#<Process::Status: pid 20540 exit 0>, "2"]
|
49
|
+
|
50
|
+
# set working dir.
|
51
|
+
System.run program, capture: :out, cwd: Dir.tmpdir
|
52
|
+
# => [#<Process::Status: pid 20545 exit 0>, "/tmp"]
|
53
|
+
|
54
|
+
# redirect to file (File or Tempfile or descendants)
|
55
|
+
program = %q{ruby -e "STDOUT.print 'hello'; STDERR.print 'world'"}
|
56
|
+
out = Tempfile.new 'out'
|
57
|
+
err = Tempfile.new 'err'
|
58
|
+
System.run program, file: [out, err]
|
59
|
+
# => #<Process::Status: pid 20553 exit 0>
|
60
|
+
out.read
|
61
|
+
# => "hello"
|
62
|
+
err.read
|
63
|
+
# => "world"
|
64
|
+
|
65
|
+
# everything works the same!
|
66
|
+
out = Tempfile.new 'out'
|
67
|
+
System.run program, file: out, capture: :both
|
68
|
+
# => #<Process::Status: pid 20591 exit 0>
|
69
|
+
out.read
|
70
|
+
# => "worldhello"
|
71
|
+
|
72
|
+
# you can specify some file to be used as stdin. this option is passed
|
73
|
+
# directly to Kernel.spawn.
|
74
|
+
input = Tempfile.new.tap { |f| f.write('system_run'); f.rewind }
|
75
|
+
echo = %q{ruby -e "print STDIN.gets"}
|
76
|
+
System.run echo, in: input, capture: :out
|
77
|
+
# => [#<Process::Status: pid 20605 exit 0>, "system_run"]
|
78
|
+
```
|
@@ -0,0 +1,118 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
$:.push '../lib'
|
5
|
+
require 'rspec'
|
6
|
+
require 'system_run'
|
7
|
+
|
8
|
+
RSpec.describe System, ".run" do
|
9
|
+
context "basic capturing of output" do
|
10
|
+
program = %q{ruby -e "STDOUT.print 'hello'; STDERR.print 'world'"}
|
11
|
+
|
12
|
+
it "can capture stdout and stderr separately" do
|
13
|
+
status, stdout, stderr = System.run program
|
14
|
+
|
15
|
+
expect(status.exitstatus).to eq 0
|
16
|
+
expect(stdout).to eq('hello')
|
17
|
+
expect(stderr).to eq('world')
|
18
|
+
end
|
19
|
+
|
20
|
+
it "can discard stderr" do
|
21
|
+
status, stdout = System.run program, capture: :out
|
22
|
+
expect(status.exitstatus).to eq 0
|
23
|
+
expect(stdout).to eq('hello')
|
24
|
+
end
|
25
|
+
|
26
|
+
it "can discard stdout, too" do
|
27
|
+
status, stderr = System.run program, capture: :err
|
28
|
+
expect(status.exitstatus).to eq 0
|
29
|
+
expect(stderr).to eq('world')
|
30
|
+
end
|
31
|
+
|
32
|
+
it "can merge both streams into one" do
|
33
|
+
status, all = System.run program, capture: :both
|
34
|
+
expect(status.exitstatus).to eq(0)
|
35
|
+
expect(all).to eq('worldhello')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "setting a timeout on subprocess" do
|
40
|
+
program = %q{ruby -e "STDERR.print 'this can only end badly'; loop { sleep 2 }"}
|
41
|
+
|
42
|
+
it "will timeout after n seconds, preserving output so-far, and kill process" do
|
43
|
+
status, all = System.run program, timeout: 2, capture: :both
|
44
|
+
|
45
|
+
expect(status.signaled?).to be true
|
46
|
+
expect(status.termsig).to eq 9
|
47
|
+
expect(all).to eq('this can only end badly')
|
48
|
+
end
|
49
|
+
|
50
|
+
it "will timeout after n seconds and execute a custom action" do
|
51
|
+
state = :ok
|
52
|
+
status, all = System.run program, timeout: 2, capture: :both, on_timeout: ->(pid) do
|
53
|
+
state = :err
|
54
|
+
Process.kill 15, pid
|
55
|
+
end
|
56
|
+
|
57
|
+
expect(state).to eq(:err)
|
58
|
+
expect(status.signaled?).to be true
|
59
|
+
expect(status.termsig).to eq 15
|
60
|
+
expect(all).to eq('this can only end badly')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "setting environment variables and changing directory prior to executing" do
|
65
|
+
program = %{ruby -e "STDERR.print ENV['hello']; STDOUT.print Dir.pwd"}
|
66
|
+
|
67
|
+
it "can set environment variables" do
|
68
|
+
status, stderr = System.run program, capture: :err, env: {'hello' => 2}
|
69
|
+
|
70
|
+
expect(status.exitstatus).to eq(0)
|
71
|
+
expect(stderr).to eq('2')
|
72
|
+
end
|
73
|
+
|
74
|
+
it "can switch working directory" do
|
75
|
+
status, stdout = System.run program, capture: :out, cwd: Dir.tmpdir
|
76
|
+
|
77
|
+
expect(status.exitstatus).to eq(0)
|
78
|
+
expect(stdout).to eq(Dir.tmpdir)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "reading and writing to files" do
|
83
|
+
program = %q{ruby -e "STDOUT.print 'hello'; STDERR.print 'world'"}
|
84
|
+
|
85
|
+
it "can redirect output to files" do
|
86
|
+
out = Tempfile.new 'out'
|
87
|
+
err = Tempfile.new 'err'
|
88
|
+
|
89
|
+
status = System.run program, file: [out, err]
|
90
|
+
|
91
|
+
expect(status.exitstatus).to eq(0)
|
92
|
+
expect(out.read).to eq('hello')
|
93
|
+
expect(err.read).to eq('world')
|
94
|
+
|
95
|
+
[out, err].each { |f| f.close; f.unlink }
|
96
|
+
end
|
97
|
+
|
98
|
+
it "works the same as with string, e.g. merging streams" do
|
99
|
+
out = Tempfile.new 'out'
|
100
|
+
|
101
|
+
status = System.run program, file: out, capture: :both
|
102
|
+
|
103
|
+
expect(status.exitstatus).to eq(0)
|
104
|
+
expect(out.read).to eq('worldhello')
|
105
|
+
out.close; out.unlink
|
106
|
+
end
|
107
|
+
|
108
|
+
it "can read input provided in a file" do
|
109
|
+
input = Tempfile.new.tap { |f| f.write('system_run'); f.rewind }
|
110
|
+
|
111
|
+
echo = %q{ruby -e "print STDIN.gets"}
|
112
|
+
status, out = System.run echo, in: input, capture: :out
|
113
|
+
|
114
|
+
expect(status.exitstatus).to eq(0)
|
115
|
+
expect(out).to eq('system_run')
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/system_run.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "system_run"
|
3
|
-
s.version = "1.0.
|
3
|
+
s.version = "1.0.2"
|
4
4
|
s.platform = Gem::Platform::RUBY
|
5
5
|
s.license = "MIT"
|
6
6
|
s.summary = "Tiny wrapper for running commands. Inspired by systemu."
|
@@ -10,9 +10,10 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.files = Dir['lib/**/*,spec/*}'] + %w(LICENSE Rakefile system_run.gemspec README.md)
|
11
11
|
s.require_path = 'lib'
|
12
12
|
s.extra_rdoc_files = ['README.md']
|
13
|
-
s.test_files = []
|
13
|
+
s.test_files = Dir['spec/system_run_spec*.rb']
|
14
14
|
|
15
15
|
s.required_ruby_version = '>=2.3.0'
|
16
|
+
s.add_development_dependency 'rspec', '~>3.0'
|
16
17
|
|
17
18
|
s.authors = ['Sonja Biedermann']
|
18
19
|
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: system_run
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sonja Biedermann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-02-
|
12
|
-
dependencies:
|
11
|
+
date: 2017-02-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
13
27
|
description: see https://github.com/biederfrau/system_run
|
14
28
|
email: s.bdrmnn@gmail.com
|
15
29
|
executables: []
|
@@ -20,6 +34,7 @@ files:
|
|
20
34
|
- LICENSE
|
21
35
|
- README.md
|
22
36
|
- Rakefile
|
37
|
+
- spec/system_run_spec.rb
|
23
38
|
- system_run.gemspec
|
24
39
|
homepage: https://github.com/biederfrau/system_run
|
25
40
|
licenses:
|
@@ -45,4 +60,5 @@ rubygems_version: 2.5.1
|
|
45
60
|
signing_key:
|
46
61
|
specification_version: 4
|
47
62
|
summary: Tiny wrapper for running commands. Inspired by systemu.
|
48
|
-
test_files:
|
63
|
+
test_files:
|
64
|
+
- spec/system_run_spec.rb
|