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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +41 -1
- data/LICENSE.txt +1 -1
- data/README.md +83 -60
- data/lib/tty-command.rb +1 -3
- data/lib/tty/command.rb +17 -17
- data/lib/tty/command/child_process.rb +9 -10
- data/lib/tty/command/cmd.rb +24 -15
- data/lib/tty/command/dry_runner.rb +3 -4
- data/lib/tty/command/exit_error.rb +1 -2
- data/lib/tty/command/printers/abstract.rb +8 -10
- data/lib/tty/command/printers/null.rb +1 -4
- data/lib/tty/command/printers/pretty.rb +23 -22
- data/lib/tty/command/printers/progress.rb +3 -8
- data/lib/tty/command/printers/quiet.rb +3 -7
- data/lib/tty/command/process_runner.rb +57 -50
- data/lib/tty/command/result.rb +4 -3
- data/lib/tty/command/truncator.rb +4 -5
- data/lib/tty/command/version.rb +2 -2
- metadata +24 -64
- data/.gitignore +0 -9
- data/.rspec +0 -4
- data/.travis.yml +0 -29
- data/CODE_OF_CONDUCT.md +0 -49
- data/Gemfile +0 -14
- data/Rakefile +0 -10
- data/appveyor.yml +0 -26
- data/benchmarks/memory.rb +0 -11
- data/bin/console +0 -6
- data/bin/setup +0 -6
- data/examples/bash.rb +0 -12
- data/examples/basic.rb +0 -9
- data/examples/cli +0 -4
- data/examples/env.rb +0 -9
- data/examples/logger.rb +0 -10
- data/examples/output.rb +0 -10
- data/examples/pty.rb +0 -7
- data/examples/redirect_stderr.rb +0 -10
- data/examples/redirect_stdin.rb +0 -15
- data/examples/redirect_stdout.rb +0 -10
- data/examples/stdin_input.rb +0 -10
- data/examples/threaded.rb +0 -12
- data/examples/timeout.rb +0 -7
- data/examples/wait.rb +0 -21
- data/tasks/console.rake +0 -11
- data/tasks/coverage.rake +0 -11
- data/tasks/spec.rake +0 -29
- data/tty-command.gemspec +0 -27
@@ -1,11 +1,10 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
|
-
require
|
3
|
+
require "thread"
|
5
4
|
|
6
|
-
require_relative
|
7
|
-
require_relative
|
8
|
-
require_relative
|
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
|
-
|
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 =
|
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(
|
89
|
+
def write_stream(stream, input)
|
101
90
|
start = Time.now
|
102
|
-
|
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
|
-
|
120
|
-
|
121
|
-
|
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
|
-
|
136
|
-
stdout_data <<
|
137
|
-
@printer.print_command_out_data(cmd,
|
138
|
-
@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
|
-
|
142
|
-
stderr_data <<
|
143
|
-
@printer.print_command_err_data(cmd,
|
144
|
-
@block.(nil,
|
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,
|
148
|
-
stderr_thread = read_stream(stderr,
|
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
|
-
|
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
|
-
|
173
|
-
|
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]
|
data/lib/tty/command/result.rb
CHANGED
@@ -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
|
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
|
-
|
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
|
data/lib/tty/command/version.rb
CHANGED
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.
|
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:
|
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.
|
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.
|
26
|
+
version: '0.8'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
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:
|
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
|
-
|
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:
|
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
|
-
|
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
data/.rspec
DELETED
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
|