cvsuser     04/01/07 07:24:07

  Modified:    App-Options MANIFEST Makefile.PL README TODO
               App-Options/lib/App Options.pm
  Log:
  first version to upload to CPAN. a bit better documented, added string and boolean 
types, added description to --help
  
  Revision  Changes    Path
  1.2       +7 -1      p5ee/App-Options/MANIFEST
  
  Index: MANIFEST
  ===================================================================
  RCS file: /cvs/public/p5ee/App-Options/MANIFEST,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- MANIFEST  16 Nov 2003 21:21:22 -0000      1.1
  +++ MANIFEST  7 Jan 2004 15:24:07 -0000       1.2
  @@ -5,5 +5,11 @@
   TODO
   bin/prefix
   lib/App/Options.pm
  -t/main.t
   t/app.conf
  +t/main.t
  +t/test1
  +t/test1.conf
  +t/test2
  +t/test3
  +t/test4
  +t/test5
  
  
  
  1.2       +2 -2      p5ee/App-Options/Makefile.PL
  
  Index: Makefile.PL
  ===================================================================
  RCS file: /cvs/public/p5ee/App-Options/Makefile.PL,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- Makefile.PL       16 Nov 2003 21:21:22 -0000      1.1
  +++ Makefile.PL       7 Jan 2004 15:24:07 -0000       1.2
  @@ -1,6 +1,6 @@
   
   ######################################################################
  -## File: $Id: Makefile.PL,v 1.1 2003/11/16 21:21:22 spadkins Exp $
  +## File: $Id: Makefile.PL,v 1.2 2004/01/07 15:24:07 spadkins Exp $
   ######################################################################
   
   use ExtUtils::MakeMaker;
  @@ -14,7 +14,7 @@
   %opts = (
       'NAME'        => 'App-Options',
       'DISTNAME'    => 'App-Options',
  -    'VERSION'     => '0.60',
  +    'VERSION'     => '0.61',
       'EXE_FILES'   => [ @programs ],
       'dist'        => {'COMPRESS'=>'gzip -9f', 'SUFFIX' => 'gz',
                         'ZIP'=>'/usr/bin/zip','ZIPFLAGS'=>'-rl'},
  
  
  
  1.2       +156 -36   p5ee/App-Options/README
  
  Index: README
  ===================================================================
  RCS file: /cvs/public/p5ee/App-Options/README,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- README    16 Nov 2003 21:21:22 -0000      1.1
  +++ README    7 Jan 2004 15:24:07 -0000       1.2
  @@ -1,54 +1,174 @@
   ######################################################################
  -## File: $Id: README,v 1.1 2003/11/16 21:21:22 spadkins Exp $
  +## File: $Id: README,v 1.2 2004/01/07 15:24:07 spadkins Exp $
   ######################################################################
   
  -This is the App-Options distribution.
  +1. What is the App-Options distribution?
   
  -It parses command line options, incorporates values from environment
  -variables and configuration files, validates option values, and
  -returns them in a simple hash structure.  It would be used instead
  -of modules like Getopt::Long, but of course it does a lot more.
  -
  -In particular, it may be run within a BEGIN block in order to
  -modify the @INC variable with additional directories so that
  -subsequent "use" and "require" statements are affected.
  -
  -FEATURES
  -
  - o Easy to use.
  - o Parse long (--whatever) and short (-w) command line options
  - o Combine options with Environment Variables
  - o Combine options with global and local config files
  - o Multiple config files can be used via "import" option
  - o Modify @INC variable with the "perlinc" option
  - o Validate "required" options provided
  - o Validate option values against types (integer, int, float,
  -   number, date, datetime, string)
  +The App-Options distribution is "yet another command line processor."
  +However, it was created for maximum ease of use with the needs of
  +the Perl 5 Enterprise Environment in mind (more on that later).
  +
  +The distribution consists of one Perl module and one shell script.
  +
  +   App::Options - a perl module which combines command line parameters,
  +       environment variables, and configuration files to produce
  +       a hash of option values.
  +
  +   prefix - a shell script which works for ksh (Korn shell) or
  +       bash (Bourne Again Shell) which allows you to change
  +       a family of environment variables (PATH, LD_LIBRARY_PATH,
  +       MANPATH, etc.) necessary for running programs out of a
  +       directory in which software has been installed.
  +
  +2. What are the features?
  +
  +FEATURES OF App::Options
  +
  + o Flexible command line syntax
  +   Parse long (--whatever) and short (-w) command line options
  +   (with [--verbose=3] or without [--verbose] arguments)
  +   and just put the values in %App::options (or some other hash
  +   that you may specify).
  + o Automatic boolean command line switches
  +   An option like "--help" is equivalent to "--help=1".
  + o Combines options with Environment Variables
  +   The --whatever=value option can be supplied with the
  +   APP_WHATEVER environment variable.
  + o Combines options with variables in global and local config files
  +   The --whatever=value option can be supplied in config files with
  +   the "whatever = value" statement.  Initialization searches
  +   "$HOME/.app/$prog.conf", "$HOME/.app/app.conf",
  +   "$progdir/$prog.conf", "$progdir/app.conf",
  +   "$prefix/$prog.conf", and "$prefix/app.conf" in order
  +   to find the option values.
  + o Import other files with "import = filename" statement
  +   Config files can, in essence, include other config files.
  + o Stop importing other files with "flush_imports = 1" statement
  +   A config file can use this statement to tell the program
  +   to stop searching for other config files it was planning
  +   on searching.
  + o Option values undergo variable expansion
  +   This means that some values may rely on other values.
  +   i.e. "prefix = /usr/mycompany/3.2.1" and "logdir = ${prefix}/log"
  + o Config files can have conditional sections
  +   A section specifier "[cleanup]" begins a section only valid
  +   for the program "cleanup" (or "cleanup.exe" or cleanup.pl, etc.).
  +   A section specifier "[ALL]" (or just "[]") begins another
  +   unconditional section.  In fact, "[cleanup]" is just a synonym
  +   for "[app=cleanup]".  Sections can be made conditional on the
  +   current values of any variables. i.e. "[country=US;city=LAX]"
  +   would begin a section of variables only valid if the two
  +   specified variables have the required values.
  + o Config files can have conditional lines
  +   Any section specifier can apply only to a single line by
  +   putting a statement after it. "[city=LAX] state = CA"
  + o Modify @INC variable with the "perlinc = path1,path2" statement
  +   If invoked in the BEGIN block, this allows the person deploying
  +   the software to set up the Perl include path so that a
  +   particular version of the software installed on the system is
  +   used.  Subsequent uses of "use" and "require" will load modules
  +   from the configured locations.
  + o Validate that "required" options are provided
  +   Certain options can be identified as required. Otherwise the
  +   program will not run.
  + o Validate option values against types
  +   Certain options can be identified as to their type or pattern
  +   (integer, int, float, number, date, datetime, string, regexp).
  +   If the option value is provided and it does not match the
  +   type or pattern, the program will not run.
    o Provide automatic "-?" and "--help" messages
  +   Adds user-friendliness to programs with no extra effort.
   
  -It is useful on its own for any perl programs which require flexible
  -and easy option processing, and it has no dependencies other than
  -on "Cwd", a module included with Perl itself.  However, it was
  -specifically designed in order to support the P5EE/App-Context
  -variant of the Perl 5 Enterprise Environment.
  +3. What were the design goals that make this distribution unique?
   
  -For more information on the P5EE project, see the web pages at
  + #1 Support multiple installations of a complex suite of software.
  +    This is useful for development and deployment of large systems,
  +    where multiple versions may be in varying states of development,
  +    testing, or production.
   
  -   http://www.officevision.com/pub/p5ee
  + #2 Support a suite of programs all using a common set of configuration
  +    files.  Large systems have many programs.  We don't want to 
  +    repeat the database name, username, and password in a separate
  +    config file for each program.
   
  -and/or join the mailing list at
  + #3 Make it so easy to use that a developer would be silly not to
  +    use it in even his smallest and simplest of scripts.  However,
  +    it should be powerful enough to support advanced features as
  +    the developer needs them.
   
  -   [EMAIL PROTECTED]
  + #4 Support conditions where the environment variables are not
  +    easy to control. i.e. CGI programs or cron jobs.
   
  -The mailing list is described at
  +These were important design goals to support the App-Context variant
  +of the Perl 5 Enterprise Environment (P5EE).  See the P5EE website
  +(http://www.officevision.com/pub/p5ee) for more details.
   
  -   http://p5ee.perl.org/mailinglist/
  -   http://lists.perl.org/showlist.cgi?name=p5ee
  +4. Why another module? Why not use Getopt::Long or others?
   
  -HOW DO I INSTALL IT?
  +There are many configuration modules on CPAN.  See
  +
  + http://search.cpan.org/modlist/Option_Parameter_Config_Processing
  +
  +The most important feature was to be able to run it within a
  +BEGIN block to modify the Perl include path (@INC).  This is
  +most of design goal #1.  This means very few dependencies and
  +only on core modules.
  +
  +I started by writing a few lines of code in a BEGIN block.
  +Then it got to be a lot of lines of code in a BEGIN block.
  +Then I moved it out to a module so I could reuse it easily.
  +Then it grew into a full-fledged command line, environment
  +variable, and config file value option processor.
  +
  +In retrospect, I don't really know whether or not the other
  +modules can run just as well in a BEGIN block and have a special
  +feature to modify @INC.  However, this met a primary design
  +goal of App::Options.
  +
  +I did try Getopt::Long, but it wasn't that easy to use, you had
  +to code your own "--help" feature, and it didn't incorporate
  +environment variables or config files.  I wanted something
  +more high-level and full-featured, so I wrote App::Options.
  +
  +I looked at the description of the AppConfig distribution,
  +and it sounds similar to what I describe here.  However,
  +the meaning of "sections" (i.e. "[cleanup]") is a conditional
  +construct in App::Options.  Thus, it supports a single
  +family of configuration files to configure a whole suite
  +of programs and scripts. (Each program can have its own
  +section, and optionally its own file in both "user" and
  +"system" places.)  This met design goal #2.
  +
  +See the section below on ease of use for design goal #3.
  +
  +Design goal #4 required the autodetection of the ${prefix}
  +variable.  Thus, the App::Options module is integrated with
  +the discipline of choosing a root directory for your
  +software installation (i.e. PREFIX=/usr/mycompany/2.0.12).
  +
  +5. You say it's so easy. Show me.
  +
  +  #!/usr/bin/perl
  +
  +  BEGIN {
  +      use App::Options;
  +      App::Options->init();
  +  }
  +
  +  # now use the %App::options hash
  +  print "yada yada\n" if ($App::options{verbose});
  +
  +It's that easy.
  +
  +And it automatically has "-?" and "--help" support without
  +you having to code a thing.
  +
  +Read the man page (or the code) if you want more power.
  +
  +6. How do I install it?
   
   To install this module, cd to the directory that contains this README
  -file and type the following:
  +file and type the following (as usual).
   
      perl Makefile.PL
      make
  
  
  
  1.2       +4 -3      p5ee/App-Options/TODO
  
  Index: TODO
  ===================================================================
  RCS file: /cvs/public/p5ee/App-Options/TODO,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- TODO      16 Nov 2003 21:21:22 -0000      1.1
  +++ TODO      7 Jan 2004 15:24:07 -0000       1.2
  @@ -1,10 +1,11 @@
   ######################################################################
  -## File: $Id: TODO,v 1.1 2003/11/16 21:21:22 spadkins Exp $
  +## File: $Id: TODO,v 1.2 2004/01/07 15:24:07 spadkins Exp $
   ######################################################################
    o quoting, var = " hello world "
  - o here documents, var = <<EOF
    o check list of configurable environment vars instead of "APP_${uc_var}"
  + o write "prefix.pod"
  + o figure out a way to do it outside the BEGIN block (i.e. use App::Options 
qw(:init))
  + o here documents, var = <<EOF
    o try use lib "dir"; instead of unshift(@INC,"dir")
  - o reconsider "perlinc", perhaps use "perl5lib" instead
    o consider checking the PERL5LIB variable under -T
   
  
  
  
  1.2       +54 -14    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.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- Options.pm        11 Dec 2003 12:55:04 -0000      1.1
  +++ Options.pm        7 Jan 2004 15:24:07 -0000       1.2
  @@ -1,6 +1,6 @@
   
   #############################################################################
  -## $Id: Options.pm,v 1.1 2003/12/11 12:55:04 spadkins Exp $
  +## $Id: Options.pm,v 1.2 2004/01/07 15:24:07 spadkins Exp $
   #############################################################################
   
   package App::Options;
  @@ -43,7 +43,7 @@
                   app_path_info => {default=>"",type=>"string"}, # as a hashref
                   prefix        => "type=string;required",
                   perlinc       => undef,         # no default
  -                debug_options     => "type=int",
  +                debug_options => "type=integer",
                   import        => "type=string",
                   flush_imports => 1,
               },
  @@ -143,9 +143,35 @@
   to modify the @INC array so that normal "use" and "require"
   statements will work with the configured @INC path.
   
  +The various named parameters of the init() method are as follows.
  +
  +    values - specify a hash reference other than %App::options to
  +        put configuration values in.
  +    options - specify a limited, ordered list of options to be
  +        displayed when the "--help" or "-?" options are invoked
  +    option - specify optional additional information about any of
  +        the various options to the program (see below)
  +    no_cmd_args - do not process command line arguments
  +    no_env_vars - do not read environment variables
  +    no_option_file - do not read in the option file
  +    print_usage - provide an alternate print_usage() function
  +
  +The additional information that can be specified about any individual
  +option variable is as follows.
  +
  +    default - the default variable if none supplied on the command
  +        line, in an environment variable, or in an option file
  +    required - the program will not run unless a value is provided
  +        for this option
  +    type - if a value is provided, the program will not run unless
  +        the value matches the type ("string", "integer", "float",
  +        "boolean", "date", "time", "datetime", regexp).
  +    description - printed next to the option in the "usage" page
  +
   The init() method stores command line options and option
  -file values all in the global %App::options hash.
  -The special keys to this hash are as follows.
  +file values all in the global %App::options hash (unless the
  +"values" argument specifies another reference to a hash to use).
  +The special keys to this resulting hash are as follows.
   
       option_file - specifies the exact file name of the option file useful
          for command line usage (i.e. "app --option_file=/path/to/app.conf")
  @@ -175,12 +201,14 @@
   
       perlinc - a path of directories to prepend to the @INC search path.
          This list of directories is separated by any combination of
  -       [,;: ] characters. (Hmmm. Windows drive specifiers could be hurt
  -       by this approach.)
  +       [,; ] characters.
   
  -    debug_options
  +    debug_options - if this is set, a variety of debug information is
  +       printed out during the option processing.  This helps in debugging
  +       which option files are being used and what the resulting variable
  +       values are.
   
  -    import
  +    import - a list of additional option files to be processed
   
   =cut
   
  @@ -469,7 +497,7 @@
       #################################################################
   
       if (defined $values->{perlinc}) {    # add perlinc entries
  -        unshift(@INC, split(/[,:; ]+/,$values->{perlinc}));
  +        unshift(@INC, split(/[,; ]+/,$values->{perlinc}));
       }
       else {
           my $libdir = "$prefix/lib";
  @@ -534,6 +562,15 @@
                       print "Error: \"$var\" must be of type \"$type\" (not 
\"$value\")\n";
                   }
               }
  +            elsif ($type eq "string") {
  +                # anything is OK
  +            }
  +            elsif ($type eq "boolean") {
  +                if ($value !~ /^[01]$/) {
  +                    $exit_status = 1;
  +                    print "Error: \"$var\" must be of type \"$type\" (\"0\" or 
\"1\") (not \"$value\")\n";
  +                }
  +            }
               elsif ($type eq "date") {
                   if ($value !~ /^[0-9]{4}-[01][0-9]-[0-3][0-9]$/) {
                       $exit_status = 1;
  @@ -593,15 +630,18 @@
           @vars = (sort keys %$values);
       }
       my ($var, $value, $type, $desc, $option);
  +    my ($var_str, $value_str, $type_str, $desc_str);
       $option = $init_options->{option} || {};
       foreach $var (@vars) {
           next if ($var eq "?" || $var eq "help");
           $value = $values->{$var};
           $type  = $option->{$var}{type} || "";
  -        $desc  = $option->{$var}{desc} || "";
  -        $type  = " ($type)" if ($type);
  -        $desc  = " $desc" if ($desc);
  -        printf STDERR "       --%-32s [%s]$type$desc\n", "$var=<$var>", (defined 
$value) ? $value : "undef";
  +        $desc  = $option->{$var}{description} || "";
  +        $var_str   = ($type eq "boolean") ? $var : ($type ? "$var=<$type>" : 
"$var=<$var>");
  +        $value_str = (defined $value) ? $value : "undef";
  +        $type_str  = ($type) ? " ($type)" : "";
  +        $desc_str  = ($desc) ? " $desc"   : "";
  +        printf STDERR "       --%-32s [%s]$type_str$desc_str\n", $var_str, 
$value_str;
       }
   }
   
  
  
  

Reply via email to