tty-command 0.8.0 → 0.10.1

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.
Files changed (48) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +41 -1
  3. data/LICENSE.txt +1 -1
  4. data/README.md +83 -60
  5. data/lib/tty-command.rb +1 -3
  6. data/lib/tty/command.rb +17 -17
  7. data/lib/tty/command/child_process.rb +9 -10
  8. data/lib/tty/command/cmd.rb +24 -15
  9. data/lib/tty/command/dry_runner.rb +3 -4
  10. data/lib/tty/command/exit_error.rb +1 -2
  11. data/lib/tty/command/printers/abstract.rb +8 -10
  12. data/lib/tty/command/printers/null.rb +1 -4
  13. data/lib/tty/command/printers/pretty.rb +23 -22
  14. data/lib/tty/command/printers/progress.rb +3 -8
  15. data/lib/tty/command/printers/quiet.rb +3 -7
  16. data/lib/tty/command/process_runner.rb +57 -50
  17. data/lib/tty/command/result.rb +4 -3
  18. data/lib/tty/command/truncator.rb +4 -5
  19. data/lib/tty/command/version.rb +2 -2
  20. metadata +24 -64
  21. data/.gitignore +0 -9
  22. data/.rspec +0 -4
  23. data/.travis.yml +0 -29
  24. data/CODE_OF_CONDUCT.md +0 -49
  25. data/Gemfile +0 -14
  26. data/Rakefile +0 -10
  27. data/appveyor.yml +0 -26
  28. data/benchmarks/memory.rb +0 -11
  29. data/bin/console +0 -6
  30. data/bin/setup +0 -6
  31. data/examples/bash.rb +0 -12
  32. data/examples/basic.rb +0 -9
  33. data/examples/cli +0 -4
  34. data/examples/env.rb +0 -9
  35. data/examples/logger.rb +0 -10
  36. data/examples/output.rb +0 -10
  37. data/examples/pty.rb +0 -7
  38. data/examples/redirect_stderr.rb +0 -10
  39. data/examples/redirect_stdin.rb +0 -15
  40. data/examples/redirect_stdout.rb +0 -10
  41. data/examples/stdin_input.rb +0 -10
  42. data/examples/threaded.rb +0 -12
  43. data/examples/timeout.rb +0 -7
  44. data/examples/wait.rb +0 -21
  45. data/tasks/console.rake +0 -11
  46. data/tasks/coverage.rake +0 -11
  47. data/tasks/spec.rake +0 -29
  48. data/tty-command.gemspec +0 -27
@@ -1,11 +1,10 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
- require 'thread'
3
+ require "thread"
5
4
 
6
- require_relative 'child_process'
7
- require_relative 'result'
8
- require_relative 'truncator'
5
+ require_relative "child_process"
6
+ require_relative "result"
7
+ require_relative "truncator"
9
8
 
10
9
  module TTY
11
10
  class Command
@@ -44,17 +43,7 @@ module TTY
44
43
 
45
44
  pid, stdin, stdout, stderr = ChildProcess.spawn(cmd)
46
45
 
47
- # no input to write, close child's stdin pipe
48
- stdin.close if (@input.nil? || @input.empty?) && !stdin.nil?
49
-
50
- writers = [@input && stdin].compact
51
-
52
- while writers.any?
53
- ready = IO.select(nil, writers, writers, @timeout)
54
- raise TimeoutExceeded if ready.nil?
55
-
56
- write_stream(ready[1], writers)
57
- end
46
+ write_stream(stdin, @input)
58
47
 
59
48
  stdout_data, stderr_data = read_streams(stdout, stderr)
60
49
 
@@ -84,7 +73,7 @@ module TTY
84
73
  private
85
74
 
86
75
  # The buffer size for reading stdout and stderr
87
- BUFSIZE = 3 * 1024
76
+ BUFSIZE = 16 * 1024
88
77
 
89
78
  # @api private
90
79
  def handle_timeout(runtime)
@@ -97,28 +86,35 @@ module TTY
97
86
  # Write the input to the process stdin
98
87
  #
