cvs commit: p5ee/App-Options/lib/App Options.pm

[email protected] (Stephen Adkins)
Newsgroups perl.cvs.p5ee
Message-ID <[email protected]>
cvsuser     05/01/14 06:01:07

  Modified:    App-Options/lib/App Options.pm
  Log:
  added --version
  
  Revision  Changes    Path
  1.12      +147 -24   p5ee/App-Options/lib/App/Options.pm
  
  Index: Options.pm
  ===================================================================
  RCS file: /cvs/public/p5ee/App-Options/lib/App/Options.pm,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- Options.pm	7 Jan 2005 13:04:38 -0000	1.11
  +++ Options.pm	14 Jan 2005 14:01:07 -0000	1.12
  @@ -1,6 +1,6 @@
   
   #############################################################################
  -## $Id: Options.pm,v 1.11 2005/01/07 13:04:38 spadkins Exp $
  +## $Id: Options.pm,v 1.12 2005/01/14 14:01:07 spadkins Exp $
   #############################################################################
   
   package App::Options;
  @@ -14,7 +14,7 @@
   use File::Spec;
   use Config;
   
  -$VERSION = "0.93";
  +$VERSION = "0.94";
   
   =head1 NAME
   
  @@ -47,8 +47,8 @@
       $HOME/.app/app.conf
       $PROGDIR/prog.conf
       $PROGDIR/app.conf
  -    $PREFIX/prog.conf
  -    $PREFIX/app.conf
  +    $PREFIX/etc/app/prog.conf
  +    $PREFIX/etc/app/app.conf
       /etc/app/app.conf
   
     with a file format like
  @@ -85,7 +85,7 @@
   /usr/myproduct/version).
   
   The description of the AppConfig distribution sounds similar
  -to is described here.  However, the following are the key
  +to what is described here.  However, the following are some key
   differences.
   
    * App::Options does its option processing in the BEGIN block.
  @@ -101,8 +101,8 @@
    * App::Options consults a cascading set of option files.
      These files include those which are system global, project
      global, and user private.  This allows for system
  -   administrators, project developers, and in individual
  -   users to all have complementary roles on defining
  +   administrators, project developers, and individual
  +   users to all have complementary roles in defining
      the configuration values.
   
    * App::Options is not a toolkit but a standardized way of
  @@ -111,7 +111,7 @@
      code the "--help" feature.  With App::Options, you simply
      "use App::Options;" and all the hard work is done.
      Advanced options can be added later as necessary as args
  -   to the "use" statement.
  +   to the "use App::Options;" statement.
   
   App::Options is also the easiest command-line processing system
   that I have found anywhere. It then provides a smooth transition to
  @@ -119,8 +119,7 @@
   quick and dirty script I ever write from now on can afford
   to use App::Options.
   
  -The documentation of App::Options takes three
  -forms below.
  +The documentation of App::Options takes three forms below.
   
     API Reference - describing the API (methods, args)
     Logic Flow - describing the order and logic of processing
  @@ -420,9 +419,9 @@
       #################################################################
       my $is_unix = 1;  # pretend we are not on Unix (use File::Spec)
   
  -    my $prog_cat = "";                   # start with no catalog
  -    my $prog_dir = $0;                   # start with the full script path
  +    my ($prog_cat, $prog_dir, $prog_file);
       if ($is_unix) {
  +        $prog_dir = $0;
           # i.e. /usr/local/bin/app, /app
           if ($prog_dir =~ m!^/!) {            # absolute path
               # i.e. /usr/local/bin/app, /app
  @@ -433,13 +432,15 @@
               $prog_dir =~ s!/?[^/]+$!!;       # trim off the program name
               $prog_dir = "." if (!$prog_dir); # if nothing left, directory is current dir
           }
  +        $prog_file = $0;
  +        $prog_file =~ s!.*/!!;
  +        $prog_cat = "";
       }
       else {
           # i.e. C:\perl\bin\app, \app
  -        my ($file);
  -        ($prog_cat, $prog_dir, $file) = File::Spec->splitpath($prog_dir);
  +        ($prog_cat, $prog_dir, $prog_file) = File::Spec->splitpath($0);
       }
  -    print STDERR "2. Found Directory of Program. catalog=[$prog_cat] dir=[$prog_dir]\n"
  +    print STDERR "2. Found Directory of Program. catalog=[$prog_cat] dir=[$prog_dir] file=[$prog_file]\n"
           if ($debug_options);
   
       #################################################################
  @@ -505,8 +506,7 @@
               }
           }
           if (!$app) {
  -            $app = $0;            # start with the full script path
  -            $app =~ s!.*/!!;      # strip off leading path
  +            $app = $prog_file;    # start with the full program name
               $app =~ s/\.[^.]+$//; # strip off trailing file type (i.e. ".pl")
               $app_origin = "program name ($0)";
           }
  @@ -672,7 +672,7 @@
       }
   
       #################################################################
  -    # 6. fill in ENV vars and defaults
  +    # 6. fill in ENV vars
       #################################################################
   
       if (!$init_args{no_env_vars}) {
  @@ -814,15 +814,40 @@
       else {
           my $libdir = "$prefix/lib";
           my $libdir_found = 0;
  +        # Look to see whether this PREFIX has been included already in @INC.
  +        # If it has, we do *not* want to automagically guess which directories
  +        # should be searched and in which order.
           foreach my $incdir (@INC) {
               if ($incdir =~ /^$libdir/) {
                   $libdir_found = 1;
  +                last;
               }
           }
  +
  +        # The traditional way to install software from CPAN uses
  +        # ExtUtils::MakeMaker via Makefile.PL with the "make install"
  +        # command.  If you are installing this software to non-standard
  +        # places, you would use the "perl Makefile.PL PREFIX=$PREFIX"
  +        # command.  This would typically put modules into the
  +        # $PREFIX/lib/perl5/site_perl/$perlversion directory.
  +
  +        # However, a newer way to install software (and recent versions
  +        # of CPAN.pm understand this) uses Module::Build via Build.PL
  +        # with the "Build install" command.  If you are installing this
  +        # software to non-standard places, you would use the 
  +        # "perl Build.PL install_base=$PREFIX" command.  This would
  +        # typically put modules into the $PREFIX/lib directory.
  +
  +        # So if we need to guess about extra directories to add to the
  +        # @INC variable ($PREFIX/lib is nowhere currently represented
  +        # in @INC), we should add directories which work for software
  +        # installed with either Module::Build or ExtUtils::MakeMaker.
  +
           if (!$libdir_found) {
               unshift(@INC, "$libdir");
               if ($^V) {
                   my $perlversion = sprintf("%vd", $^V);
  +                unshift(@INC, $libdir);
                   unshift(@INC, "$libdir/perl5/site_perl/$perlversion");  # site_perl goes first!
                   unshift(@INC, "$libdir/perl5/$perlversion");
               }
  @@ -850,7 +875,16 @@
       }
   
       #################################################################
  -    # 11. perform validations, print help, and exit
  +    # 11. print version information (--version)
  +    #################################################################
  +
  +    if ($values->{version}) {
  +        &print_version($prog_file, $values);
  +        exit(0);
  +    }
  +
  +    #################################################################
  +    # 12. perform validations, print help, and exit
       #################################################################
   
       my $exit_status = -1;
  @@ -907,13 +941,13 @@
               elsif ($type eq "datetime") {
                   if ($value !~ /^[0-9]{4}-[01][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]$/) {
                       $exit_status = 1;
  -                    print "Error: \"$var\" must be of type \"$type\" (format \"YYYY-MM-DD HH:MM::SS\") (not \"$value\")\n";
  +                    print "Error: \"$var\" must be of type \"$type\" (format \"YYYY-MM-DD HH:MM:SS\") (not \"$value\")\n";
                   }
               }
               elsif ($type eq "time") {
                   if ($value !~ /^[0-2][0-9]:[0-5][0-9]:[0-5][0-9]$/) {
                       $exit_status = 1;
  -                    print "Error: \"$var\" must be of type \"$type\" (format \"HH:MM::SS\") (not \"$value\")\n";
  +                    print "Error: \"$var\" must be of type \"$type\" (format \"HH:MM:SS\") (not \"$value\")\n";
                   }
               }
               elsif ($type =~ m!^/(.*)/$!) {
  @@ -997,6 +1031,80 @@
       }
   }
   
  +sub print_version {
  +    my ($prog_file, $values) = @_;
  +    print "Program: $prog_file\n";
  +    print "(use --version_packages to see version info for specific perl packages)\n";
  +    my ($module, $package, $version, $full_path);
  +    if ($values->{version_packages}) {
  +        foreach my $package (split(/[ ;,]+/,$values->{version_packages})) {
  +            $module = "$package.pm";
  +            $module =~ s!::!/!g;
  +            if ($package =~ /^[A-Z][A-Za-z0-9:_]*$/) {
  +                eval {
  +                    require $module;
  +                };
  +                if ($@) {
  +                    my $error = $@;
  +                    $error =~ s/ *\(\@INC contains:.*//s;
  +                    print "WARNING: $package: $error\n";
  +                }
  +            }
  +        }
  +    }
  +    print "Version Package\n";
  +    print "------- ----------------------------\n";
  +    printf("%7s main\n", $main::VERSION || "undef");
  +
  +    my ($show_module, @package_pattern, $version_sys_packages);
  +
  +    # There are lots of modules which get loaded up which have
  +    # nothing to do with your program and which you would ordinarily
  +    # not want to see.  So ...
  +    #    --version=1  will show only the packages you specify
  +    #    --version=2  will show all packages
  +    if ($values->{version_packages}) {
  +        $version_sys_packages = $values->{version_sys_packages};
  +        $version_sys_packages = "App::Options,Carp,Sys::Hostname,Cwd,File::Spec,Config"
  +            if (!defined $version_sys_packages);
  +        @package_pattern = split(/[ ;,]+/,$version_sys_packages);
  +        if ($values->{version_packages}) {
  +            push(@package_pattern, split(/[ ;,]+/,$values->{version_packages}));
  +        }
  +    }
  +
  +    # I should look into doing this from the symbol table rather
  +    # than %INC which reflects the *modules*, not the packages.
  +    # For most purposes, this will be good enough.
  +    foreach $module (sort keys %INC) {
  +        $full_path = $INC{$module};
  +        $package = $module;
  +        $package =~ s/\.p[lm]$//;
  +        $package =~ s!/!::!g;
  +
  +        if ($values->{version_packages} && $values->{version} eq "1") {
  +            $show_module = 0;
  +            foreach my $package_pattern (@package_pattern) {
  +                if ($package =~ /$package_pattern/) {
  +                    $show_module = 1;
  +                    last;
  +                }
  +            }
  +        }
  +        else {
  +            $show_module = 1;
  +        }
  +
  +        if ($show_module) {
  +            $version = "";
  +            eval "\$version = \$${package}::VERSION;";
  +            $version = "undef" if (!$version);
  +            printf("%7s %-20s\n", $version, $package);
  +            #printf("%7s %-20s %s\n", "", $module, $full_path);
  +        }
  +    }
  +}
  +
   =head1 LOGIC FLOW: OPTION PROCESSING DETAILS
   
   Basic Concept - By calling App::Options->init(),
  @@ -1359,6 +1467,19 @@
   and the resulting list of include directories (@INC) is printed
   out.
   
  +=head2 Version
  +
  +If the "--version" option is set on the command line,
  +the version information for the loaded modules is printed,
  +and the program is exited.
  +
  +If additional modules should be loaded so that their version
  +number can be ascertained, use the --version_packages option.
  +
  +   prog --version
  +   prog --version --version_packages=CGI
  +   prog --version --version_packages=CGI,Template
  +
   =head2 Help and Validations
   
   After all values have been parsed, various conditions are
  @@ -1423,6 +1544,9 @@
       demo1 --debug_options -?
       demo1 -x=5 --verbose=10 --foo=bar --debug_options -?
   
  +    demo1 --version
  +    demo1 --version --version_packages=CGI
  +
   Now create a copy of the program.
   
       cp demo1 demo2
  @@ -1517,8 +1641,8 @@
   PREFIX environment variable and the program is not installed in
   $PREFIX/bin, he would have to put the above lines
   in either the "app.conf" file or the "listcust.conf" file
  -in either the global /etc/app directory or in the same
  -directory as "listcust".
  +in the same directory as "listcust" or in the global
  +"/etc/app/app.conf" option file.
   
   A user (without privileges to the "$PREFIX/etc/app" directory
   or the directory in which "listcust" lives) would have to put
  @@ -1672,7 +1796,6 @@
               "first_name", "last_name", "birth_dt", "company_id",
               "wholesale_ind", "change_dttm",
           ],
  -        show_all => 1,
       );
   
   Using the "options" arg causes the options to
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.