terrapin 0.6.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: fe1ba61cb02d982ac5535ff8423186dcb045c9de
4
- data.tar.gz: d1eae833ed7b0041442275d6a005188c4300a5fa
2
+ SHA256:
3
+ metadata.gz: 63194360423231cdc4e8a9d8029d6a13cefb7adaf18393e9c440c5bd78d9cda9
4
+ data.tar.gz: df7766c516b75cf3e4a3cdc9e34db75f71b445401412f2fa0d56731642bcf62a
5
5
  SHA512:
6
- metadata.gz: d8d2a8e41b0f12e41062cfcbbacaa7abcc9e2d02519ffe27214a4ffaa93c5c0243b681066fa76e59c66e13dd2f8abf87258644b5cf421c7e66e47118434c764d
7
- data.tar.gz: 3e3e8d27c8a9e569fe99b30a09baacbe05a7dae3a260b36470453bcaaa7303f685a6868d84304d6e1afd55661ead32b31d89f3d4debf01bd7b31c67379ac47b0
6
+ metadata.gz: 605061255a57c1565265f4b80c14fe246cdaea034c17148ac499022e6cbe34612551c455d506429c8ba5b071449a2d0b4137140757135b3a2c983af404bb0514
7
+ data.tar.gz: a609c3fb7fbca55d3382a8c8f41c93de29761aa19221a2768100e80107afe789d6984f46945b48eadea49def31a59bf7eab1812304fb66c1add37784f489e263
@@ -0,0 +1,30 @@
1
+ name: CI
2
+ on:
3
+ - push
4
+ - pull_request
5
+
6
+ jobs:
7
+ build:
8
+ name: Ruby ${{ matrix.ruby }}
9
+ if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
10
+ strategy:
11
+ fail-fast: false
12
+ matrix:
13
+ ruby:
14
+ - jruby-9.4.1.0
15
+ - "2.7"
16
+ - "3.0"
17
+ - "3.1"
18
+ - "3.2"
19
+
20
+ runs-on: 'ubuntu-latest'
21
+
22
+ steps:
23
+ - uses: actions/checkout@v2
24
+ - uses: ruby/setup-ruby@v1
25
+ with:
26
+ ruby-version: ${{ matrix.ruby }}
27
+ - name: Setup project
28
+ run: bundle install
29
+ - name: Run test
30
+ run: bundle exec rake
data/.travis.yml CHANGED
@@ -2,5 +2,8 @@ rvm:
2
2
  - 1.9.3
3
3
  - 2.0.0
4
4
  - 2.1.5
5
+ - 2.2.9
6
+ - 2.3.6
7
+ - 2.4.3
8
+ - 2.5.0
5
9
  - jruby-19mode
6
- - rbx-2
data/Gemfile CHANGED
@@ -1,7 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
-
5
- platforms :ruby do
6
- gem "posix-spawn"
7
- end
data/NEWS.md CHANGED
@@ -1,3 +1,8 @@
1
+ New for 1.0.0:
2
+
3
+ * Terrapin::CommandLine::PosixRunner was removed. You can replace any usage of this with Terrapin::CommandLine::ProcessRunner, which uses Ruby’s builtin Process.spawn.
4
+ * Moved CI from Travis to GH Actions.
5
+
1
6
  New for 0.6.0:
2
7
 
3
8
  * Rename the project to Terrapin
data/README.md CHANGED
@@ -105,11 +105,11 @@ line.command # => "lolwut", but it looks in /opt/bin for it.
105
105
  You can even give it a bunch of places to look:
106
106
 
107
107
  ```ruby
108
- FileUtils.rm("/opt/bin/lolwut")
109
- File.open('/usr/local/bin/lolwut') {|f| f.write('echo Hello') }
110
- Terrapin::CommandLine.path = ["/opt/bin", "/usr/local/bin"]
111
- line = Terrapin::CommandLine.new("lolwut")
112
- line.run # => prints 'Hello', because it searches the path
108
+ FileUtils.rm("/opt/bin/lolwut")
109
+ File.open('/usr/local/bin/lolwut') { |f| f.write('echo Hello') }
110
+ Terrapin::CommandLine.path = ["/opt/bin", "/usr/local/bin"]
111
+ line = Terrapin::CommandLine.new("lolwut")
112
+ line.run # => prints 'Hello', because it searches the path
113
113
  ```
114
114
 
115
115
  Or just put it in the command:
@@ -145,23 +145,18 @@ second argument of `new`. Terrapin assumes that you will not be manually
145
145
  passing user-generated data to that argument and will be using it as a template
146
146
  for your command line's structure.
147
147
 
148
- ## POSIX Spawn
148
+ ## Runners
149
149
 
