terrapin 1.0.1 → 1.1.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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +4 -2
- data/.github/workflows/dynamic-readme.yml +17 -0
- data/.github/workflows/dynamic-security.yml +19 -0
- data/CODEOWNERS +15 -0
- data/NEWS.md +12 -0
- data/README.md +20 -9
- data/SECURITY.md +20 -0
- data/lib/terrapin/command_line/multi_pipe.rb +38 -6
- data/lib/terrapin/command_line.rb +1 -1
- data/lib/terrapin/version.rb +1 -1
- data/spec/support/nonblocking_examples.rb +12 -1
- data/spec/terrapin/command_line/runners/backticks_runner_spec.rb +1 -1
- data/spec/terrapin/command_line/runners/popen_runner_spec.rb +1 -1
- data/spec/terrapin/command_line/runners/process_runner_spec.rb +1 -1
- data/terrapin.gemspec +1 -0
- metadata +21 -7
- data/.travis.yml +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 066c74dc23f8fa6c2327eb3fec6f31b8169bc240164716937b96acd3796e7df6
|
4
|
+
data.tar.gz: 25bf6daf469817cb75d15c17b83880faaeb0289f054a876f53a411532c4026f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c5324dc84dbff0c5487cc74bc94053f4551038586a7a36b8b4cfcb87f1947a318b271ec83e23f3396d2f038ea30243b35fcd5211c79172c2d90c708855e8439
|
7
|
+
data.tar.gz: 9236fe888b471278554bbbba8e89bfd26ae943e87698b8e647247bd153a6ab6195a38ff52b6407d1859e7c02fd050166b42deb9dd308ff50ef65fb4df70bd5d1
|
data/.github/workflows/ci.yml
CHANGED
@@ -11,16 +11,18 @@ jobs:
|
|
11
11
|
fail-fast: false
|
12
12
|
matrix:
|
13
13
|
ruby:
|
14
|
-
- jruby-9.4.
|
14
|
+
- jruby-9.4.12.0
|
15
15
|
- "2.7"
|
16
16
|
- "3.0"
|
17
17
|
- "3.1"
|
18
18
|
- "3.2"
|
19
|
+
- "3.3"
|
20
|
+
- "3.4"
|
19
21
|
|
20
22
|
runs-on: 'ubuntu-latest'
|
21
23
|
|
22
24
|
steps:
|
23
|
-
- uses: actions/checkout@
|
25
|
+
- uses: actions/checkout@v4
|
24
26
|
- uses: ruby/setup-ruby@v1
|
25
27
|
with:
|
26
28
|
ruby-version: ${{ matrix.ruby }}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
name: update-templates
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- main
|
7
|
+
workflow_dispatch:
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
update-templates:
|
11
|
+
permissions:
|
12
|
+
contents: write
|
13
|
+
pull-requests: write
|
14
|
+
pages: write
|
15
|
+
uses: thoughtbot/templates/.github/workflows/dynamic-readme.yaml@main
|
16
|
+
secrets:
|
17
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
name: update-security
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
paths:
|
6
|
+
- SECURITY.md
|
7
|
+
branches:
|
8
|
+
- main
|
9
|
+
workflow_dispatch:
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
update-security:
|
13
|
+
permissions:
|
14
|
+
contents: write
|
15
|
+
pull-requests: write
|
16
|
+
pages: write
|
17
|
+
uses: thoughtbot/templates/.github/workflows/dynamic-security.yaml@main
|
18
|
+
secrets:
|
19
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
data/CODEOWNERS
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Lines starting with '#' are comments.
|
2
|
+
# Each line is a file pattern followed by one or more owners.
|
3
|
+
|
4
|
+
# More details are here: https://help.github.com/articles/about-codeowners/
|
5
|
+
|
6
|
+
# The '*' pattern is global owners.
|
7
|
+
|
8
|
+
# Order is important. The last matching pattern has the most precedence.
|
9
|
+
# The folders are ordered as follows:
|
10
|
+
|
11
|
+
# In each subsection folders are ordered first by depth, then alphabetically.
|
12
|
+
# This should make it easy to add new rules without breaking existing ones.
|
13
|
+
|
14
|
+
# Global rule:
|
15
|
+
* @cpytel
|
data/NEWS.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
New for 1.1.0:
|
2
|
+
|
3
|
+
* Remove Travis CI configuration
|
4
|
+
* Fix the stderr test
|
5
|
+
* Add Ruby 3.3, 3.4 to the build matrix
|
6
|
+
* Upgrade actions/checkout from v2 to v4
|
7
|
+
* Upgrade JRuby to 9.4.12.0
|
8
|
+
* Insert an inspect on the exit status
|
9
|
+
* Don't hang on stderr
|
10
|
+
* Add 'logger' as development dependency (fixes ruby 3.4 warning)
|
11
|
+
* Use String.new to create a mutable string
|
12
|
+
|
1
13
|
New for 1.0.1:
|
2
14
|
|
3
15
|
* Relax version requirement for `climate_control` dependency
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Terrapin
|
1
|
+
# Terrapin
|
2
2
|
|
3
3
|
Run shell commands safely, even with user-supplied values
|
4
4
|
|
@@ -207,16 +207,27 @@ Question? Idea? Problem? Bug? Comment? Concern? Like using question marks?
|
|
207
207
|
Thank you to all [the
|
208
208
|
contributors](https://github.com/thoughtbot/terrapin/graphs/contributors)!
|
209
209
|
|
210
|
-

|
211
|
-
|
212
|
-
Terrapin is maintained and funded by [thoughtbot,
|
213
|
-
inc](http://thoughtbot.com/community)
|
214
|
-
|
215
|
-
The names and logos for thoughtbot are trademarks of thoughtbot, inc.
|
216
|
-
|
217
210
|
## License
|
218
211
|
|
219
|
-
Copyright 2011
|
212
|
+
Copyright © 2011 Jon Yurek and thoughtbot, inc. This is free software, and
|
220
213
|
may be redistributed under the terms specified in the
|
221
214
|
[LICENSE](https://github.com/thoughtbot/terrapin/blob/master/LICENSE)
|
222
215
|
file.
|
216
|
+
|
217
|
+
<!-- START /templates/footer.md -->
|
218
|
+
## About thoughtbot
|
219
|
+
|
220
|
+

|
221
|
+
|
222
|
+
This repo is maintained and funded by thoughtbot, inc.
|
223
|
+
The names and logos for thoughtbot are trademarks of thoughtbot, inc.
|
224
|
+
|
225
|
+
We love open source software!
|
226
|
+
See [our other projects][community].
|
227
|
+
We are [available for hire][hire].
|
228
|
+
|
229
|
+
[community]: https://thoughtbot.com/community?utm_source=github
|
230
|
+
[hire]: https://thoughtbot.com/hire-us?utm_source=github
|
231
|
+
|
232
|
+
|
233
|
+
<!-- END /templates/footer.md -->
|
data/SECURITY.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
<!-- START /templates/security.md -->
|
2
|
+
# Security Policy
|
3
|
+
|
4
|
+
## Supported Versions
|
5
|
+
|
6
|
+
Only the the latest version of this project is supported at a given time. If
|
7
|
+
you find a security issue with an older version, please try updating to the
|
8
|
+
latest version first.
|
9
|
+
|
10
|
+
If for some reason you can't update to the latest version, please let us know
|
11
|
+
your reasons so that we can have a better understanding of your situation.
|
12
|
+
|
13
|
+
## Reporting a Vulnerability
|
14
|
+
|
15
|
+
For security inquiries or vulnerability reports, visit
|
16
|
+
<https://thoughtbot.com/security>.
|
17
|
+
|
18
|
+
If you have any suggestions to improve this policy, visit <https://thoughtbot.com/security>.
|
19
|
+
|
20
|
+
<!-- END /templates/security.md -->
|
@@ -29,19 +29,51 @@ module Terrapin
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def read
|
32
|
-
@
|
33
|
-
@stderr_output = read_stream(@stderr_in)
|
32
|
+
read_streams(@stdout_in, @stderr_in)
|
34
33
|
end
|
35
34
|
|
36
35
|
def close_read
|
37
|
-
|
36
|
+
begin
|
37
|
+
@stdout_in.close
|
38
|
+
rescue IOError
|
39
|
+
# do nothing
|
40
|
+
end
|
41
|
+
|
42
|
+
begin
|
38
43
|
@stderr_in.close
|
44
|
+
rescue IOError
|
45
|
+
# do nothing
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def read_streams(output, error)
|
50
|
+
@stdout_output = ""
|
51
|
+
@stderr_output = ""
|
52
|
+
read_fds = [output, error]
|
53
|
+
while !read_fds.empty?
|
54
|
+
to_read, = IO.select(read_fds)
|
55
|
+
if to_read.include?(output)
|
56
|
+
@stdout_output << read_stream(output)
|
57
|
+
read_fds.delete(output) if output.closed?
|
58
|
+
end
|
59
|
+
|
60
|
+
if to_read.include?(error)
|
61
|
+
@stderr_output << read_stream(error)
|
62
|
+
read_fds.delete(error) if error.closed?
|
63
|
+
end
|
64
|
+
end
|
39
65
|
end
|
40
66
|
|
41
67
|
def read_stream(io)
|
42
|
-
result =
|
43
|
-
|
44
|
-
|
68
|
+
result = String.new
|
69
|
+
begin
|
70
|
+
while partial_result = io.read_nonblock(8192)
|
71
|
+
result << partial_result
|
72
|
+
end
|
73
|
+
rescue EOFError, Errno::EPIPE
|
74
|
+
io.close
|
75
|
+
rescue Errno::EINTR, Errno::EWOULDBLOCK, Errno::EAGAIN
|
76
|
+
# do nothing
|
45
77
|
end
|
46
78
|
result
|
47
79
|
end
|
@@ -89,7 +89,7 @@ module Terrapin
|
|
89
89
|
|
90
90
|
unless @expected_outcodes.include?(@exit_status)
|
91
91
|
message = [
|
92
|
-
"Command '#{full_command}' returned #{@exit_status}. Expected #{@expected_outcodes.join(", ")}",
|
92
|
+
"Command '#{full_command}' returned #{@exit_status.inspect}. Expected #{@expected_outcodes.join(", ")}",
|
93
93
|
"Here is the command output: STDOUT:\n", command_output,
|
94
94
|
"\nSTDERR:\n", command_error_output
|
95
95
|
].join("\n")
|
data/lib/terrapin/version.rb
CHANGED
@@ -1,4 +1,15 @@
|
|
1
|
-
shared_examples_for "a command that does not block" do
|
1
|
+
shared_examples_for "a command that does not block" do |opts = {}|
|
2
|
+
if opts[:supports_stderr]
|
3
|
+
it "does not block if the command output a lot on stderr" do
|
4
|
+
Timeout.timeout(5) do
|
5
|
+
output = subject.call("ruby -e '$stdout.puts %{hello}; $stderr.puts %{goodbye}*10_000'")
|
6
|
+
|
7
|
+
expect(output.output).to eq "hello\n"
|
8
|
+
expect(output.error_output).to eq "#{"goodbye" * 10_000}\n"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
2
13
|
it 'does not block if the command outputs a lot of data' do
|
3
14
|
garbage_file = Tempfile.new("garbage")
|
4
15
|
10.times{ garbage_file.write("A" * 1024 * 1024) }
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Terrapin::CommandLine::BackticksRunner do
|
4
4
|
if Terrapin::CommandLine::BackticksRunner.supported?
|
5
|
-
it_behaves_like 'a command that does not block'
|
5
|
+
it_behaves_like 'a command that does not block', { :supports_stderr => false }
|
6
6
|
|
7
7
|
it 'runs the command given and captures the output in an Output' do
|
8
8
|
output = subject.call("echo hello")
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Terrapin::CommandLine::PopenRunner do
|
4
4
|
if Terrapin::CommandLine::PopenRunner.supported?
|
5
|
-
it_behaves_like 'a command that does not block'
|
5
|
+
it_behaves_like 'a command that does not block', { :supports_stderr => false }
|
6
6
|
|
7
7
|
it 'runs the command given and captures the output in an Output' do
|
8
8
|
output = subject.call("echo hello")
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Terrapin::CommandLine::ProcessRunner do
|
4
4
|
if Terrapin::CommandLine::ProcessRunner.supported?
|
5
|
-
it_behaves_like "a command that does not block"
|
5
|
+
it_behaves_like "a command that does not block", { :supports_stderr => true }
|
6
6
|
|
7
7
|
it 'runs the command given and captures the output' do
|
8
8
|
output = subject.call("echo hello")
|
data/terrapin.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: terrapin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Yurek
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-03-24 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: climate_control
|
@@ -86,6 +85,20 @@ dependencies:
|
|
86
85
|
- - ">="
|
87
86
|
- !ruby/object:Gem::Version
|
88
87
|
version: '0'
|
88
|
+
- !ruby/object:Gem::Dependency
|
89
|
+
name: logger
|
90
|
+
requirement: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
type: :development
|
96
|
+
prerelease: false
|
97
|
+
version_requirements: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
89
102
|
description: Run shell commands safely, even with user-supplied values
|
90
103
|
email: jyurek@thoughtbot.com
|
91
104
|
executables: []
|
@@ -93,14 +106,17 @@ extensions: []
|
|
93
106
|
extra_rdoc_files: []
|
94
107
|
files:
|
95
108
|
- ".github/workflows/ci.yml"
|
109
|
+
- ".github/workflows/dynamic-readme.yml"
|
110
|
+
- ".github/workflows/dynamic-security.yml"
|
96
111
|
- ".gitignore"
|
97
|
-
-
|
112
|
+
- CODEOWNERS
|
98
113
|
- GOALS
|
99
114
|
- Gemfile
|
100
115
|
- LICENSE
|
101
116
|
- NEWS.md
|
102
117
|
- README.md
|
103
118
|
- Rakefile
|
119
|
+
- SECURITY.md
|
104
120
|
- lib/terrapin.rb
|
105
121
|
- lib/terrapin/command_line.rb
|
106
122
|
- lib/terrapin/command_line/multi_pipe.rb
|
@@ -133,7 +149,6 @@ homepage: https://github.com/thoughtbot/terrapin
|
|
133
149
|
licenses:
|
134
150
|
- MIT
|
135
151
|
metadata: {}
|
136
|
-
post_install_message:
|
137
152
|
rdoc_options: []
|
138
153
|
require_paths:
|
139
154
|
- lib
|
@@ -148,8 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
163
|
- !ruby/object:Gem::Version
|
149
164
|
version: '0'
|
150
165
|
requirements: []
|
151
|
-
rubygems_version: 3.
|
152
|
-
signing_key:
|
166
|
+
rubygems_version: 3.6.2
|
153
167
|
specification_version: 4
|
154
168
|
summary: Run shell commands safely, even with user-supplied values
|
155
169
|
test_files: []
|