tty-command 0.8.1 → 0.8.2

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 +9 -0
  3. data/examples/bash.rb +2 -2
  4. data/examples/basic.rb +2 -2
  5. data/examples/env.rb +3 -3
  6. data/examples/logger.rb +2 -2
  7. data/examples/output.rb +2 -2
  8. data/examples/pty.rb +3 -1
  9. data/examples/redirect_stderr.rb +2 -2
  10. data/examples/redirect_stdin.rb +2 -2
  11. data/examples/redirect_stdout.rb +2 -2
  12. data/examples/stdin_input.rb +2 -2
  13. data/examples/threaded.rb +3 -1
  14. data/examples/timeout.rb +7 -3
  15. data/examples/timeout_input.rb +2 -2
  16. data/examples/wait.rb +2 -2
  17. data/lib/tty/command/process_runner.rb +3 -0
  18. data/lib/tty/command/version.rb +1 -1
  19. data/spec/spec_helper.rb +78 -0
  20. data/spec/unit/binmode_spec.rb +27 -0
  21. data/spec/unit/cmd_spec.rb +152 -0
  22. data/spec/unit/dry_run_spec.rb +42 -0
  23. data/spec/unit/exit_error_spec.rb +25 -0
  24. data/spec/unit/input_spec.rb +11 -0
  25. data/spec/unit/output_spec.rb +25 -0
  26. data/spec/unit/printer_spec.rb +50 -0
  27. data/spec/unit/printers/custom_spec.rb +48 -0
  28. data/spec/unit/printers/null_spec.rb +36 -0
  29. data/spec/unit/printers/pretty_spec.rb +172 -0
  30. data/spec/unit/printers/progress_spec.rb +45 -0
  31. data/spec/unit/printers/quiet_spec.rb +71 -0
  32. data/spec/unit/pty_spec.rb +60 -0
  33. data/spec/unit/redirect_spec.rb +104 -0
  34. data/spec/unit/result_spec.rb +64 -0
  35. data/spec/unit/ruby_spec.rb +20 -0
  36. data/spec/unit/run_spec.rb +161 -0
  37. data/spec/unit/test_spec.rb +11 -0
  38. data/spec/unit/timeout_spec.rb +36 -0
  39. data/spec/unit/truncator_spec.rb +73 -0
  40. data/tty-command.gemspec +1 -1
  41. metadata +24 -10
  42. data/.gitignore +0 -9
  43. data/.rspec +0 -4
  44. data/.travis.yml +0 -29
  45. data/CODE_OF_CONDUCT.md +0 -49
  46. data/Gemfile +0 -14
  47. data/appveyor.yml +0 -26
  48. data/benchmarks/memory.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9c645ef5e1ef832ee5503018bc7aab93cdd71c17
4
- data.tar.gz: 99b9fffd1e85616b3e36d4d0002684611a3a4dc0
2
+ SHA256:
3
+ metadata.gz: 01a539add505698f2073117f6df6c957e09dbeb349b6eae684eccf121d3a8a2b
4
+ data.tar.gz: eae4769195fd22d266c9c76093b9f85e3b8faeb61152197d5af65e3e435dfa83
5
5
  SHA512:
6
- metadata.gz: 16830dc6e8c5ac16616e4d14981924f18128800e1ddcae4cca6c1432c1649424a2dd758221a678267b1a76963c8c1aeebf49ff6da7a0e736d5dcb8abbc68dca5
7
- data.tar.gz: 6ac45eeef2482b4f59ff9a5ec2486d2953b01bb1d7c9b6a99a373ecae7d89a3cf26f4aae464dbc984e893f898c34f6e4af88bc12de3a947b3f586459cb5ed918
6
+ metadata.gz: f3a44386dd5eb460ca3d8c7740f7c7e0660f6aeda18f0e0c7c4d67bfb30e962f4e96f34509584c5e7120d69fd415c2321b0b61d997f2f12cad101f63dfed5a93
7
+ data.tar.gz: 022477365445a4da55e3ee87c4d3c23305003e6da7d7c94b6de7857e409396e4105596584ea66a7c904d7f5f5725716527e6a353391e1a97ea78928fcb1052d0
@@ -1,5 +1,13 @@
1
1
  # Change log
