simple-cli 0.2.18 → 0.2.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/simple/cli/runner/command_help.rb +28 -19
- data/lib/simple/cli/runner/module_ex.rb +69 -0
- data/lib/simple/cli/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ad5562abdf4690d3ba8a6733c0669f42cdffe673c9a9833f1e4d8e43c4d048b
|
4
|
+
data.tar.gz: 1ab4c259ffb2372efd1caaf6aed9b5df6e634cfa849b7fd22d071c00e87179fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d821d8d77506188106ad50627f7336569a61cd07dc60ace53697c6d7d2cd8ce6ce63a881b69454e0f791ae3c771dd91cf36a07e2e2b3b39c2e5da393f17093c
|
7
|
+
data.tar.gz: 7e2d94b98fa2f5e068a91869da0624891a271ea320845719b08196fd25b3f87137f6958cf3dba66fa8b24144daaff018e3c70a19d8d6144b34188bb06deffc1a
|
@@ -2,6 +2,8 @@
|
|
2
2
|
# rubocop:disable Metrics/CyclomaticComplexity
|
3
3
|
# rubocop:disable Metrics/MethodLength
|
4
4
|
|
5
|
+
require_relative "./module_ex"
|
6
|
+
|
5
7
|
class Simple::CLI::Runner::CommandHelp
|
6
8
|
def self.option_names(app, subcommand)
|
7
9
|
new(app, subcommand).option_names
|
@@ -9,10 +11,12 @@ class Simple::CLI::Runner::CommandHelp
|
|
9
11
|
[]
|
10
12
|
end
|
11
13
|
|
12
|
-
def initialize(mod,
|
13
|
-
raise(ArgumentError, "#{
|
14
|
-
|
15
|
-
@
|
14
|
+
def initialize(mod, method_id)
|
15
|
+
raise(ArgumentError, "#{method_id.inspect} should be a Symbol") unless method_id.is_a?(Symbol)
|
16
|
+
|
17
|
+
@method_id = method_id
|
18
|
+
@method = mod.instance_method(@method_id)
|
19
|
+
@method_parameters_ex = mod.method_parameters_ex(@method_id)
|
16
20
|
end
|
17
21
|
|
18
22
|
# First line of the help as read from the method comments.
|
@@ -26,9 +30,7 @@ class Simple::CLI::Runner::CommandHelp
|
|
26
30
|
end
|
27
31
|
|
28
32
|
def option_names
|
29
|
-
|
30
|
-
|
31
|
-
option_names = method.parameters.map do |mode, name|
|
33
|
+
option_names = @method_parameters_ex.map do |mode, name, _|
|
32
34
|
case mode
|
33
35
|
when :key then name
|
34
36
|
when :keyreq then name
|
@@ -42,20 +44,27 @@ class Simple::CLI::Runner::CommandHelp
|
|
42
44
|
|
43
45
|
# A help string constructed from the commands method signature.
|
44
46
|
def interface(binary_name, command_name)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
args = @method_parameters_ex.map do |mode, name|
|
48
|
+
case mode
|
49
|
+
when :req then "<#{name}>"
|
50
|
+
when :opt then "[ <#{name}> ]"
|
51
|
+
when :rest then "[ <#{name}> .. ]"
|
52
|
+
end
|
53
|
+
end.compact
|
49
54
|
|
50
|
-
|
55
|
+
options = @method_parameters_ex.map do |mode, name, default_value|
|
51
56
|
case mode
|
52
|
-
when :
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
+
when :key then
|
58
|
+
case default_value
|
59
|
+
when false then "[ --#{name} ]"
|
60
|
+
when true then "[ --no-#{name} ]"
|
61
|
+
when nil then "[ --#{name}=<#{name}> ]"
|
62
|
+
else "[ --#{name}=#{default_value} ]"
|
63
|
+
end
|
64
|
+
when :keyreq then
|
65
|
+
"--#{name}=<#{name}>"
|
57
66
|
end
|
58
|
-
end
|
67
|
+
end.compact
|
59
68
|
|
60
69
|
help = "#{binary_name} #{command_to_string(command_name)}"
|
61
70
|
help << " #{options.join(' ')}" unless options.empty?
|
@@ -71,7 +80,7 @@ class Simple::CLI::Runner::CommandHelp
|
|
71
80
|
|
72
81
|
def comments
|
73
82
|
@comments ||= begin
|
74
|
-
file, line = @
|
83
|
+
file, line = @method.source_location
|
75
84
|
extract_comments(from: parsed_source(file), before_line: line)
|
76
85
|
end
|
77
86
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# rubocop:disable Metrics/MethodLength
|
2
|
+
# rubocop:disable Metrics/AbcSize
|
3
|
+
|
4
|
+
class Module
|
5
|
+
#
|
6
|
+
# returns an array with entries like the following:
|
7
|
+
#
|
8
|
+
# [ :key, name, default_value ]
|
9
|
+
# [ :keyreq, name [, nil ] ]
|
10
|
+
# [ :req, name [, nil ] ]
|
11
|
+
# [ :opt, name [, nil ] ]
|
12
|
+
# [ :rest, name [, nil ] ]
|
13
|
+
#
|
14
|
+
def method_parameters_ex(method_id)
|
15
|
+
method = instance_method(method_id)
|
16
|
+
parameters = method.parameters
|
17
|
+
|
18
|
+
# method parameters with a :key mode are optional keyword arguments. We only
|
19
|
+
# support defaults for those - if there are none we abort here already.
|
20
|
+
keys = parameters.map { |mode, name| name if mode == :key }.compact
|
21
|
+
return parameters if keys.empty?
|
22
|
+
|
23
|
+
# We are now doing a fake call to the method, with a minimal viable set of
|
24
|
+
# arguments, to let the ruby runtime fill in default values for arguments.
|
25
|
+
# We do not, however, let the call complete. Instead we use a TracePoint to
|
26
|
+
# abort as soon as the method is called, and use the its binding to determine
|
27
|
+
# the default values.
|
28
|
+
|
29
|
+
fake_recipient = Object.new.extend(self)
|
30
|
+
fake_call_args = minimal_arguments(method)
|
31
|
+
|
32
|
+
trace_point = TracePoint.trace(:call) do |tp|
|
33
|
+
throw :received_fake_call, tp.binding if tp.defined_class == self && tp.method_id == method_id
|
34
|
+
end
|
35
|
+
|
36
|
+
bnd = catch(:received_fake_call) do
|
37
|
+
fake_recipient.send(method_id, *fake_call_args)
|
38
|
+
end
|
39
|
+
|
40
|
+
trace_point.disable
|
41
|
+
|
42
|
+
# extract default values from the received binding, and merge with the
|
43
|
+
# parameters array.
|
44
|
+
default_values = keys.each_with_object({}) do |key_parameter, hsh|
|
45
|
+
hsh[key_parameter] = bnd.local_variable_get(key_parameter)
|
46
|
+
end
|
47
|
+
|
48
|
+
parameters.map do |mode, name|
|
49
|
+
[mode, name, default_values[name]]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# returns a minimal Array of arguments, which is suitable for a call to the method
|
56
|
+
def minimal_arguments(method)
|
57
|
+
# Build an arguments array with holds all required parameters. The actual
|
58
|
+
# values for these arguments doesn't matter at all.
|
59
|
+
args = method.parameters.select { |mode, _name| mode == :req }
|
60
|
+
|
61
|
+
# Add a hash with all required keyword arguments
|
62
|
+
required_keyword_args = method.parameters.each_with_object({}) do |(mode, name), hsh|
|
63
|
+
hsh[name] = :anything if mode == :keyreq
|
64
|
+
end
|
65
|
+
args << required_keyword_args if required_keyword_args
|
66
|
+
|
67
|
+
args
|
68
|
+
end
|
69
|
+
end
|
data/lib/simple/cli/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- radiospiel
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-
|
12
|
+
date: 2019-07-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -89,6 +89,7 @@ files:
|
|
89
89
|
- lib/simple/cli/runner.rb
|
90
90
|
- lib/simple/cli/runner/autocompletion.rb
|
91
91
|
- lib/simple/cli/runner/command_help.rb
|
92
|
+
- lib/simple/cli/runner/module_ex.rb
|
92
93
|
- lib/simple/cli/version.rb
|
93
94
|
- log/.gitkeep
|
94
95
|
- simple-cli.gemspec
|
@@ -113,8 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
114
|
- !ruby/object:Gem::Version
|
114
115
|
version: '0'
|
115
116
|
requirements: []
|
116
|
-
|
117
|
-
rubygems_version: 2.7.6
|
117
|
+
rubygems_version: 3.0.2
|
118
118
|
signing_key:
|
119
119
|
specification_version: 4
|
120
120
|
summary: Simple CLI builder for ruby
|