command_kit 0.1.0 → 0.3.0
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 +4 -4
- data/.github/workflows/ruby.yml +18 -3
- data/.rubocop.yml +141 -0
- data/ChangeLog.md +165 -0
- data/Gemfile +3 -0
- data/README.md +186 -118
- data/Rakefile +3 -2
- data/command_kit.gemspec +4 -4
- data/examples/command.rb +1 -1
- data/gemspec.yml +7 -0
- data/lib/command_kit/arguments/argument.rb +2 -2
- data/lib/command_kit/arguments.rb +36 -7
- data/lib/command_kit/colors.rb +702 -53
- data/lib/command_kit/command.rb +2 -3
- data/lib/command_kit/commands/auto_load.rb +8 -1
- data/lib/command_kit/commands/help.rb +3 -2
- data/lib/command_kit/commands/subcommand.rb +1 -1
- data/lib/command_kit/commands.rb +24 -9
- data/lib/command_kit/env/path.rb +1 -1
- data/lib/command_kit/file_utils.rb +46 -0
- data/lib/command_kit/help/man.rb +17 -33
- data/lib/command_kit/inflector.rb +47 -17
- data/lib/command_kit/interactive.rb +9 -0
- data/lib/command_kit/main.rb +7 -9
- data/lib/command_kit/man.rb +44 -0
- data/lib/command_kit/open_app.rb +69 -0
- data/lib/command_kit/options/option.rb +41 -27
- data/lib/command_kit/options/option_value.rb +3 -2
- data/lib/command_kit/options/parser.rb +17 -22
- data/lib/command_kit/options.rb +102 -14
- data/lib/command_kit/os/linux.rb +157 -0
- data/lib/command_kit/os.rb +159 -11
- data/lib/command_kit/package_manager.rb +200 -0
- data/lib/command_kit/pager.rb +46 -4
- data/lib/command_kit/printing/indent.rb +4 -4
- data/lib/command_kit/printing.rb +14 -3
- data/lib/command_kit/program_name.rb +9 -0
- data/lib/command_kit/sudo.rb +40 -0
- data/lib/command_kit/terminal.rb +5 -0
- data/lib/command_kit/version.rb +1 -1
- data/spec/arguments/argument_spec.rb +1 -1
- data/spec/arguments_spec.rb +84 -1
- data/spec/colors_spec.rb +357 -70
- data/spec/command_spec.rb +77 -6
- data/spec/commands/auto_load_spec.rb +33 -2
- data/spec/commands_spec.rb +101 -29
- data/spec/env/path_spec.rb +6 -0
- data/spec/exception_handler_spec.rb +1 -1
- data/spec/file_utils_spec.rb +59 -0
- data/spec/fixtures/template.erb +5 -0
- data/spec/help/man_spec.rb +54 -57
- data/spec/inflector_spec.rb +70 -8
- data/spec/man_spec.rb +46 -0
- data/spec/open_app_spec.rb +85 -0
- data/spec/options/option_spec.rb +38 -2
- data/spec/options/option_value_spec.rb +55 -0
- data/spec/options/parser_spec.rb +0 -10
- data/spec/options_spec.rb +328 -0
- data/spec/os/linux_spec.rb +164 -0
- data/spec/os_spec.rb +200 -13
- data/spec/package_manager_spec.rb +806 -0
- data/spec/pager_spec.rb +71 -6
- data/spec/printing/indent_spec.rb +7 -5
- data/spec/printing_spec.rb +23 -1
- data/spec/program_name_spec.rb +8 -0
- data/spec/sudo_spec.rb +51 -0
- data/spec/terminal_spec.rb +30 -0
- data/spec/usage_spec.rb +1 -1
- metadata +23 -4
data/lib/command_kit/command.rb
CHANGED
@@ -8,8 +8,7 @@ require 'command_kit/options'
|
|
8
8
|
require 'command_kit/examples'
|
9
9
|
require 'command_kit/description'
|
10
10
|
require 'command_kit/exception_handler'
|
11
|
-
|
12
|
-
require 'fileutils'
|
11
|
+
require 'command_kit/file_utils'
|
13
12
|
|
14
13
|
module CommandKit
|
15
14
|
#
|
@@ -56,7 +55,7 @@ module CommandKit
|
|
56
55
|
# end
|
57
56
|
# end
|
58
57
|
#
|
59
|
-
# ### initialize and using
|
58
|
+
# ### initialize and using instance variables
|
60
59
|
#
|
61
60
|
# option :verbose, short: '-v', desc: "Increase verbose level" do
|
62
61
|
# @verbose += 1
|
@@ -162,7 +162,14 @@ module CommandKit
|
|
162
162
|
#
|
163
163
|
def included(command)
|
164
164
|
command.include Commands
|
165
|
-
|
165
|
+
|
166
|
+
@commands.each do |name,subcommand|
|
167
|
+
command.commands[name] = subcommand
|
168
|
+
|
169
|
+
subcommand.aliases.each do |alias_name|
|
170
|
+
command.command_aliases[alias_name] = name
|
171
|
+
end
|
172
|
+
end
|
166
173
|
end
|
167
174
|
end
|
168
175
|
end
|
@@ -14,7 +14,8 @@ module CommandKit
|
|
14
14
|
|
15
15
|
include ParentCommand
|
16
16
|
|
17
|
-
argument :command,
|
17
|
+
argument :command, required: false,
|
18
|
+
desc: 'Command name to lookup'
|
18
19
|
|
19
20
|
#
|
20
21
|
# Prints the given commands `--help` output or lists registered commands.
|
@@ -34,7 +35,7 @@ module CommandKit
|
|
34
35
|
|
35
36
|
subcommand.help
|
36
37
|
else
|
37
|
-
print_error "
|
38
|
+
print_error "unknown command: #{command}"
|
38
39
|
exit(1)
|
39
40
|
end
|
40
41
|
end
|
data/lib/command_kit/commands.rb
CHANGED
@@ -59,6 +59,13 @@ module CommandKit
|
|
59
59
|
context.extend ModuleMethods
|
60
60
|
else
|
61
61
|
context.usage "[options] [COMMAND [ARGS...]]"
|
62
|
+
context.argument :command, required: false,
|
63
|
+
desc: 'The command name to run'
|
64
|
+
|
65
|
+
context.argument :args, required: false,
|
66
|
+
repeats: true,
|
67
|
+
desc: 'Additional arguments for the command'
|
68
|
+
|
62
69
|
context.extend ClassMethods
|
63
70
|
context.command Help
|
64
71
|
end
|
@@ -81,10 +88,10 @@ module CommandKit
|
|
81
88
|
#
|
82
89
|
def commands
|
83
90
|
@commands ||= if superclass.kind_of?(ClassMethods)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
91
|
+
superclass.commands.dup
|
92
|
+
else
|
93
|
+
{}
|
94
|
+
end
|
88
95
|
end
|
89
96
|
|
90
97
|
#
|
@@ -140,11 +147,10 @@ module CommandKit
|
|
140
147
|
end
|
141
148
|
|
142
149
|
subcommand = Subcommand.new(command_class,**kwargs)
|
143
|
-
|
144
150
|
commands[name] = subcommand
|
145
151
|
|
146
|
-
subcommand.aliases.each do |
|
147
|
-
command_aliases[
|
152
|
+
subcommand.aliases.each do |alias_name|
|
153
|
+
command_aliases[alias_name] = name
|
148
154
|
end
|
149
155
|
|
150
156
|
return subcommand
|
@@ -220,7 +226,9 @@ module CommandKit
|
|
220
226
|
end
|
221
227
|
|
222
228
|
if command_class.include?(Env)
|
223
|
-
kwargs[:env] = env.
|
229
|
+
kwargs[:env] = if env.eql?(ENV) then env.to_h
|
230
|
+
else env.dup
|
231
|
+
end
|
224
232
|
end
|
225
233
|
|
226
234
|
if command_class.include?(Options)
|
@@ -296,6 +304,7 @@ module CommandKit
|
|
296
304
|
exit invoke(command,*argv)
|
297
305
|
else
|
298
306
|
help
|
307
|
+
exit(1)
|
299
308
|
end
|
300
309
|
end
|
301
310
|
|
@@ -309,8 +318,14 @@ module CommandKit
|
|
309
318
|
puts
|
310
319
|
puts "Commands:"
|
311
320
|
|
321
|
+
command_aliases = Hash.new { |hash,key| hash[key] = [] }
|
322
|
+
|
323
|
+
self.class.command_aliases.each do |alias_name,name|
|
324
|
+
command_aliases[name] << alias_name
|
325
|
+
end
|
326
|
+
|
312
327
|
self.class.commands.sort.each do |name,subcommand|
|
313
|
-
names = [name, *
|
328
|
+
names = [name, *command_aliases[name]].join(', ')
|
314
329
|
|
315
330
|
if subcommand.summary
|
316
331
|
puts " #{names}\t#{subcommand.summary}"
|
data/lib/command_kit/env/path.rb
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
module CommandKit
|
5
|
+
#
|
6
|
+
# File manipulation related methods.
|
7
|
+
#
|
8
|
+
# @since 0.3.0
|
9
|
+
#
|
10
|
+
# @api public
|
11
|
+
#
|
12
|
+
module FileUtils
|
13
|
+
include ::FileUtils
|
14
|
+
|
15
|
+
#
|
16
|
+
# Renders an erb file and optionally writes it out to a destination file.
|
17
|
+
#
|
18
|
+
# @param [String] source
|
19
|
+
# The path to the erb template file.
|
20
|
+
#
|
21
|
+
# @param [String, nil] dest
|
22
|
+
# The path to the destination file.
|
23
|
+
#
|
24
|
+
# @return [String, nil]
|
25
|
+
# If no destination path argument is given, the rendered erb template
|
26
|
+
# String will be returned.
|
27
|
+
#
|
28
|
+
# @example Rendering a ERB template and saving it's output:
|
29
|
+
# erb File.join(template_dir,'README.md.erb'), 'README.md'
|
30
|
+
#
|
31
|
+
# @example Rendering a ERB template and capturing it's output:
|
32
|
+
# output = erb(File.join(template_dir,'_partial.erb'))
|
33
|
+
#
|
34
|
+
def erb(source,dest=nil)
|
35
|
+
erb = ERB.new(File.read(source), trim_mode: '-')
|
36
|
+
result = erb.result(binding)
|
37
|
+
|
38
|
+
if dest
|
39
|
+
File.write(dest,result)
|
40
|
+
return
|
41
|
+
else
|
42
|
+
return result
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/command_kit/help/man.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'command_kit/command_name'
|
4
4
|
require 'command_kit/help'
|
5
5
|
require 'command_kit/stdio'
|
6
|
+
require 'command_kit/man'
|
6
7
|
|
7
8
|
module CommandKit
|
8
9
|
module Help
|
@@ -23,6 +24,7 @@ module CommandKit
|
|
23
24
|
include CommandName
|
24
25
|
include Help
|
25
26
|
include Stdio
|
27
|
+
include CommandKit::Man
|
26
28
|
|
27
29
|
#
|
28
30
|
# @api private
|
@@ -68,7 +70,7 @@ module CommandKit
|
|
68
70
|
#
|
69
71
|
def man_dir(new_man_dir=nil)
|
70
72
|
if new_man_dir
|
71
|
-
@man_dir = new_man_dir
|
73
|
+
@man_dir = File.expand_path(new_man_dir)
|
72
74
|
else
|
73
75
|
@man_dir || if superclass.kind_of?(ClassMethods)
|
74
76
|
superclass.man_dir
|
@@ -96,29 +98,6 @@ module CommandKit
|
|
96
98
|
end
|
97
99
|
end
|
98
100
|
|
99
|
-
#
|
100
|
-
# Displays the given man page.
|
101
|
-
#
|
102
|
-
# @param [String] page
|
103
|
-
# The man page file name.
|
104
|
-
#
|
105
|
-
# @param [Integer, String, nil] section
|
106
|
-
# The optional section number to specify.
|
107
|
-
#
|
108
|
-
# @return [Boolean, nil]
|
109
|
-
# Specifies whether the `man` command was successful or not.
|
110
|
-
# Returns `nil` when the `man` command is not installed.
|
111
|
-
#
|
112
|
-
# @api public
|
113
|
-
#
|
114
|
-
def man(page, section: nil)
|
115
|
-
if section
|
116
|
-
system('man',section.to_s,page.to_s)
|
117
|
-
else
|
118
|
-
system('man',page.to_s)
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
101
|
#
|
123
102
|
# Provides help information by showing one of the man pages within
|
124
103
|
# {ClassMethods#man_dir .man_dir}.
|
@@ -131,13 +110,13 @@ module CommandKit
|
|
131
110
|
# Returns `nil` when the `man` command is not installed.
|
132
111
|
#
|
133
112
|
# @raise [NotImplementedError]
|
134
|
-
# {ClassMethods#man_dir .man_dir}
|
113
|
+
# {ClassMethods#man_dir .man_dir} was not set in the class.
|
135
114
|
#
|
136
115
|
# @api semipublic
|
137
116
|
#
|
138
117
|
def help_man(man_page=self.class.man_page)
|
139
118
|
unless self.class.man_dir
|
140
|
-
raise(NotImplementedError,"#{self.class}
|
119
|
+
raise(NotImplementedError,"man_dir was not set in #{self.class}")
|
141
120
|
end
|
142
121
|
|
143
122
|
man_path = File.join(self.class.man_dir,man_page)
|
@@ -149,22 +128,27 @@ module CommandKit
|
|
149
128
|
# Displays the {ClassMethods#man_page .man_page} in
|
150
129
|
# {ClassMethods#man_dir .man_dir} instead of the usual `--help` output.
|
151
130
|
#
|
152
|
-
# @raise [NotImplementedError]
|
153
|
-
# {ClassMethods#man_dir .man_dir} does not have a value.
|
154
|
-
#
|
155
131
|
# @note
|
156
|
-
# if `TERM` is `dumb` or `$stdout` is not a TTY,
|
157
|
-
# the usual `--help` output.
|
132
|
+
# if `TERM` is `dumb` or `$stdout` is not a TTY, will fall back to
|
133
|
+
# printing the usual `--help` output.
|
158
134
|
#
|
159
135
|
# @api public
|
160
136
|
#
|
161
137
|
def help
|
162
138
|
if stdout.tty?
|
163
|
-
if
|
164
|
-
|
139
|
+
if self.class.man_dir
|
140
|
+
status = help_man
|
141
|
+
|
142
|
+
if status.nil?
|
143
|
+
# the `man` command is not installed
|
144
|
+
super
|
145
|
+
end
|
146
|
+
else
|
147
|
+
# man_dir was not set
|
165
148
|
super
|
166
149
|
end
|
167
150
|
else
|
151
|
+
# stdout is not a TTY
|
168
152
|
super
|
169
153
|
end
|
170
154
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'strscan'
|
4
|
+
|
3
5
|
module CommandKit
|
4
6
|
#
|
5
7
|
# A very simple inflector.
|
@@ -33,16 +35,37 @@ module CommandKit
|
|
33
35
|
# @return [String]
|
34
36
|
# The resulting under_scored name.
|
35
37
|
#
|
38
|
+
# @raise [ArgumentError]
|
39
|
+
# The given string contained non-alpha-numeric characters.
|
40
|
+
#
|
36
41
|
def self.underscore(name)
|
37
|
-
|
38
|
-
|
42
|
+
scanner = StringScanner.new(name.to_s)
|
43
|
+
new_string = String.new
|
44
|
+
|
45
|
+
until scanner.eos?
|
46
|
+
if (separator = scanner.scan(/[_-]+/))
|
47
|
+
new_string << ('_' * separator.length)
|
48
|
+
else
|
49
|
+
if (capitalized = scanner.scan(/[A-Z][a-z\d]+/))
|
50
|
+
new_string << capitalized
|
51
|
+
elsif (uppercase = scanner.scan(/[A-Z][A-Z\d]*(?=[A-Z_-]|$)/))
|
52
|
+
new_string << uppercase
|
53
|
+
elsif (lowercase = scanner.scan(/[a-z][a-z\d]*/))
|
54
|
+
new_string << lowercase
|
55
|
+
else
|
56
|
+
raise(ArgumentError,"cannot convert string to underscored: #{scanner.string.inspect}")
|
57
|
+
end
|
39
58
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
59
|
+
if (separator = scanner.scan(/[_-]+/))
|
60
|
+
new_string << ('_' * separator.length)
|
61
|
+
elsif !scanner.eos?
|
62
|
+
new_string << '_'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
44
66
|
|
45
|
-
|
67
|
+
new_string.downcase!
|
68
|
+
new_string
|
46
69
|
end
|
47
70
|
|
48
71
|
#
|
@@ -67,20 +90,27 @@ module CommandKit
|
|
67
90
|
# @return [String]
|
68
91
|
# The CamelCased name.
|
69
92
|
#
|
93
|
+
# @raise [ArgumentError]
|
94
|
+
# The given under_scored string contained non-alpha-numeric characters.
|
95
|
+
#
|
70
96
|
def self.camelize(name)
|
71
|
-
|
72
|
-
|
73
|
-
# sourced from: https://github.com/dry-rb/dry-inflector/blob/c918f967ff82611da374eb0847a77b7e012d3fa8/lib/dry/inflector.rb#L329-L334
|
74
|
-
name.sub!(/^[a-z\d]*/,&:capitalize)
|
75
|
-
name.gsub!(%r{(?:[_-]|(/))([a-z\d]*)}i) do |match|
|
76
|
-
slash = Regexp.last_match(1)
|
77
|
-
word = Regexp.last_match(2)
|
97
|
+
scanner = StringScanner.new(name.to_s)
|
98
|
+
new_string = String.new
|
78
99
|
|
79
|
-
|
100
|
+
until scanner.eos?
|
101
|
+
if (word = scanner.scan(/[A-Za-z\d]+/))
|
102
|
+
word.capitalize!
|
103
|
+
new_string << word
|
104
|
+
elsif scanner.scan(/[_-]+/)
|
105
|
+
# skip
|
106
|
+
elsif scanner.scan(/\//)
|
107
|
+
new_string << '::'
|
108
|
+
else
|
109
|
+
raise(ArgumentError,"cannot convert string to CamelCase: #{scanner.string.inspect}")
|
110
|
+
end
|
80
111
|
end
|
81
112
|
|
82
|
-
|
83
|
-
name
|
113
|
+
new_string
|
84
114
|
end
|
85
115
|
end
|
86
116
|
end
|
@@ -218,6 +218,15 @@ module CommandKit
|
|
218
218
|
#
|
219
219
|
# Asks the user for secret input.
|
220
220
|
#
|
221
|
+
# @param [String] prompt
|
222
|
+
# The prompt that will be printed before reading input.
|
223
|
+
#
|
224
|
+
# @param [Boolean] required
|
225
|
+
# Requires non-empty input.
|
226
|
+
#
|
227
|
+
# @return [String]
|
228
|
+
# The user input.
|
229
|
+
#
|
221
230
|
# @example
|
222
231
|
# ask_secret("Password")
|
223
232
|
# # Password:
|
data/lib/command_kit/main.rb
CHANGED
@@ -49,15 +49,13 @@ module CommandKit
|
|
49
49
|
# @api public
|
50
50
|
#
|
51
51
|
def start(argv=ARGV, **kwargs)
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
exit 0
|
60
|
-
end
|
52
|
+
exit main(argv, **kwargs)
|
53
|
+
rescue Interrupt
|
54
|
+
# https://tldp.org/LDP/abs/html/exitcodes.html
|
55
|
+
exit 130
|
56
|
+
rescue Errno::EPIPE
|
57
|
+
# STDOUT pipe broken
|
58
|
+
exit 0
|
61
59
|
end
|
62
60
|
|
63
61
|
#
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CommandKit
|
4
|
+
#
|
5
|
+
# Allows displaying man pages.
|
6
|
+
#
|
7
|
+
# ## Examples
|
8
|
+
#
|
9
|
+
# man "passwd"
|
10
|
+
# man "passwd", section: 5
|
11
|
+
#
|
12
|
+
# @since 0.2.0
|
13
|
+
#
|
14
|
+
module Man
|
15
|
+
#
|
16
|
+
# Displays the given man page.
|
17
|
+
#
|
18
|
+
# @param [String] page
|
19
|
+
# The man page file name.
|
20
|
+
#
|
21
|
+
# @param [Integer, String, nil] section
|
22
|
+
# The optional section number to specify.
|
23
|
+
#
|
24
|
+
# @return [Boolean, nil]
|
25
|
+
# Specifies whether the `man` command was successful or not.
|
26
|
+
# Returns `nil` when the `man` command is not installed.
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# man "passwd"
|
30
|
+
#
|
31
|
+
# @example Display a man-page from a specific section:
|
32
|
+
# man "passwd", section: 5
|
33
|
+
#
|
34
|
+
# @api public
|
35
|
+
#
|
36
|
+
def man(page, section: nil)
|
37
|
+
if section
|
38
|
+
system('man',section.to_s,page.to_s)
|
39
|
+
else
|
40
|
+
system('man',page.to_s)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'command_kit/os'
|
2
|
+
require 'command_kit/env/path'
|
3
|
+
|
4
|
+
module CommandKit
|
5
|
+
#
|
6
|
+
# Allows opening a file or a URI with the system's preferred application for
|
7
|
+
# that file type or URI scheme.
|
8
|
+
#
|
9
|
+
# ## Examples
|
10
|
+
#
|
11
|
+
# open_app_for "movie.avi"
|
12
|
+
# open_app_for "https://github.com/postmodern/command_kit.rb#readme"
|
13
|
+
#
|
14
|
+
# @since 0.2.0
|
15
|
+
#
|
16
|
+
module OpenApp
|
17
|
+
include OS
|
18
|
+
include Env::Path
|
19
|
+
|
20
|
+
#
|
21
|
+
# Initializes the command and determines which open command to use.
|
22
|
+
#
|
23
|
+
# @param [Hash{Symbol => Object}] kwargs
|
24
|
+
# Additional keyword arguments.
|
25
|
+
#
|
26
|
+
# @api public
|
27
|
+
#
|
28
|
+
def initialize(**kwargs)
|
29
|
+
super(**kwargs)
|
30
|
+
|
31
|
+
@open_command = if macos?
|
32
|
+
'open'
|
33
|
+
elsif linux? || bsd?
|
34
|
+
if command_installed?('xdg-open')
|
35
|
+
'xdg-open'
|
36
|
+
end
|
37
|
+
elsif windows?
|
38
|
+
if command_installed?('invoke-item')
|
39
|
+
'invoke-item'
|
40
|
+
else
|
41
|
+
'start'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Opens a file or URI using the system's preferred application for that
|
48
|
+
# file type or URI scheme.
|
49
|
+
#
|
50
|
+
# @param [String, URI] file_or_uri
|
51
|
+
# The file path or URI to open.
|
52
|
+
#
|
53
|
+
# @return [Boolean, nil]
|
54
|
+
# Specifies whether the file or URI was successfully opened or not.
|
55
|
+
# If the open command could not be determined, `nil` is returned.
|
56
|
+
#
|
57
|
+
# @example Open a file:
|
58
|
+
# open_app_for "movie.avi"
|
59
|
+
#
|
60
|
+
# @example Open a URI:
|
61
|
+
# open_app_for "https://github.com/postmodern/command_kit.rb"
|
62
|
+
#
|
63
|
+
def open_app_for(file_or_uri)
|
64
|
+
if @open_command
|
65
|
+
system(@open_command,file_or_uri.to_s)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -35,16 +35,18 @@ module CommandKit
|
|
35
35
|
# @return [OptionValue, nil]
|
36
36
|
attr_reader :value
|
37
37
|
|
38
|
-
# The option's description.
|
39
|
-
#
|
40
|
-
# @return [String]
|
41
|
-
attr_reader :desc
|
42
|
-
|
43
38
|
# The optional block that will receive the parsed option value.
|
44
39
|
#
|
45
40
|
# @return [Proc, nil]
|
46
41
|
attr_reader :block
|
47
42
|
|
43
|
+
# The optional category to group the option under.
|
44
|
+
#
|
45
|
+
# @return [String, nil]
|
46
|
+
#
|
47
|
+
# @since 0.3.0
|
48
|
+
attr_reader :category
|
49
|
+
|
48
50
|
#
|
49
51
|
# Initializes the option.
|
50
52
|
#
|
@@ -70,9 +72,12 @@ module CommandKit
|
|
70
72
|
# @option value [String, nil] usage
|
71
73
|
# The usage string for the option's value.
|
72
74
|
#
|
73
|
-
# @param [String] desc
|
75
|
+
# @param [String, Array<String>] desc
|
74
76
|
# The description for the option.
|
75
77
|
#
|
78
|
+
# @param [String, nil] category
|
79
|
+
# The optional category to group the option under.
|
80
|
+
#
|
76
81
|
# @yield [(value)]
|
77
82
|
# If a block is given, it will be called when the option is parsed.
|
78
83
|
#
|
@@ -83,25 +88,27 @@ module CommandKit
|
|
83
88
|
# The `value` keyword argument was not a `Hash`, `true`, `false`, or
|
84
89
|
# `nil`.
|
85
90
|
#
|
86
|
-
def initialize(name, short:
|
87
|
-
long:
|
88
|
-
equals:
|
89
|
-
value:
|
90
|
-
desc:
|
91
|
+
def initialize(name, short: nil,
|
92
|
+
long: self.class.default_long_opt(name),
|
93
|
+
equals: false,
|
94
|
+
value: nil,
|
95
|
+
desc: ,
|
96
|
+
category: nil,
|
91
97
|
&block)
|
92
|
-
@name
|
93
|
-
@short
|
94
|
-
@long
|
95
|
-
@equals
|
96
|
-
@value
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
@desc
|
104
|
-
@
|
98
|
+
@name = name
|
99
|
+
@short = short
|
100
|
+
@long = long
|
101
|
+
@equals = equals
|
102
|
+
@value = case value
|
103
|
+
when Hash then OptionValue.new(**value)
|
104
|
+
when true then OptionValue.new()
|
105
|
+
when false, nil then nil
|
106
|
+
else
|
107
|
+
raise(TypeError,"value: keyword must be Hash, true, false, or nil")
|
108
|
+
end
|
109
|
+
@desc = desc
|
110
|
+
@category = category
|
111
|
+
@block = block
|
105
112
|
end
|
106
113
|
|
107
114
|
#
|
@@ -128,7 +135,7 @@ module CommandKit
|
|
128
135
|
end
|
129
136
|
|
130
137
|
#
|
131
|
-
# The separator
|
138
|
+
# The separator character between the option and option value.
|
132
139
|
#
|
133
140
|
# @return ['=', ' ', nil]
|
134
141
|
#
|
@@ -184,7 +191,7 @@ module CommandKit
|
|
184
191
|
#
|
185
192
|
# The option description.
|
186
193
|
#
|
187
|
-
# @return [String]
|
194
|
+
# @return [String, Array<String>]
|
188
195
|
#
|
189
196
|
# @note
|
190
197
|
# If {#default_value} returns a value, the description will contain the
|
@@ -192,7 +199,14 @@ module CommandKit
|
|
192
199
|
#
|
193
200
|
def desc
|
194
201
|
if (value = default_value)
|
195
|
-
"
|
202
|
+
default_text = "(Default: #{value})"
|
203
|
+
|
204
|
+
case @desc
|
205
|
+
when Array
|
206
|
+
@desc + [default_text]
|
207
|
+
else
|
208
|
+
"#{@desc} #{default_text}"
|
209
|
+
end
|
196
210
|
else
|
197
211
|
@desc
|
198
212
|
end
|
@@ -41,7 +41,7 @@ module CommandKit
|
|
41
41
|
|
42
42
|
# The desired type of the argument value.
|
43
43
|
#
|
44
|
-
# @return [Class, Hash, Array, Regexp
|
44
|
+
# @return [Class, Hash, Array, Regexp]
|
45
45
|
attr_reader :type
|
46
46
|
|
47
47
|
# The default parsed value for the argument value.
|
@@ -92,10 +92,11 @@ module CommandKit
|
|
92
92
|
def self.default_usage(type)
|
93
93
|
USAGES.fetch(type) do
|
94
94
|
case type
|
95
|
-
when Class then Inflector.underscore(type.name).upcase
|
96
95
|
when Hash then type.keys.join('|')
|
97
96
|
when Array then type.join('|')
|
98
97
|
when Regexp then type.source
|
98
|
+
when Class
|
99
|
+
Inflector.underscore(Inflector.demodularize(type.name)).upcase
|
99
100
|
else
|
100
101
|
raise(TypeError,"unsupported option type: #{type.inspect}")
|
101
102
|
end
|