99
88
  # @api private
100
- def write_stream(ready_writers, writers)
89
+ def write_stream(stream, input)
101
90
  start = Time.now
102
- ready_writers.each do |fd|
103
- begin
104
- err = nil
105
- size = fd.write(@input)
106
- @input = @input.byteslice(size..-1)
107
- rescue IO::WaitWritable
108
- rescue Errno::EPIPE => err
109
- # The pipe closed before all input written
110
- # Probably process exited prematurely
111
- fd.close
112
- writers.delete(fd)
113
- end
114
- if err || @input.bytesize == 0
115
- fd.close
116
- writers.delete(fd)
117
- end
91
+ writers = [input && stream].compact
118
92
 
119
- # control total time spent writing
120
- runtime = Time.now - start
121
- handle_timeout(runtime)
93
+ while writers.any?
94
+ ready = IO.select(nil, writers, writers, @timeout)
95
+ raise TimeoutExceeded if ready.nil?
96
+
97
+ ready[1].each do |writer|
98
+ begin
99
+ err = nil
100
+ size = writer.write(@input)
101
+ input = input.byteslice(size..-1)
102
+ rescue IO::WaitWritable
103
+ rescue Errno::EPIPE => err
104
+ # The pipe closed before all input written
105
+ # Probably process exited prematurely
106
+ writer.close
107
+ writers.delete(writer)
108
+ end
109
+ if err || input.bytesize == 0
110
+ writer.close
111
+ writers.delete(writer)
112
+ end
113
+
114
+ # control total time spent writing
115
+ runtime = Time.now - start
116
+ handle_timeout(runtime)
117
+ end
122
118
  end
123
119
  end
124
120
 
@@ -132,20 +128,20 @@ module TTY
132
128
  stdout_data = []
133
129
  stderr_data = Truncator.new
134
130
 
