From 17619ce8da4536a2899260f914bbe60dd3452c1f Mon Sep 17 00:00:00 2001 From: Petrik Date: Thu, 9 Feb 2023 16:51:49 +0100 Subject: [PATCH] Properly pad aliases for option usage When printing the options of a command, options without aliases are padded so they aligned with options with aliases The size of the padding is calculated by multiplying the max number of aliases for an option by the number 4 (a dash, a letter, a comma and a space?). Options can have aliases of arbitrary length, not just just a dash with a single letter. For example in Rails the `main` option has the [alias](https://github.com/rails/rails/blob/main/railties/lib/rails/generators/app_base.rb#L100)` --master`. Also, the current implementation adds padding only to options without aliases. This results in strange output when callings `bin/rails new -h`: ```console -T, [--skip-test], [--no-skip-test] # Skip test files [--skip-system-test], [--no-skip-system-test] # Skip system test files [--skip-bootsnap], [--no-skip-bootsnap] # Skip bootsnap gem ... [--edge], [--no-edge] # Set up the application with a Gemfile pointing to the main branch on the Rails repository --master, [--main], [--no-main] # Set up the application with Gemfile pointing to Rails repository main branch ``` When printing the usage for options we should look at the actual formatted options. __Before (examples)__ ```console Usage: thor my_counter N [N] Options: -t, [--third=THREE] # The third argument # Default: 3 [--fourth=N] # The fourth argument z, [--simple=N] y, r, [--symbolic=N] ``` __After (examples)__ ```console Usage: thor my_counter N [N] Options: -t, [--third=THREE] # The third argument # Default: 3 [--fourth=N] # The fourth argument z, [--simple=N] y, r, [--symbolic=N] ``` --- lib/thor/base.rb | 3 +-- lib/thor/parser/option.rb | 8 ++++++-- spec/base_spec.rb | 5 +++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/thor/base.rb b/lib/thor/base.rb index 6d7bae3db..c0fb960cf 100644 --- a/lib/thor/base.rb +++ b/lib/thor/base.rb @@ -558,8 +558,7 @@ def print_options(shell, options, group_name = nil) return if options.empty? list = [] - padding = options.map { |o| o.aliases.size }.max.to_i * 4 - + padding = options.map { |o| o.aliases_for_usage.size }.max.to_i options.each do |option| next if option.hide item = [option.usage(padding)] diff --git a/lib/thor/parser/option.rb b/lib/thor/parser/option.rb index a7647bbe0..3d389063c 100644 --- a/lib/thor/parser/option.rb +++ b/lib/thor/parser/option.rb @@ -93,10 +93,14 @@ def usage(padding = 0) sample << ", [#{dasherize('no-' + human_name)}]" unless (name == "force") || name.start_with?("no-") end + aliases_for_usage.ljust(padding) + sample + end + + def aliases_for_usage if aliases.empty? - (" " * padding) << sample + "" else - "#{aliases.join(', ')}, #{sample}" + "#{aliases.join(', ')}, " end end diff --git a/spec/base_spec.rb b/spec/base_spec.rb index e5a9561c2..29ff7bd9c 100644 --- a/spec/base_spec.rb +++ b/spec/base_spec.rb @@ -139,8 +139,9 @@ def hello end it "use padding in options that do not have aliases" do - expect(@content).to match(/^ -t, \[--third/) - expect(@content).to match(/^ \[--fourth/) + expect(@content).to match(/^ -t, \[--third/) + expect(@content).to match(/^ \[--fourth/) + expect(@content).to match(/^ y, r, \[--symbolic/) end it "allows extra options to be given" do