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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c6bd63c23713abf1d6a2ce4c456048e313fd7a3
4
- data.tar.gz: 304ba5539f1f046ad9eb73bcc0d139fda00b27e0
3
+ metadata.gz: cd6598275fe6de6a8b62779ad1ad194634552787
4
+ data.tar.gz: 6323869c240f230dc367ca83183c74fc6e10e283
5
5
  SHA512:
6
- metadata.gz: 107eafe0bccfa161b5450977034a1b860bf6f9a73c3db07726c902ad23e260e7616001f1caf045fb2a0e53d9f15f3cc7a678f48c2121af1bb13a080831213057
7
- data.tar.gz: 07d0a846819655436dcbbac434d28d48031f1038725a823266d1d02ecb8a8b0fc82fc51bdc58cd26641313ae5db6d9a03da5419c3ddc3d3a6affcc66200840b2
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
- Inspired by systemu.
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
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "system_run"
3
- s.version = "1.0.1"
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.1
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-07 00:00:00.000000000 Z
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