cheetah 0.5.2 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ffad6048946bc9340bf92edbc08b4955a2444da86ed5c029bcf3a2f5b799f78
4
- data.tar.gz: d3fc65ea30218372099bf81ab8ab86d4c5a2eb5314faac7c972c5518f910331c
3
+ metadata.gz: bd4cbe464be1d5ee56434c1a380d958cf0cbcb40095d8f21fcfb3cf7b2320db2
4
+ data.tar.gz: 3572805d086b24911c1feb6169b5911723a918fcf1ca0547d2f28984e0827ade
5
5
  SHA512:
6
- metadata.gz: ff33b7ccf7423baf8c8158287be0efd1ad184069a6542f0d945fa493ea04c2a43c98b84e4e6e50f54d119ddb09575cddd0780fdaa7676fff3f9e839539db591c
7
- data.tar.gz: f930f40f3eac5de9c611061ea0c3844d47e4c3475a392f4cfb74a3fe4350519eaca35e57eda0a9ef9fead81157d90b2967c14943b599e9d456220ee68a42b72c
6
+ metadata.gz: 032f86dbf253379e1663e01d03f8a5a013a13829e4bb5b9c3f880d73611a2c92176e51086402b604cfd20a30d28dfa1571766b9fa2e4eb5377e4c12a6bda1b39
7
+ data.tar.gz: 1ecf8c2ff66d2eef73b658f925bbb5a7c6292861ce4fd52a9f2ed6fab91e49f3ba25fe5cd84f8da294b6340887872c9ef5100f2799fa8f8c319afbcead8ced3e
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ 1.0.0 (2021-11-30)
2
+ ------------------
3
+
4
+ * Add support for ruby 3.0
5
+ As side effect now Recorder#record_status receive additional parameter
6
+
1
7
  0.5.2 (2020-01-06)
2
8
  ------------------
3
9
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.2
1
+ 1.0.0
@@ -3,5 +3,5 @@
3
3
  # Cheetah namespace
4
4
  module Cheetah
5
5
  # Cheetah version (uses [semantic versioning](http://semver.org/)).
6
- VERSION = File.read(File.dirname(__FILE__) + "/../../VERSION").strip
6
+ VERSION = File.read("#{File.dirname(__FILE__)}/../../VERSION").strip
7
7
  end
data/lib/cheetah.rb CHANGED
@@ -5,7 +5,7 @@ require "logger"
5
5
  require "shellwords"
6
6
  require "stringio"
7
7
 
8
- require File.expand_path(File.dirname(__FILE__) + "/cheetah/version")
8
+ require File.expand_path("#{File.dirname(__FILE__)}/cheetah/version")
9
9
 
10
10
  # Your swiss army knife for executing external commands in Ruby safely and
11
11
  # conveniently.
@@ -121,6 +121,7 @@ module Cheetah
121
121
  #
122
122
  # @abstract
123
123
  # @param [Process::Status] status the executed command exit status
124
+ # @param [Boolean] allowed_status whether the exit code is in the list of allowed exit codes
124
125
  abstract_method :record_status
125
126
  end
126
127
 
@@ -135,7 +136,7 @@ module Cheetah
135
136
 
136
137
  def record_stderr(_stderr); end
137
138
 
138
- def record_status(_status); end
139
+ def record_status(_status, _allowed_status); end
139
140
  end
140
141
 
141
142
  # A default recorder. It uses the `Logger::INFO` level for normal messages and
@@ -150,6 +151,8 @@ module Cheetah
150
151
  }.freeze
151
152
 
152
153
  def initialize(logger)
154
+ super()
155
+
153
156
  @logger = logger
154
157
 
155
158
  @stream_used = { stdin: false, stdout: false, stderr: false }
@@ -172,19 +175,19 @@ module Cheetah
172
175
  log_stream_increment(:stderr, stderr)
173
176
  end
174
177
 
175
- def record_status(status)
178
+ def record_status(status, allowed_status)
176
179
  log_stream_remainder(:stdin)
177
180
  log_stream_remainder(:stdout)
178
181
  log_stream_remainder(:stderr)
179
182
 
180
- @logger.send status.success? ? :info : :error,
183
+ @logger.send allowed_status ? :info : :error,
181
184
  "Status: #{status.exitstatus}"
182
185
  end
183
186
 
184
187
  protected
185
188
 
186
189
  def format_commands(commands)
187
- '"' + commands.map { |c| Shellwords.join(c) }.join(" | ") + '"'
190
+ "\"#{commands.map { |c| Shellwords.join(c) }.join(' | ')}\""
188
191
  end
189
192
 
190
193
  def log_stream_increment(stream, data)
@@ -402,14 +405,19 @@ module Cheetah
402
405
  select_loop(streams, pipes, recorder)
403
406
  _pid, status = Process.wait2(pid)
404
407
 
405
- # when more exit status are allowed, then redefine success as command
406
- # not failed (bsc#1153749)
407
- adapt_status(status, options)
408
+ # when more exit status are allowed, then pass it below that it did
409
+ # not fail (bsc#1153749)
410
+ success = allowed_status?(status, options)
408
411
 
409
412
  begin
410
- check_errors(commands, status, streams, streamed)
413
+ report_errors(commands, status, streams, streamed) if !success
411
414
  ensure
412
- recorder.record_status(status)
415
+ # backward compatibility for recorders with just single parameter
416
+ if recorder.method(:record_status).arity == 1
417
+ recorder.record_status(status)
418
+ else
419
+ recorder.record_status(status, success)
420
+ end
413
421
  end
414
422
 
415
423
  build_result(streams, status, options)
