commander 4.3.0 → 4.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -4
- data/.rubocop_todo.yml +4 -139
- data/History.rdoc +5 -0
- data/bin/commander +1 -1
- data/commander.gemspec +1 -1
- data/lib/commander/blank.rb +0 -1
- data/lib/commander/command.rb +4 -5
- data/lib/commander/configure.rb +0 -3
- data/lib/commander/core_ext/array.rb +0 -1
- data/lib/commander/core_ext/object.rb +0 -1
- data/lib/commander/core_ext.rb +0 -1
- data/lib/commander/delegates.rb +2 -2
- data/lib/commander/help_formatters/base.rb +0 -1
- data/lib/commander/help_formatters/terminal.rb +0 -1
- data/lib/commander/help_formatters/terminal_compact.rb +0 -1
- data/lib/commander/help_formatters.rb +0 -1
- data/lib/commander/import.rb +0 -2
- data/lib/commander/methods.rb +7 -8
- data/lib/commander/platform.rb +0 -1
- data/lib/commander/runner.rb +124 -118
- data/lib/commander/user_interaction.rb +41 -33
- data/lib/commander/version.rb +1 -1
- data/lib/commander.rb +1 -0
- data/spec/core_ext/object_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 61e13c07b5343657433d60e4c43e472a2ed3d556
|
4
|
+
data.tar.gz: 514acee724f197f3500138992a32dc604b91765c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cbef7c7332b5399567cbbfffdc3849e49fbeb513814466f0494d32a7326f02c794c0fde96693950287687c84d955b51e23f89dc4c1c9ddf9ab3a7f897a5d6c33
|
7
|
+
data.tar.gz: 75e421ef03d886623685b3f0f25460b1d72de46ce37d0034384cf098bab9a77d57ce80587220f0a8fba428031b70a62148219eaf6ad6cd2464666e81cc6e95d5
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
@@ -1,19 +1,10 @@
|
|
1
1
|
# This configuration was generated by `rubocop --auto-gen-config`
|
2
|
-
# on 2015-02-
|
2
|
+
# on 2015-02-16 16:08:54 -0800 using RuboCop version 0.29.0.
|
3
3
|
# The point is for the user to remove these configuration records
|
4
4
|
# one by one as the offenses are removed from the code base.
|
5
5
|
# Note that changes in the inspected code, or installation of new
|
6
6
|
# versions of RuboCop, may require this file to be generated again.
|
7
7
|
|
8
|
-
# Offense count: 5
|
9
|
-
Lint/AmbiguousOperator:
|
10
|
-
Enabled: false
|
11
|
-
|
12
|
-
# Offense count: 1
|
13
|
-
# Configuration parameters: AllowSafeAssignment.
|
14
|
-
Lint/AssignmentInCondition:
|
15
|
-
Enabled: false
|
16
|
-
|
17
8
|
# Offense count: 2
|
18
9
|
Lint/Eval:
|
19
10
|
Enabled: false
|
@@ -22,19 +13,6 @@ Lint/Eval:
|
|
22
13
|
Lint/HandleExceptions:
|
23
14
|
Enabled: false
|
24
15
|
|
25
|
-
# Offense count: 1
|
26
|
-
Lint/RescueException:
|
27
|
-
Enabled: false
|
28
|
-
|
29
|
-
# Offense count: 2
|
30
|
-
Lint/ShadowingOuterLocalVariable:
|
31
|
-
Enabled: false
|
32
|
-
|
33
|
-
# Offense count: 1
|
34
|
-
# Cop supports --auto-correct.
|
35
|
-
Lint/UnusedBlockArgument:
|
36
|
-
Enabled: false
|
37
|
-
|
38
16
|
# Offense count: 5
|
39
17
|
Metrics/AbcSize:
|
40
18
|
Max: 29
|
@@ -42,13 +20,13 @@ Metrics/AbcSize:
|
|
42
20
|
# Offense count: 1
|
43
21
|
# Configuration parameters: CountComments.
|
44
22
|
Metrics/ClassLength:
|
45
|
-
Max:
|
23
|
+
Max: 230
|
46
24
|
|
47
25
|
# Offense count: 4
|
48
26
|
Metrics/CyclomaticComplexity:
|
49
27
|
Max: 13
|
50
28
|
|
51
|
-
# Offense count:
|
29
|
+
# Offense count: 89
|
52
30
|
# Configuration parameters: AllowURI, URISchemes.
|
53
31
|
Metrics/LineLength:
|
54
32
|
Max: 242
|
@@ -56,7 +34,7 @@ Metrics/LineLength:
|
|
56
34
|
# Offense count: 7
|
57
35
|
# Configuration parameters: CountComments.
|
58
36
|
Metrics/MethodLength:
|
59
|
-
Max:
|
37
|
+
Max: 36
|
60
38
|
|
61
39
|
# Offense count: 4
|
62
40
|
Metrics/PerceivedComplexity:
|
@@ -66,147 +44,34 @@ Metrics/PerceivedComplexity:
|
|
66
44
|
Style/AccessorMethodName:
|
67
45
|
Enabled: false
|
68
46
|
|
69
|
-
# Offense count: 5
|
70
|
-
# Cop supports --auto-correct.
|
71
|
-
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
72
|
-
Style/AndOr:
|
73
|
-
Enabled: false
|
74
|
-
|
75
|
-
# Offense count: 1
|
76
|
-
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
77
|
-
Style/ClassAndModuleChildren:
|
78
|
-
Enabled: false
|
79
|
-
|
80
47
|
# Offense count: 18
|
81
48
|
Style/Documentation:
|
82
49
|
Enabled: false
|
83
50
|
|
84
|
-
# Offense count: 2
|
85
|
-
Style/EachWithObject:
|
86
|
-
Enabled: false
|
87
|
-
|
88
|
-
# Offense count: 1
|
89
|
-
# Cop supports --auto-correct.
|
90
|
-
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
91
|
-
Style/EmptyLinesAroundClassBody:
|
92
|
-
Enabled: false
|
93
|
-
|
94
|
-
# Offense count: 1
|
95
|
-
# Cop supports --auto-correct.
|
96
|
-
Style/EmptyLinesAroundMethodBody:
|
97
|
-
Enabled: false
|
98
|
-
|
99
|
-
# Offense count: 5
|
100
|
-
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
101
|
-
Style/FormatString:
|
102
|
-
Enabled: false
|
103
|
-
|
104
51
|
# Offense count: 12
|
105
52
|
# Configuration parameters: AllowedVariables.
|
106
53
|
Style/GlobalVars:
|
107
54
|
Enabled: false
|
108
55
|
|
109
|
-
# Offense count: 2
|
110
|
-
# Configuration parameters: MinBodyLength.
|
111
|
-
Style/GuardClause:
|
112
|
-
Enabled: false
|
113
|
-
|
114
|
-
# Offense count: 7
|
115
|
-
# Cop supports --auto-correct.
|
116
|
-
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
117
|
-
Style/HashSyntax:
|
118
|
-
Enabled: false
|
119
|
-
|
120
56
|
# Offense count: 1
|
121
57
|
# Configuration parameters: MaxLineLength.
|
122
58
|
Style/IfUnlessModifier:
|
123
59
|
Enabled: false
|
124
60
|
|
125
|
-
# Offense count: 2
|
126
|
-
# Cop supports --auto-correct.
|
127
|
-
Style/Lambda:
|
128
|
-
Enabled: false
|
129
|
-
|
130
|
-
# Offense count: 17
|
131
|
-
# Cop supports --auto-correct.
|
132
|
-
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
133
|
-
Style/MethodDefParentheses:
|
134
|
-
Enabled: false
|
135
|
-
|
136
61
|
# Offense count: 1
|
137
62
|
Style/MultilineBlockChain:
|
138
63
|
Enabled: false
|
139
64
|
|
140
|
-
# Offense count: 1
|
141
|
-
# Cop supports --auto-correct.
|
142
|
-
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
143
|
-
Style/MultilineOperationIndentation:
|
144
|
-
Enabled: false
|
145
|
-
|
146
65
|
# Offense count: 1
|
147
66
|
Style/MultilineTernaryOperator:
|
148
67
|
Enabled: false
|
149
68
|
|
150
|
-
# Offense count: 1
|
151
|
-
# Cop supports --auto-correct.
|
152
|
-
Style/Not:
|
153
|
-
Enabled: false
|
154
|
-
|
155
|
-
# Offense count: 1
|
156
|
-
# Cop supports --auto-correct.
|
157
|
-
# Configuration parameters: PreferredDelimiters.
|
158
|
-
Style/PercentLiteralDelimiters:
|
159
|
-
Enabled: false
|
160
|
-
|
161
|
-
# Offense count: 3
|
162
|
-
# Cop supports --auto-correct.
|
163
|
-
# Configuration parameters: AllowMultipleReturnValues.
|
164
|
-
Style/RedundantReturn:
|
165
|
-
Enabled: false
|
166
|
-
|
167
69
|
# Offense count: 5
|
168
70
|
Style/RescueModifier:
|
169
71
|
Enabled: false
|
170
72
|
|
171
|
-
# Offense count: 3
|
172
|
-
# Cop supports --auto-correct.
|
173
|
-
# Configuration parameters: AllowAsExpressionSeparator.
|
174
|
-
Style/Semicolon:
|
175
|
-
Enabled: false
|
176
|
-
|
177
|
-
# Offense count: 2
|
178
|
-
# Cop supports --auto-correct.
|
179
|
-
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
180
|
-
Style/SignalException:
|
181
|
-
Enabled: false
|
182
|
-
|
183
|
-
# Offense count: 1
|
184
|
-
# Cop supports --auto-correct.
|
185
|
-
Style/SpecialGlobalVars:
|
186
|
-
Enabled: false
|
187
|
-
|
188
|
-
# Offense count: 1
|
189
|
-
# Cop supports --auto-correct.
|
190
|
-
# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles.
|
191
|
-
Style/TrailingComma:
|
192
|
-
Enabled: false
|
193
|
-
|
194
|
-
# Offense count: 74
|
195
|
-
# Cop supports --auto-correct.
|
196
|
-
Style/TrailingWhitespace:
|
197
|
-
Enabled: false
|
198
|
-
|
199
73
|
# Offense count: 2
|
200
74
|
# Cop supports --auto-correct.
|
201
75
|
# Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, Whitelist.
|
202
76
|
Style/TrivialAccessors:
|
203
77
|
Enabled: false
|
204
|
-
|
205
|
-
# Offense count: 1
|
206
|
-
Style/UnlessElse:
|
207
|
-
Enabled: false
|
208
|
-
|
209
|
-
# Offense count: 1
|
210
|
-
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
211
|
-
Style/VariableName:
|
212
|
-
Enabled: false
|
data/History.rdoc
CHANGED
data/bin/commander
CHANGED
data/commander.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
18
18
|
s.require_paths = ['lib']
|
19
19
|
|
20
|
-
s.add_runtime_dependency('highline', '~> 1.
|
20
|
+
s.add_runtime_dependency('highline', '~> 1.7.1')
|
21
21
|
|
22
22
|
s.add_development_dependency('rspec', '~> 2.14')
|
23
23
|
s.add_development_dependency('rake')
|
data/lib/commander/blank.rb
CHANGED
data/lib/commander/command.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require 'optparse'
|
3
2
|
|
4
3
|
module Commander
|
@@ -112,7 +111,7 @@ module Commander
|
|
112
111
|
args: args,
|
113
112
|
proc: proc,
|
114
113
|
switches: switches,
|
115
|
-
description: description
|
114
|
+
description: description,
|
116
115
|
}
|
117
116
|
end
|
118
117
|
|
@@ -162,7 +161,7 @@ module Commander
|
|
162
161
|
|
163
162
|
def parse_options_and_call_procs(*args)
|
164
163
|
return args if args.empty?
|
165
|
-
@options.
|
164
|
+
@options.each_with_object(OptionParser.new) do |option, opts|
|
166
165
|
opts.on(*option[:args], &option[:proc])
|
167
166
|
opts
|
168
167
|
end.parse! args
|
@@ -187,7 +186,7 @@ module Commander
|
|
187
186
|
# collected by the #option_proc.
|
188
187
|
|
189
188
|
def proxy_option_struct
|
190
|
-
proxy_options.
|
189
|
+
proxy_options.each_with_object(Options.new) do |(option, value), options|
|
191
190
|
# options that are present will evaluate to true
|
192
191
|
value = true if value.nil?
|
193
192
|
options.__send__ :"#{option}=", value
|
@@ -201,7 +200,7 @@ module Commander
|
|
201
200
|
# and work with option values.
|
202
201
|
|
203
202
|
def option_proc(switches)
|
204
|
-
|
203
|
+
->(value) { proxy_options << [Runner.switch_to_sym(switches.last), value] }
|
205
204
|
end
|
206
205
|
|
207
206
|
def inspect
|
data/lib/commander/configure.rb
CHANGED
data/lib/commander/core_ext.rb
CHANGED
data/lib/commander/delegates.rb
CHANGED
@@ -12,8 +12,8 @@ module Commander
|
|
12
12
|
never_trace!
|
13
13
|
).each do |meth|
|
14
14
|
eval <<-END, binding, __FILE__, __LINE__
|
15
|
-
def #{meth}
|
16
|
-
::Commander::Runner.instance.#{meth}
|
15
|
+
def #{meth}(*args, &block)
|
16
|
+
::Commander::Runner.instance.#{meth}(*args, &block)
|
17
17
|
end
|
18
18
|
END
|
19
19
|
end
|
data/lib/commander/import.rb
CHANGED
data/lib/commander/methods.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Commander
|
2
|
+
module Methods
|
3
|
+
include Commander::UI
|
4
|
+
include Commander::UI::AskForClass
|
5
|
+
include Commander::Delegates
|
3
6
|
|
4
|
-
|
5
|
-
|
6
|
-
include Commander::UI::AskForClass
|
7
|
-
include Commander::Delegates
|
8
|
-
|
9
|
-
$terminal.wrap_at = HighLine::SystemExtensions.terminal_size.first - 5 rescue 80 if $stdin.tty?
|
7
|
+
$terminal.wrap_at = HighLine::SystemExtensions.terminal_size.first - 5 rescue 80 if $stdin.tty?
|
8
|
+
end
|
10
9
|
end
|
data/lib/commander/platform.rb
CHANGED
data/lib/commander/runner.rb
CHANGED
@@ -2,71 +2,77 @@ require 'optparse'
|
|
2
2
|
|
3
3
|
module Commander
|
4
4
|
class Runner
|
5
|
-
|
6
5
|
#--
|
7
6
|
# Exceptions
|
8
7
|
#++
|
9
8
|
|
10
9
|
class CommandError < StandardError; end
|
11
10
|
class InvalidCommandError < CommandError; end
|
12
|
-
|
11
|
+
|
13
12
|
##
|
14
13
|
# Array of commands.
|
15
|
-
|
14
|
+
|
16
15
|
attr_reader :commands
|
17
|
-
|
16
|
+
|
18
17
|
##
|
19
18
|
# Global options.
|
20
|
-
|
19
|
+
|
21
20
|
attr_reader :options
|
22
|
-
|
21
|
+
|
23
22
|
##
|
24
23
|
# Hash of help formatter aliases.
|
25
|
-
|
24
|
+
|
26
25
|
attr_reader :help_formatter_aliases
|
27
26
|
|
28
27
|
##
|
29
28
|
# Initialize a new command runner. Optionally
|
30
29
|
# supplying _args_ for mocking, or arbitrary usage.
|
31
|
-
|
32
|
-
def initialize
|
30
|
+
|
31
|
+
def initialize(args = ARGV)
|
33
32
|
@args, @commands, @aliases, @options = args, {}, {}, []
|
34
33
|
@help_formatter_aliases = help_formatter_alias_defaults
|
35
34
|
@program = program_defaults
|
35
|
+
@always_trace = false
|
36
|
+
@never_trace = false
|
36
37
|
create_default_commands
|
37
38
|
end
|
38
|
-
|
39
|
+
|
39
40
|
##
|
40
41
|
# Return singleton Runner instance.
|
41
|
-
|
42
|
+
|
42
43
|
def self.instance
|
43
44
|
@singleton ||= new
|
44
45
|
end
|
45
|
-
|
46
|
+
|
46
47
|
##
|
47
48
|
# Run command parsing and execution process.
|
48
|
-
|
49
|
+
|
49
50
|
def run!
|
50
51
|
trace = @always_trace || false
|
51
52
|
require_program :version, :description
|
52
53
|
trap('INT') { abort program(:int_message) } if program(:int_message)
|
53
54
|
trap('INT') { program(:int_block).call } if program(:int_block)
|
54
55
|
global_option('-h', '--help', 'Display help documentation') do
|
55
|
-
args = @args - %w
|
56
|
+
args = @args - %w(-h --help)
|
56
57
|
command(:help).run(*args)
|
57
58
|
return
|
58
59
|
end
|
59
|
-
global_option('-v', '--version', 'Display version information')
|
60
|
+
global_option('-v', '--version', 'Display version information') do
|
61
|
+
say version
|
62
|
+
return
|
63
|
+
end
|
60
64
|
global_option('-t', '--trace', 'Display backtrace when an error occurs') { trace = true } unless @never_trace || @always_trace
|
61
65
|
parse_global_options
|
62
66
|
remove_global_options options, @args
|
63
|
-
|
67
|
+
if trace
|
68
|
+
run_active_command
|
69
|
+
else
|
64
70
|
begin
|
65
71
|
run_active_command
|
66
72
|
rescue InvalidCommandError => e
|
67
73
|
abort "#{e}. Use --help for more information"
|
68
74
|
rescue \
|
69
|
-
OptionParser::InvalidOption,
|
75
|
+
OptionParser::InvalidOption,
|
70
76
|
OptionParser::InvalidArgument,
|
71
77
|
OptionParser::MissingArgument => e
|
72
78
|
abort e.to_s
|
@@ -77,16 +83,14 @@ module Commander
|
|
77
83
|
abort "error: #{e}. Use --trace to view backtrace"
|
78
84
|
end
|
79
85
|
end
|
80
|
-
else
|
81
|
-
run_active_command
|
82
86
|
end
|
83
87
|
end
|
84
|
-
|
88
|
+
|
85
89
|
##
|
86
90
|
# Return program version.
|
87
|
-
|
91
|
+
|
88
92
|
def version
|
89
|
-
'%s %s'
|
93
|
+
format('%s %s', program(:name), program(:version))
|
90
94
|
end
|
91
95
|
|
92
96
|
##
|
@@ -109,7 +113,7 @@ module Commander
|
|
109
113
|
# Assign program information.
|
110
114
|
#
|
111
115
|
# === Examples
|
112
|
-
#
|
116
|
+
#
|
113
117
|
# # Set data
|
114
118
|
# program :name, 'Commander'
|
115
119
|
# program :version, Commander::VERSION
|
@@ -119,7 +123,7 @@ module Commander
|
|
119
123
|
# program :int_message 'Bye bye!'
|
120
124
|
# program :help_formatter, :compact
|
121
125
|
# program :help_formatter, Commander::HelpFormatter::TerminalCompact
|
122
|
-
#
|
126
|
+
#
|
123
127
|
# # Get data
|
124
128
|
# program :name # => 'Commander'
|
125
129
|
#
|
@@ -132,9 +136,9 @@ module Commander
|
|
132
136
|
# :help Allows addition of arbitrary global help blocks
|
133
137
|
# :int_message Message to display when interrupted (CTRL + C)
|
134
138
|
#
|
135
|
-
|
136
|
-
def program
|
137
|
-
if key == :help
|
139
|
+
|
140
|
+
def program(key, *args, &block)
|
141
|
+
if key == :help && !args.empty?
|
138
142
|
@program[:help] ||= {}
|
139
143
|
@program[:help][args.first] = args.at(1)
|
140
144
|
elsif key == :help_formatter && !args.empty?
|
@@ -148,150 +152,154 @@ module Commander
|
|
148
152
|
@program[key]
|
149
153
|
end
|
150
154
|
end
|
151
|
-
|
155
|
+
|
152
156
|
##
|
153
157
|
# Creates and yields a command instance when a block is passed.
|
154
158
|
# Otherwise attempts to return the command, raising InvalidCommandError when
|
155
159
|
# it does not exist.
|
156
160
|
#
|
157
161
|
# === Examples
|
158
|
-
#
|
162
|
+
#
|
159
163
|
# command :my_command do |c|
|
160
164
|
# c.when_called do |args|
|
161
165
|
# # Code
|
162
166
|
# end
|
163
167
|
# end
|
164
168
|
#
|
165
|
-
|
166
|
-
def command
|
169
|
+
|
170
|
+
def command(name, &block)
|
167
171
|
yield add_command(Commander::Command.new(name)) if block
|
168
172
|
@commands[name.to_s]
|
169
173
|
end
|
170
|
-
|
174
|
+
|
171
175
|
##
|
172
176
|
# Add a global option; follows the same syntax as Command#option
|
173
177
|
# This would be used for switches such as --version, --trace, etc.
|
174
|
-
|
175
|
-
def global_option
|
176
|
-
switches, description = Runner.separate_switches_from_description
|
178
|
+
|
179
|
+
def global_option(*args, &block)
|
180
|
+
switches, description = Runner.separate_switches_from_description(*args)
|
177
181
|
@options << {
|
178
|
-
:
|
179
|
-
:
|
180
|
-
:
|
181
|
-
:
|
182
|
+
args: args,
|
183
|
+
proc: block,
|
184
|
+
switches: switches,
|
185
|
+
description: description,
|
182
186
|
}
|
183
187
|
end
|
184
|
-
|
188
|
+
|
185
189
|
##
|
186
190
|
# Alias command _name_ with _alias_name_. Optionally _args_ may be passed
|
187
191
|
# as if they were being passed straight to the original command via the command-line.
|
188
|
-
|
189
|
-
def alias_command
|
192
|
+
|
193
|
+
def alias_command(alias_name, name, *args)
|
190
194
|
@commands[alias_name.to_s] = command name
|
191
195
|
@aliases[alias_name.to_s] = args
|
192
196
|
end
|
193
|
-
|
197
|
+
|
194
198
|
##
|
195
199
|
# Default command _name_ to be used when no other
|
196
200
|
# command is found in the arguments.
|
197
|
-
|
198
|
-
def default_command
|
201
|
+
|
202
|
+
def default_command(name)
|
199
203
|
@default_command = name
|
200
204
|
end
|
201
|
-
|
205
|
+
|
202
206
|
##
|
203
207
|
# Add a command object to this runner.
|
204
|
-
|
205
|
-
def add_command
|
208
|
+
|
209
|
+
def add_command(command)
|
206
210
|
@commands[command.name] = command
|
207
211
|
end
|
208
|
-
|
212
|
+
|
209
213
|
##
|
210
214
|
# Check if command _name_ is an alias.
|
211
|
-
|
212
|
-
def alias?
|
215
|
+
|
216
|
+
def alias?(name)
|
213
217
|
@aliases.include? name.to_s
|
214
218
|
end
|
215
|
-
|
219
|
+
|
216
220
|
##
|
217
221
|
# Check if a command _name_ exists.
|
218
|
-
|
219
|
-
def command_exists?
|
222
|
+
|
223
|
+
def command_exists?(name)
|
220
224
|
@commands[name.to_s]
|
221
225
|
end
|
222
|
-
|
226
|
+
|
223
227
|
#:stopdoc:
|
224
|
-
|
228
|
+
|
225
229
|
##
|
226
230
|
# Get active command within arguments passed to this runner.
|
227
|
-
|
231
|
+
|
228
232
|
def active_command
|
229
233
|
@__active_command ||= command(command_name_from_args)
|
230
234
|
end
|
231
|
-
|
235
|
+
|
232
236
|
##
|
233
237
|
# Attempts to locate a command name from within the arguments.
|
234
238
|
# Supports multi-word commands, using the largest possible match.
|
235
|
-
|
239
|
+
|
236
240
|
def command_name_from_args
|
237
241
|
@__command_name_from_args ||= (valid_command_names_from(*@args.dup).sort.last || @default_command)
|
238
242
|
end
|
239
|
-
|
243
|
+
|
240
244
|
##
|
241
245
|
# Returns array of valid command names found within _args_.
|
242
|
-
|
243
|
-
def valid_command_names_from
|
246
|
+
|
247
|
+
def valid_command_names_from(*args)
|
244
248
|
arg_string = args.delete_if { |value| value =~ /^-/ }.join ' '
|
245
249
|
commands.keys.find_all { |name| name if /^#{name}\b/.match arg_string }
|
246
250
|
end
|
247
|
-
|
251
|
+
|
248
252
|
##
|
249
253
|
# Help formatter instance.
|
250
|
-
|
254
|
+
|
251
255
|
def help_formatter
|
252
256
|
@__help_formatter ||= program(:help_formatter).new self
|
253
257
|
end
|
254
|
-
|
258
|
+
|
255
259
|
##
|
256
260
|
# Return arguments without the command name.
|
257
|
-
|
261
|
+
|
258
262
|
def args_without_command_name
|
259
263
|
removed = []
|
260
264
|
parts = command_name_from_args.split rescue []
|
261
265
|
@args.dup.delete_if do |arg|
|
262
|
-
removed << arg if parts.include?(arg)
|
266
|
+
removed << arg if parts.include?(arg) && !removed.include?(arg)
|
263
267
|
end
|
264
268
|
end
|
265
|
-
|
269
|
+
|
266
270
|
##
|
267
271
|
# Returns hash of help formatter alias defaults.
|
268
|
-
|
272
|
+
|
269
273
|
def help_formatter_alias_defaults
|
270
|
-
|
274
|
+
{
|
275
|
+
compact: HelpFormatter::TerminalCompact,
|
276
|
+
}
|
271
277
|
end
|
272
|
-
|
278
|
+
|
273
279
|
##
|
274
280
|
# Returns hash of program defaults.
|
275
|
-
|
281
|
+
|
276
282
|
def program_defaults
|
277
|
-
|
278
|
-
|
283
|
+
{
|
284
|
+
help_formatter: HelpFormatter::Terminal,
|
285
|
+
name: File.basename($PROGRAM_NAME),
|
286
|
+
}
|
279
287
|
end
|
280
|
-
|
288
|
+
|
281
289
|
##
|
282
|
-
# Creates default commands such as 'help' which is
|
290
|
+
# Creates default commands such as 'help' which is
|
283
291
|
# essentially the same as using the --help switch.
|
284
|
-
|
292
|
+
|
285
293
|
def create_default_commands
|
286
294
|
command :help do |c|
|
287
295
|
c.syntax = 'commander help [command]'
|
288
296
|
c.description = 'Display global or [command] help documentation'
|
289
297
|
c.example 'Display global help', 'command help'
|
290
298
|
c.example "Display help for 'foo'", 'command help foo'
|
291
|
-
c.when_called do |args,
|
299
|
+
c.when_called do |args, _options|
|
292
300
|
UI.enable_paging
|
293
301
|
if args.empty?
|
294
|
-
say help_formatter.render
|
302
|
+
say help_formatter.render
|
295
303
|
else
|
296
304
|
command = command args.join(' ')
|
297
305
|
begin
|
@@ -304,33 +312,33 @@ module Commander
|
|
304
312
|
end
|
305
313
|
end
|
306
314
|
end
|
307
|
-
|
315
|
+
|
308
316
|
##
|
309
317
|
# Raises InvalidCommandError when a _command_ is not found.
|
310
|
-
|
311
|
-
def require_valid_command
|
312
|
-
|
318
|
+
|
319
|
+
def require_valid_command(command = active_command)
|
320
|
+
fail InvalidCommandError, 'invalid command', caller if command.nil?
|
313
321
|
end
|
314
|
-
|
322
|
+
|
315
323
|
##
|
316
324
|
# Removes global _options_ from _args_. This prevents an invalid
|
317
325
|
# option error from occurring when options are parsed
|
318
326
|
# again for the command.
|
319
|
-
|
320
|
-
def remove_global_options
|
327
|
+
|
328
|
+
def remove_global_options(options, args)
|
321
329
|
# TODO: refactor with flipflop, please TJ ! have time to refactor me !
|
322
330
|
options.each do |option|
|
323
331
|
switches = option[:switches].dup
|
324
332
|
next if switches.empty?
|
325
333
|
|
326
|
-
if
|
334
|
+
if (switch_has_arg = switches.any? { |s| s =~ /[ =]/ })
|
327
335
|
switches.map! { |s| s[0, s.index('=') || s.index(' ') || s.length] }
|
328
336
|
end
|
329
337
|
|
330
338
|
past_switch, arg_removed = false, false
|
331
339
|
args.delete_if do |arg|
|
332
340
|
if switches.any? { |s| arg[0, s.length] == s }
|
333
|
-
arg_removed = !
|
341
|
+
arg_removed = !switch_has_arg
|
334
342
|
past_switch = true
|
335
343
|
elsif past_switch && !arg_removed && arg !~ /^-/
|
336
344
|
arg_removed = true
|
@@ -341,14 +349,13 @@ module Commander
|
|
341
349
|
end
|
342
350
|
end
|
343
351
|
end
|
344
|
-
|
352
|
+
|
345
353
|
##
|
346
354
|
# Parse global command options.
|
347
|
-
|
348
|
-
def parse_global_options
|
349
355
|
|
356
|
+
def parse_global_options
|
350
357
|
parser = options.inject(OptionParser.new) do |options, option|
|
351
|
-
options.on
|
358
|
+
options.on(*option[:args], &global_option_proc(option[:switches], &option[:proc]))
|
352
359
|
end
|
353
360
|
|
354
361
|
options = @args.dup
|
@@ -360,44 +367,44 @@ module Commander
|
|
360
367
|
retry
|
361
368
|
end
|
362
369
|
end
|
363
|
-
|
370
|
+
|
364
371
|
##
|
365
372
|
# Returns a proc allowing for commands to inherit global options.
|
366
373
|
# This functionality works whether a block is present for the global
|
367
374
|
# option or not, so simple switches such as --verbose can be used
|
368
375
|
# without a block, and used throughout all commands.
|
369
|
-
|
370
|
-
def global_option_proc
|
376
|
+
|
377
|
+
def global_option_proc(switches, &block)
|
371
378
|
lambda do |value|
|
372
379
|
unless active_command.nil?
|
373
380
|
active_command.proxy_options << [Runner.switch_to_sym(switches.last), value]
|
374
381
|
end
|
375
|
-
yield value if block
|
382
|
+
yield value if block && !value.nil?
|
376
383
|
end
|
377
384
|
end
|
378
|
-
|
385
|
+
|
379
386
|
##
|
380
387
|
# Raises a CommandError when the program any of the _keys_ are not present, or empty.
|
381
|
-
|
382
|
-
def require_program
|
388
|
+
|
389
|
+
def require_program(*keys)
|
383
390
|
keys.each do |key|
|
384
|
-
|
391
|
+
fail CommandError, "program #{key} required" if program(key).nil? || program(key).empty?
|
385
392
|
end
|
386
393
|
end
|
387
|
-
|
394
|
+
|
388
395
|
##
|
389
396
|
# Return switches and description separated from the _args_ passed.
|
390
397
|
|
391
|
-
def self.separate_switches_from_description
|
392
|
-
switches = args.find_all { |arg| arg.to_s =~ /^-/ }
|
393
|
-
description = args.last
|
394
|
-
|
398
|
+
def self.separate_switches_from_description(*args)
|
399
|
+
switches = args.find_all { |arg| arg.to_s =~ /^-/ }
|
400
|
+
description = args.last if args.last.is_a?(String) && !args.last.match(/^-/)
|
401
|
+
[switches, description]
|
395
402
|
end
|
396
|
-
|
403
|
+
|
397
404
|
##
|
398
405
|
# Attempts to generate a method name symbol from +switch+.
|
399
406
|
# For example:
|
400
|
-
#
|
407
|
+
#
|
401
408
|
# -h # => :h
|
402
409
|
# --trace # => :trace
|
403
410
|
# --some-switch # => :some_switch
|
@@ -405,26 +412,25 @@ module Commander
|
|
405
412
|
# --file FILE # => :file
|
406
413
|
# --list of,things # => :list
|
407
414
|
#
|
408
|
-
|
409
|
-
def self.switch_to_sym
|
415
|
+
|
416
|
+
def self.switch_to_sym(switch)
|
410
417
|
switch.scan(/[\-\]](\w+)/).join('_').to_sym rescue nil
|
411
418
|
end
|
412
|
-
|
419
|
+
|
413
420
|
##
|
414
421
|
# Run the active command.
|
415
|
-
|
422
|
+
|
416
423
|
def run_active_command
|
417
424
|
require_valid_command
|
418
425
|
if alias? command_name_from_args
|
419
|
-
active_command.run
|
426
|
+
active_command.run(*(@aliases[command_name_from_args.to_s] + args_without_command_name))
|
420
427
|
else
|
421
|
-
active_command.run
|
422
|
-
end
|
423
|
-
end
|
424
|
-
|
425
|
-
def say *args #:nodoc:
|
426
|
-
$terminal.say *args
|
428
|
+
active_command.run(*args_without_command_name)
|
429
|
+
end
|
427
430
|
end
|
428
431
|
|
432
|
+
def say(*args) #:nodoc:
|
433
|
+
$terminal.say(*args)
|
434
|
+
end
|
429
435
|
end
|
430
436
|
end
|
@@ -53,7 +53,7 @@ module Commander
|
|
53
53
|
#
|
54
54
|
|
55
55
|
def log(action, *args)
|
56
|
-
say '%15s %s'
|
56
|
+
say format('%15s %s', action, args.join(' '))
|
57
57
|
end
|
58
58
|
|
59
59
|
##
|
@@ -165,18 +165,24 @@ module Commander
|
|
165
165
|
|
166
166
|
def converse(prompt, responses = {})
|
167
167
|
i, commands = 0, responses.map { |_key, value| value.inspect }.join(',')
|
168
|
-
statement = responses.inject '' do |
|
169
|
-
|
170
|
-
|
171
|
-
|
168
|
+
statement = responses.inject '' do |inner_statement, (key, value)|
|
169
|
+
inner_statement <<
|
170
|
+
(
|
171
|
+
(i += 1) == 1 ?
|
172
|
+
%(if response is "#{value}" then\n) :
|
173
|
+
%(else if response is "#{value}" then\n)
|
174
|
+
) <<
|
175
|
+
%(do shell script "echo '#{key}'"\n)
|
172
176
|
end
|
173
|
-
applescript(
|
177
|
+
applescript(
|
178
|
+
%(
|
174
179
|
tell application "SpeechRecognitionServer"
|
175
180
|
set response to listen for {#{commands}} with prompt "#{prompt}"
|
176
181
|
#{statement}
|
177
182
|
end if
|
178
183
|
end tell
|
179
|
-
|
184
|
+
),
|
185
|
+
).strip.to_sym
|
180
186
|
end
|
181
187
|
|
182
188
|
##
|
@@ -214,10 +220,9 @@ module Commander
|
|
214
220
|
def io(input = nil, output = nil, &block)
|
215
221
|
$stdin = File.new(input) if input
|
216
222
|
$stdout = File.new(output, 'r+') if output
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
end
|
223
|
+
return unless block
|
224
|
+
yield
|
225
|
+
reset_io
|
221
226
|
end
|
222
227
|
|
223
228
|
##
|
@@ -279,7 +284,8 @@ module Commander
|
|
279
284
|
|
280
285
|
if Kernel.fork
|
281
286
|
$stdin.reopen read
|
282
|
-
write.close
|
287
|
+
write.close
|
288
|
+
read.close
|
283
289
|
Kernel.select [$stdin]
|
284
290
|
ENV['LESS'] = 'FSRX' unless ENV.key? 'LESS'
|
285
291
|
pager = ENV['PAGER'] || 'less'
|
@@ -288,7 +294,8 @@ module Commander
|
|
288
294
|
# subprocess
|
289
295
|
$stdout.reopen write
|
290
296
|
$stderr.reopen write if $stderr.tty?
|
291
|
-
write.close
|
297
|
+
write.close
|
298
|
+
read.close
|
292
299
|
end
|
293
300
|
rescue NotImplementedError
|
294
301
|
ensure
|
@@ -318,15 +325,17 @@ module Commander
|
|
318
325
|
|
319
326
|
module AskForClass
|
320
327
|
# All special cases in HighLine::Question#convert, except those that implement #parse
|
321
|
-
(
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
328
|
+
(
|
329
|
+
[Float, Integer, String, Symbol, Regexp, Array, File, Pathname] +
|
330
|
+
# All Classes that respond to #parse
|
331
|
+
Object.constants.map do |const|
|
332
|
+
# const_get(:Config) issues a deprecation warning on ruby 1.8.7
|
333
|
+
# TODO: clean up now that we're not supporting Ruby 1.8
|
334
|
+
Object.const_get(const) unless const == :Config
|
335
|
+
end.select do |const|
|
336
|
+
const.class == Class && const.respond_to?(:parse)
|
337
|
+
end
|
338
|
+
).each do |klass|
|
330
339
|
define_method "ask_for_#{klass.to_s.downcase}" do |prompt|
|
331
340
|
$terminal.ask(prompt, klass)
|
332
341
|
end
|
@@ -337,8 +346,8 @@ module Commander
|
|
337
346
|
# Substitute _hash_'s keys with their associated values in _str_.
|
338
347
|
|
339
348
|
def replace_tokens(str, hash) #:nodoc:
|
340
|
-
hash.inject
|
341
|
-
|
349
|
+
hash.inject(str) do |string, (key, value)|
|
350
|
+
string.gsub ":#{key}", value.to_s
|
342
351
|
end
|
343
352
|
end
|
344
353
|
|
@@ -465,8 +474,8 @@ module Commander
|
|
465
474
|
step: @step,
|
466
475
|
steps_remaining: steps_remaining,
|
467
476
|
total_steps: @total_steps,
|
468
|
-
time_elapsed: '%0.2fs'
|
469
|
-
time_remaining: @step > 0 ? '%0.2fs'
|
477
|
+
time_elapsed: format('%0.2fs', time_elapsed),
|
478
|
+
time_remaining: @step > 0 ? format('%0.2fs', time_remaining) : '',
|
470
479
|
}.merge! @tokens
|
471
480
|
end
|
472
481
|
|
@@ -474,13 +483,12 @@ module Commander
|
|
474
483
|
# Output the progress bar.
|
475
484
|
|
476
485
|
def show
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
end
|
486
|
+
return if finished?
|
487
|
+
erase_line
|
488
|
+
if completed?
|
489
|
+
$terminal.say UI.replace_tokens(@complete_message, generate_tokens) if @complete_message.is_a? String
|
490
|
+
else
|
491
|
+
$terminal.say UI.replace_tokens(@format, generate_tokens) << ' '
|
484
492
|
end
|
485
493
|
end
|
486
494
|
|
data/lib/commander/version.rb
CHANGED
data/lib/commander.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: commander
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.3.
|
4
|
+
version: 4.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- TJ Holowaychuk
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-03-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: highline
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 1.
|
20
|
+
version: 1.7.1
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 1.
|
27
|
+
version: 1.7.1
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: rspec
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -156,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
156
|
version: '0'
|
157
157
|
requirements: []
|
158
158
|
rubyforge_project:
|
159
|
-
rubygems_version: 2.
|
159
|
+
rubygems_version: 2.2.2
|
160
160
|
signing_key:
|
161
161
|
specification_version: 4
|
162
162
|
summary: The complete solution for Ruby command-line executables
|