dry-cli-help 0.5.1 → 0.6.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/CHANGELOG.md +6 -0
- data/README.md +56 -13
- data/lib/dry/cli/help/configuration.rb +2 -0
- data/lib/dry/cli/help/integration.rb +72 -13
- data/lib/dry/cli/help/screens/base.rb +40 -4
- data/lib/dry/cli/help/screens/command.rb +40 -21
- data/lib/dry/cli/help/screens/listing.rb +1 -1
- data/lib/dry/cli/help/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c804fb8b2d9f9e370e85b45d2e4174c27e0c06aea1139d4af5055c31fb8709f7
|
|
4
|
+
data.tar.gz: ea846d4e056da46f9762e77b9df2a65c145df4003e58b41707446de94341b74c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e95c0a85b03b6a4837726c65419a6caa138f7041bcff9e184585a72bf29d49c6b7542e74bcc3f2941537f36cc06765d17cbd5be953a4ec68a0fd88d589273b9e
|
|
7
|
+
data.tar.gz: 314634677bcdcef0c69b366e01b9356e6abff0956db0896ce5e8d2fb6bf5b87cc6ed4c40b20f5935c74c46bd73bff7a53be1787249f2ebbd80661f25684a09aa
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.6.0] - Unreleased
|
|
4
|
+
|
|
5
|
+
- `--help-include-hidden` prints help that also lists hidden commands and options, each marked `(hidden)`. An option is hidden when declared with `hidden: true`, which dry-cli keeps and its parser ignores; plain help leaves it out. The flag works before or after a command's name and never appears in help itself.
|
|
6
|
+
- Works with the kigster fork of dry-cli as well as dry-cli 1.4: the help integration reads the CLI's streams as `stdout`/`stderr` where those exist and `out`/`err` otherwise, and `help` accepts the fork's `long:` keyword. With `long: true` a command's help prints its `long_desc` when it declares one. The spec helper passes whichever stream keywords `Dry::CLI#call` takes.
|
|
7
|
+
- New setting `command_arguments`, off by default. When set, a listing prints each command with its arguments, required ones bare and optional ones in brackets: `completion SHELL`, `migrate [FILE]`. It applies to the commands of a registry level and to the subcommands on a command's own help.
|
|
8
|
+
|
|
3
9
|
## [0.5.1] - 2026-09-21
|
|
4
10
|
|
|
5
11
|
- An empty example, `example [""]`, no longer raises `NoMethodError` and takes the whole help screen with it. It prints the program name on its own, which is what a command that runs with no arguments means by it.
|
data/README.md
CHANGED
|
@@ -132,7 +132,49 @@ OPTIONS
|
|
|
132
132
|
Documentation: https://example.com/my-cli
|
|
133
133
|
```
|
|
134
134
|
|
|
135
|
-
A command reachable as `--version` lists under Options by its dashed names. Commands marked `hidden: true` in the registry stay out of every list, and a non-dashed alias prints next to its command, as in `build, b`.
|
|
135
|
+
A command reachable as `--version` lists under Options by its dashed names. Commands marked `hidden: true` in the registry stay out of every list unless `--help-include-hidden` asks for them, and a non-dashed alias prints next to its command, as in `build, b`.
|
|
136
|
+
|
|
137
|
+
### Hidden commands and options
|
|
138
|
+
|
|
139
|
+
dry-cli hides a command registered with `hidden: true`. This gem adds the same for options: declare one with `hidden: true` and plain help leaves it out. dry-cli's parser ignores the key, so the option still works.
|
|
140
|
+
|
|
141
|
+
```ruby
|
|
142
|
+
class Deploy < Dry::CLI::Command
|
|
143
|
+
desc "Deploy the application"
|
|
144
|
+
option :force, type: :boolean, aliases: ["-f"], desc: "Skip confirmation"
|
|
145
|
+
option :trace, type: :boolean, default: false, hidden: true, desc: "Print every step"
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
register "deploy", Deploy
|
|
149
|
+
register "console", Console, hidden: true
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
`--help-include-hidden` prints help with every hidden command and option listed and marked. It works anywhere `-h` does, before or after the command's name, and no help screen lists it.
|
|
153
|
+
|
|
154
|
+
```text
|
|
155
|
+
$ my-cli --help-include-hidden
|
|
156
|
+
USAGE
|
|
157
|
+
my-cli COMMAND [OPTIONS]
|
|
158
|
+
|
|
159
|
+
COMMANDS
|
|
160
|
+
deploy Deploy the application
|
|
161
|
+
console Open a console on a server (hidden)
|
|
162
|
+
|
|
163
|
+
OPTIONS
|
|
164
|
+
-h, --help Show help
|
|
165
|
+
|
|
166
|
+
$ my-cli deploy --help-include-hidden
|
|
167
|
+
USAGE
|
|
168
|
+
my-cli deploy [OPTIONS]
|
|
169
|
+
|
|
170
|
+
DESCRIPTION
|
|
171
|
+
Deploy the application
|
|
172
|
+
|
|
173
|
+
OPTIONS
|
|
174
|
+
-f, --[no-]force Skip confirmation
|
|
175
|
+
--[no-]trace Print every step (hidden; default: false)
|
|
176
|
+
-h, --help Show help
|
|
177
|
+
```
|
|
136
178
|
|
|
137
179
|
A block that takes an argument receives the configuration instead of running against it:
|
|
138
180
|
|
|
@@ -309,18 +351,19 @@ In a terminal the headings print bold yellow, usage lines, commands and examples
|
|
|
309
351
|
|
|
310
352
|
The gem offers a compact DSL in the general spirit of Ruby and `dry-rb` in particular, and makes the following methods available within the `configure` block.
|
|
311
353
|
|
|
312
|
-
| Setting | Values | Default | What it does
|
|
313
|
-
| ----------------------------- | -------------------------------- | --------------- |
|
|
314
|
-
| `title` | String | none | Prints the first line of the banner, above the top-level help
|
|
315
|
-
| `description` | String | none | Prints paragraphs under the title, reflowed to the wrap width
|
|
316
|
-
| `epilogue` | String | none | Prints paragraphs at the very end of the top-level help
|
|
317
|
-
| `color` | `true`, `false`, `:auto` | `:auto` | Paints headings, commands, arguments and options; `:auto` paints only a terminal
|
|
318
|
-
| `wrap` | `true`, `false` | `true` | Wraps descriptions with a hanging indent; `false` prints each one on a single line as written
|
|
319
|
-
| `width` | `:terminal`, Integer | `:terminal` | Sets the column text wraps at; `:terminal` follows the terminal's width
|
|
320
|
-
| `margin` | Integer | `0` | Keeps that many columns free at the right edge when `width` is `:terminal`
|
|
321
|
-
| `exit_code_without_arguments` | 0 to 255 | `1` | Sets the exit status of `my-cli` or `my-cli db` run with no command; `0` also prints the help to stdout instead of stderr
|
|
322
|
-
| `banner_on_subcommands` | `true`, `false` | `false` | Prints the title and description above command help and group listings too, not only above the top-level help
|
|
323
|
-
| `
|
|
354
|
+
| Setting | Values | Default | What it does |
|
|
355
|
+
| ----------------------------- | -------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
356
|
+
| `title` | String | none | Prints the first line of the banner, above the top-level help |
|
|
357
|
+
| `description` | String | none | Prints paragraphs under the title, reflowed to the wrap width |
|
|
358
|
+
| `epilogue` | String | none | Prints paragraphs at the very end of the top-level help |
|
|
359
|
+
| `color` | `true`, `false`, `:auto` | `:auto` | Paints headings, commands, arguments and options; `:auto` paints only a terminal |
|
|
360
|
+
| `wrap` | `true`, `false` | `true` | Wraps descriptions with a hanging indent; `false` prints each one on a single line as written |
|
|
361
|
+
| `width` | `:terminal`, Integer | `:terminal` | Sets the column text wraps at; `:terminal` follows the terminal's width |
|
|
362
|
+
| `margin` | Integer | `0` | Keeps that many columns free at the right edge when `width` is `:terminal` |
|
|
363
|
+
| `exit_code_without_arguments` | 0 to 255 | `1` | Sets the exit status of `my-cli` or `my-cli db` run with no command; `0` also prints the help to stdout instead of stderr |
|
|
364
|
+
| `banner_on_subcommands` | `true`, `false` | `false` | Prints the title and description above command help and group listings too, not only above the top-level help |
|
|
365
|
+
| `command_arguments` | `true`, `false` | `false` | Lists each command with its arguments, as in `deploy ENVIRONMENT` and `migrate [FILE]`: required ones bare, optional ones in brackets |
|
|
366
|
+
| `command_order` | `:registration`, `:alphabetical` | `:registration` | Lists commands in the order you registered them, or sorted by name as dry-cli does |
|
|
324
367
|
|
|
325
368
|
`color :auto` colors a terminal and honors [`NO_COLOR`](https://no-color.org). `width :terminal` reads `COLUMNS`, then the console, then falls back to 80, and `margin` keeps columns free at the right edge.
|
|
326
369
|
|
|
@@ -67,6 +67,7 @@ module Dry
|
|
|
67
67
|
margin: ->(value) { value.is_a?(Integer) && !value.negative? },
|
|
68
68
|
exit_code_without_arguments: ->(value) { value.is_a?(Integer) && value.between?(0, 255) },
|
|
69
69
|
banner_on_subcommands: BOOLEAN,
|
|
70
|
+
command_arguments: BOOLEAN,
|
|
70
71
|
command_order: ->(value) { COMMAND_ORDERS.include?(value) }
|
|
71
72
|
}.freeze
|
|
72
73
|
|
|
@@ -80,6 +81,7 @@ module Dry
|
|
|
80
81
|
margin: 0,
|
|
81
82
|
exit_code_without_arguments: 1,
|
|
82
83
|
banner_on_subcommands: false,
|
|
84
|
+
command_arguments: false,
|
|
83
85
|
command_order: :registration
|
|
84
86
|
}.freeze
|
|
85
87
|
|
|
@@ -6,23 +6,58 @@ module Dry
|
|
|
6
6
|
# The only code that touches dry-cli. Everything else renders.
|
|
7
7
|
module Integration
|
|
8
8
|
# Prepended to Dry::CLI. Overrides the two private methods dry-cli
|
|
9
|
-
# prints help from, and nothing else.
|
|
9
|
+
# prints help from, and the two it dispatches through, and nothing else.
|
|
10
10
|
#
|
|
11
|
-
#
|
|
12
|
-
# exist: a dry-cli release that renames them fails this gem's specs
|
|
11
|
+
# All four are `@api private` in dry-cli, which is why the suite asserts
|
|
12
|
+
# they exist: a dry-cli release that renames them fails this gem's specs
|
|
13
13
|
# rather than a host's help screen.
|
|
14
14
|
module CLIMethods
|
|
15
15
|
HELP_FLAGS = %w[-h --help].freeze
|
|
16
16
|
|
|
17
|
+
# Asks for help that also lists hidden commands and options. No help
|
|
18
|
+
# screen lists the flag itself.
|
|
19
|
+
INCLUDE_HIDDEN_FLAG = "--help-include-hidden"
|
|
20
|
+
|
|
17
21
|
private
|
|
18
22
|
|
|
19
|
-
# dry-cli
|
|
20
|
-
|
|
23
|
+
# dry-cli's `call` hands the arguments to one of these two. They are
|
|
24
|
+
# hooked rather than `call`, whose keywords differ between dry-cli 1.4
|
|
25
|
+
# and the kigster fork.
|
|
26
|
+
def perform_command(arguments)
|
|
27
|
+
super(without_include_hidden_flag(arguments))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def perform_registry(arguments)
|
|
31
|
+
super(without_include_hidden_flag(arguments))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# dry-cli would reject the flag as an unknown option, so it is taken
|
|
35
|
+
# out of the arguments before dry-cli sees them. A `--help` goes last
|
|
36
|
+
# in its place, unless one is there already, so the flag works before
|
|
37
|
+
# the command's name as well as after it.
|
|
38
|
+
#
|
|
39
|
+
# Everything after `--` belongs to the command, flags included.
|
|
40
|
+
def without_include_hidden_flag(arguments)
|
|
41
|
+
@help_include_hidden = false
|
|
42
|
+
options = arguments.take_while { it != "--" }
|
|
43
|
+
index = options.index(INCLUDE_HIDDEN_FLAG)
|
|
44
|
+
return arguments unless index
|
|
45
|
+
|
|
46
|
+
@help_include_hidden = true
|
|
47
|
+
rest = arguments.dup
|
|
48
|
+
rest.delete_at(index)
|
|
49
|
+
rest.insert(options.length - 1, "--help") unless options.intersect?(HELP_FLAGS)
|
|
50
|
+
rest
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# dry-cli calls this for `mycli deploy -h`, and the kigster fork also
|
|
54
|
+
# for `--help`, with `long: true` so the long description is shown.
|
|
55
|
+
def help(command, prog_name, long: false)
|
|
21
56
|
screen = Screens::Command.new(
|
|
22
|
-
command:, prog_name:, top_level: !kommand.nil?,
|
|
23
|
-
config: Help.config, io:
|
|
57
|
+
command:, prog_name:, long:, top_level: !kommand.nil?,
|
|
58
|
+
config: Help.config, io: help_out, include_hidden: help_include_hidden?
|
|
24
59
|
)
|
|
25
|
-
|
|
60
|
+
help_out.puts screen.render
|
|
26
61
|
exit(0)
|
|
27
62
|
end
|
|
28
63
|
|
|
@@ -35,18 +70,42 @@ module Dry
|
|
|
35
70
|
|
|
36
71
|
if unmatched.empty?
|
|
37
72
|
status = config.exit_code_without_arguments
|
|
38
|
-
list(result, config, status.zero? ?
|
|
73
|
+
list(result, config, status.zero? ? help_out : help_err, status)
|
|
39
74
|
elsif HELP_FLAGS.include?(unmatched.first)
|
|
40
|
-
list(result, config,
|
|
75
|
+
list(result, config, help_out, 0)
|
|
41
76
|
else
|
|
42
77
|
suggestion = SpellChecker.call(result, arguments)
|
|
43
|
-
|
|
44
|
-
list(result, config,
|
|
78
|
+
help_err.puts "#{suggestion}\n\n" if suggestion
|
|
79
|
+
list(result, config, help_err, 1)
|
|
45
80
|
end
|
|
46
81
|
end
|
|
47
82
|
|
|
83
|
+
# dry-cli 1.4 holds its streams as `out` and `err`; the kigster fork
|
|
84
|
+
# renamed them `stdout` and `stderr`. Both are supported.
|
|
85
|
+
def help_out
|
|
86
|
+
plain(respond_to?(:stdout, true) ? stdout : out)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def help_err
|
|
90
|
+
plain(respond_to?(:stderr, true) ? stderr : err)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# The fork wraps each stream in a `Dry::CLI::Stream` that strips ANSI
|
|
94
|
+
# from anything written when it decides the stream has no color. The
|
|
95
|
+
# help screen has already made that decision for the same stream, so
|
|
96
|
+
# it writes to the IO underneath. The test is the class, not
|
|
97
|
+
# `respond_to?(:raw)`: `io/console` gives every IO a `raw` of its own,
|
|
98
|
+
# which puts a terminal into raw mode and raises ENOTTY on a pipe.
|
|
99
|
+
def plain(io)
|
|
100
|
+
defined?(Dry::CLI::Stream) && io.is_a?(Dry::CLI::Stream) ? io.raw : io
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def help_include_hidden?
|
|
104
|
+
@help_include_hidden
|
|
105
|
+
end
|
|
106
|
+
|
|
48
107
|
def list(result, config, io, status)
|
|
49
|
-
io.puts Screens::Listing.new(result:, config:, io:).render
|
|
108
|
+
io.puts Screens::Listing.new(result:, config:, io:, include_hidden: help_include_hidden?).render
|
|
50
109
|
exit(status)
|
|
51
110
|
end
|
|
52
111
|
end
|
|
@@ -17,8 +17,11 @@ module Dry
|
|
|
17
17
|
# @param config [Configuration]
|
|
18
18
|
# @param io [IO] where the screen prints
|
|
19
19
|
# @param terminal_width [Integer]
|
|
20
|
-
|
|
20
|
+
# @param include_hidden [Boolean] list hidden commands and options too,
|
|
21
|
+
# as `--help-include-hidden` asks
|
|
22
|
+
def initialize(config:, io:, terminal_width: Terminal.width, include_hidden: false)
|
|
21
23
|
@config = config
|
|
24
|
+
@include_hidden = include_hidden
|
|
22
25
|
@format = Formatter.new(config, io, terminal_width:)
|
|
23
26
|
end
|
|
24
27
|
|
|
@@ -66,15 +69,48 @@ module Dry
|
|
|
66
69
|
format.definitions(rows, column)
|
|
67
70
|
end
|
|
68
71
|
|
|
69
|
-
|
|
72
|
+
def include_hidden?
|
|
73
|
+
@include_hidden
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# The nodes of one registry level in the configured order, hidden
|
|
77
|
+
# ones left out unless asked for.
|
|
70
78
|
def visible(children)
|
|
71
|
-
shown = children.to_a
|
|
79
|
+
shown = children.to_a
|
|
80
|
+
shown = shown.reject { |_, node| node.hidden } unless include_hidden?
|
|
72
81
|
config.command_order == :alphabetical ? shown.sort_by(&:first) : shown
|
|
73
82
|
end
|
|
74
83
|
|
|
84
|
+
# A command's name as a listing prints it: followed by its arguments
|
|
85
|
+
# when `command_arguments` is set, "deploy ENVIRONMENT".
|
|
86
|
+
def command_term(name, node)
|
|
87
|
+
return name unless config.command_arguments && node.command
|
|
88
|
+
|
|
89
|
+
"#{name}#{usage_arguments(node.command)}"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Required arguments bare, optional ones in brackets: " RULES [OUTPUT]".
|
|
93
|
+
def usage_arguments(command)
|
|
94
|
+
required = command.required_arguments.map { argument_name(it) }
|
|
95
|
+
optional = command.optional_arguments.map { "[#{argument_name(it)}]" }
|
|
96
|
+
names = [*required, *optional]
|
|
97
|
+
" #{names.join(' ')}" unless names.empty?
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def argument_name(argument)
|
|
101
|
+
name = argument.name.to_s.upcase
|
|
102
|
+
argument.array? ? "#{name}..." : name
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# A hidden node, listed only when asked for, says so after its description.
|
|
106
|
+
def describe_node(node)
|
|
107
|
+
text = node_description(node)
|
|
108
|
+
node.hidden ? [text, "(hidden)"].compact.join(" ") : text
|
|
109
|
+
end
|
|
110
|
+
|
|
75
111
|
# A group registered without a command has no description of its own,
|
|
76
112
|
# so it describes itself by what it contains.
|
|
77
|
-
def
|
|
113
|
+
def node_description(node)
|
|
78
114
|
return node.command.description if node.command
|
|
79
115
|
|
|
80
116
|
names = visible(node.children).map(&:first)
|
|
@@ -12,11 +12,13 @@ module Dry
|
|
|
12
12
|
# @param prog_name [String] the program and command path, "mycli db migrate"
|
|
13
13
|
# @param top_level [Boolean] true when the command is the whole CLI,
|
|
14
14
|
# as with `Dry::CLI.new(SomeCommand)`
|
|
15
|
-
|
|
15
|
+
# @param long [Boolean] show the command's `long_desc` when it has one
|
|
16
|
+
def initialize(command:, prog_name:, top_level: false, long: false, **)
|
|
16
17
|
super(**)
|
|
17
18
|
@command = command
|
|
18
19
|
@prog_name = prog_name
|
|
19
20
|
@top_level = top_level
|
|
21
|
+
@long = long
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
private
|
|
@@ -32,13 +34,20 @@ module Dry
|
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
def render_usage
|
|
35
|
-
lines = ["#{prog_name}#{usage_arguments} [OPTIONS]"]
|
|
37
|
+
lines = ["#{prog_name}#{usage_arguments(command)} [OPTIONS]"]
|
|
36
38
|
lines << "#{prog_name} COMMAND [OPTIONS]" if subcommand_rows.any?
|
|
37
39
|
section(:usage, lines.map { INDENT + format.paint(it, :usage) })
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
def render_description
|
|
41
|
-
section(:description, format.paragraph(
|
|
43
|
+
section(:description, format.paragraph(description, indent: INDENT))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# The long description for `--help` where the command declares one
|
|
47
|
+
# (`long_desc`, kigster/dry-cli), otherwise the one-line `desc`.
|
|
48
|
+
def description
|
|
49
|
+
long = command.long_description if @long && command.respond_to?(:long_description)
|
|
50
|
+
long || command.description
|
|
42
51
|
end
|
|
43
52
|
|
|
44
53
|
def render_subcommands
|
|
@@ -60,8 +69,7 @@ module Dry
|
|
|
60
69
|
# all", and String#split answers [] for it, so `line` is nil and only
|
|
61
70
|
# the program name is left to print.
|
|
62
71
|
def render_examples
|
|
63
|
-
rows =
|
|
64
|
-
line, comment = example.split(" # ", 2)
|
|
72
|
+
rows = example_pairs.map do |line, comment|
|
|
65
73
|
term = [prog_name, line&.strip].reject { it.nil? || it.empty? }.join(" ")
|
|
66
74
|
Row.new(term: term, text: comment&.strip,
|
|
67
75
|
term_style: :example, text_style: :example_comment)
|
|
@@ -69,20 +77,31 @@ module Dry
|
|
|
69
77
|
section(:examples, format.definitions(rows, format.column_for(rows)))
|
|
70
78
|
end
|
|
71
79
|
|
|
72
|
-
|
|
73
|
-
|
|
80
|
+
# Every example as `[args, comment]`. dry-cli 1.4 keeps one string per
|
|
81
|
+
# example, "args # comment". The kigster fork keeps `[args, description]`
|
|
82
|
+
# pairs, and a list handed to it in the 1.4 spelling arrives as one pair
|
|
83
|
+
# holding the list and an empty description.
|
|
84
|
+
def example_pairs
|
|
85
|
+
command.examples.flat_map { pairs_of(it) }
|
|
74
86
|
end
|
|
75
87
|
|
|
76
|
-
def
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
88
|
+
def pairs_of(example)
|
|
89
|
+
return [example.split(" # ", 2)] unless example.is_a?(Array)
|
|
90
|
+
|
|
91
|
+
text, description = example
|
|
92
|
+
return text.flat_map { pairs_of(it) } if text.is_a?(Array)
|
|
93
|
+
return pairs_of(text) if description.nil? || description.empty?
|
|
94
|
+
|
|
95
|
+
[[text, description]]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def aligned_rows
|
|
99
|
+
subcommand_rows + argument_rows + option_rows
|
|
81
100
|
end
|
|
82
101
|
|
|
83
102
|
def subcommand_rows
|
|
84
103
|
@subcommand_rows ||= visible(command.subcommands).map do |name, node|
|
|
85
|
-
Row.new(term: name, text: describe_node(node))
|
|
104
|
+
Row.new(term: command_term(name, node), text: describe_node(node))
|
|
86
105
|
end
|
|
87
106
|
end
|
|
88
107
|
|
|
@@ -92,15 +111,14 @@ module Dry
|
|
|
92
111
|
end
|
|
93
112
|
end
|
|
94
113
|
|
|
114
|
+
# An option declared `hidden: true` lists only when hidden ones are asked for.
|
|
95
115
|
def option_rows
|
|
96
|
-
@option_rows ||= command.options.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
end
|
|
116
|
+
@option_rows ||= command.options.filter_map do |option|
|
|
117
|
+
hidden = option.options.fetch(:hidden, false)
|
|
118
|
+
next if hidden && !include_hidden?
|
|
100
119
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
argument.array? ? "#{name}..." : name
|
|
120
|
+
Row.new(term: option_term(option), text: describe(option, hidden:), term_style: :option)
|
|
121
|
+
end
|
|
104
122
|
end
|
|
105
123
|
|
|
106
124
|
# Short aliases, then the option, then long aliases: "-f, --[no-]force".
|
|
@@ -117,8 +135,9 @@ module Dry
|
|
|
117
135
|
end
|
|
118
136
|
|
|
119
137
|
# The description, then what a reader needs to use the value.
|
|
120
|
-
def describe(param)
|
|
138
|
+
def describe(param, hidden: false)
|
|
121
139
|
notes = []
|
|
140
|
+
notes << "hidden" if hidden
|
|
122
141
|
notes << "required" if param.required?
|
|
123
142
|
notes << "one of: #{param.values.join(', ')}" if param.values
|
|
124
143
|
notes << "default: #{param.default.inspect}" unless param.default.nil?
|
|
@@ -66,7 +66,7 @@ module Dry
|
|
|
66
66
|
@command_rows ||= entries.each_with_object({}) do |(name, node, aliases), rows|
|
|
67
67
|
next if name.start_with?("-")
|
|
68
68
|
|
|
69
|
-
term = [name, *aliases.reject { it.start_with?("-") }].join(", ")
|
|
69
|
+
term = [command_term(name, node), *aliases.reject { it.start_with?("-") }].join(", ")
|
|
70
70
|
rows[[*result.names, name].join(" ")] = Row.new(term:, text: describe_node(node))
|
|
71
71
|
end
|
|
72
72
|
end
|
data/lib/dry/cli/help/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dry-cli-help
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Konstantin Gredeskoul
|
|
@@ -86,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
86
86
|
- !ruby/object:Gem::Version
|
|
87
87
|
version: '0'
|
|
88
88
|
requirements: []
|
|
89
|
-
rubygems_version: 4.0.
|
|
89
|
+
rubygems_version: 4.0.22
|
|
90
90
|
specification_version: 4
|
|
91
91
|
summary: Configurable, wrapped, colored help screens for dry-cli applications
|
|
92
92
|
test_files: []
|