=pod

=head1 NAME

LEOCHARRE::CLI2 - Some quick help for writing cli scripts.

=head1 SYNOPSIS

In script.pl:

   use LEOCHARRE::CLI2 
      'ko:', # options
      ':all', # subs to import
      'This program shows example usage.', # description of what script does
      '(manpage suggested)', # where to look for more info in man pages
      '[parent package name], # parent package name
      'argv_cwd', # explicit sub import name
      ;
   
   our $VERSION = 1;
   
   $opt_o or die("Missing -o opt");
   
   my @files_selected = argv_files();
   
   my @base_dir_selected = argv_cwd();
   
   my @all_dirs_selected = argv_dirs();
   
   my ($countfiles, $countdirs) = ( argv_dirs_count(), argv_files_count() );
   
   debug("You chose $countfiles files and $countdirs dirs.");

Then to get help:
   $ script.pl -h

To get version:
   $ script.pl -v

To see debug:
   $ script.pl -d -o "my value" ./files* ./dirs*

=head1 DESCRIPTION

Some quick help for writing cli scripts.
Forces by default that -h triggers help, that -d triggers debug, and -v version..
Automates help, debug, version etc.
If you use LEOCHARRE::CLI2, we alter the OPTIONS automatically.
Also we automatically generate HELP.

=head1 Environment Variables

New environment variables are set. They are..

=head2 $ENV{SCRIPT_FILENAME}

Holds name of your script, no leading path.
Is accessible to main.

=head1 SCRIPT_DESCRIPTION

If you define this, and you don't define usage(), the usage help output generated will 
contain this string.

   use LEOCHARRE::CLI2 'This is a script description because it has spaces.';

When -h is called, if there is not usage() defined, this would spit out:

   /bin/file [OPTION]..
   This is a script description because it has spaces.
   
      -d    debug
      -h    help
      -v    version

=head1 SCRIPT PARENT PACKAGE

   use LEOCHARRE::CLI2 '[MyPkg]';

=head1 SCRIPT MAN PAGE

   use LEOCHARRE::CLI2 '(manpagename)';

=head1 Argument Variables

For path arguments on disk specified via @ARGV.

You can optionally use these to see any files, dirs, etc that a user defined in the cli.
These must all be paths that resolve to disk.
They all return abs path.


Files and dirs, holds absolute paths on disk.
Count holds number, 0 if none.

To make these accessible, import.

   use LEOCHARRE::CLI2 ':argv'; # for all
   use LEOCHARRE::CLI2  qw/argv_files argv_files_count argv_dirs argv_dirs_count argv_cwd/; # same

Usage: script ./pathtodir ./path2dir2 ./path2file.txt
Then in our script:

   my @dirs = argv_dirs(); # holds abs path to dirs
   my $dirs_count = argv_dirs_count();
   
   argv_files_count() 
      or die("you forgot to specidy files on disk.");

Note that this alters @ARGV.

If you wish to import these.. Either use export tag ':all' or ':argv'.

=head2 argv_cwd()

Sometimes you want a destination dir to do something to.
You want the option for the user to say;
   script ./path_to/

But if none is provided, you want to assume './'.
   my $base_dir = argv_cwd();

=head2 argv_files()

Returns array of files abs paths. Undef if none.

=head2 argv_files_count()

Returns count of files, 0 if none.

=head2 argv_dirs()

Returns array of dirs abs paths. Undef if none.

=head2 argv_dirs_count()

Returns count of dirs abs paths, 0 if none.

=head2 argv_cwd()

Returns dirs chosen by user, or './' abs path.

=pod


=head2 MODULES LOADED AND AVAILABLE

YAML, Carp, Cwd


=head2 abs_path(), cwd()

Available and exported if you choose :all

=head2 slurp()

Arg is file on disk.
If not there, warns and returns undef.
If can't do it, warns and returns undef.
Returns content.
If no content, warns and returns whatever was inside.

   my $txt = slurp('./this.txt') or die;

In scalar context returns all text.
In array context returns all lines, as list.

=head2 burp()

Arg is path on disk, and content. Dumps to path.
Warns and returns undef on failure.

   burp('./this.out','content') or die;


=head2 yn()

Argument is what to ask the user, they select y or n.
Returns bool.
Prompts user.

   if (yn('please say y to continue..')){
      warn " # continuing.. \n";
   }

=head2 sq()

Argument is thing to quote for shell use.
Shortcut to String::ShellQuote::shell_quote().

   my $weird = '/home/myself/path to funny*named, file';
   my $quoted = sq($weird);
   my $quoted = sq $weird;


=head1 OPTIONS

This uses Getopt::Std, it works very similar to Getopt::Std::Strict.
By default unless it is already there, -d -h and -v flags are set to trigger

   -h will trigger help, if no usage() sub is defined, one is generated.
   -d will enable debug
   -v will print version and exit


=head1 HELP

If you want to write your own help, define a usage() sub.
If you don't defined one, and the user says -h, a help is automatically generated.
It will contain all your flags, name of script, etc.

In this example, we generate our own help, and a manual.
Usage simply returns a string.

   use LEOCHARRE::CLI2;
   
   sub usage {
      q{script [OPTION]...
      -h    help
      -d    debug
      -v    version
      
      Try 'man script' for more info.
      }
   }
   
   __END__
   
   =pod
   
   =head1 NAME
   
   script
   
   =head1 DESCRIPTION
   
   Hi.. I do x y z.

All cli should have a minimal help that triggers when the user says -h.
If you define a SCRIPT_DESCRIPTION, it will be placed in the usage generated.

=head1 CAVEATS

Alpha software.

=head1 SEE ALSO

L<Getopt::Std::Strict>
L<String::ShellQuote>
L<YAML>
:<Carp>
L<Cwd>

=head1 AUTHOR

Leo Charre leocharre at cpan dot org

=head1 LICENSE

This package is free software; you can redistribute it and/or modify it under the same terms as Perl itself, i.e., under the terms of the "Artistic License" or the "GNU General Public License".

=head1 DISCLAIMER

This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the "GNU General Public License" for more details.

=cut