135
- out_buffer = ->(line) {
136
- stdout_data << line
137
- @printer.print_command_out_data(cmd, line)
138
- @block.(line, nil) if @block
131
+ out_handler = ->(data) {
132
+ stdout_data << data
133
+ @printer.print_command_out_data(cmd, data)
134
+ @block.(data, nil) if @block
139
135
  }
140
136
 
141
- err_buffer = ->(line) {
142
- stderr_data << line
143
- @printer.print_command_err_data(cmd, line)
144
- @block.(nil, line) if @block
137
+ err_handler = ->(data) {
138
+ stderr_data << data
139
+ @printer.print_command_err_data(cmd, data)
140
+ @block.(nil, data) if @block
145
141
  }
146
142
 
147
- stdout_thread = read_stream(stdout, out_buffer)
148
- stderr_thread = read_stream(stderr, err_buffer)
143
+ stdout_thread = read_stream(stdout, out_handler)
144
+ stderr_thread = read_stream(stderr, err_handler)
149
145
 
150
146
  stdout_thread.join
151
147
  stderr_thread.join
@@ -158,8 +154,19 @@ module TTY
158
154
  ]
159
155
  end
160
156
 
161
- def read_stream(stream, buffer)
157
+ # Read stream and invoke handler when data becomes available
158
+ #
159
+ # @param [IO] stream
160
+ # the stream to read data from
161
+ # @param [Proc] handler
162
+ # the handler to call when data becomes available
163
+ #
164
+ # @api private
165
+ def read_stream(stream, handler)
162
166
  Thread.new do
167
+ if Thread.current.respond_to?(:report_on_exception)
168
+ Thread.current.report_on_exception = false
169
+ end
163
170
  Thread.current[:cmd_start] = Time.now
164
171
  readers = [stream]
165
172
 
@@ -169,8 +176,8 @@ module TTY
169
176
 
170
177
  ready[0].each do |reader|
171
178
  begin
172
- line = reader.readpartial(BUFSIZE)
173
- buffer.(line)
179
+ chunk = reader.readpartial(BUFSIZE)
180
+ handler.(chunk)
174
181
 
175
182
  # control total time spent reading
176
183
  runtime = Time.now - Thread.current[:cmd_start]
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module TTY
@@ -35,12 +34,13 @@ module TTY
35
34
  # @param [String] separator
36
35
  #
37
36
  # @api public
38
- def each(separator = nil)
37
+ def each(separator = nil, &block)
39
38
  sep = separator || TTY::Command.record_separator
40
39
  return unless @out
40
+
41
41
  elements = @out.split(sep)
42
42
  if block_given?
43
- elements.each { |line| yield(line) }
43
+ elements.each(&block)
44
44
  else
45
45
  elements.to_enum
46
46
  end
@@ -83,6 +83,7 @@ module TTY
83
83
 
84
84
  def ==(other)
85
85
  return false unless other.is_a?(TTY::Command::Result)
86
+
86
87
  @status == other.to_i && to_ary == other.to_ary
87
88
  end
88
89
  end # Result
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module TTY
@@ -18,8 +17,8 @@ module TTY
18
17
  # @api public
19
18
  def initialize(options = {})
20
19
  @max_size = options.fetch(:max_size) { DEFAULT_SIZE }
21
- @prefix = ''
22
- @suffix = ''
20
+ @prefix = ""
21
+ @suffix = ""
23
22
  @skipped = 0
24
23
  end
25
24
 
@@ -62,7 +61,7 @@ module TTY
62
61
  return @prefix << @suffix
63
62
  end
64
63
 
65
- @prefix + "\n... omitting #{@skipped} bytes ...\n" + @suffix
64
+ @prefix + "\n... omitting #{@skipped} bytes ...\n" + @suffix
66
65
  end
67
66
  alias to_s read
68
67
 
@@ -93,7 +92,7 @@ module TTY
93
92
  # @api private
94
93
  def append(value, dst)
95
94
  remain = @max_size - dst.bytesize
96
- remaining = ''
95
+ remaining = ""
97
96
  if remain > 0
98
97
  value_bytes = value.to_s.bytesize
99
98
  offset = value_bytes < remain ? value_bytes : remain
@@ -1,7 +1,7 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module TTY
4
4
  class Command
5
- VERSION = '0.8.0'
5
+ VERSION = "0.10.1"
6
6
  end # Command
7
7
  end # TTY
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tty-command
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-22 00:00:00.000000000 Z
11
+ date: 2021-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pastel
@@ -16,98 +16,57 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.7.0
19
+ version: '0.8'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.7.0
26
+ version: '0.8'
27
27
  - !ruby/object:Gem::Dependency
28
- name: bundler
28
+ name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 1.5.0
34
- - - "<"
35
- - !ruby/object:Gem::Version
36
- version: '2.0'
33
+ version: '0'
37
34
  type: :development
38
35
  prerelease: false
39
36
  version_requirements: !ruby/object:Gem::Requirement
40
37
  requirements:
41
38
  - - ">="
42
39
  - !ruby/object:Gem::Version
43
- version: 1.5.0
44
- - - "<"
45
- - !ruby/object:Gem::Version
46
- version: '2.0'
47
- - !ruby/object:Gem::Dependency
48
- name: rake
49
- requirement: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
52
- - !ruby/object:Gem::Version
53
- version: '10.0'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: '10.0'
40
+ version: '0'
61
41
  - !ruby/object:Gem::Dependency
62
42
  name: rspec
63
43
  requirement: !ruby/object:Gem::Requirement
64
44
  requirements:
65
- - - "~>"
45
+ - - ">="
66
46
  - !ruby/object:Gem::Version
67
47
  version: '3.0'
68
48
  type: :development
69
49
  prerelease: false
70
50
  version_requirements: !ruby/object:Gem::Requirement
71
51
  requirements:
72
- - - "~>"
52
+ - - ">="
73
53
  - !ruby/object:Gem::Version
74
54
  version: '3.0'
75
55
  description: Execute shell commands with pretty output logging and capture their stdout,
76
56
  stderr and exit status. Redirect stdin, stdout and stderr of each command to a file
77
57
  or a string.
78
58
  email:
79
- - ''
59
+ - piotr@piotrmurach.com
80
60
  executables: []
81
61
  extensions: []
82
- extra_rdoc_files: []
62
+ extra_rdoc_files:
63
+ - README.md
64
+ - CHANGELOG.md
65
+ - LICENSE.txt
83
66
  files:
84
- - ".gitignore"
85
- - ".rspec"
86
- - ".travis.yml"
87
67
  - CHANGELOG.md
88
- - CODE_OF_CONDUCT.md
89
- - Gemfile
90
68
  - LICENSE.txt
91
69
  - README.md
92
- - Rakefile
93
- - appveyor.yml
94
- - benchmarks/memory.rb
95
- - bin/console
96
- - bin/setup
97
- - examples/bash.rb
98
- - examples/basic.rb
99
- - examples/cli
100
- - examples/env.rb
101
- - examples/logger.rb
102
- - examples/output.rb
103
- - examples/pty.rb
104
- - examples/redirect_stderr.rb
105
- - examples/redirect_stdin.rb
106
- - examples/redirect_stdout.rb
107
- - examples/stdin_input.rb
108
- - examples/threaded.rb
109
- - examples/timeout.rb
110
- - examples/wait.rb
111
70
  - lib/tty-command.rb
112
71
  - lib/tty/command.rb
113
72
  - lib/tty/command/child_process.rb
@@ -123,14 +82,16 @@ files:
123
82
  - lib/tty/command/result.rb
124
83
  - lib/tty/command/truncator.rb
125
84
  - lib/tty/command/version.rb
126
- - tasks/console.rake
127
- - tasks/coverage.rake
128
- - tasks/spec.rake
129
- - tty-command.gemspec
130
- homepage: https://piotrmurach.github.io/tty
85
+ homepage: https://ttytoolkit.org
131
86
  licenses:
132
87
  - MIT
133
- metadata: {}
88
+ metadata:
89
+ allowed_push_host: https://rubygems.org
90
+ bug_tracker_uri: https://github.com/piotrmurach/tty-command/issues
91
+ changelog_uri: https://github.com/piotrmurach/tty-command/blob/master/CHANGELOG.md
92
+ documentation_uri: https://www.rubydoc.info/gems/tty-command
93
+ homepage_uri: https://ttytoolkit.org
94
+ source_code_uri: https://github.com/piotrmurach/tty-command
134
95
  post_install_message:
135
96
  rdoc_options: []
136
97
  require_paths:
@@ -139,15 +100,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
139
100
  requirements:
140
101
  - - ">="
141
102
  - !ruby/object:Gem::Version
142
- version: '0'
103
+ version: 2.0.0
143
104
  required_rubygems_version: !ruby/object:Gem::Requirement
144
105
  requirements:
145
106
  - - ">="
146
107
  - !ruby/object:Gem::Version
147
108
  version: '0'
148
109
  requirements: []
149
- rubyforge_project:
150
- rubygems_version: 2.5.1
110
+ rubygems_version: 3.1.2
151
111
  signing_key:
152
112
  specification_version: 4
153
113
  summary: Execute shell commands with pretty output logging and capture their stdout,
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
data/.rspec DELETED
@@ -1,4 +0,0 @@
1
- --require spec_helper
2
- --color
3
- --format doc
4
- --warnings
data/.travis.yml DELETED
@@ -1,29 +0,0 @@
1
- ---
2
- language: ruby
3
- sudo: false
4
- cache: bundler
5
- before_install: "gem update bundler"
6
- script: "bundle exec rake ci"
7
- rvm:
8
- - 2.0.0
9
- - 2.1.10
10
- - 2.2.8
11
- - 2.3.6
12
- - 2.4.3
13
- - 2.5.0
14
- - ruby-head
15
- - jruby-9.1.1.0
16
- - jruby-head
17
- env:
18
- global:
19
- - JRUBY_OPTS=''
20
- matrix:
21
- allow_failures:
22
- - rvm: ruby-head
23
- - rvm: jruby-head
24
- - rvm: jruby-9.1.1.0
25
- fast_finish: true
26
- branches:
27
- only: master
28
- notifications:
29
- email: false