150
- You can potentially increase performance by installing [the posix-spawn
151
- gem](https://rubygems.org/gems/posix-spawn). This gem can keep your
152
- application's heap from being copied when forking command line
153
- processes. For applications with large heaps the gain can be
154
- significant. To include `posix-spawn`, simply add it to your `Gemfile` or,
155
- if you don't use bundler, install the gem.
150
+ Terrapin will choose from among a couple different ways of running commands.
151
+ The simplest is `Process.spawn`, which is also the default. Terrapin can also just use [backticks], so if for some reason you'd prefer that, you can ask Terrapin to use that:
156
152
 
157
- ## Runners
153
+ ```ruby
154
+ Terrapin::CommandLine.runner = Terrapin::CommandLine::BackticksRunner.new
155
+ ```
156
+
157
+ And if you really want to, you can define your own Runner, though I can't imagine why you would.
158
158
 
159
- Terrapin will attempt to choose from among 3 different ways of running commands.
160
- The simplest is using backticks, and is the default in 1.8. In Ruby 1.9, it
161
- will attempt to use `Process.spawn`. And, as mentioned above, if the
162
- `posix-spawn` gem is installed, it will attempt to use that. If for some reason
163
- one of the `.spawn` runners don't work for you, you can override them manually
164
- by setting a new runner, like so:
159
+ [backticks]: https://ruby-doc.org/3.2.1/Kernel.html#method-i-60
165
160
 
166
161
  ```ruby
167
162
  Terrapin::CommandLine.runner = Terrapin::CommandLine::BackticksRunner.new
@@ -2,6 +2,5 @@
2
2
 
3
3
  require 'terrapin/command_line/runners/backticks_runner'
4
4
  require 'terrapin/command_line/runners/process_runner'
5
- require 'terrapin/command_line/runners/posix_runner'
6
5
  require 'terrapin/command_line/runners/popen_runner'
7
6
  require 'terrapin/command_line/runners/fake_runner'
@@ -38,7 +38,7 @@ module Terrapin
38
38
  private
39
39
 
40
40
  def best_runner
41
- [PosixRunner, ProcessRunner, BackticksRunner].detect do |runner|
41
+ [ProcessRunner, BackticksRunner].detect do |runner|
42
42
  runner.supported?
43
43
  end.new
44
44
  end
@@ -49,15 +49,20 @@ module Terrapin
49
49
  attr_reader :exit_status, :runner
50
50
 
51
51
  def initialize(binary, params = "", options = {})
52
- @binary = binary.dup
53
- @params = params.dup
54
- @options = options.dup
55
- @runner = @options.delete(:runner) || self.class.runner
56
- @logger = @options.delete(:logger) || self.class.logger
57
- @swallow_stderr = @options.delete(:swallow_stderr)
52
+ if options.nil?
53
+ raise ArgumentError, "3rd argument to CommandLine.new should be a" \
54
+ "hash of values that will be interpolated into the command line"
55
+ end
56
+
57
+ @options = options.dup
58
+ @binary = binary.dup
59
+ @params = params.to_s.dup
60
+ @runner = @options.delete(:runner) || self.class.runner
61
+ @logger = @options.delete(:logger) || self.class.logger
62
+ @swallow_stderr = @options.delete(:swallow_stderr)
58
63
  @expected_outcodes = @options.delete(:expected_outcodes) || [0]
59
- @environment = @options.delete(:environment) || {}
60
- @runner_options = @options.delete(:runner_options) || {}
64
+ @environment = @options.delete(:environment) || {}
65
+ @runner_options = @options.delete(:runner_options) || {}
61
66
  end
62
67
 
63
68
  def command(interpolations = {})
@@ -1,4 +1,4 @@
1
1
  # coding: UTF-8
2
2
  module Terrapin
3
- VERSION = "0.6.0".freeze
3
+ VERSION = "1.0.0".freeze
4
4
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,4 @@
1
1
  require 'rspec'
2
- require 'mocha/api'
3
- require 'bourne'
4
2
  require 'terrapin'
5
3
  require 'timeout'
6
4
  require 'tempfile'
@@ -14,10 +12,8 @@ begin; require 'active_support/buffered_logger'; rescue LoadError; end
14
12
  Dir[File.dirname(__FILE__) + "/support/**.rb"].each{|support_file| require support_file }
15
13
 
16
14
  RSpec.configure do |config|
17
- config.mock_with :mocha
18
15
  config.include WithExitstatus
19
16
  config.include StubOS
20
- config.include UnsettingExitstatus
21
17
  end
22
18
 
23
19
  def best_logger
@@ -5,8 +5,8 @@ shared_examples_for "a command that does not block" do
5
5
 
6
6
  Timeout.timeout(5) do
7
7
  output = subject.call("cat '#{garbage_file.path}'")
8
- $?.exitstatus.should == 0
9
- output.output.length.should == 10 * 1024 * 1024
8
+ expect($?.exitstatus).to eq(0)
9
+ expect(output.output.length).to eq(10 * 1024 * 1024)
10
10
  end
11
11
 
12
12
  garbage_file.close
@@ -1,25 +1,25 @@
1
1
  module StubOS
2
2
  def on_windows!
3
3
  stub_os('mswin')
4
- Terrapin::OS.stubs(:path_separator).returns(";")
4
+ allow(Terrapin::OS).to receive(:path_separator).and_return(";")
5
5
  end
6
6
 
7
7
  def on_unix!
8
8
  stub_os('darwin11.0.0')
9
- Terrapin::OS.stubs(:path_separator).returns(":")
9
+ allow(Terrapin::OS).to receive(:path_separator).and_return(":")
10
10
  end
11
11
 
12
12
  def on_mingw!
13
13
  stub_os('mingw')
14
- Terrapin::OS.stubs(:path_separator).returns(";")
14
+ allow(Terrapin::OS).to receive(:path_separator).and_return(";")
15
15
  end
16
16
 
17
17
  def on_java!
18
- Terrapin::OS.stubs(:arch).returns("universal-java1.7")
18
+ allow(Terrapin::OS).to receive(:arch).and_return("universal-java1.7")
19
19
  end
20
20
 
21
21
  def stub_os(host_string)
22
22
  # http://blog.emptyway.com/2009/11/03/proper-way-to-detect-windows-platform-in-ruby/
23
- RbConfig::CONFIG.stubs(:[]).with('host_os').returns(host_string)
23
+ allow(RbConfig::CONFIG).to receive(:[]).with('host_os').and_return(host_string)
24
24
  end
25
25
  end
@@ -16,9 +16,9 @@ describe Terrapin::CommandLine::BackticksRunner do
16
16
 
17
17
  it 'sets the exitstatus when a command completes' do
18
18
  subject.call("ruby -e 'exit 0'")
19
- $?.exitstatus.should == 0
19
+ expect($?.exitstatus).to eq(0)
20
20
  subject.call("ruby -e 'exit 5'")
21
- $?.exitstatus.should == 5
21
+ expect($?.exitstatus).to eq(5)
22
22
  end
23
23
  end
24
24
  end
@@ -4,19 +4,19 @@ describe Terrapin::CommandLine::FakeRunner do
4
4
  it 'records commands' do
5
5
  subject.call("some command", :environment)
6
6
  subject.call("other command", :other_environment)
7
- subject.commands.should eq [["some command", :environment], ["other command", :other_environment]]
7
+ expect(subject.commands).to eq [["some command", :environment], ["other command", :other_environment]]
8
8
  end
9
9
 
10
10
  it 'can tell if a command was run' do
11
11
  subject.call("some command", :environment)
12
12
  subject.call("other command", :other_environment)
13
- subject.ran?("some command").should eq true
14
- subject.ran?("no command").should eq false
13
+ expect(subject.ran?("some command")).to eq true
14
+ expect(subject.ran?("no command")).to eq false
15
15
  end
16
16
 
17
17
  it 'can tell if a command was run even if shell options were set' do
18
18
  subject.call("something 2>/dev/null", :environment)
19
- subject.ran?("something").should eq true
19
+ expect(subject.ran?("something")).to eq true
20
20
  end
21
21
 
22
22
  end
@@ -16,9 +16,9 @@ describe Terrapin::CommandLine::PopenRunner do
16
16
 
17
17
  it 'sets the exitstatus when a command completes' do
18
18
  subject.call("ruby -e 'exit 0'")
19
- $?.exitstatus.should == 0
19
+ expect($?.exitstatus).to eq(0)
20
20
  subject.call("ruby -e 'exit 5'")
21
- $?.exitstatus.should == 5
21
+ expect($?.exitstatus).to eq(5)
22
22
  end
23
23
  end
24
24
  end
@@ -21,9 +21,9 @@ describe Terrapin::CommandLine::ProcessRunner do
21
21
 
22
22
  it 'sets the exitstatus when a command completes' do
23
23
  subject.call("ruby -e 'exit 0'")
24
- $?.exitstatus.should == 0
24
+ expect($?.exitstatus).to eq(0)
25
25
  subject.call("ruby -e 'exit 5'")
26
- $?.exitstatus.should == 5
26
+ expect($?.exitstatus).to eq(5)
27
27
  end
28
28
 
29
29
  it "runs the command it's given and allows access to stderr afterwards" do
@@ -6,37 +6,49 @@ describe Terrapin::CommandLine do
6
6
  on_unix! # Assume we're on unix unless otherwise specified.
7
7
  end
8
8
 
9
+ describe ".new" do
10
+ it "treats nil params as blank" do
11
+ cmd = Terrapin::CommandLine.new("echo", nil)
12
+ expect(cmd.run).to eq("\n")
13
+ end
14
+
15
+ it "raises when given nil options" do
16
+ expect { Terrapin::CommandLine.new("echo", "", nil) }
17
+ .to raise_error(ArgumentError)
18
+ end
19
+ end
20
+
9
21
  it "takes a command and parameters and produces a Bash command line" do
10
22
  cmd = Terrapin::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
11
- cmd.command.should == "convert a.jpg b.png"
23
+ expect(cmd.command).to eq("convert a.jpg b.png")
12
24
  end
13
25
 
14
26
  it "specifies the $PATH where the command can be found on unix" do
15
27
  Terrapin::CommandLine.path = ["/path/to/command/dir", "/"]
16
28
  cmd = Terrapin::CommandLine.new("ls")
17
- cmd.command.should == "PATH=/path/to/command/dir:/:$PATH; ls"
29
+ expect(cmd.command).to eq("PATH=/path/to/command/dir:/:$PATH; ls")
18
30
  end
19
31
 
20
32
  it "specifies the %PATH% where the command can be found on windows" do
21
33
  on_windows!
22
34
  Terrapin::CommandLine.path = ['C:\system32', 'D:\\']
23
35
  cmd = Terrapin::CommandLine.new("dir")
24
- cmd.command.should == 'SET PATH=C:\system32;D:\;%PATH% & dir'
36
+ expect(cmd.command).to eq('SET PATH=C:\system32;D:\;%PATH% & dir')
25
37
  end
26
38
 
27
39
  it "specifies more than one path where the command can be found" do
28
40
  Terrapin::CommandLine.path = ["/path/to/command/dir", "/some/other/path"]
29
41
  cmd = Terrapin::CommandLine.new("ruby", "-e 'puts ENV[%{PATH}]'")
30
42
  output = cmd.run
31
- output.should match(%r{/path/to/command/dir})
32
- output.should match(%r{/some/other/path})
43
+ expect(output).to match(%r{/path/to/command/dir})
44
+ expect(output).to match(%r{/some/other/path})
33
45
  end
34
46
 
35
47
  it "temporarily changes specified environment variables" do
36
48
  Terrapin::CommandLine.environment['TEST'] = 'Hello, world!'
37
49
  cmd = Terrapin::CommandLine.new("ruby", "-e 'puts ENV[%{TEST}]'")
38
50
  output = cmd.run
39
- output.should match(%r{Hello, world!})
51
+ expect(output).to match(%r{Hello, world!})
40
52
  end
41
53
 
42
54
  it 'changes environment variables for the command line' do
@@ -45,13 +57,13 @@ describe Terrapin::CommandLine do
45
57
  "-e 'puts ENV[%{TEST}]'",
46
58
  :environment => {'TEST' => 'Hej hej'})
47
59
  output = cmd.run
48
- output.should match(%r{Hej hej})
60
+ expect(output).to match(%r{Hej hej})
49
61
  end
50
62
 
51
63
  it 'passes the existing environment variables through to the runner' do
52
64
  command = Terrapin::CommandLine.new('echo', '$HOME')
53
65
  output = command.run
54
- output.chomp.should_not == ''
66
+ expect(output.chomp).not_to eq('')
55
67
  end
56
68
 
57
69
  it "can interpolate quoted variables into the command line's parameters" do
@@ -60,7 +72,7 @@ describe Terrapin::CommandLine do
60
72
  :swallow_stderr => false)
61
73
 
62
74
  command_string = cmd.command(:one => "a.jpg", :two => "b.png")
63
- command_string.should == "convert 'a.jpg' 'b.png'"
75
+ expect(command_string).to eq("convert 'a.jpg' 'b.png'")
64
76
  end
65
77
 
66
78
  it 'does not over-interpolate in a command line' do
@@ -69,17 +81,17 @@ describe Terrapin::CommandLine do
69
81
  :swallow_stderr => false)
70
82
 
71
83
  command_string = cmd.command(:hell => "a.jpg", :two => "b.png", :hello => "c.tiff")
72
- command_string.should == "convert 'a.jpg' 'b.png' 'c.tiff'"
84
+ expect(command_string).to eq("convert 'a.jpg' 'b.png' 'c.tiff'")
73
85
  end
74
86
 
75
87
  it "interpolates when running a command" do
76
88
  command = Terrapin::CommandLine.new("echo", ":hello_world")
77
- command.run(:hello_world => "Hello, world").should match(/Hello, world/)
89
+ expect(command.run(:hello_world => "Hello, world")).to match(/Hello, world/)
78
90
  end
79
91
 
80
92
  it "interpolates any Array arguments when running a command" do
81
93
  command = Terrapin::CommandLine.new("echo", "Hello :worlds and :dwarfs")
82
- command.command(:worlds => %w[mercury venus earth], :dwarfs => "pluto").should == "echo Hello 'mercury' 'venus' 'earth' and 'pluto'"
94
+ expect(command.command(:worlds => %w[mercury venus earth], :dwarfs => "pluto")).to eq("echo Hello 'mercury' 'venus' 'earth' and 'pluto'")
83
95
  end
84
96
 
85
97
  it "quotes command line options differently if we're on windows" do
@@ -88,7 +100,7 @@ describe Terrapin::CommandLine do
88
100
  ":one :{two}",
89
101
  :swallow_stderr => false)
90
102
  command_string = cmd.command(:one => "a.jpg", :two => "b.png")
91
- command_string.should == 'convert "a.jpg" "b.png"'
103
+ expect(command_string).to eq('convert "a.jpg" "b.png"')
92
104
  end
93
105
 
94
106
  it "can quote and interpolate dangerous variables" do
@@ -96,12 +108,12 @@ describe Terrapin::CommandLine do
96
108
  ":one :two",
97
109
  :swallow_stderr => false)
98
110
  command_string = cmd.command(:one => "`rm -rf`.jpg", :two => "ha'ha.png'")
99
- command_string.should == "convert '`rm -rf`.jpg' 'ha'\\''ha.png'\\'''"
111
+ expect(command_string).to eq("convert '`rm -rf`.jpg' 'ha'\\''ha.png'\\'''")
100
112
  end
101
113
 
102
114
  it 'cannot recursively introduce a place where user-supplied commands can run' do
103
115
  cmd = Terrapin::CommandLine.new('convert', ':foo :bar')
104
- cmd.command(:foo => ':bar', :bar => '`rm -rf`').should == 'convert \':bar\' \'`rm -rf`\''
116
+ expect(cmd.command(:foo => ':bar', :bar => '`rm -rf`')).to eq('convert \':bar\' \'`rm -rf`\'')
105
117
  end
106
118
 
107
119
  it "can quote and interpolate dangerous variables even on windows" do
@@ -110,7 +122,7 @@ describe Terrapin::CommandLine do
110
122
  ":one :two",
111
123
  :swallow_stderr => false)
112
124
  command_string = cmd.command(:one => "`rm -rf`.jpg", :two => "ha'ha.png")
113
- command_string.should == %{convert "`rm -rf`.jpg" "ha'ha.png"}
125
+ expect(command_string).to eq(%{convert "`rm -rf`.jpg" "ha'ha.png"})
114
126
  end
115
127
 
116
128
  it "quotes blank values into the command line's parameters" do
@@ -118,18 +130,18 @@ describe Terrapin::CommandLine do
118
130
  "-X POST -d :data :url",
119
131
  :swallow_stderr => false)
120
132
  command_string = cmd.command(:data => "", :url => "http://localhost:9000")
121
- command_string.should == "curl -X POST -d '' 'http://localhost:9000'"
133
+ expect(command_string).to eq("curl -X POST -d '' 'http://localhost:9000'")
122
134
  end
123
135
 
124
136
  it "allows colons in parameters" do
125
137
  cmd = Terrapin::CommandLine.new("convert", "'a.jpg' xc:black 'b.jpg'", :swallow_stderr => false)
126
- cmd.command.should == "convert 'a.jpg' xc:black 'b.jpg'"
138
+ expect(cmd.command).to eq("convert 'a.jpg' xc:black 'b.jpg'")
127
139
  end
128
140
 
129
141
  it 'handles symbols in user supplied values' do
130
142
  cmd = Terrapin::CommandLine.new("echo", ":foo")
131
143
  command_string = cmd.command(:foo => :bar)
132
- command_string.should == "echo 'bar'"
144
+ expect(command_string).to eq("echo 'bar'")
133
145
  end
134
146
 
135
147
  it "can redirect stderr to the bit bucket if requested" do
@@ -137,7 +149,7 @@ describe Terrapin::CommandLine do
137
149
  "a.jpg b.png",
138
150
  :swallow_stderr => true)
139
151
 
140
- cmd.command.should == "convert a.jpg b.png 2>/dev/null"
152
+ expect(cmd.command).to eq("convert a.jpg b.png 2>/dev/null")
141
153
  end
142
154
 
143
155
  it "can redirect stderr to the bit bucket on windows" do
@@ -146,7 +158,7 @@ describe Terrapin::CommandLine do
146
158
  "a.jpg b.png",
147
159
  :swallow_stderr => true)
148
160
 
149
- cmd.command.should == "convert a.jpg b.png 2>NUL"
161
+ expect(cmd.command).to eq("convert a.jpg b.png 2>NUL")
150
162
  end
151
163
 
152
164
  it "runs the command it's given and returns the output" do
@@ -163,33 +175,33 @@ describe Terrapin::CommandLine do
163
175
  it "colorizes the output to a tty" do
164
176
  logger = FakeLogger.new(:tty => true)
165
177
  Terrapin::CommandLine.new("echo", "'Logging!' :foo", :logger => logger).run(:foo => "bar")
166
- logger.entries.should include("\e[32mCommand\e[0m :: echo 'Logging!' 'bar'")
178
+ expect(logger.entries).to include("\e[32mCommand\e[0m :: echo 'Logging!' 'bar'")
167
179
  end
168
180
 
169
181
  it 'can still take something that does not respond to tty as a logger' do
170
182
  output_buffer = StringIO.new
171
183
  logger = best_logger.new(output_buffer)
172
- logger.should_not respond_to(:tty?)
184
+ expect(logger).not_to respond_to(:tty?)
173
185
  Terrapin::CommandLine.new("echo", "'Logging!' :foo", :logger => logger).run(:foo => "bar")
174
186
  output_buffer.rewind
175
- output_buffer.read.should == "Command :: echo 'Logging!' 'bar'\n"
187
+ expect(output_buffer.read).to eq("Command :: echo 'Logging!' 'bar'\n")
176
188
  end
177
189
 
178
190
  it "logs the command to a supplied logger" do
179
191
  logger = FakeLogger.new
180
192
  Terrapin::CommandLine.new("echo", "'Logging!' :foo", :logger => logger).run(:foo => "bar")
181
- logger.entries.should include("Command :: echo 'Logging!' 'bar'")
193
+ expect(logger.entries).to include("Command :: echo 'Logging!' 'bar'")
182
194
  end
183
195
 
184
196
  it "logs the command to a default logger" do
185
197
  Terrapin::CommandLine.logger = FakeLogger.new
186
198
  Terrapin::CommandLine.new("echo", "'Logging!'").run
187
- Terrapin::CommandLine.logger.entries.should include("Command :: echo 'Logging!'")
199
+ expect(Terrapin::CommandLine.logger.entries).to include("Command :: echo 'Logging!'")
188
200
  end
189
201
 
190
202
  it "is fine if no logger is supplied" do
191
203
  Terrapin::CommandLine.logger = nil
192
204
  cmd = Terrapin::CommandLine.new("echo", "'Logging!'", :logger => nil)
193
- lambda { cmd.run }.should_not raise_error
205
+ expect { cmd.run }.not_to raise_error
194
206
  end
195
207
  end
@@ -3,38 +3,36 @@ require 'spec_helper'
3
3
  describe "When an error happens" do
4
4
  it "raises a CommandLineError if the result code command isn't expected" do
5
5
  cmd = Terrapin::CommandLine.new("echo", "hello")
6
- cmd.stubs(:execute)
6
+ expect(cmd).to receive(:execute)
7
7
  with_exitstatus_returning(1) do
8
- lambda { cmd.run }.should raise_error(Terrapin::CommandLineError)
8
+ expect { cmd.run }.to raise_error(Terrapin::CommandLineError)
9
9
  end
10
10
  end
11
11
 
12
12
  it "does not raise if the result code is expected, even if nonzero" do
13
13
  cmd = Terrapin::CommandLine.new("echo", "hello", expected_outcodes: [0, 1])
14
- cmd.stubs(:execute)
14
+ expect(cmd).to receive(:execute)
15
15
  with_exitstatus_returning(1) do
16
- lambda { cmd.run }.should_not raise_error
16
+ expect { cmd.run }.not_to raise_error
17
17
  end
18
18
  end
19
19
 
20
20
  it "adds command output to exception message if the result code is nonzero" do
21
21
  cmd = Terrapin::CommandLine.new("echo", "hello")
22
22
  error_output = "Error 315"
23
- cmd.
24
- stubs(:execute).
25
- returns(Terrapin::CommandLine::Output.new("", error_output))
23
+ expect(cmd).to receive(:execute).and_return(Terrapin::CommandLine::Output.new("", error_output))
26
24
  with_exitstatus_returning(1) do
27
25
  begin
28
26
  cmd.run
29
27
  rescue Terrapin::ExitStatusError => e
30
- e.message.should =~ /STDERR:\s+#{error_output}/
28
+ expect(e.message).to match(/STDERR:\s+#{error_output}/)
31
29
  end
32
30
  end
33
31
  end
34
32
 
35
33
  it 'passes the error message to the exception when command is not found' do
36
34
  cmd = Terrapin::CommandLine.new('test', '')
37
- cmd.stubs(:execute).raises(Errno::ENOENT.new("not found"))
35
+ expect(cmd).to receive(:execute).and_raise(Errno::ENOENT.new("not found"))
38
36
  begin
39
37
  cmd.run
40
38
  rescue Terrapin::CommandNotFoundError => e
@@ -44,19 +42,18 @@ describe "When an error happens" do
44
42
 
45
43
  it "should keep result code in #exitstatus" do
46
44
  cmd = Terrapin::CommandLine.new("convert")
47
- cmd.stubs(:execute).with("convert").returns(:correct_value)
45
+ expect(cmd).to receive(:execute).with("convert").and_return(:correct_value)
48
46
  with_exitstatus_returning(1) do
49
47
  cmd.run rescue nil
50
48
  end
51
- cmd.exit_status.should == 1
49
+ expect(cmd.exit_status).to eq(1)
52
50
  end
53
51
 
54
52
  it "does not blow up if running the command errored before execution" do
55
- assuming_no_processes_have_been_run
56
- command = Terrapin::CommandLine.new("echo", ":hello_world")
57
- command.stubs(:command).raises("An Error")
53
+ cmd = Terrapin::CommandLine.new("echo", ":hello_world")
54
+ expect(cmd).to receive(:command).and_raise("An Error")
58
55
 
59
- lambda{ command.run }.should raise_error("An Error")
60
- command.exit_status.should eq 0
56
+ expect{ cmd.run }.to raise_error("An Error")
57
+ expect(cmd.exit_status).to eq 0
61
58
  end
62
59
  end
@@ -3,21 +3,21 @@ require 'spec_helper'
3
3
  describe Terrapin::OSDetector do
4
4
  it "detects that the system is unix" do
5
5
  on_unix!
6
- Terrapin::OS.should be_unix
6
+ expect(Terrapin::OS).to be_unix
7
7
  end
8
8
 
9
9
  it "detects that the system is windows" do
10
10
  on_windows!
11
- Terrapin::OS.should be_windows
11
+ expect(Terrapin::OS).to be_windows
12
12
  end
13
13
 
14
14
  it "detects that the system is windows (mingw)" do
15
15
  on_mingw!
16
- Terrapin::OS.should be_windows
16
+ expect(Terrapin::OS).to be_windows
17
17
  end
18
18
 
19
19
  it "detects that the current Ruby is on Java" do
20
20
  on_java!
21
- Terrapin::OS.should be_java
21
+ expect(Terrapin::OS).to be_java
22
22
  end
23
23
  end
@@ -2,49 +2,37 @@ require 'spec_helper'
2
2
 
3
3
  describe "When picking a Runner" do
4
4
  it "uses the BackticksRunner by default" do
5
- Terrapin::CommandLine::ProcessRunner.stubs(:supported?).returns(false)
6
- Terrapin::CommandLine::PosixRunner.stubs(:supported?).returns(false)
5
+ expect(Terrapin::CommandLine::ProcessRunner).to receive(:supported?).and_return(false)
7
6
 
8
7
  cmd = Terrapin::CommandLine.new("echo", "hello")
9
8
 
10
- cmd.runner.class.should == Terrapin::CommandLine::BackticksRunner
9
+ expect(cmd.runner.class).to eq(Terrapin::CommandLine::BackticksRunner)
11
10
  end
12
11
 
13
12
  it "uses the ProcessRunner on 1.9 and it's available" do
14
- Terrapin::CommandLine::ProcessRunner.stubs(:supported?).returns(true)
15
- Terrapin::CommandLine::PosixRunner.stubs(:supported?).returns(false)
13
+ expect(Terrapin::CommandLine::ProcessRunner).to receive(:supported?).and_return(true)
16
14
 
17
15
  cmd = Terrapin::CommandLine.new("echo", "hello")
18
- cmd.runner.class.should == Terrapin::CommandLine::ProcessRunner
16
+ expect(cmd.runner.class).to eq(Terrapin::CommandLine::ProcessRunner)
19
17
  end
20
18
 
21
- it "uses the PosixRunner if the PosixRunner is available" do
22
- Terrapin::CommandLine::PosixRunner.stubs(:supported?).returns(true)
23
-
24
- cmd = Terrapin::CommandLine.new("echo", "hello")
25
- cmd.runner.class.should == Terrapin::CommandLine::PosixRunner
26
- end
27
-
28
- it "uses the BackticksRunner if the PosixRunner is available, but we told it to use Backticks all the time" do
29
- Terrapin::CommandLine::PosixRunner.stubs(:supported?).returns(true)
19
+ it "uses the BackticksRunner if we told it to use Backticks all the time" do
30
20
  Terrapin::CommandLine.runner = Terrapin::CommandLine::BackticksRunner.new
31
21
 
32
22
  cmd = Terrapin::CommandLine.new("echo", "hello")
33
- cmd.runner.class.should == Terrapin::CommandLine::BackticksRunner
23
+ expect(cmd.runner.class).to eq(Terrapin::CommandLine::BackticksRunner)
34
24
  end
35
25
 
36
- it "uses the BackticksRunner if the PosixRunner is available, but we told it to use Backticks" do
37
- Terrapin::CommandLine::PosixRunner.stubs(:supported?).returns(true)
38
-
26
+ it "uses the BackticksRunner, if we told it to use Backticks" do
39
27
  cmd = Terrapin::CommandLine.new("echo", "hello", :runner => Terrapin::CommandLine::BackticksRunner.new)
40
- cmd.runner.class.should == Terrapin::CommandLine::BackticksRunner
28
+ expect(cmd.runner.class).to eq(Terrapin::CommandLine::BackticksRunner)
41
29
  end
42
30
 
43
31
  it "can go into 'Fake' mode" do
44
32
  Terrapin::CommandLine.fake!
45
33
 
46
34
  cmd = Terrapin::CommandLine.new("echo", "hello")
47
- cmd.runner.class.should eq Terrapin::CommandLine::FakeRunner
35
+ expect(cmd.runner.class).to eq Terrapin::CommandLine::FakeRunner
48
36
  end
49
37
 
50
38
  it "can turn off Fake mode" do
@@ -52,14 +40,14 @@ describe "When picking a Runner" do
52
40
  Terrapin::CommandLine.unfake!
53
41
 
54
42
  cmd = Terrapin::CommandLine.new("echo", "hello")
55
- cmd.runner.class.should_not eq Terrapin::CommandLine::FakeRunner
43
+ expect(cmd.runner.class).not_to eq Terrapin::CommandLine::FakeRunner
56
44
  end
57
45
 
58
46
  it "can use a FakeRunner even if not in Fake mode" do
59
47
  Terrapin::CommandLine.unfake!
60
48
 
61
49
  cmd = Terrapin::CommandLine.new("echo", "hello", :runner => Terrapin::CommandLine::FakeRunner.new)
62
- cmd.runner.class.should eq Terrapin::CommandLine::FakeRunner
50
+ expect(cmd.runner.class).to eq Terrapin::CommandLine::FakeRunner
63
51
  end
64
52
  end
65
53
 
@@ -78,7 +66,6 @@ describe 'When running an executable in the supplemental path' do
78
66
  [
79
67
  Terrapin::CommandLine::BackticksRunner,
80
68
  Terrapin::CommandLine::PopenRunner,
81
- Terrapin::CommandLine::PosixRunner,
82
69
  Terrapin::CommandLine::ProcessRunner
83
70
  ].each do |runner_class|
84
71
  if runner_class.supported?
data/terrapin.gemspec CHANGED
@@ -1,28 +1,24 @@
1
1
  $LOAD_PATH.push File.expand_path("../lib", __FILE__)
2
- require 'terrapin/version'
2
+ require "terrapin/version"
3
3
 
4
4
  Gem::Specification.new do |s|
5
- s.name = "terrapin"
6
- s.version = Terrapin::VERSION.dup
7
- s.platform = Gem::Platform::RUBY
8
- s.author = "Jon Yurek"
9
- s.email = "jyurek@thoughtbot.com"
10
- s.homepage = "https://github.com/thoughtbot/terrapin"
11
- s.summary = "Run shell commands safely, even with user-supplied values"
12
- s.description = "Run shell commands safely, even with user-supplied values"
13
- s.license = "MIT"
5
+ s.name = "terrapin"
6
+ s.version = Terrapin::VERSION.dup
7
+ s.platform = Gem::Platform::RUBY
8
+ s.author = "Jon Yurek"
9
+ s.email = "jyurek@thoughtbot.com"
10
+ s.homepage = "https://github.com/thoughtbot/terrapin"
11
+ s.summary = "Run shell commands safely, even with user-supplied values"
12
+ s.description = "Run shell commands safely, even with user-supplied values"
13
+ s.license = "MIT"
14
14
 
15
- s.files = `git ls-files`.split("\n")
16
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
- s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
15
+ s.files = `git ls-files`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
18
17
  s.require_paths = ["lib"]
19
18
 
20
- s.add_dependency('climate_control', '>= 0.0.3', '< 1.0')
21
- s.add_development_dependency('rspec')
22
- s.add_development_dependency('bourne')
23
- s.add_development_dependency('mocha')
24
- s.add_development_dependency('rake')
25
- s.add_development_dependency('activesupport', ">= 3.0.0", "< 5.0")
26
- s.add_development_dependency('pry')
19
+ s.add_dependency("climate_control")
20
+ s.add_development_dependency("rspec")
21
+ s.add_development_dependency("rake")
22
+ s.add_development_dependency("activesupport", ">= 3.0.0", "< 5.0")
23
+ s.add_development_dependency("pry")
27
24
  end
28
-
metadata CHANGED
@@ -1,57 +1,23 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terrapin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Yurek
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-02 00:00:00.000000000 Z
11
+ date: 2023-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control
15
15
  requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 0.0.3
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '1.0'
23
- type: :runtime
24
- prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: 0.0.3
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: '1.0'
33
- - !ruby/object:Gem::Dependency
34
- name: rspec
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: '0'
40
- type: :development
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
16
  requirements:
44
17
  - - ">="
45
18
  - !ruby/object:Gem::Version
46
19
  version: '0'
47
- - !ruby/object:Gem::Dependency
48
- name: bourne
49
- requirement: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: '0'
54
- type: :development
20
+ type: :runtime
55
21
  prerelease: false
56
22
  version_requirements: !ruby/object:Gem::Requirement
57
23
  requirements:
@@ -59,7 +25,7 @@ dependencies:
59
25
  - !ruby/object:Gem::Version
60
26
  version: '0'
61
27
  - !ruby/object:Gem::Dependency
62
- name: mocha
28
+ name: rspec
63
29
  requirement: !ruby/object:Gem::Requirement
64
30
  requirements:
65
31
  - - ">="
@@ -126,6 +92,7 @@ executables: []
126
92
  extensions: []
127
93
  extra_rdoc_files: []
128
94
  files:
95
+ - ".github/workflows/ci.yml"
129
96
  - ".gitignore"
130
97
  - ".travis.yml"
131
98
  - GOALS
@@ -142,7 +109,6 @@ files:
142
109
  - lib/terrapin/command_line/runners/backticks_runner.rb
143
110
  - lib/terrapin/command_line/runners/fake_runner.rb
144
111
  - lib/terrapin/command_line/runners/popen_runner.rb
145
- - lib/terrapin/command_line/runners/posix_runner.rb
146
112
  - lib/terrapin/command_line/runners/process_runner.rb
147
113
  - lib/terrapin/exceptions.rb
148
114
  - lib/terrapin/os_detector.rb
@@ -152,13 +118,11 @@ files:
152
118
  - spec/support/have_output.rb
153
119
  - spec/support/nonblocking_examples.rb
154
120
  - spec/support/stub_os.rb
155
- - spec/support/unsetting_exitstatus.rb
156
121
  - spec/support/with_exitstatus.rb
157
122
  - spec/terrapin/command_line/output_spec.rb
158
123
  - spec/terrapin/command_line/runners/backticks_runner_spec.rb
159
124
  - spec/terrapin/command_line/runners/fake_runner_spec.rb
160
125
  - spec/terrapin/command_line/runners/popen_runner_spec.rb
161
- - spec/terrapin/command_line/runners/posix_runner_spec.rb
162
126
  - spec/terrapin/command_line/runners/process_runner_spec.rb
163
127
  - spec/terrapin/command_line_spec.rb
164
128
  - spec/terrapin/errors_spec.rb
@@ -169,7 +133,7 @@ homepage: https://github.com/thoughtbot/terrapin
169
133
  licenses:
170
134
  - MIT
171
135
  metadata: {}
172
- post_install_message:
136
+ post_install_message:
173
137
  rdoc_options: []
174
138
  require_paths:
175
139
  - lib
@@ -184,26 +148,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
184
148
  - !ruby/object:Gem::Version
185
149
  version: '0'
186
150
  requirements: []
187
- rubyforge_project:
188
- rubygems_version: 2.6.14
189
- signing_key:
151
+ rubygems_version: 3.4.10
152
+ signing_key:
190
153
  specification_version: 4
191
154
  summary: Run shell commands safely, even with user-supplied values
192
- test_files:
193
- - spec/spec_helper.rb
194
- - spec/support/fake_logger.rb
195
- - spec/support/have_output.rb
196
- - spec/support/nonblocking_examples.rb
197
- - spec/support/stub_os.rb
198
- - spec/support/unsetting_exitstatus.rb
199
- - spec/support/with_exitstatus.rb
200
- - spec/terrapin/command_line/output_spec.rb
201
- - spec/terrapin/command_line/runners/backticks_runner_spec.rb
202
- - spec/terrapin/command_line/runners/fake_runner_spec.rb
203
- - spec/terrapin/command_line/runners/popen_runner_spec.rb
204
- - spec/terrapin/command_line/runners/posix_runner_spec.rb
205
- - spec/terrapin/command_line/runners/process_runner_spec.rb
206
- - spec/terrapin/command_line_spec.rb
207
- - spec/terrapin/errors_spec.rb
208
- - spec/terrapin/os_detector_spec.rb
209
- - spec/terrapin/runners_spec.rb
155
+ test_files: []
@@ -1,49 +0,0 @@
1
- # coding: UTF-8
2
-
3
- module Terrapin
4
- class CommandLine
5
- class PosixRunner
6
- def self.available?
7
- return @available unless @available.nil?
8
-
9
- @available = posix_spawn_gem_available?
10
- end
11
-
12
- def self.supported?
13
- available? && !OS.java?
14
- end
15
-
16
- def supported?
17
- self.class.supported?
18
- end
19
-
20
- def call(command, env = {}, options = {})
21
- pipe = MultiPipe.new
22
- pid = spawn(env, command, options.merge(pipe.pipe_options))
23
- pipe.read_and_then do
24
- waitpid(pid)
25
- end
26
- pipe.output
27
- end
28
-
29
- private
30
-
31
- def spawn(*args)
32
- POSIX::Spawn.spawn(*args)
33
- end
34
-
35
- def waitpid(pid)
36
- Process.waitpid(pid)
37
- end
38
-
39
- def self.posix_spawn_gem_available?
40
- require 'posix/spawn'
41
- true
42
- rescue LoadError
43
- false
44
- end
45
-
46
- private_class_method :posix_spawn_gem_available?
47
- end
48
- end
49
- end
@@ -1,7 +0,0 @@
1
- module UnsettingExitstatus
2
- def assuming_no_processes_have_been_run
3
- class << $?
4
- undef_method :exitstatus
5
- end
6
- end
7
- end
@@ -1,40 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Terrapin::CommandLine::PosixRunner do
4
- if Terrapin::CommandLine::PosixRunner.supported?
5
- it_behaves_like 'a command that does not block'
6
-
7
- it 'runs the command given and captures the output' do
8
- output = subject.call("echo hello")
9
- expect(output).to have_output "hello\n"
10
- end
11
-
12
- it 'runs the command given and captures the error output' do
13
- output = subject.call("echo hello 1>&2")
14
- expect(output).to have_error_output "hello\n"
15
- end
16
-
17
- it 'modifies the environment and runs the command given' do
18
- output = subject.call("echo $yes", {"yes" => "no"})
19
- expect(output).to have_output "no\n"
20
- end
21
-
22
- it 'sets the exitstatus when a command completes' do
23
- subject.call("ruby -e 'exit 0'")
24
- $?.exitstatus.should == 0
25
- subject.call("ruby -e 'exit 5'")
26
- $?.exitstatus.should == 5
27
- end
28
-
29
- it "runs the command it's given and allows access to stderr afterwards" do
30
- cmd = Terrapin::CommandLine.new(
31
- "ruby",
32
- "-e '$stdout.puts %{hello}; $stderr.puts %{goodbye}'",
33
- :swallow_stderr => false
34
- )
35
- cmd.run
36
- expect(cmd.command_output).to eq "hello\n"
37
- expect(cmd.command_error_output).to eq "goodbye\n"
38
- end
39
- end
40
- end