qbash 0.0.3 → 0.0.5

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
  SHA256:
3
- metadata.gz: d3ac44ac6da719be360ee7785811de7c2b465efbe274c8ae9f7b0992647c05c0
4
- data.tar.gz: cf4e840be85b2b9fc19df98fc2e7f45f45b6c93a525b209a4f715be104870ef5
3
+ metadata.gz: 629198be7c8f09f07807f2fdc3f43b771df5d1b97ef33ae3a827c1d56a9ec98c
4
+ data.tar.gz: f7b85be41ea296b819d13e3f4cb23f9d0bfb8137de8f05cd6f10737e535c68a7
5
5
  SHA512:
6
- metadata.gz: 5eaf974307cfb04ead1c2a890c6c34cb68c1ba9a1f4a3e1f2b858f5eda0579361296fb5e95f8fd3349455f07b5acf4ea8a9fac400f6cde5ace0d1f7381b64cb9
7
- data.tar.gz: 554613f18dd98fcac12d7e0d4ce56f1cc8d0aaeaea5866fad42ef41f5bb96dfaddb37d00b75fdefde6665eb0b59f1f1add15668d618379e1e14829457b87844f
6
+ metadata.gz: 026321cb7140203439059803f02a305980c5c44b988c9ebab82522eb8ede41d9d45dad8c6b1d312fcf7a9ae2192cabd2a67b7305e98d8836fd25d5276ceb6a48
7
+ data.tar.gz: fd16b90f2af7f1a8ff116e0c1d95cc66a760e4c6c74fcc2763990d9ccf8b07517b6886277e81c8e18164db4c794ac7b619f5df98a20eed888b36fc0fbd300423
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.5', require: false
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.23.1', require: false
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.0)
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.7)
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.5)
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.23.1)
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.1)
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.5)
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.23.1)
261
+ webmock (= 3.24.0)
261
262
  yard (= 0.9.37)
262
263
 
263
264
  BUNDLED WITH
data/README.md CHANGED
@@ -27,7 +27,7 @@ Then, you can use [qbash][qbash] global function:
27
27
 
28
28
  ```ruby
29
29
  require 'qbash'
30
- stdout = qbash('echo "Hello, world!"')
30
+ stdout = qbash('echo "Hello, world!"', log: $stdout)
31
31
  ```
32
32
 
33
33
  If the command fails, an exception will be raised.
@@ -38,13 +38,13 @@ It's possible to provide the standard input and environment variables:
38
38
  stdout = qbash('cat > $FILE', env: { 'FILE' => 'a.txt' }, stdin: 'Hello!')
39
39
  ```
40
40
 
41
- It's possible to configure the logging facility too, with the help
41
+ It's possible to configure the logging facility too, for example, with the help
42
42
  of the [loog](https://github.com/yegor256/loog) gem (the output
43
43
  will be returned _and_ printed to the logger):
44
44
 
45
45
  ```ruby
46
46
  require 'loog'
47
- qbash('echo "Hello, world!"', loog: Loog::VERBOSE)
47
+ qbash('echo "Hello, world!"', log: Loog::VERBOSE)
48
48
  ```
49
49
 
50
50
  You can also make it return both stdout and exit code, with the help
@@ -82,6 +82,14 @@ qbash("cat #{Shellwords.escape(file)}")
82
82
  Without such an escaping, in this example, a space inside the `file`
83
83
  will lead to an unpredicatable result of the execution.
84
84
 
85
+ You can also set the maximum time for the command:
86
+
87
+ ```ruby
88
+ qbash("sleep 100", timeout: 4)
89
+ ```
90
+
91
+ This command will raise exception after four seconds.
92
+
85
93
  ## How to contribute
86
94
 
87
95
  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
  #
@@ -37,14 +38,18 @@ module Kernel
37
38
  #
38
39
  # To escape arguments, use +Shellwords.escape()+ method.
39
40
  #
41
+ # Read this <a href="https://github.com/yegor256/qbash">README</a> file for more details.
42
+ #
40
43
  # @param [String] cmd The command to run, for example +echo "Hello, world!"+
41
44
  # @param [String] stdin The +stdin+ to provide to the command
42
45
  # @param [Hash] env Hash of environment variables
43
46
  # @param [Loog|IO] log Logging facility with +.debug()+ method (or +$stdout+)
44
47
  # @param [Array] accept List of accepted exit codes (accepts all if the list is empty)
45
48
  # @param [Boolean] both If set to TRUE, the function returns an array +(stdout, code)+
49
+ # @param [Integer] timeout If it's set to non-NIL, the execution will fail after this number of seconds
46
50
  # @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)
51
+ def qbash(cmd, stdin: '', env: {}, log: Loog::NULL, accept: [0], both: false, timeout: nil)
52
+ cmd = cmd.join(' ') if cmd.is_a?(Array)
48
53
  if log.respond_to?(:debug)
49
54
  log.debug("+ #{cmd}")
50
55
  else
@@ -52,26 +57,32 @@ module Kernel
52
57
  end
53
58
  buf = ''
54
59
  e = 1
55
- cmd = cmd.join(' ') if cmd.is_a?(Array)
56
- Open3.popen2e(env, "/bin/bash -c #{Shellwords.escape(cmd)}") do |sin, sout, thr|
57
- sin.write(stdin)
58
- sin.close
59
- until sout.eof?
60
- begin
61
- ln = sout.gets
62
- rescue IOError => e
63
- ln = Backtrace.new(e).to_s
60
+ start = Time.now
61
+ thread =
62
+ Thread.new do
63
+ Open3.popen2e(env, "/bin/bash -c #{Shellwords.escape(cmd)}") do |sin, sout, thr|
64
+ sin.write(stdin)
65
+ sin.close
66
+ until sout.eof?
67
+ begin
68
+ ln = sout.gets
69
+ rescue IOError => e
70
+ ln = Backtrace.new(e).to_s
71
+ end
72
+ if log.respond_to?(:debug)
73
+ log.debug(ln)
74
+ else
75
+ log.print("#{ln}\n")
76
+ end
77
+ buf += ln
78
+ end
79
+ e = thr.value.to_i
80
+ if !accept.empty? && !accept.include?(e)
81
+ raise "The command '#{cmd}' failed with exit code ##{e} in #{start.ago}\n#{buf}"
82
+ end
64
83
  end
65
- if log.respond_to?(:debug)
66
- log.debug(ln)
67
- else
68
- log.print("#{ln}\n")
69
- end
70
- buf += ln
71
84
  end
72
- e = thr.value.to_i
73
- raise "The command '#{cmd}' failed with exit code ##{e}\n#{buf}" if !accept.empty? && !accept.include?(e)
74
- end
85
+ raise "Execution of #{cmd} timed out in #{start.ago}" if thread.join(timeout).nil?
75
86
  return [buf, e] if both
76
87
  buf
77
88
  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.3'
29
+ s.version = '0.0.5'
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
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.3
4
+ version: 0.0.5
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-09-23 00:00:00.000000000 Z
11
+ date: 2024-10-02 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