tty-command 0.8.0 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
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