qbash 0.0.4 → 0.0.6
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/Gemfile +2 -2
- data/Gemfile.lock +8 -7
- data/README.md +11 -0
- data/lib/qbash.rb +36 -19
- data/qbash.gemspec +2 -1
- data/test/test_qbash.rb +8 -2
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ddc357961a48953ee7c479583b6d648d9ad34873510e7ef6d8096a7bd8e596b5
|
4
|
+
data.tar.gz: 16dfe814c412365131380e239a93e90532419ece6e66fb3ce0c74bf6566cae5b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15ae921b000efb256d6907b1b69cda9e60a63612d25eccab76b09f0c765d6aa9d1337ed43580b3bf18cfd84a73e69b4f16aaad62065c8df9644a87779c0d8485
|
7
|
+
data.tar.gz: 6de449a43159e54803266ca16cb960bd09772abbb9a33ad3b5fa77fa25be63cef6e38fa0edb003c342e2c495bfd37b98035365aa76a9a2b9271d99385498ac96
|
data/Gemfile
CHANGED
@@ -32,9 +32,9 @@ gem 'random-port', '~>0.0', require: false
|
|
32
32
|
gem 'rspec-rails', '7.0.1', require: false
|
33
33
|
gem 'rubocop', '1.66.1', require: false
|
34
34
|
gem 'rubocop-performance', '1.22.1', require: false
|
35
|
-
gem 'rubocop-rspec', '3.0
|
35
|
+
gem 'rubocop-rspec', '3.1.0', require: false
|
36
36
|
gem 'simplecov', '0.22.0', require: false
|
37
37
|
gem 'simplecov-cobertura', '2.1.0', require: false
|
38
38
|
gem 'w3c_validators', '1.3.7', require: false
|
39
|
-
gem 'webmock', '3.
|
39
|
+
gem 'webmock', '3.24.0', require: false
|
40
40
|
gem 'yard', '0.9.37', require: false
|
data/Gemfile.lock
CHANGED
@@ -5,6 +5,7 @@ PATH
|
|
5
5
|
backtrace (> 0)
|
6
6
|
elapsed (> 0)
|
7
7
|
loog (> 0)
|
8
|
+
tago (> 0)
|
8
9
|
|
9
10
|
GEM
|
10
11
|
remote: https://rubygems.org/
|
@@ -94,7 +95,7 @@ GEM
|
|
94
95
|
i18n (1.14.6)
|
95
96
|
concurrent-ruby (~> 1.0)
|
96
97
|
io-console (0.7.2)
|
97
|
-
irb (1.14.
|
98
|
+
irb (1.14.1)
|
98
99
|
rdoc (>= 4.0.0)
|
99
100
|
reline (>= 0.4.2)
|
100
101
|
json (2.7.2)
|
@@ -166,7 +167,7 @@ GEM
|
|
166
167
|
regexp_parser (2.9.2)
|
167
168
|
reline (0.5.10)
|
168
169
|
io-console (~> 0.5)
|
169
|
-
rexml (3.3.
|
170
|
+
rexml (3.3.8)
|
170
171
|
rspec-core (3.13.1)
|
171
172
|
rspec-support (~> 3.13.0)
|
172
173
|
rspec-expectations (3.13.3)
|
@@ -199,7 +200,7 @@ GEM
|
|
199
200
|
rubocop-performance (1.22.1)
|
200
201
|
rubocop (>= 1.48.1, < 2.0)
|
201
202
|
rubocop-ast (>= 1.31.1, < 2.0)
|
202
|
-
rubocop-rspec (3.0
|
203
|
+
rubocop-rspec (3.1.0)
|
203
204
|
rubocop (~> 1.61)
|
204
205
|
ruby-progressbar (1.13.0)
|
205
206
|
securerandom (0.3.1)
|
@@ -225,11 +226,11 @@ GEM
|
|
225
226
|
json (>= 1.8)
|
226
227
|
nokogiri (~> 1.6)
|
227
228
|
rexml (~> 3.2)
|
228
|
-
webmock (3.
|
229
|
+
webmock (3.24.0)
|
229
230
|
addressable (>= 2.8.0)
|
230
231
|
crack (>= 0.3.2)
|
231
232
|
hashdiff (>= 0.4.0, < 2.0.0)
|
232
|
-
webrick (1.8.
|
233
|
+
webrick (1.8.2)
|
233
234
|
yard (0.9.37)
|
234
235
|
zeitwerk (2.6.18)
|
235
236
|
|
@@ -253,11 +254,11 @@ DEPENDENCIES
|
|
253
254
|
rspec-rails (= 7.0.1)
|
254
255
|
rubocop (= 1.66.1)
|
255
256
|
rubocop-performance (= 1.22.1)
|
256
|
-
rubocop-rspec (= 3.0
|
257
|
+
rubocop-rspec (= 3.1.0)
|
257
258
|
simplecov (= 0.22.0)
|
258
259
|
simplecov-cobertura (= 2.1.0)
|
259
260
|
w3c_validators (= 1.3.7)
|
260
|
-
webmock (= 3.
|
261
|
+
webmock (= 3.24.0)
|
261
262
|
yard (= 0.9.37)
|
262
263
|
|
263
264
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -32,6 +32,9 @@ stdout = qbash('echo "Hello, world!"', log: $stdout)
|
|
32
32
|
|
33
33
|
If the command fails, an exception will be raised.
|
34
34
|
|
35
|
+
The function automatically merges `stderr` with `stdout`
|
36
|
+
(you can't change this).
|
37
|
+
|
35
38
|
It's possible to provide the standard input and environment variables:
|
36
39
|
|
37
40
|
```ruby
|
@@ -82,6 +85,14 @@ qbash("cat #{Shellwords.escape(file)}")
|
|
82
85
|
Without such an escaping, in this example, a space inside the `file`
|
83
86
|
will lead to an unpredicatable result of the execution.
|
84
87
|
|
88
|
+
You can also set the maximum time for the command:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
qbash("sleep 100", timeout: 4)
|
92
|
+
```
|
93
|
+
|
94
|
+
This command will raise exception after four seconds.
|
95
|
+
|
85
96
|
## How to contribute
|
86
97
|
|
87
98
|
Read
|
data/lib/qbash.rb
CHANGED
@@ -24,6 +24,7 @@ require 'backtrace'
|
|
24
24
|
require 'loog'
|
25
25
|
require 'open3'
|
26
26
|
require 'shellwords'
|
27
|
+
require 'tago'
|
27
28
|
|
28
29
|
# Execute one bash command.
|
29
30
|
#
|
@@ -33,18 +34,27 @@ require 'shellwords'
|
|
33
34
|
module Kernel
|
34
35
|
# Execute a single bash command.
|
35
36
|
#
|
37
|
+
# For example:
|
38
|
+
#
|
39
|
+
# year = qbash('date +%Y')
|
40
|
+
#
|
36
41
|
# If exit code is not zero, an exception will be raised.
|
37
42
|
#
|
38
43
|
# To escape arguments, use +Shellwords.escape()+ method.
|
39
44
|
#
|
45
|
+
# Stderr automatically merges with stdout.
|
46
|
+
#
|
47
|
+
# Read this <a href="https://github.com/yegor256/qbash">README</a> file for more details.
|
48
|
+
#
|
40
49
|
# @param [String] cmd The command to run, for example +echo "Hello, world!"+
|
41
50
|
# @param [String] stdin The +stdin+ to provide to the command
|
42
51
|
# @param [Hash] env Hash of environment variables
|
43
52
|
# @param [Loog|IO] log Logging facility with +.debug()+ method (or +$stdout+)
|
44
|
-
# @param [Array] accept List of accepted exit codes (accepts all if the list is
|
53
|
+
# @param [Array] accept List of accepted exit codes (accepts all if the list is +nil+)
|
45
54
|
# @param [Boolean] both If set to TRUE, the function returns an array +(stdout, code)+
|
55
|
+
# @param [Integer] timeout If it's set to non-NIL, the execution will fail after this number of seconds
|
46
56
|
# @return [String] Everything that was printed to the +stdout+ by the command
|
47
|
-
def qbash(cmd, stdin: '', env: {}, log: Loog::NULL, accept: [0], both: false)
|
57
|
+
def qbash(cmd, stdin: '', env: {}, log: Loog::NULL, accept: [0], both: false, timeout: nil)
|
48
58
|
cmd = cmd.join(' ') if cmd.is_a?(Array)
|
49
59
|
if log.respond_to?(:debug)
|
50
60
|
log.debug("+ #{cmd}")
|
@@ -53,25 +63,32 @@ module Kernel
|
|
53
63
|
end
|
54
64
|
buf = ''
|
55
65
|
e = 1
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
start = Time.now
|
67
|
+
thread =
|
68
|
+
Thread.new do
|
69
|
+
Open3.popen2e(env, "/bin/bash -c #{Shellwords.escape(cmd)}") do |sin, sout, thr|
|
70
|
+
sin.write(stdin)
|
71
|
+
sin.close
|
72
|
+
until sout.eof?
|
73
|
+
begin
|
74
|
+
ln = sout.gets
|
75
|
+
rescue IOError => e
|
76
|
+
ln = Backtrace.new(e).to_s
|
77
|
+
end
|
78
|
+
if log.respond_to?(:debug)
|
79
|
+
log.debug(ln)
|
80
|
+
else
|
81
|
+
log.print("#{ln}\n")
|
82
|
+
end
|
83
|
+
buf += ln
|
84
|
+
end
|
85
|
+
e = thr.value.to_i
|
86
|
+
if !accept.nil? && !accept.include?(e)
|
87
|
+
raise "The command '#{cmd}' failed with exit code ##{e} in #{start.ago}\n#{buf}"
|
88
|
+
end
|
69
89
|
end
|
70
|
-
buf += ln
|
71
90
|
end
|
72
|
-
|
73
|
-
raise "The command '#{cmd}' failed with exit code ##{e}\n#{buf}" if !accept.empty? && !accept.include?(e)
|
74
|
-
end
|
91
|
+
raise "Execution of #{cmd} timed out in #{start.ago}" if thread.join(timeout).nil?
|
75
92
|
return [buf, e] if both
|
76
93
|
buf
|
77
94
|
end
|
data/qbash.gemspec
CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
|
27
27
|
s.required_ruby_version = '>=3.2'
|
28
28
|
s.name = 'qbash'
|
29
|
-
s.version = '0.0.
|
29
|
+
s.version = '0.0.6'
|
30
30
|
s.license = 'MIT'
|
31
31
|
s.summary = 'Quick Executor of a BASH Command'
|
32
32
|
s.description =
|
@@ -42,5 +42,6 @@ Gem::Specification.new do |s|
|
|
42
42
|
s.add_dependency 'backtrace', '>0'
|
43
43
|
s.add_dependency 'elapsed', '>0'
|
44
44
|
s.add_dependency 'loog', '>0'
|
45
|
+
s.add_dependency 'tago', '>0'
|
45
46
|
s.metadata['rubygems_mfa_required'] = 'true'
|
46
47
|
end
|
data/test/test_qbash.rb
CHANGED
@@ -57,6 +57,12 @@ class TestQbash < Minitest::Test
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
+
def test_with_timeout
|
61
|
+
assert_raises do
|
62
|
+
qbash('sleep 100', timeout: 0.1)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
60
66
|
def test_with_special_symbols
|
61
67
|
assert_equal("'hi'\n", qbash("echo \"'hi'\""))
|
62
68
|
end
|
@@ -69,13 +75,13 @@ class TestQbash < Minitest::Test
|
|
69
75
|
|
70
76
|
def test_ignore_errors
|
71
77
|
Dir.mktmpdir do |home|
|
72
|
-
qbash("cat #{Shellwords.escape(File.join(home, 'b.txt'))}", accept:
|
78
|
+
qbash("cat #{Shellwords.escape(File.join(home, 'b.txt'))}", accept: nil)
|
73
79
|
end
|
74
80
|
end
|
75
81
|
|
76
82
|
def test_with_both
|
77
83
|
Dir.mktmpdir do |home|
|
78
|
-
stdout, code = qbash("cat #{Shellwords.escape(File.join(home, 'foo.txt'))}", accept:
|
84
|
+
stdout, code = qbash("cat #{Shellwords.escape(File.join(home, 'foo.txt'))}", accept: nil, both: true)
|
79
85
|
assert(code.positive?)
|
80
86
|
assert(!stdout.empty?)
|
81
87
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qbash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backtrace
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: tago
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description: With the help of Open3 executes bash command and conveniently returns
|
56
70
|
its output and exit code
|
57
71
|
email: yegor256@gmail.com
|