tty-command 0.8.1 → 0.8.2

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 +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