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
data/lib/tty-command.rb CHANGED
@@ -1,3 +1 @@
1
- # encoding: utf-8
2
-
3
- require 'tty/command'
1
+ require_relative "tty/command"
data/lib/tty/command.rb CHANGED
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rbconfig'
4
-
5
- require_relative 'command/cmd'
6
- require_relative 'command/exit_error'
7
- require_relative 'command/dry_runner'
8
- require_relative 'command/process_runner'
9
- require_relative 'command/printers/null'
10
- require_relative 'command/printers/pretty'
11
- require_relative 'command/printers/progress'
12
- require_relative 'command/printers/quiet'
13
- require_relative 'command/version'
3
+ require "rbconfig"
4
+
5
+ require_relative "command/cmd"
6
+ require_relative "command/exit_error"
7
+ require_relative "command/dry_runner"
8
+ require_relative "command/process_runner"
9
+ require_relative "command/printers/null"
10
+ require_relative "command/printers/pretty"
11
+ require_relative "command/printers/progress"
12
+ require_relative "command/printers/quiet"
13
+ require_relative "command/version"
14
14
 
15
15
  module TTY
16
16
  class Command
@@ -19,9 +19,9 @@ module TTY
19
19
  TimeoutExceeded = Class.new(StandardError)
20
20
 
21
21
  # Path to the current Ruby