2
2
 
3
+ ## [v0.8.2] - 2018-08-07
4
+
5
+ ### Changed
6
+ * Change gemspec to load only required files
7
+
8
+ ### Fixed
9
+ * Fix issue with Ruby greater than 2.5.0 displaying thread error traceback by default
10
+
3
11
  ## [v0.8.1] - 2018-05-20
4
12
 
5
13
  ### Changed
@@ -115,6 +123,7 @@
115
123
 
116
124
  * Initial implementation and release
117
125
 
126
+ [v0.8.2]: https://github.com/piotrmurach/tty-command/compare/v0.8.1...v0.8.2
118
127
  [v0.8.1]: https://github.com/piotrmurach/tty-command/compare/v0.8.0...v0.8.1
119
128
  [v0.8.0]: https://github.com/piotrmurach/tty-command/compare/v0.7.0...v0.8.0
120
129
  [v0.7.0]: https://github.com/piotrmurach/tty-command/compare/v0.6.0...v0.7.0
@@ -1,6 +1,6 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'tty-command'
3
+ require_relative '../lib/tty-command'
4
4
 
5
5
  cmd = TTY::Command.new
6
6
 
@@ -1,6 +1,6 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'tty-command'
3
+ require_relative '../lib/tty-command'
4
4
 
5
5
  cmd = TTY::Command.new
6
6
 
@@ -1,9 +1,9 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'tty-command'
3
+ require_relative '../lib/tty-command'
4
4
 
5
5
  cmd = TTY::Command.new
6
6
 
7
- out, err = cmd.run("env | grep FOO", env: { 'FOO' =>'hello'})
7
+ out, _ = cmd.run("env | grep FOO", env: { 'FOO' =>'hello'})
8
8
 
9
9
  puts "Result: #{out}"
@@ -1,7 +1,7 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'logger'
4
- require 'tty-command'
4
+ require_relative '../lib/tty-command'
5
5
 
6
6
  logger = Logger.new('dev.log')
7
7
 
@@ -1,6 +1,6 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'tty-command'
3
+ require_relative '../lib/tty-command'
4
4
 
5
5
  cmd = TTY::Command.new
6
6
  cmd.run("i=0; while true; do i=$[$i+1]; echo 'hello '$i; sleep 1; done") do |out, err|
@@ -1,4 +1,6 @@
1
- require 'tty-command'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/tty-command'
2
4
 
3
5
  cmd = TTY::Command.new
4
6
 
@@ -1,6 +1,6 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'tty-command'
3
+ require_relative '../lib/tty-command'
4
4
 
5
5
  cmd = TTY::Command.new
6
6
 
@@ -1,6 +1,6 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'tty-command'
3
+ require_relative '../lib/tty-command'
4
4
 
5
5
  cli = File.expand_path('cli', __dir__)
6
6
  cmd = TTY::Command.new
@@ -1,6 +1,6 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'tty-command'
3
+ require_relative '../lib/tty-command'
4
4
 
5
5
  cmd = TTY::Command.new
6
6
 
@@ -1,7 +1,7 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'tty-command'
4
3
  require 'pathname'
4
+ require_relative '../lib/tty-command'
5
5
 
6
6
  cmd = TTY::Command.new
7
7
  cli = Pathname.new('examples/cli')
@@ -1,4 +1,6 @@
1
- require 'tty-command'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/tty-command'
2
4
 
3
5
  cmd = TTY::Command.new
4
6
 
@@ -1,7 +1,11 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'tty-command'
3
+ require_relative '../lib/tty-command'
4
4
 
5
5
  cmd = TTY::Command.new
6
6
 
7
- cmd.run("while test 1; do echo 'hello'; sleep 1; done", timeout: 5, signal: :KILL)
7
+ begin
8
+ cmd.run("while test 1; do echo 'hello'; sleep 1; done", timeout: 5, signal: :KILL)
9
+ rescue TTY::Command::TimeoutExceeded
10
+ puts 'BOOM!'
11
+ end
@@ -1,6 +1,6 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'tty-command'
3
+ require_relative '../lib/tty-command'
4
4
 
5
5
  cmd = TTY::Command.new
6
6
 
@@ -1,7 +1,7 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'tty-command'
4
3
  require 'logger'