@@ -417,12 +425,11 @@ module Cheetah
417
425
 
418
426
  private
419
427
 
420
- def adapt_status(status, options)
421
- return unless allowed_exitstatus?(options)
428
+ def allowed_status?(status, options)
429
+ exit_status = status.exitstatus
430
+ return exit_status.zero? unless allowed_exitstatus?(options)
422
431
 
423
- status.define_singleton_method(:success?) do
424
- options[:allowed_exitstatus].include?(exitstatus)
425
- end
432
+ options[:allowed_exitstatus].include?(exit_status)
426
433
  end
427
434
 
428
435
  # Parts of Cheetah.run
@@ -519,51 +526,49 @@ module Cheetah
519
526
 
520
527
  def fork_commands_recursive(commands, pipes, options)
521
528
  fork do
522
- begin
523
- # support chrooting
524
- options = chroot_step(options)
525
-
526
- if commands.size == 1
527
- from_pipe(STDIN, pipes[:stdin])
528
- else
529
- pipe_to_child = IO.pipe
530
-
531
- fork_commands_recursive(commands[0..-2],
532
- {
533
- stdin: pipes[:stdin],
534
- stdout: pipe_to_child,
535
- stderr: pipes[:stderr]
536
- },
537
- options)
538
-
539
- pipes[:stdin][READ].close
540
- pipes[:stdin][WRITE].close
541
-
542
- from_pipe(STDIN, pipe_to_child)
543
- end
529
+ # support chrooting
530
+ options = chroot_step(options)
544
531
 
545
- into_pipe(STDOUT, pipes[:stdout])
546
- into_pipe(STDERR, pipes[:stderr])
532
+ if commands.size == 1
533
+ from_pipe($stdin, pipes[:stdin])
534
+ else
535
+ pipe_to_child = IO.pipe
547
536
 
548
- close_fds
537
+ fork_commands_recursive(commands[0..-2],
538
+ {
539
+ stdin: pipes[:stdin],
540
+ stdout: pipe_to_child,
541
+ stderr: pipes[:stderr]
542
+ },
543
+ options)
549
544
 
550
- command, *args = commands.last
551
- with_env(options[:env]) do
552
- exec([command, command], *args)
553
- end
554
- rescue SystemCallError => e
555
- # depends when failed, if pipe is already redirected or not, so lets find it
556
- output = pipes[:stderr][WRITE].closed? ? STDERR : pipes[:stderr][WRITE]
557
- output.puts e.message
545
+ pipes[:stdin][READ].close
546
+ pipes[:stdin][WRITE].close
547
+
548
+ from_pipe($stdin, pipe_to_child)
549
+ end
558
550
 
559
- exit!(127)
551
+ into_pipe($stdout, pipes[:stdout])
552
+ into_pipe($stderr, pipes[:stderr])
553
+
554
+ close_fds
555
+
556
+ command, *args = commands.last
557
+ with_env(options[:env]) do
558
+ exec([command, command], *args)
560
559
  end
560
+ rescue SystemCallError => e
561
+ # depends when failed, if pipe is already redirected or not, so lets find it
562
+ output = pipes[:stderr][WRITE].closed? ? $stderr : pipes[:stderr][WRITE]
563
+ output.puts e.message
564
+
565
+ exit!(127)
561
566
  end
562
567
  end
563
568
 
564
569
  # closes all open fds starting with 3 and above
565
570
  def close_fds
566
- # note: this will work only if unix has /proc filesystem. If it does not
571
+ # NOTE: this will work only if unix has /proc filesystem. If it does not
567
572
  # have it, it won't close other fds.
568
573
  Dir.glob("/proc/self/fd/*").each do |path|
569
574
  fd = File.basename(path).to_i
@@ -655,7 +660,7 @@ module Cheetah
655
660
  end
656
661
  end
657
662
 
658
- def check_errors(commands, status, streams, streamed)
663
+ def report_errors(commands, status, streams, streamed)
659
664
  return if status.success?
660
665
 
661
666
  stderr_part = if streamed[:stderr]
@@ -664,7 +669,7 @@ module Cheetah
664
669
  " (no error output)"
665
670
  else
666
671
  lines = streams[:stderr].string.split("\n")
667
- ": " + lines.first + (lines.size > 1 ? " (...)" : "")
672
+ ": #{lines.first}#{lines.size > 1 ? ' (...)' : ''}"
668
673
  end
669
674
 
670
675
  raise ExecutionFailed.new(
@@ -707,7 +712,7 @@ module Cheetah
707
712
  end
708
713
 
709
714
  def format_commands(commands)
710
- '"' + commands.map { |c| Shellwords.join(c) }.join(" | ") + '"'
715
+ "\"#{commands.map { |c| Shellwords.join(c) }.join(' | ')}\""
711
716
  end
712
717
  end
713
718
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cheetah
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Majda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-06 00:00:00.000000000 Z
11
+ date: 2021-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: abstract_method
@@ -77,7 +77,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
77
77
  requirements:
78
78
  - - ">="
79
79
  - !ruby/object:Gem::Version
80
- version: '0'
80
+ version: '2.5'
81
81
  required_rubygems_version: !ruby/object:Gem::Requirement
82
82
  requirements:
83
83
  - - ">="
@@ -85,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
85
  version: '0'
86
86
  requirements: []
87
87
  rubyforge_project:
88
- rubygems_version: 2.7.6.2
88
+ rubygems_version: 2.7.6.3
89
89
  signing_key:
90
90
  specification_version: 4
91
91
  summary: Your swiss army knife for executing external commands in Ruby safely and