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 via email to