Re: Stanford IDG internal Perl style
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)
Reply to: