Module: Space::Core::CLI::Help
- Defined in:
- lib/space_core/cli/help.rb
Overview
Colourful replacement for dry-cli’s plain ‘Usage` listing — the “global help” shown by `space`, `architect`, and every bare namespace (`space repo`, `worktree`, …). Per-command help still flows through dry-cli’s Banner, whose content we like; only the listing is reskinned.
We reopen Dry::CLI::Usage.call (below) to delegate here, so BOTH the intercepted top-level help and dry-cli’s own bare-namespace path get the same treatment from one place. Colour follows CLI.help_pastel, set once per invocation from the output stream’s tty-ness and –color, so piped and test output stay plain. The ‘src` binary never loads space_core, so its own plain Usage is untouched.
Constant Summary collapse
- TAGLINE =
"date-prefixed workspaces; repos provisioned on fibers at copy-on-write speed"
Class Method Summary collapse
- .arguments(command) ⇒ Object
- .banner(node) ⇒ Object
- .call(result, pastel: CLI.help_pastel) ⇒ Object
- .description(node) ⇒ Object
- .footer(result, pastel) ⇒ Object
-
.header(result, pastel) ⇒ Object
The richer header only makes sense at the true root (‘space` / `architect`), not on every sub-namespace listing.
- .label(result, name, node) ⇒ Object
-
.listing(result) ⇒ Object
- [label_with_banner, description_or_nil], …
-
sorted by command name.
-
.program_prefix(result) ⇒ Object
“space” at the root, “space repo” inside a namespace.
Class Method Details
.arguments(command) ⇒ Object
82 83 84 85 86 87 88 |
# File 'lib/space_core/cli/help.rb', line 82 def arguments(command) return "" unless command.respond_to?(:required_arguments) names = command.required_arguments.map { |arg| arg.name.to_s.upcase } names += command.optional_arguments.map { |arg| "[#{arg.name.to_s.upcase}]" } names.empty? ? "" : " #{names.join(" ")}" end |
.banner(node) ⇒ Object
72 73 74 75 76 77 78 79 80 |
# File 'lib/space_core/cli/help.rb', line 72 def (node) if node.command && node.leaf? && node.children? " [ARGUMENT|SUBCOMMAND]" elsif node.leaf? arguments(node.command) else " [SUBCOMMAND]" end end |
.call(result, pastel: CLI.help_pastel) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/space_core/cli/help.rb', line 23 def call(result, pastel: CLI.help_pastel) rows = listing(result) width = rows.map { |label, _| label.length }.max || 0 lines = rows.map do |label, description| painted = pastel.cyan(label.ljust(width)) description ? " #{painted} #{pastel.dim("# #{description}")}" : " #{painted}" end [header(result, pastel), pastel.bold("Commands:"), *lines, (result, pastel)] .compact.join("\n") end |
.description(node) ⇒ Object
90 91 92 93 94 |
# File 'lib/space_core/cli/help.rb', line 90 def description(node) return unless node.leaf? && node.command.respond_to?(:description) node.command.description end |
.footer(result, pastel) ⇒ Object
45 46 47 |
# File 'lib/space_core/cli/help.rb', line 45 def (result, pastel) "\n#{pastel.dim("Run `#{program_prefix(result)} <command> --help` for details on a command.")}" end |
.header(result, pastel) ⇒ Object
The richer header only makes sense at the true root (‘space` / `architect`), not on every sub-namespace listing.
38 39 40 41 42 43 |
# File 'lib/space_core/cli/help.rb', line 38 def header(result, pastel) return unless result.names.empty? "#{pastel.bold.cyan("space-architect")} #{pastel.dim(Space::Core::VERSION)} " \ "#{pastel.dim("— #{TAGLINE}")}\n" end |
.label(result, name, node) ⇒ Object
68 69 70 |
# File 'lib/space_core/cli/help.rb', line 68 def label(result, name, node) "#{program_prefix(result)} #{name}#{(node)}" end |
.listing(result) ⇒ Object
- [label_with_banner, description_or_nil], …
-
sorted by command name.
60 61 62 63 64 65 66 |
# File 'lib/space_core/cli/help.rb', line 60 def listing(result) result.children.sort_by { |name, _| name }.filter_map do |name, node| next if node.hidden [label(result, name, node), description(node)] end end |
.program_prefix(result) ⇒ Object
“space” at the root, “space repo” inside a namespace. The ‘space`/`architect` binaries inject their name into ARGV, so $PROGRAM_NAME and the leading namespace segment can collide (“space space …”); drop the duplicate.
52 53 54 55 56 57 |
# File 'lib/space_core/cli/help.rb', line 52 def program_prefix(result) prog = File.basename($PROGRAM_NAME) names = result.names.dup names.shift if names.first == prog [prog, *names].join(" ") end |