On 2013-04-06 23:13, Niels Thykier wrote: > On 2013-04-06 05:26, Russ Allbery wrote: >>> $opt->mode eq 't' instead of $opt->mode eq 'tags' >>> $opt->h instead of $opt->help >> Yeah, I was looking at that when I reviewed the document, and I think >> that's backwards. It's left over from an old style we had for >> Getopt::Long where it didn't matter. I'm going to change that. >> > > Noted. :) > > Do you have some examples of complex usage of Getopt::Long::Descriptive > by the way? I had a stab at rewriting lintian's option parsing and for > sometimes I cannot find the way to do it with G::L::Descriptive. >
My progress so far is in the attached script. It is missing a few options. > Particularly, --display-info + --pedantic is translated to > --display-level. While it is trivial to collect all the information and > merge it manually it loses the order. (i.e. --pedantic --display-level > X is sometimes different from --display-level X --pedantic). > > The possibility to having a sub interpreting the opt+value would do just > fine but I have not figured how to do it (if at all possible). > Still haven't found a solution to this. I also noticed that Getopt::Long::Descriptive does not include "arguments" in its usage (see usage-normal.txt). Apparently that is a known bug[1]. I have written a few patches for upstream, which are available at [2]. There is also a "usage-patched.txt" in the upstream bug, if you want to see how the help info looks with the patched version. ~Niels [1] https://rt.cpan.org/Public/Bug/Display.html?id=79982 [2] https://rt.cpan.org/Public/Bug/Display.html?id=84487 I intended for it to be a follow up, but apparently I got the RT syntax wrong. :-/
#!/usr/bin/perl use strict; use warnings; use Data::Dumper; use Getopt::Long; use Getopt::Long::Descriptive; my @mode_specs = ( ['check|c', 'check packages (default action)'], ['unpack|u', 'only unpack packages in the lab'], ['remove|r', 'remove package from the lab'], ['setup-lab|S', 'set up static lab'], ['remove-lab|R', 'remove static lab'], ); my @option_specs = ( ['[Actions]'], ['mode', \@mode_specs], # TODO: --check-part, --tags(-from-file), --dont-check-part [], ['[General options]'], ['debug|d+', q{turn Lintian's debug messages ON}, { implies => 'verbose' }], ['help|h' , 'display short help text'], ['print-version', 'print unadorned version number and exit'], ['quiet', 'suppress all informational messages'], ['verbose|v', 'verbose messages'], ['version|V', 'display Lintian version and exit', { implies => 'print_version'}], [], ['[Behaviour options]'], ['allow-root', q{suppress lintian's warning when run as root}], ['color=s', 'disable, enable, or enable color for TTY', { default => 'never', regex => qr{^never|always|auto|html$} }], ['display-source=s%', 'restrict displayed tags by source', { default => {} }], ['display-experimental|E!', 'display "X:" tags (normally suppressed)'], ['fail-on-warnings', 'return a non-zero exit status if warnings found'], ['ftp-master-rejects|F', 'only check for automatic reject tags'], ['info|i', 'give detailed info about tags'], ['display-info|I', 'display "I:" tags (normally suppressed)'], ['keep-lab', 'keep lab after run, even if temporary'], ['display-level|L=s@', 'display tags with the specified level', { default => [] }], ['no-override|o', 'ignore overrides'], ['pedantic', 'display "P:" tags (normally suppressed)'], ['profile=s', 'use the given vendor profile', { 'default' => '{VENDOR}' } ], ['show-overrides', 'output tags that have been overriden' ], ['suppress-tags=s@', 'do not show the specified tags'], ['suppress-tags-from-file=s@', 'do not show the tags listed in the given file'], ['unpack-info|U=s@', 'specify additional info to be collected'], [], ['[Configuration options]'], ['cfg=s', 'use the given file for configuration'], ['no-cfg', 'do not read any config files'], ['ignore-lintian-env', 'ignore LINTIAN_* ENV variables'], ['include-dir=s@', 'include checks, libraries (etc.) for the given dir'], ['jobs|j:i', 'limit the number of parallel unpacking jobs'], ['lab=s', 'use the given dir as permanent/static lab'], ['root=s', 'use the given dir instead of /usr/share/lintian'], ['user-dirs!', 'whether to use files from user dirs'], [], ['[Package selection options]'], ['packages-from-file=s', 'process the packages in a file (if "-" use stdin)'], # remove --all, --binary, --source, --udeb ? Nobody uses them ); my ($opt, $usage) = describe_options( 'Usage: %c %o ... ', @option_specs, ); if ($opt->help) { print $usage, "\n"; exit 0; } if (defined $opt->jobs) { print STDERR "Jobs: ", $opt->jobs, "\n"; } print Dumper($opt), "\n"; __END__ sub syntax { print "$BANNER\n"; print <<"EOT-EOT-EOT"; Syntax: lintian [action] [options] [--] [packages] ... Actions: -C X, --check-part X check only certain aspects -F, --ftp-master-rejects only check for automatic reject tags -T X, --tags X only run checks needed for requested tags --tags-from-file X like --tags, but read list from file -X X, --dont-check-part X don\'t check certain aspects Package selection options: -a, --all process all packages in distribution -b, --binary process only binary packages --packages-from-file X process the packages in a file (if "-" use stdin) -s, --source process only source packages --udeb process only udeb packages EOT-EOT-EOT my %opthash = ( # ------------------ actions 'setup-lab|S' => \&record_action, 'remove-lab|R' => \&record_action, 'check|c' => \&record_action, 'check-part|C=s' => \&record_check_part, 'tags|T=s' => \&record_check_tags, 'tags-from-file=s' => \&record_check_tags_from_file, 'ftp-master-rejects|F' => \$ftpmaster_tags, 'dont-check-part|X=s' => \&record_dont_check_part, 'unpack|u' => \&record_action, 'remove|r' => \&record_action, # ------------------ general options 'help|h' => \&syntax, 'version|V' => \&banner, 'print-version' => \&banner, 'verbose|v' => \$opt{'verbose'}, 'debug|d+' => \$debug, # Count the -d flags 'quiet|q' => \&record_quiet, # sets $opt{'verbose'} to -1 # ------------------ behaviour options 'info|i' => \$opt{'info'}, 'display-info|I' => \&display_infotags, 'display-experimental|E!' => \$opt{'display-experimental'}, 'pedantic' => \&display_pedantictags, 'display-level|L=s' => \&record_display_level, 'display-source=s' => \&record_display_source, 'suppress-tags=s' => \&record_suppress_tags, 'suppress-tags-from-file=s' => \&record_suppress_tags_from_file, 'no-override|o' => \$opt{'no-override'}, 'show-overrides' => \$opt{'show-overrides'}, 'color=s' => \$opt{'color'}, 'unpack-info|U=s' => \@unpack_info, 'allow-root' => \$allow_root, 'fail-on-warnings' => \$opt{'fail-on-warnings'}, 'keep-lab' => \$keep_lab, # ------------------ configuration options 'cfg=s' => \$opt{'LINTIAN_CFG'}, 'no-cfg' => \$no_conf, 'lab=s' => \$opt{'LINTIAN_LAB'}, 'profile=s' => \$opt{'LINTIAN_PROFILE'}, 'root=s' => \$opt{'LINTIAN_ROOT'}, 'jobs|j:i' => \$opt{'jobs'}, 'ignore-lintian-env' => \$opt{'ignore-lintian-env'}, 'include-dir=s' => \@search_dirs, 'user-dirs!' => \$opt{'user-dirs'}, # ------------------ package selection options 'all|a' => \$check_everything, 'binary|b' => \&record_pkgmode, 'source|s' => \&record_pkgmode, 'udeb' => \&record_pkgmode, 'packages-from-file=s' => \$opt{'packages-from-file'}, # ------------------ experimental 'exp-output:s' => \$experimental_output_opts, );
Usage: lintian-getopt-long-desc-prototype [-cdEFhIijLoRrSUuVv] [long options...] ... [Actions] -c --check check packages (default action) -u --unpack only unpack packages in the lab -r --remove remove package from the lab -S --setup-lab set up static lab -R --remove-lab remove static lab [General options] -d --debug turn Lintian's debug messages ON -h --help display short help text --print-version print unadorned version number and exit --quiet suppress all informational messages -v --verbose verbose messages -V --version display Lintian version and exit [Behaviour options] --allow-root suppress lintian's warning when run as root --color disable, enable, or enable color for TTY --display-source restrict displayed tags by source -E --display-experimental display "X:" tags (normally suppressed) --fail-on-warnings return a non-zero exit status if warnings found -F --ftp-master-rejects only check for automatic reject tags -i --info give detailed info about tags -I --display-info display "I:" tags (normally suppressed) --keep-lab keep lab after run, even if temporary -L --display-level display tags with the specified level -o --no-override ignore overrides --pedantic display "P:" tags (normally suppressed) --profile use the given vendor profile --show-overrides output tags that have been overriden --suppress-tags do not show the specified tags --suppress-tags-from-file do not show the tags listed in the given file -U --unpack-info specify additional info to be collected [Configuration options] --cfg use the given file for configuration --no-cfg do not read any config files --ignore-lintian-env ignore LINTIAN_* ENV variables --include-dir include checks, libraries (etc.) for the given dir -j --jobs limit the number of parallel unpacking jobs --lab use the given dir as permanent/static lab --root use the given dir instead of /usr/share/lintian --user-dirs whether to use files from user dirs [Package selection options] --packages-from-file process the packages in a file (if "-" use stdin)