Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

CLI Args and Config Files: Best Practices?

by temporal (Pilgrim)
on Jan 31, 2013 at 22:02 UTC ( #1016403=perlquestion: print w/ replies, xml ) Need Help??
temporal has asked for the wisdom of the Perl Monks concerning the following question:

First off, sorry about the double post - just one of those days when I want The Wisdom.

I'm writing a little daemon that I'd like to take arguments from both CLI and a config file. Currently, CLI arguments override config file settings and that's that - I figure if the user specifically requests a value set in the command line they're serious about it.

However, now I'd like to refresh the configs each time the daemon runs, just in case something in the config file has changed. Now I run into a problem - should these changes overwrite CLI arguments originally provided? I'd rather they not. But I'd like to set any of those other configs that have may have changed.

So what has arisen organically is that I was using Getopt::Long to handle CLI arguments, then added config files later on using Config::Simple. Okay, that works. But I'd really like to bring all my argument/options handling under one process - easier to track and maintain, for sure. It's awfully ugly juggling configuration variables between the two parsing utilities.

Enter AppConfig. Yay, it parses config files - even recognizes inline comments (Config::Simple does not) and is more sophisticated in lots of other ways to boot. It also does CLI args, even providing the option of just using Getopt::Long. All in one module, stored in the same spot with lots of utility built in.

I think this module (AppConfig) is pretty popular for building scripts and such that have more complex configuration requirements. So here's a quick question (which hopefully won't start a war) - what do you use?

BOOOOM!... and while that war wages - on to my real question:
What would be the best practice within AppConfig for enforcing the case I described initially - that is, CLI args are loaded at script startup and preserved throughout execution despite reloading from the config file with each lifecycle of the daemon?

Okay, high time for a code example:

use strict; use AppConfig qw(:argcount); # my usual AppConfig initialization my $temp_conf = AppConfig->new( { CREATE => 1, GLOBAL => { ARGCOUNT => ARGCOUNT_ONE, DEFAULT => "<undef>",}, } ); # ->define() some default values and set any options for them in this +sub define_defaults(); # load in CLI args $temp_conf->args(); # parse conf file (path specified in CLI args, otherwise use default) $temp_conf->file( $temp_conf->config_file() );

So, hm. Now I've got my initial configuration. However, I'm not giving the CLI arguments precedence over config file settings. Problem being that I have to load them first to get the possible supplied config file path, which consumes the arguments. I suppose I could save the CLI args to an array and do something like this:

# save the CLI args my @CLI = @ARGV; # load in CLI args, gets those useful ones like path right off the bat $temp_conf->args(); # parse conf file (path specified in CLI args, otherwise use default) $temp_conf->file( $temp_conf->config_file() ); # reinforce those CLI args! $temp_conf->args(\@CLI);

Is there an AppConfig option for this or is this something I'll have to implement manually (like above)? Or maybe some enterprising monk has an entirely different approach?

Comment on CLI Args and Config Files: Best Practices?
Select or Download Code
Re: CLI Args and Config Files: Best Practices?
by perl514 (Pilgrim) on Feb 01, 2013 at 03:55 UTC

    Hi,

     

    Not sure if this will help, but you can try the Config::Tiny Module. From what I know, it has to read the config file everytime you start your perl script.

    Perlpetually Indebted To PerlMonks

    use Learning::Perl; use Beginning::Perl::Ovid; print "Awesome Books";
    Finally a proud owner of a Thinkpad T430!!

Re: CLI Args and Config Files: Best Practices? (documented)
by Anonymous Monk on Feb 01, 2013 at 09:24 UTC

    What would be the best practice within AppConfig for enforcing the case I described initially - that is, CLI args are loaded at script startup and preserved throughout execution despite reloading from the config file with each lifecycle of the daemon?

    I imagine do whatever makes sense to you, and document it

    Take a look at the defaults of Daemon::Generic, you could (in your subclass) inject a --preserveargv or --discardargv option ...

    Document whatever you choose, documentation is key

Re: CLI Args and Config Files: Best Practices?
by temporal (Pilgrim) on Feb 01, 2013 at 10:21 UTC

    Thanks for the reply perl514. Config::Tiny is fine for half of my problem. I was already using Config::Simple, which is about the same sort of thing just a little more feature-rich. I really wanted to bring all my argument handling under one roof - which AppConfig does really well

    Anonymous Monk - yup, I just went ahead and did the AppConfig swicheroo specced out in my OP which works just fine for now, scribbled down a note about it just in case I need to change things. Excellent documentation! =)

    It's also worth noting that most daemon(izer|ing|esque) modules don't play nice on Windows (as in, do not have ported incarnations compiled and waiting in the Perl Package Manager). Of course you had no way of knowing that I am shackled to a Windows machine. Oh, how I miss the days in sunny Linux pastures; frolicking with the tame, OS-supported fork implementations.

    So to summarize my current solution: before initializing AppConfig I save @ARGV to more permanent place and just reparse all those arguments immediately after refreshing from the config file. This way I get to keep my CLI args just like I want but I can change other arguments 'on the fly' through the config file.

    Now I'll just have to dream up a way to override that behavior, if necessary...

    Strange things are afoot at the Circle-K.

Re: CLI Args and Config Files: Best Practices?
by perl514 (Pilgrim) on Feb 01, 2013 at 13:02 UTC

    Hi,

     

    I noticed you have mentioned PPM in your reply. If by any chance you are on Activestate Perl, I would urge you to try DWIM Perl. Please see my signature for the link. Its got loads of modules pre installed. Its based on Strawberry Perl. And both these come with Windows Compatible version of GCC/gmake/dmake pre installed. I have manually installed a module and it all worked fine. Hope this piece of info helps you

    Perlpetually Indebted To PerlMonks

    use Learning::Perl; use Beginning::Perl::Ovid; print "Awesome Books";
    http://dwimperl.com/windows.html is a boon for Windows.

      Absolutely, I agree; I prefer Strawberry Perl as well. It's my Windows flavor of choice for personal use. Unfortunately, I'm stuck with ActiveState in my work environment. Oh well!

      Strange things are afoot at the Circle-K.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1016403]
Approved by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (11)
As of 2014-08-28 11:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (259 votes), past polls