22
- RUBY = ENV['RUBY'] || ::File.join(
23
- RbConfig::CONFIG['bindir'],
24
- RbConfig::CONFIG['ruby_install_name'] + RbConfig::CONFIG['EXEEXT']
22
+ RUBY = ENV["RUBY"] || ::File.join(
23
+ RbConfig::CONFIG["bindir"],
24
+ RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"]
25
25
  )
26
26
 
27
27
  WIN_PLATFORMS = /cygwin|mswin|mingw|bccwin|wince|emx/.freeze
@@ -35,7 +35,7 @@ module TTY
35
35
  end
36
36
 
37
37
  def self.windows?
38
- !!(RbConfig::CONFIG['host_os'] =~ WIN_PLATFORMS)
38
+ !!(RbConfig::CONFIG["host_os"] =~ WIN_PLATFORMS)
39
39
  end
40
40
 
41
41
  attr_reader :printer
@@ -128,7 +128,7 @@ module TTY
128
128
  def wait(*args)
129
129
  pattern = args.pop
130
130
  unless pattern
131
- raise ArgumentError, 'Please provide condition to wait for'
131
+ raise ArgumentError, "Please provide condition to wait for"
132
132
  end
133
133
 
134
134
  run(*args) do |out, _|
@@ -204,7 +204,7 @@ module TTY
204
204
  #
205
205
  # @api private
206
206
  def find_printer_class(name)
207
- const_name = name.to_s.split('_').map(&:capitalize).join.to_sym
207
+ const_name = name.to_s.split("_").map(&:capitalize).join.to_sym
208
208
  if const_name.empty? || !TTY::Command::Printers.const_defined?(const_name)
209
209
  raise ArgumentError, %(Unknown printer type "#{name}")
210
210
  end
@@ -1,9 +1,8 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
- require 'tempfile'
5
- require 'securerandom'
6
- require 'io/console'
3
+ require "tempfile"
4
+ require "securerandom"
5
+ require "io/console"
7
6
 
8
7
  module TTY
9
8
  class Command
@@ -28,12 +27,12 @@ module TTY
28
27
  verbose = cmd.options[:verbose]
29
28
 
30
29
  pty = try_loading_pty(verbose) if pty
31
- require('pty') if pty # load within this scope
30
+ require("pty") if pty # load within this scope
32
31
 
33
32
  # Create pipes
34
- in_rd, in_wr = pty ? PTY.open : IO.pipe('utf-8') # reading
35
- out_rd, out_wr = pty ? PTY.open : IO.pipe('utf-8') # writing
36
- err_rd, err_wr = pty ? PTY.open : IO.pipe('utf-8') # error
33
+ in_rd, in_wr = pty ? PTY.open : IO.pipe("utf-8") # reading
34
+ out_rd, out_wr = pty ? PTY.open : IO.pipe("utf-8") # writing
35
+ err_rd, err_wr = pty ? PTY.open : IO.pipe("utf-8") # error
37
36
  in_wr.sync = true
38
37
 
39
38
  if binmode
@@ -133,7 +132,7 @@ module TTY
133
132
  key = fd_to_process_key(spawn_key)
134
133
  value = spawn_value
135
134
 
136
- if key.to_s == 'in'
135
+ if key.to_s == "in"
137
136
  value = convert_to_fd(spawn_value)
138
137
  end
139
138
 
@@ -196,7 +195,7 @@ module TTY
196
195
  return object
197
196
  end
198
197
 
199
- tmp = ::Tempfile.new(::SecureRandom.uuid.split('-')[0])
198
+ tmp = ::Tempfile.new(::SecureRandom.uuid.split("-")[0])
200
199
  content = try_reading(object)
201
200
  tmp.write(content)
202
201
  tmp.rewind
@@ -1,10 +1,13 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'securerandom'
4
- require 'shellwords'
3
+ require "securerandom"
4
+ require "shellwords"
5
5
 
6
6
  module TTY
7
7
  class Command
8
+ # Encapsulates the executed command
9
+ #
10
+ # @api private
8
11
  class Cmd
9
12
  # A string command name, or shell program
10
13
  # @api public
@@ -33,14 +36,15 @@ module TTY
33
36
  if env_or_cmd.respond_to?(:to_hash)
34
37
  @env = env_or_cmd
35
38
  unless command = args.shift
36
- raise ArgumentError, 'Cmd requires command argument'
39
+ raise ArgumentError, "Cmd requires command argument"
37
40
  end
38
41
  else
39
42
  command = env_or_cmd
40
43
  end
41
44
 
42
45
  if args.empty? && cmd = command.to_s
43
- raise ArgumentError, 'No command provided' if cmd.empty?
46
+ raise ArgumentError, "No command provided" if cmd.empty?
47
+
44
48
  @command = sanitize(cmd)
45
49
  @argv = []
46
50
  else
@@ -55,7 +59,7 @@ module TTY
55
59
  @env ||= {}
56
60
  @options = opts
57
61
 
58
- @uuid = SecureRandom.uuid.split('-')[0]
62
+ @uuid = SecureRandom.uuid.split("-")[0]
59
63
  @only_output_on_error = opts.fetch(:only_output_on_error) { false }
60
64
  freeze
61
65
  end
@@ -63,8 +67,8 @@ module TTY
63
67
  # Extend command options if keys don't already exist
64
68
  #
65
69
  # @api public
66
- def update(**options)
67
- @options.update(options.update(@options))
70
+ def update(options)
71
+ @options.update(options.merge(@options))
68
72
  end
69
73
 
70
74
  # The shell environment variables
@@ -79,32 +83,37 @@ module TTY
79
83
  converted_key = key.is_a?(Symbol) ? key.to_s.upcase : key.to_s
80
84
  escaped_val = val.to_s.gsub(/"/, '\"')
81
85
  %(#{converted_key}="#{escaped_val}")
82
- end.join(' ')
86
+ end.join(" ")
83
87
  end
84
88
 
85
89
  def evars(value, &block)
86
90
  return (value || block) unless environment.any?
87
- %(( export #{environment_string} ; %s )) % [value || block.call]
91
+
92
+ "( export #{environment_string} ; #{value || block.call} )"
88
93
  end
89
94
 
90
95
  def umask(value)
91
96
  return value unless options[:umask]
97
+
92
98
  %(umask #{options[:umask]} && %s) % [value]
93
99
  end
94
100
 
95
101
  def chdir(value)
96
102
  return value unless options[:chdir]
97
- %(cd #{options[:chdir]} && %s) % [value]
103
+
104
+ %(cd #{Shellwords.escape(options[:chdir])} && #{value})
98
105
  end
99
106
 
100
107
  def user(value)
101
108
  return value unless options[:user]
102
- vars = environment.any? ? "#{environment_string} " : ''
109
+
110
+ vars = environment.any? ? "#{environment_string} " : ""
103
111
  %(sudo -u #{options[:user]} #{vars}-- sh -c '%s') % [value]
104
112
  end
105
113
 
106
114
  def group(value)
107
115
  return value unless options[:group]
116
+
108
117
  %(sg #{options[:group]} -c \\\"%s\\\") % [value]
109
118
  end
110
119
 
@@ -123,15 +132,15 @@ module TTY
123
132
 
124
133
  # @api public
125
134
  def to_s
126
- [command.to_s, *Array(argv)].join(' ')
135
+ [command.to_s, *Array(argv)].join(" ")
127
136
  end
128
137
 
129
138
  # @api public
130
139
  def to_hash
131
140
  {
132
141
  command: command,
133
- argv: argv,
134
- uuid: uuid
142
+ argv: argv,
143
+ uuid: uuid
135
144
  }
136
145
  end
137
146
 
@@ -1,7 +1,6 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
- require_relative 'result'
3
+ require_relative "result"
5
4
 
6
5
  module TTY
7
6
  class Command
@@ -18,10 +17,10 @@ module TTY
18
17
  # @api public
19
18
  def run!(*)
20
19
  cmd.to_command
21
- message = "#{@printer.decorate('(dry run)', :blue)} " +
20
+ message = "#{@printer.decorate("(dry run)", :blue)} " +
22
21
  @printer.decorate(cmd.to_command, :yellow, :bold)
23
22
  @printer.write(cmd, message, cmd.uuid)
24
- Result.new(0, '', '')
23
+ Result.new(0, "", "")
25
24
  end
26
25
  end # DryRunner
27
26
  end # Command
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module TTY
@@ -25,7 +24,7 @@ module TTY
25
24
  end
26
25
 
27
26
  def extract_output(value)
28
- (value || '').strip.empty? ? 'Nothing written' : value.strip
27
+ (value || "").strip.empty? ? "Nothing written" : value.strip
29
28
  end
30
29
  end # ExitError
31
30
  end # Command
@@ -1,6 +1,4 @@
1
- # encoding: utf-8
2
-
3
- require 'pastel'
1
+ require "pastel"
4
2
 
5
3
  module TTY
6
4
  class Command
@@ -22,11 +20,11 @@ module TTY
22
20
  def initialize(output, options = {})
23
21
  @output = output
24
22
  @options = options
25
- @enabled = options.fetch(:color) { true }
26
- @color = ::Pastel.new(output: output, enabled: @enabled)
23
+ @enabled = options.fetch(:color, true)
24
+ @color = ::Pastel.new(enabled: @enabled)
27
25
 
28
- @out_data = ''
29
- @err_data = ''
26
+ @out_data = ""
27
+ @err_data = ""
30
28
  end
31
29
 
32
30
  def print_command_start(cmd, *args)
@@ -34,15 +32,15 @@ module TTY
34
32
  end
35
33
 
36
34
  def print_command_out_data(cmd, *args)
37
- write(args.join(' '))
35
+ write(args.join(" "))
38
36
  end
39
37
 
40
38
  def print_command_err_data(cmd, *args)
41
- write(args.join(' '))
39
+ write(args.join(" "))
42
40
  end
43
41
 
44
42
  def print_command_exit(cmd, *args)
45
- write(args.join(' '))
43
+ write(args.join(" "))
46
44
  end
47
45
 
48
46
  def write(cmd, message)
@@ -1,7 +1,4 @@
1
- # encoding: utf-8
2
- # frozen_string_literal: true
3
-
4
- require_relative 'abstract'
1
+ require_relative "abstract"
5
2
 
6
3
  module TTY
7
4
  class Command
@@ -1,53 +1,54 @@
1
- # encoding: utf-8
2
- # frozen_string_literal: true
3
-
4
- require 'pastel'
5
-
6
- require_relative 'abstract'
1
+ require_relative "abstract"
7
2
 
8
3
  module TTY
9
4
  class Command
10
5
  module Printers
11
6
  class Pretty < Abstract
12
- TIME_FORMAT = "%5.3f %s".freeze
7
+ TIME_FORMAT = "%5.3f %s"
8
+
9
+ def initialize(*)
10
+ super
11
+ @uuid = options.fetch(:uuid, true)
12
+ end
13
13
 
14
14
  def print_command_start(cmd, *args)
15
15
  message = ["Running #{decorate(cmd.to_command, :yellow, :bold)}"]
16
- message << args.map(&:chomp).join(' ') unless args.empty?
17
- write(cmd, message.join, cmd.uuid)
16
+ message << args.map(&:chomp).join(" ") unless args.empty?
17
+ write(cmd, message.join)
18
18
  end
19
19
 
20
20
  def print_command_out_data(cmd, *args)
21
- message = args.map(&:chomp).join(' ')
22
- write(cmd, "\t#{message}", cmd.uuid, out_data)
21
+ message = args.map(&:chomp).join(" ")
22
+ write(cmd, "\t#{message}", out_data)
23
23
  end
24
24
 
25
25
  def print_command_err_data(cmd, *args)
26
- message = args.map(&:chomp).join(' ')
27
- write(cmd, "\t" + decorate(message, :red), cmd.uuid, err_data)
26
+ message = args.map(&:chomp).join(" ")
27
+ write(cmd, "\t" + decorate(message, :red), err_data)
28
28
  end
29
29
 
30
30
  def print_command_exit(cmd, status, runtime, *args)
31
- unless !cmd.only_output_on_error || status.zero?
31
+ if cmd.only_output_on_error && !status.zero?
32
32
  output << out_data
33
33
  output << err_data
34
34
  end
35
35
 
36
- runtime = TIME_FORMAT % [runtime, pluralize(runtime, 'second')]
36
+ runtime = TIME_FORMAT % [runtime, pluralize(runtime, "second")]
37
37
  message = ["Finished in #{runtime}"]
38
38
  message << " with exit status #{status}" if status
39
39
  message << " (#{success_or_failure(status)})"
40
- write(cmd, message.join, cmd.uuid)
40
+ write(cmd, message.join)
41
41
  end
42
42
 
43
43
  # Write message out to output
44
44
  #
45
45
  # @api private
46
- def write(cmd, message, uuid = nil, data = nil)
47
- uuid_needed = options.fetch(:uuid) { true }
46
+ def write(cmd, message, data = nil)
47
+ cmd_set_uuid = cmd.options.fetch(:uuid, true)
48
+ uuid_needed = cmd.options[:uuid].nil? ? @uuid : cmd_set_uuid
48
49
  out = []
49
50
  if uuid_needed
50
- out << "[#{decorate(uuid, :green)}] " unless uuid.nil?
51
+ out << "[#{decorate(cmd.uuid, :green)}] " unless cmd.uuid.nil?
51
52
  end
52
53
  out << "#{message}\n"
53
54
  target = (cmd.only_output_on_error && !data.nil?) ? data : output
@@ -60,15 +61,15 @@ module TTY
60
61
  #
61
62
  # @api private
62
63
  def pluralize(count, word)
63
- "#{word}#{'s' unless count.to_f == 1}"
64
+ "#{word}#{'s' unless count.to_i == 1}"
64
65
  end
65
66
 
66
67
  # @api private
67
68
  def success_or_failure(status)
68
69
  if status == 0
69
- decorate('successful', :green, :bold)
70
+ decorate("successful", :green, :bold)
70
71
  else
71
- decorate('failed', :red, :bold)
72
+ decorate("failed", :red, :bold)
72
73
  end
73
74
  end
74
75
  end # Pretty
@@ -1,14 +1,9 @@
1
- # encoding: utf-8
2
- # frozen_string_literal: true
3
-
4
- require 'pastel'
5
- require_relative 'abstract'
1
+ require_relative "abstract"
6
2
 
7
3
  module TTY
8
4
  class Command
9
5
  module Printers
10
6
  class Progress < Abstract
11
-
12
7
  def print_command_exit(cmd, status, runtime, *args)
13
8
  output.print(success_or_failure(status))
14
9
  end
@@ -21,9 +16,9 @@ module TTY
21
16
  # @api private
22
17
  def success_or_failure(status)
23
18
  if status == 0
24
- decorate('.', :green)
19
+ decorate(".", :green)
25
20
  else
26
- decorate('F', :red)
21
+ decorate("F", :red)
27
22
  end
28
23
  end
29
24
  end # Progress
@@ -1,23 +1,19 @@
1
- # encoding: utf-8
2
-
3
- require_relative 'abstract'
1
+ require_relative "abstract"
4
2
 
5
3
  module TTY
6
4
  class Command
7
5
  module Printers
8
6
  class Quiet < Abstract
9
- attr_reader :output, :options
10
-
11
7
  def print_command_start(cmd)
12
8
  # quiet
13
9
  end
14
10
 
15
11
  def print_command_out_data(cmd, *args)
16
- write(cmd, args.join(' '), out_data)
12
+ write(cmd, args.join(" "), out_data)
17
13
  end
18
14
 
19
15
  def print_command_err_data(cmd, *args)
20
- write(cmd, args.join(' '), err_data)
16
+ write(cmd, args.join(" "), err_data)
21
17
  end
22
18
 
23
19
  def print_command_exit(cmd, status, *args)