diff --git a/bin/codebasin b/bin/codebasin index 3b0c8a5..5ced861 100755 --- a/bin/codebasin +++ b/bin/codebasin @@ -16,23 +16,61 @@ from codebasin.walkers.platform_mapper import PlatformMapper version = "1.2.0" +def _help_string(*lines: str, is_long=False, is_last=False): + """ + Parameters + ---------- + *lines: str + Each line in the help string. + + is_long: bool + A flag indicating whether the option is long enough to generate an + initial newline by default. + + is_last: bool + A flag indicating whether the option is the last in the list. + + Returns + ------- + An argparse help string formatted as a paragraph. + """ + result = "" + + # A long option like --exclude will force a newline. + if not is_long: + result = "\n" + + # argparse.HelpFormatter indents by 24 characters. + # We cannot override this directly, but can delete them with backspaces. + lines = ["\b" * 20 + x for x in lines] + + # The additional space is required for argparse to respect newlines. + result += "\n".join(lines) + + if not is_last: + result += "\n " + + return result + + def main(): # Read command-line arguments parser = argparse.ArgumentParser( description="Code Base Investigator " + str(version), + formatter_class=argparse.RawTextHelpFormatter, add_help=False, ) parser.add_argument( "-h", "--help", action="help", - help="Display help message and exit.", + help=_help_string("Display help message and exit."), ) parser.add_argument( "--version", action="version", version=f"Code Base Investigator {version}", - help="Display version information and exit.", + help=_help_string("Display version information and exit."), ) parser.add_argument( "-v", @@ -40,7 +78,7 @@ def main(): dest="verbose", action="count", default=0, - help="Increase verbosity level.", + help=_help_string("Increase verbosity level."), ) parser.add_argument( "-q", @@ -48,7 +86,7 @@ def main(): dest="quiet", action="count", default=0, - help="Decrease verbosity level.", + help=_help_string("Decrease verbosity level."), ) parser.add_argument( "-R", @@ -58,9 +96,12 @@ def main(): action="append", default=[], choices=["all", "summary", "clustering"], - help="Generate a report of the specified type. " - + "May be specified multiple times. " - + "If not specified, all reports will be generated.", + help=_help_string( + "Generate a report of the specified type.", + "May be specified multiple times.", + "If not specified, all reports will be generated.", + is_long=True, + ), ) parser.add_argument( "-x", @@ -69,8 +110,11 @@ def main(): metavar="", action="append", default=[], - help="Exclude files matching this pattern from the code base. " - + "May be specified multiple times.", + help=_help_string( + "Exclude files matching this pattern from the code base.", + "May be specified multiple times.", + is_long=True, + ), ) parser.add_argument( "-p", @@ -79,15 +123,23 @@ def main(): metavar="", action="append", default=[], - help="Include the specified platform in the analysis. " - + "May be specified multiple times. " - + "If not specified, all platforms will be included.", + help=_help_string( + "Include the specified platform in the analysis.", + "May be specified multiple times.", + "If not specified, all platforms will be included.", + is_long=True, + is_last=True, + ), ) + parser.add_argument( "analysis_file", metavar="", - help="TOML file describing the analysis to be performed, " - + "including the codebase and platform descriptions.", + help=_help_string( + "TOML file describing the analysis to be performed, " + + "including the codebase and platform descriptions.", + is_last=True, + ), ) args = parser.parse_args()