4
+ require_relative '../lib/tty-command'
5
5
 
6
6
  logger = Logger.new('dev.log')
7
7
  cmd = TTY::Command.new
@@ -157,6 +157,9 @@ module TTY
157
157
 
158
158
  def read_stream(stream, buffer)
159
159
  Thread.new do
160
+ if Thread.current.respond_to?(:report_on_exception)
161
+ Thread.current.report_on_exception = false
162
+ end
160
163
  Thread.current[:cmd_start] = Time.now
161
164
  readers = [stream]
162
165
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  class Command
5
- VERSION = '0.8.1'
5
+ VERSION = '0.8.2'.freeze
6
6
  end # Command
7
7
  end # TTY
@@ -0,0 +1,78 @@
1
+ if RUBY_VERSION > '1.9' and (ENV['COVERAGE'] || ENV['TRAVIS'])
2
+ require 'simplecov'
3
+ require 'coveralls'
4
+
5
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
6
+ SimpleCov::Formatter::HTMLFormatter,
7
+ Coveralls::SimpleCov::Formatter
8
+ ]
9
+
10
+ SimpleCov.start do
11
+ command_name 'spec'
12
+ add_filter 'spec'
13
+ end
14
+ end
15
+
16
+ require 'tty-command'
17
+
18
+ module TestHelpers
19
+ module Paths
20
+ def gem_root
21
+ File.expand_path(File.join(File.dirname(__FILE__), ".."))
22
+ end
23
+
24
+ def dir_path(*args)
25
+ path = File.join(gem_root, *args)
26
+ FileUtils.mkdir_p(path) unless ::File.exist?(path)
27
+ File.realpath(path)
28
+ end
29
+
30
+ def tmp_path(*args)
31
+ File.expand_path(File.join(dir_path('tmp'), *args))
32
+ end
33
+
34
+ def fixtures_path(*args)
35
+ File.expand_path(File.join(dir_path('spec/fixtures'), *args))
36
+ end
37
+ end
38
+
39
+ module Platform
40
+ def jruby?
41
+ RUBY_PLATFORM == "java"
42
+ end
43
+ end
44
+ end
45
+
46
+ RSpec.configure do |config|
47
+ config.include(TestHelpers::Paths)
48
+ config.include(TestHelpers::Platform)
49
+
50
+ config.after(:each, type: :cli) do
51
+ FileUtils.rm_rf(tmp_path)
52
+ end
53
+
54
+ config.expect_with :rspec do |expectations|
55
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
56
+ end
57
+
58
+ config.mock_with :rspec do |mocks|
59
+ mocks.verify_partial_doubles = true
60
+ end
61
+
62
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
63
+ config.disable_monkey_patching!
64
+
65
+ # This setting enables warnings. It's recommended, but in some cases may
66
+ # be too noisy due to issues in dependencies.
67
+ config.warnings = true
68
+
69
+ if config.files_to_run.one?
70
+ config.default_formatter = 'doc'
71
+ end
72
+
73
+ config.profile_examples = 2
74
+
75
+ config.order = :random
76
+
77
+ Kernel.srand config.seed
78
+ end
@@ -0,0 +1,27 @@
1
+ RSpec.describe TTY::Command, '#run' do
2
+ it "encodes output as unicode by default" do
3
+ output = StringIO.new
4
+ cmd = TTY::Command.new(output: output)
5
+ out, _ = cmd.run("echo '昨夜のコンサートは'")
6
+
7
+ expect(out.encoding).to eq(Encoding::UTF_8)
8
+ # expect(out.chomp).to eq("昨夜のコンサートは")
9
+ end
10
+
11
+ it "encodes output as binary" do
12
+ output = StringIO.new
13
+ cmd = TTY::Command.new(output: output)
14
+ out, _ = cmd.run("echo '昨夜のコンサートは'", binmode: true)
15
+
16
+ expect(out.encoding).to eq(Encoding::BINARY)
17
+ #expect(out.chomp).to eq("\xE6\x98\xA8\xE5\xA4\x9C\xE3\x81\xAE\xE3\x82\xB3\xE3\x83\xB3\xE3\x82\xB5\xE3\x83\xBC\xE3\x83\x88\xE3\x81\xAF".force_encoding(Encoding::BINARY))
18
+ end
19
+
20
+ it "encodes all commands output as binary" do
21
+ output = StringIO.new
22
+ cmd = TTY::Command.new(output: output, binmode: true)
23
+ out, _ = cmd.run("echo 'hello'")
24
+
25
+ expect(out.encoding).to eq(Encoding::BINARY)
26
+ end
27
+ end
@@ -0,0 +1,152 @@
1
+ # encoding: utf-8
2
+
3
+ RSpec.describe TTY::Command::Cmd, '::new' do
4
+ it "requires at least command argument" do
5
+ expect {
6
+ TTY::Command::Cmd.new({})
7
+ }.to raise_error(ArgumentError, /Cmd requires command argument/)
8
+ end
9
+
10
+ it "requires non empty command argument" do
11
+ expect {
12
+ TTY::Command::Cmd.new(nil)
13
+ }.to raise_error(ArgumentError, /No command provided/)
14
+ end
15
+
16
+ it "accepts a command" do
17
+ cmd = TTY::Command::Cmd.new(:echo)
18
+ expect(cmd.command).to eq('echo')
19
+ expect(cmd.argv).to eq([])
20
+ expect(cmd.options).to eq({})
21
+ expect(cmd.to_command).to eq('echo')
22
+ end
23
+
24
+ it "accepts a command as heredoc" do
25
+ cmd = TTY::Command::Cmd.new <<-EOHEREDOC
26
+ if [[ $? -eq 0]]; then
27
+ echo "Bash it!"
28
+ fi
29
+ EOHEREDOC
30
+ expect(cmd.argv).to eq([])
31
+ expect(cmd.options).to eq({})
32
+ expect(cmd.to_command).to eq([
33
+ " if [[ $? -eq 0]]; then",
34
+ " echo \"Bash it!\"",
35
+ " fi\n"
36
+ ].join("\n"))
37
+ end
38
+
39
+ it "accepts command as [cmdname, arg1, ...]" do
40
+ cmd = TTY::Command::Cmd.new(:echo, '-n', 'hello')
41
+ expect(cmd.command).to eq('echo')
42
+ expect(cmd.argv).to eq(['-n', 'hello'])
43
+ expect(cmd.to_command).to eq('echo -n hello')
44
+ end
45
+
46
+ it "accepts command as [[cmdname, argv0], arg1, ...]" do
47
+ cmd = TTY::Command::Cmd.new([:echo, '-n'], 'hello')
48
+ expect(cmd.command).to eq('echo')
49
+ expect(cmd.argv).to eq(['-n', 'hello'])
50
+ expect(cmd.to_command).to eq('echo -n hello')
51
+ end
52
+
53
+ it "accepts command with environment as [cmdname, arg1, ..., opts]" do
54
+ cmd = TTY::Command::Cmd.new(:echo, 'hello', env: {foo: 'bar'})
55
+ expect(cmd.to_command).to eq(%{( export FOO=\"bar\" ; echo hello )})
56
+ end
57
+
58
+ it "accepts command with multiple environment keys" do
59
+ cmd = TTY::Command::Cmd.new(:echo, 'hello', env: {foo: 'a', bar: 'b'})
60
+ expect(cmd.to_command).to eq(%{( export FOO=\"a\" BAR=\"b\" ; echo hello )})
61
+ end
62
+
63
+ it "accepts command with environemnt string keys" do
64
+ cmd = TTY::Command::Cmd.new(:echo, 'hello', env: {'FOO_bar' => 'a', bar: 'b'})
65
+ expect(cmd.to_command).to eq(%{( export FOO_bar=\"a\" BAR=\"b\" ; echo hello )})
66
+ end
67
+
68
+ it "escapes environment values" do
69
+ cmd = TTY::Command::Cmd.new(:echo, 'hello', env: {foo: 'abc"def'})
70
+ expect(cmd.to_command).to eq(%{( export FOO=\"abc\\\"def\" ; echo hello )})
71
+ end
72
+
73
+ it "accepts environment as first argument" do
74
+ cmd = TTY::Command::Cmd.new({'FOO' => true, 'BAR' => 1}, :echo, 'hello')
75
+ expect(cmd.to_command).to eq(%{( export FOO=\"true\" BAR=\"1\" ; echo hello )})
76
+ end
77
+
78
+ it "runs command in specified directory" do
79
+ cmd = TTY::Command::Cmd.new(:echo, 'hello', chdir: '/tmp')
80
+ expect(cmd.to_command).to eq("cd /tmp && echo hello")
81
+ end
82
+
83
+ it "runs command in specified directory with environment" do
84
+ cmd = TTY::Command::Cmd.new(:echo, 'hello', chdir: '/tmp', env: {foo: 'bar'})
85
+ expect(cmd.to_command).to eq(%{cd /tmp && ( export FOO=\"bar\" ; echo hello )})
86
+ end
87
+
88
+ it "runs command as a user" do
89
+ cmd = TTY::Command::Cmd.new(:echo, 'hello', user: 'piotrmurach')
90
+ expect(cmd.to_command).to eq("sudo -u piotrmurach -- sh -c 'echo hello'")
91
+ end
92
+
93
+ it "runs command as a group" do
94
+ cmd = TTY::Command::Cmd.new(:echo, 'hello', group: 'devs')
95
+ expect(cmd.to_command).to eq("sg devs -c \\\"echo hello\\\"")
96
+ end
97
+
98
+ it "runs command as a user in a group" do
99
+ cmd = TTY::Command::Cmd.new(:echo, 'hello', user: 'piotrmurach', group: 'devs')
100
+ expect(cmd.to_command).to eq("sudo -u piotrmurach -- sh -c 'sg devs -c \\\"echo hello\\\"'")
101
+ end
102
+
103
+ it "runs command with umask" do
104
+ cmd = TTY::Command::Cmd.new(:echo, 'hello', umask: '077')
105
+ expect(cmd.to_command).to eq("umask 077 && echo hello")
106
+ end
107
+
108
+ it "runs command with umask, chdir" do
109
+ cmd = TTY::Command::Cmd.new(:echo, 'hello', umask: '077', chdir: '/tmp')
110
+ expect(cmd.to_command).to eq("cd /tmp && umask 077 && echo hello")
111
+ end
112
+
113
+ it "runs command with umask, chdir & user" do
114
+ cmd = TTY::Command::Cmd.new(:echo, 'hello', umask: '077', chdir: '/tmp', user: 'piotrmurach')
115
+ expect(cmd.to_command).to eq("cd /tmp && umask 077 && sudo -u piotrmurach -- sh -c 'echo hello'")
116
+ end
117
+
118
+ it "runs command with umask, user, chdir and env" do
119
+ cmd = TTY::Command::Cmd.new(:echo, 'hello', umask: '077', chdir: '/tmp', user: 'piotrmurach', env: {foo: 'bar'})
120
+ expect(cmd.to_command).to eq(%{cd /tmp && umask 077 && ( export FOO=\"bar\" ; sudo -u piotrmurach FOO=\"bar\" -- sh -c 'echo hello' )})
121
+ end
122
+
123
+ it "provides unique identifier" do
124
+ cmd = TTY::Command::Cmd.new(:echo, 'hello')
125
+ expect(cmd.uuid).to match(/^\w{8}$/)
126
+ end
127
+
128
+ it "converts command to hash" do
129
+ cmd = TTY::Command::Cmd.new(:echo, 'hello')
130
+ expect(cmd.to_hash).to include({
131
+ command: 'echo',
132
+ argv: ['hello']
133
+ })
134
+ end
135
+
136
+ it "escapes arguments that need escaping" do
137
+ cmd = TTY::Command::Cmd.new(:echo, 'hello world')
138
+ expect(cmd.to_hash).to include({
139
+ command: 'echo',
140
+ argv: ["hello\\ world"]
141
+ })
142
+ end
143
+
144
+ it "escapes special characters in split arguments" do
145
+ args = %w(git for-each-ref --format='%(refname)' refs/heads/)
146
+ cmd = TTY::Command::Cmd.new(*args)
147
+ expect(cmd.to_hash).to include({
148
+ command: 'git',
149
+ argv: ["for-each-ref", "--format\\=\\'\\%\\(refname\\)\\'", "refs/heads/"]
150
+ })
151
+ end
152
+ end