Skip to content

Commit

Permalink
Enhance OptionParser to support customizable summary_width and `s…
Browse files Browse the repository at this point in the history
…ummary_indent`

#14153
  • Loading branch information
kojix2 committed Jan 7, 2025
1 parent 3421975 commit a636b4d
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 5 deletions.
114 changes: 114 additions & 0 deletions spec/std/option_parser_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -789,3 +789,117 @@ describe "OptionParser" do
args.should eq(%w(file --bar))
end
end

describe "OptionParser with summary_width and summary_indent" do
it "formats flags and descriptions with default summary_width and summary_indent" do
parser = OptionParser.new

parser.on("-f", "--flag", "A short description") { }
parser.on("-l", "--long-flag", "A long description for testing purposes") { }

output = parser.to_s

expected_output = <<-USAGE
-f, --flag A short description
-l, --long-flag A long description for testing purposes
USAGE

output.should eq(expected_output)
end

it "formats flags and descriptions with custom summary_width and summary_indent" do
parser = OptionParser.new
parser.summary_width = 40
parser.summary_indent = "|" * 6

parser.on("-f", "--flag", "A short description") { }
parser.on("-l", "--long-flag", "A long description for testing purposes") { }

output = parser.to_s

expected_output = <<-USAGE
||||||-f, --flag A short description
||||||-l, --long-flag A long description for testing purposes
USAGE

output.should eq(expected_output)
end

it "handles multiline descriptions correctly with summary_width" do
parser = OptionParser.new
parser.summary_width = 20
parser.summary_indent = " " * 4

parser.on("--complex-option", "This is a detailed description\nspanning multiple lines for testing") { }

output = parser.to_s

expected_output = <<-USAGE
--complex-option This is a detailed description
spanning multiple lines for testing
USAGE

output.should eq(expected_output)
end

it "adjusts formatting when flag length exceeds summary_width" do
parser = OptionParser.new
parser.summary_width = 20
parser.summary_indent = " " * 4

parser.on("--very-very-long-option", "Description that follows a very\nlong flag") { }

output = parser.to_s

expected_output = <<-USAGE
--very-very-long-option
Description that follows a very
long flag
USAGE

output.should eq(expected_output)
end

it "handles extreme summary_width values (e.g., 0)" do
parser = OptionParser.new
parser.summary_width = 0
parser.summary_indent = " " * 4

parser.on("--short", "No space for flags!") { }

output = parser.to_s

expected_output = <<-USAGE
--short
No space for flags!
USAGE

output.should eq(expected_output)
end

it "handles extreme summary_indent values (e.g., empty string)" do
parser = OptionParser.new
parser.summary_width = 20
parser.summary_indent = ""

parser.on("--test", "Indentation removed") { }

output = parser.to_s

expected_output = <<-USAGE
--test Indentation removed
USAGE

output.should eq(expected_output)
end

# it "raises an error for invalid summary_width or summary_indent" do
# parser = OptionParser.new
# expect_raises ArgumentError, "Invalid summary width: -10" do
# parser.summary_width = -10
# end
# expect_raises ArgumentError, "Invalid summary indent: -5" do
# parser.summary_indent = -5
# end
# end
end
17 changes: 12 additions & 5 deletions src/option_parser.cr
Original file line number Diff line number Diff line change
Expand Up @@ -316,13 +316,20 @@ class OptionParser
@flags.join io, '\n'
end

# Width for option list portion of summary.
property summary_width : Int32 = 32

# Indentation for summary.
property summary_indent : String = " "

private def append_flag(flag, description)
indent = " " * 37
description = description.gsub("\n", "\n#{indent}")
if flag.size >= 33
@flags << " #{flag}\n#{indent}#{description}"
description_indent = "#{summary_indent}#{" " * summary_width} " # Adjust the indent based on summary_width
description = description.gsub("\n", "\n#{description_indent}")

if flag.size >= summary_width
@flags << "#{summary_indent}#{flag}\n#{description_indent}#{description}"
else
@flags << " #{flag}#{" " * (33 - flag.size)}#{description}"
@flags << "#{summary_indent}#{flag}#{" " * (summary_width - flag.size)} #{description}"
end
end

Expand Down

0 comments on commit a636b4d

Please sign in to comment.