From e928ea6fa7dfdeeec570d9f90620112044f5372b Mon Sep 17 00:00:00 2001 From: Sylphrena <86712892+BigBoyBarney@users.noreply.github.com> Date: Sun, 10 Aug 2025 22:47:23 +0200 Subject: [PATCH 1/2] feat: print parent command name in subcommand's usage --- examples/greet/welcome_command.cr | 2 ++ spec/formatter_spec.cr | 24 ++++++++++++++++++++++-- src/cling/formatter.cr | 26 +++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/examples/greet/welcome_command.cr b/examples/greet/welcome_command.cr index accc7d8..30ff086 100644 --- a/examples/greet/welcome_command.cr +++ b/examples/greet/welcome_command.cr @@ -4,6 +4,8 @@ class WelcomeCommand < Cling::Command @summary = @description = "sends a friendly welcome message" add_argument "name", description: "the name of the person to greet", required: true + add_option 'h', "help", description: "sends help information" + # this will inherit the header and footer properties @inherit_borders = true # this will NOT inherit the parent flag options diff --git a/spec/formatter_spec.cr b/spec/formatter_spec.cr index 39a3c96..672f26b 100644 --- a/spec/formatter_spec.cr +++ b/spec/formatter_spec.cr @@ -19,6 +19,9 @@ class WelcomeCommand < Cling::Command def setup : Nil @name = "welcome" @summary = @description = "sends a friendly welcome message" + + add_argument "name", description: "the name of the person to greet", required: true + add_option 'h', "help", description: "sends help information" end def run(arguments : Cling::Arguments, options : Cling::Options) : Nil @@ -26,9 +29,14 @@ class WelcomeCommand < Cling::Command end command_with_subcommand = GreetCommand.new -command_with_subcommand.add_command WelcomeCommand.new - command_without_subcommand = GreetCommand.new + +subcommand = WelcomeCommand.new +command_with_subcommand.add_command subcommand + +sub_subcommand = WelcomeCommand.new +subcommand.add_command sub_subcommand + formatter = Cling::Formatter.new describe Cling::Formatter do @@ -92,6 +100,18 @@ describe Cling::Formatter do end.should eq "Usage:\n\tgreet [options]\n\n" end + it "generates a usage section for subcommand" do + String.build do |io| + formatter.format_usage(subcommand, io) + end.should eq "Usage:\n\tgreet welcome [options]\n\n" + end + + it "generates a usage section for nested subcommand" do + String.build do |io| + formatter.format_usage(sub_subcommand, io) + end.should eq "Usage:\n\tgreet welcome welcome [options]\n\n" + end + it "generates an arguments section" do String.build do |io| formatter.format_arguments(command_with_subcommand, io) diff --git a/src/cling/formatter.cr b/src/cling/formatter.cr index 3160c1a..6c7936d 100644 --- a/src/cling/formatter.cr +++ b/src/cling/formatter.cr @@ -62,7 +62,14 @@ module Cling io << "Usage:" if command.usage.empty? - io << "\n\t" << command.name + io << "\n\t" + + if parent = command.parent + print_parent_command_usage(command, io) + end + + io << command.name + unless command.children.empty? io << " " end @@ -164,5 +171,22 @@ module Cling return unless footer = command.footer io << footer << "\n\n" end + + private def print_parent_command_usage(command : Command, io : IO) : Nil + current_command = command + + commands = Array(String).new + + loop do + break unless parent = current_command.parent + + current_command = parent + commands << current_command.name + end + + commands.reverse_each do |command_name| + io << command_name << " " + end + end end end From d6dd2093329d4bfeef0563bbce59ed4abf3ac81d Mon Sep 17 00:00:00 2001 From: Sylphrena <86712892+BigBoyBarney@users.noreply.github.com> Date: Mon, 11 Aug 2025 20:46:55 +0200 Subject: [PATCH 2/2] change array approach to recursion --- src/cling/formatter.cr | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/cling/formatter.cr b/src/cling/formatter.cr index 6c7936d..6f46da4 100644 --- a/src/cling/formatter.cr +++ b/src/cling/formatter.cr @@ -64,11 +64,7 @@ module Cling if command.usage.empty? io << "\n\t" - if parent = command.parent - print_parent_command_usage(command, io) - end - - io << command.name + print_command_names(command, io) unless command.children.empty? io << " " @@ -172,21 +168,14 @@ module Cling io << footer << "\n\n" end - private def print_parent_command_usage(command : Command, io : IO) : Nil - current_command = command - - commands = Array(String).new - - loop do - break unless parent = current_command.parent - - current_command = parent - commands << current_command.name + # Recursively prints all command names, including parent commands. + private def print_command_names(command : Command, io : IO) : Nil + if parent = command.parent + print_command_names(parent, io) end - commands.reverse_each do |command_name| - io << command_name << " " - end + io << " " if parent + io << command.name end end end