diff options
author | Joey Hess <joey@kodama.kitenet.net> | 2008-10-21 14:00:09 -0400 |
---|---|---|
committer | Joey Hess <joey@kodama.kitenet.net> | 2008-10-21 14:00:09 -0400 |
commit | 3c458775d1180d034217c4b44e3871d8b87bf382 (patch) | |
tree | 344bd8b90c67ed54be8fb26dceb9ae4636241879 | |
parent | 4839c4003b54b6f030e5ea58db5b591dc1088080 (diff) |
Allow individual debhelper programs to define their own special options by passing a hash to init(), which is later passed on the Getopt::Long. Closes: #370823
-rw-r--r-- | Debian/Debhelper/Dh_Getopt.pm | 170 | ||||
-rw-r--r-- | Debian/Debhelper/Dh_Lib.pm | 4 | ||||
-rw-r--r-- | debian/changelog | 3 | ||||
-rw-r--r-- | doc/PROGRAMMING | 9 | ||||
-rw-r--r-- | doc/TODO | 28 |
5 files changed, 99 insertions, 115 deletions
diff --git a/Debian/Debhelper/Dh_Getopt.pm b/Debian/Debhelper/Dh_Getopt.pm index f8e02889..a676eaaa 100644 --- a/Debian/Debhelper/Dh_Getopt.pm +++ b/Debian/Debhelper/Dh_Getopt.pm @@ -9,12 +9,8 @@ use strict; use Debian::Debhelper::Dh_Lib; use Getopt::Long; -use Exporter; -#use vars qw{@ISA @EXPORT}; -#@ISA=qw(Exporter); -#@EXPORT=qw(&aparseopts); # FIXME: for some reason, this doesn't work. -my (%options, %exclude_package); +my %exclude_package; sub showhelp { my $prog=basename($0); @@ -29,19 +25,19 @@ sub showhelp { # order. sub AddPackage { my($option,$value)=@_; if ($option eq 'i' or $option eq 'indep') { - push @{$options{DOPACKAGES}}, getpackages('indep'); - $options{DOINDEP}=1; + push @{$dh{DOPACKAGES}}, getpackages('indep'); + $dh{DOINDEP}=1; } elsif ($option eq 'a' or $option eq 'arch') { - push @{$options{DOPACKAGES}}, getpackages('arch'); - $options{DOARCH}=1; + push @{$dh{DOPACKAGES}}, getpackages('arch'); + $dh{DOARCH}=1; } elsif ($option eq 'p' or $option eq 'package') { - push @{$options{DOPACKAGES}}, $value; + push @{$dh{DOPACKAGES}}, $value; } elsif ($option eq 's' or $option eq 'same-arch') { - push @{$options{DOPACKAGES}}, getpackages('same'); - $options{DOSAME}=1; + push @{$dh{DOPACKAGES}}, getpackages('same'); + $dh{DOSAME}=1; } else { error("bad option $option - should never happen!\n"); @@ -50,7 +46,7 @@ sub AddPackage { my($option,$value)=@_; # Adds packages to the list of debug packages. sub AddDebugPackage { my($option,$value)=@_; - push @{$options{DEBUGPACKAGES}}, $value; + push @{$dh{DEBUGPACKAGES}}, $value; } # Add a package to a list of packages that should not be acted on. @@ -60,31 +56,31 @@ sub ExcludePackage { my($option,$value)=@_; # Add another item to the exclude list. sub AddExclude { my($option,$value)=@_; - push @{$options{EXCLUDE}},$value; + push @{$dh{EXCLUDE}},$value; } # Add a file to the ignore list. sub AddIgnore { my($option,$file)=@_; - $options{IGNORE}->{$file}=1; + $dh{IGNORE}->{$file}=1; } # Add an item to the with list. sub AddWith { my($option,$value)=@_; - push @{$options{WITH}},$value; + push @{$dh{WITH}},$value; } # This collects non-options values. sub NonOption { - push @{$options{ARGV}}, @_; + push @{$dh{ARGV}}, @_; } -# Parse options and return a hash of the values. +# Parse options and set %dh values. sub parseopts { - undef %options; - + my %options=%{shift()} if ref $_[0]; + my $ret=GetOptions( - "v" => \$options{VERBOSE}, - "verbose" => \$options{VERBOSE}, + "v" => \$dh{VERBOSE}, + "verbose" => \$dh{VERBOSE}, "i" => \&AddPackage, "indep" => \&AddPackage, @@ -103,91 +99,93 @@ sub parseopts { "N=s" => \&ExcludePackage, "no-package=s" => \&ExcludePackage, - "n" => \$options{NOSCRIPTS}, - "noscripts" => \$options{NOSCRIPTS}, - "o" => \$options{ONLYSCRIPTS}, - "onlyscripts" => \$options{ONLYSCRIPTS}, + "n" => \$dh{NOSCRIPTS}, + "noscripts" => \$dh{NOSCRIPTS}, + "o" => \$dh{ONLYSCRIPTS}, + "onlyscripts" => \$dh{ONLYSCRIPTS}, - "x" => \$options{INCLUDE_CONFFILES}, # is -x for some unknown historical reason.. - "include-conffiles" => \$options{INCLUDE_CONFFILES}, + "x" => \$dh{INCLUDE_CONFFILES}, # is -x for some unknown historical reason.. + "include-conffiles" => \$dh{INCLUDE_CONFFILES}, "X=s" => \&AddExclude, "exclude=s" => \&AddExclude, "ignore=s" => \&AddIgnore, - "d" => \$options{D_FLAG}, - "remove-d" => \$options{D_FLAG}, - "dirs-only" => \$options{D_FLAG}, + "d" => \$dh{D_FLAG}, + "remove-d" => \$dh{D_FLAG}, + "dirs-only" => \$dh{D_FLAG}, - "r" => \$options{R_FLAG}, - "no-restart-on-upgrade" => \$options{R_FLAG}, - "no-start" => \$options{NO_START}, - "R|restart-after-upgrade" => \$options{RESTART_AFTER_UPGRADE}, + "r" => \$dh{R_FLAG}, + "no-restart-on-upgrade" => \$dh{R_FLAG}, + "no-start" => \$dh{NO_START}, + "R|restart-after-upgrade" => \$dh{RESTART_AFTER_UPGRADE}, - "k" => \$options{K_FLAG}, - "keep" => \$options{K_FLAG}, - "keep-debug" => \$options{K_FLAG}, + "k" => \$dh{K_FLAG}, + "keep" => \$dh{K_FLAG}, + "keep-debug" => \$dh{K_FLAG}, - "P=s" => \$options{TMPDIR}, - "tmpdir=s" => \$options{TMPDIR}, + "P=s" => \$dh{TMPDIR}, + "tmpdir=s" => \$dh{TMPDIR}, - "u=s", => \$options{U_PARAMS}, - "update-rcd-params=s", => \$options{U_PARAMS}, - "dpkg-shlibdeps-params=s", => \$options{U_PARAMS}, - "dpkg-gencontrol-params=s", => \$options{U_PARAMS}, + "u=s", => \$dh{U_PARAMS}, + "update-rcd-params=s", => \$dh{U_PARAMS}, + "dpkg-shlibdeps-params=s", => \$dh{U_PARAMS}, + "dpkg-gencontrol-params=s", => \$dh{U_PARAMS}, - "l=s", => \$options{L_PARAMS}, + "l=s", => \$dh{L_PARAMS}, - "m=s", => \$options{M_PARAMS}, - "major=s" => \$options{M_PARAMS}, + "m=s", => \$dh{M_PARAMS}, + "major=s" => \$dh{M_PARAMS}, - "V:s", => \$options{V_FLAG}, - "version-info:s" => \$options{V_FLAG}, + "V:s", => \$dh{V_FLAG}, + "version-info:s" => \$dh{V_FLAG}, - "A" => \$options{PARAMS_ALL}, - "all" => \$options{PARAMS_ALL}, + "A" => \$dh{PARAMS_ALL}, + "all" => \$dh{PARAMS_ALL}, - "no-act" => \$options{NO_ACT}, + "no-act" => \$dh{NO_ACT}, - "init-script=s" => \$options{INIT_SCRIPT}, + "init-script=s" => \$dh{INIT_SCRIPT}, - "sourcedir=s" => \$options{SOURCEDIR}, + "sourcedir=s" => \$dh{SOURCEDIR}, - "destdir=s" => \$options{DESTDIR}, + "destdir=s" => \$dh{DESTDIR}, - "filename=s" => \$options{FILENAME}, + "filename=s" => \$dh{FILENAME}, - "priority=s" => \$options{PRIORITY}, + "priority=s" => \$dh{PRIORITY}, - "flavor=s" => \$options{FLAVOR}, + "flavor=s" => \$dh{FLAVOR}, - "autodest" => \$options{AUTODEST}, + "autodest" => \$dh{AUTODEST}, "h|help" => \&showhelp, - "mainpackage=s" => \$options{MAINPACKAGE}, + "mainpackage=s" => \$dh{MAINPACKAGE}, - "list-missing" => \$options{LIST_MISSING}, + "list-missing" => \$dh{LIST_MISSING}, - "fail-missing" => \$options{FAIL_MISSING}, + "fail-missing" => \$dh{FAIL_MISSING}, - "L|libpackage=s" => \$options{LIBPACKAGE}, + "L|libpackage=s" => \$dh{LIBPACKAGE}, - "name=s" => \$options{NAME}, + "name=s" => \$dh{NAME}, - "error-handler=s" => \$options{ERROR_HANDLER}, + "error-handler=s" => \$dh{ERROR_HANDLER}, - "add-udeb=s" => \$options{SHLIBS_UDEB}, + "add-udeb=s" => \$dh{SHLIBS_UDEB}, - "language=s" => \$options{LANGUAGE}, + "language=s" => \$dh{LANGUAGE}, - "until=s" => \$options{UNTIL}, - "after=s" => \$options{AFTER}, - "before=s" => \$options{BEFORE}, - "remaining" => \$options{REMAINING}, + "until=s" => \$dh{UNTIL}, + "after=s" => \$dh{AFTER}, + "before=s" => \$dh{BEFORE}, + "remaining" => \$dh{REMAINING}, "with=s" => \&AddWith, + %options, + "<>" => \&NonOption, ); @@ -197,21 +195,21 @@ sub parseopts { # Check to see if -V was specified. If so, but no parameters were # passed, the variable will be defined but empty. - if (defined($options{V_FLAG})) { - $options{V_FLAG_SET}=1; + if (defined($dh{V_FLAG})) { + $dh{V_FLAG_SET}=1; } # If we have not been given any packages to act on, assume they # want us to act on them all. Note we have to do this before excluding # packages out, below. - if (! defined $options{DOPACKAGES} || ! @{$options{DOPACKAGES}}) { - if ($options{DOINDEP} || $options{DOARCH} || $options{DOSAME}) { + if (! defined $dh{DOPACKAGES} || ! @{$dh{DOPACKAGES}}) { + if ($dh{DOINDEP} || $dh{DOARCH} || $dh{DOSAME}) { # User specified that all arch (in)dep package be # built, and there are none of that type. warning("I have no package to build"); exit(0); } - push @{$options{DOPACKAGES}},getpackages(); + push @{$dh{DOPACKAGES}},getpackages(); } # Remove excluded packages from the list of packages to act on. @@ -220,7 +218,7 @@ sub parseopts { my @package_list; my $package; my %packages_seen; - foreach $package (@{$options{DOPACKAGES}}) { + foreach $package (@{$dh{DOPACKAGES}}) { if (! $exclude_package{$package}) { if (! exists $packages_seen{$package}) { $packages_seen{$package}=1; @@ -228,27 +226,25 @@ sub parseopts { } } } - @{$options{DOPACKAGES}}=@package_list; + @{$dh{DOPACKAGES}}=@package_list; # If there are no packages to act on now, it's an error. - if (! defined $options{DOPACKAGES} || ! @{$options{DOPACKAGES}}) { + if (! defined $dh{DOPACKAGES} || ! @{$dh{DOPACKAGES}}) { error("I have no package to build"); } - if (defined $options{U_PARAMS}) { + if (defined $dh{U_PARAMS}) { # Split the U_PARAMS up into an array. - my $u=$options{U_PARAMS}; - undef $options{U_PARAMS}; - push @{$options{U_PARAMS}}, split(/\s+/,$u); + my $u=$dh{U_PARAMS}; + undef $dh{U_PARAMS}; + push @{$dh{U_PARAMS}}, split(/\s+/,$u); } # Anything left in @ARGV is options that appeared after a -- # These options are added to the U_PARAMS array, while the # non-option values we collected replace them in @ARGV; - push @{$options{U_PARAMS}}, @ARGV; - @ARGV=@{$options{ARGV}} if exists $options{ARGV}; - - return %options; + push @{$dh{U_PARAMS}}, @ARGV; + @ARGV=@{$dh{ARGV}} if exists $dh{ARGV}; } sub import { diff --git a/Debian/Debhelper/Dh_Lib.pm b/Debian/Debhelper/Dh_Lib.pm index 6be25f9d..82efc5be 100644 --- a/Debian/Debhelper/Dh_Lib.pm +++ b/Debian/Debhelper/Dh_Lib.pm @@ -20,6 +20,8 @@ use vars qw(@ISA @EXPORT %dh); my $max_compat=7; sub init { + my %params=@_; + # If DH_OPTIONS is set, prepend it @ARGV. if (defined($ENV{DH_OPTIONS})) { # Ignore leading/trailing whitespace. @@ -42,7 +44,7 @@ sub init { if ($parseopt) { eval "use Debian::Debhelper::Dh_Getopt"; error($!) if $@; - %dh=Debian::Debhelper::Dh_Getopt::parseopts(); + Debian::Debhelper::Dh_Getopt::parseopts($params{options}); } # Another way to set excludes. diff --git a/debian/changelog b/debian/changelog index dc358aa5..37695cb1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,6 +5,9 @@ debhelper (7.0.18) UNRELEASED; urgency=low * dh_gencontrol: Ensure misc:Depends is set in substvars to avoid dpkg complaining about it when it's empty. Closes: #498666 * dh: Fix typo in example. Closes: #500836 + * Allow individual debhelper programs to define their own special options + by passing a hash to init(), which is later passed on the Getopt::Long. + Closes: #370823 -- Joey Hess <joeyh@debian.org> Wed, 10 Sep 2008 13:58:00 -0400 diff --git a/doc/PROGRAMMING b/doc/PROGRAMMING index bd6645ee..0d96457f 100644 --- a/doc/PROGRAMMING +++ b/doc/PROGRAMMING @@ -77,6 +77,13 @@ All debhelper programs should respond to certain arguments, such as -v, -i, -a, and -p. To help you make this work right, Dh_Lib.pm handles argument processing. Just call init(). +You can add support for additional options to your command by passing an +options hash to init(). The hash is then passed on the Getopt::Long to +parse the command line options. For example, to add a --foo option, which +sets $dh{FOO}: + +init(options => { foo => \$dh{FOO} }); + After argument processing, some global variables are used to hold the results; programs can use them later. These variables are elements of the %dh hash. @@ -150,8 +157,6 @@ switch variable description Any additional command line parameters that do not start with "-" will be ignored, and you can access them later just as you normally would. -If you need a new command line option, just ask me, and I will add it. - Global variables: ---------------- @@ -4,32 +4,10 @@ list grows - I welcome patches to fix items on it! Wishlist items: * All debhelper programs should only accept the options they are documented - to accept (rather than accepting all debhelper options). They should - be able to print brief usage summaries. + to accept (rather than accepting all debhelper options). This is mostly a + matter of moving command-specific options out of Dh_Getopt and into the + individial command's calls to init(). (#112349) - I think this calls for a restructuring. Make a Debhelper.pm class. Each - program subclasses the class. The class provides command line parsing, - useful functions, and so on. Skeleton of a debhelper command would then - be: - - use base qw{Debhelper}; - - sub startup { - # Add initialization stuff here. - } - - sub perpackage { - my $package=shift; - - # Stuff to do for each package here. - } - - sub fini { - # And final stuff here, if any. - } - - This needs more thought. - v8: * escaping in config files (for whitespace)? |