1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
# Movable Type (r) Open Source (C) 2001-2012 Six Apart, Ltd.
# This program is distributed under the terms of the
# GNU General Public License, version 2.
#
# $Id$
package MT::Tool;
use strict;
use warnings;
use charnames qw( :full );
use Carp qw( croak );
use English qw( -no_match_vars );
use Getopt::Long;
sub show_help {
my $class = shift;
my $help = $class->help();
# TODO: strip spaces more smartly for people who may format
# their help() methods differently.
$help =~ s/ ^ [\N{SPACE}]{4} //xmsg;
print $help;
}
sub show_usage {
my $class = shift;
print qq{usage: $PROGRAM_NAME },
join( qq{\n $PROGRAM_NAME }, $class->usage() ),
qq{\n};
}
sub usage;
sub help;
sub options { }
sub set_up_app {
# TODO: a Tool should probably be its own App, so we can use *all*
# the MT::App infrastructure. For now fake it like rpt does.
require MT;
my $mt = MT->new() or die MT->errstr;
$mt->{vtbl} = {};
$mt->{is_admin} = 0;
$mt->{template_dir} = 'cms';
$mt->{user_class} = 'MT::Author';
$mt->{plugin_template_path} = 'tmpl';
$mt->run_callbacks( 'init_app', $mt );
return $mt;
}
sub main {
my $class = shift;
$class->set_up_app();
my $verbose;
my $opts_good = GetOptions(
'help!' => sub { $class->show_usage(); $class->show_help(); exit; },
'usage!' => sub { $class->show_usage(); exit; },
'verbose|v+' => \$verbose,
$class->options(),
);
$class->show_usage(), exit if !$opts_good;
return $verbose;
}
1;
__END__
=head1 NAME
MT::Tool - shared infrastructure for command line tools
=head1 SYNOPSIS
package Foobar::Tool::MakeQuuxen
use strict;
use lib qw( extlib lib );
use base qw( MT::Tool );
sub help {
q{
--special Make extra special quuxen.
};
}
sub usage { '[--special]' }
my ($special);
sub options {
return (
'special!' => \$special,
);
}
sub main {
my $class = shift;
($verbose) = $class->SUPER::main(@_);
## Make those quuxen!
...
}
__PACKAGE__->main() unless caller;
1;
=head1 DESCRIPTION
I<MT::Tool> provides shared infrastructure around command line tools for MT
applications. With these, you can provide a standard interface for your tools
similar to MT's other command line applications.
=head1 USAGE
=head2 use base qw( MT::Tool )
Declares the current package is a new tool conforming to the MT::Tool
interface. The following class methods should be defined as appropriate for
your tool.
=head2 $class-E<gt>help()
Return the text to use for your tool's C<--help> command.
=head2 $class-E<gt>usage()
Return the option text to use for your tool's C<--usage> command. The text is
also used for the C<--help> synopsis and when invalid options are used.
=head2 $class-E<gt>options()
Return the definition of your tool's additional options, as a hash suitable to
pass to Getopt::Long's C<GetOptions()>. The most common definitions for
Getopt::Long options are:
=over 4
=item * C<I<option>!>
Your option is a flag users can specify up to once. A bound variable will be
set when the flag is found.
The contrary option C<--noI<option>> will be automatically provided. It will
clear the bound variable.
=item * C<I<option>+>
Your option is a flag users can specify more than once. A bound variable will
be B<incremented> when the flag is found.
=item * C<I<option>=s>
Your option takes a string argument. A bound scalar will be set to the argument
the user specifies when the option is found. If an arrayref is bound instead,
arguments will be added to the list when the option is given more than once.
=item * C<I<option>|I<o>>
Your option is availble both as the long form C<--I<option>> and the
abbreviated short form C<-I<o>>. Abbreviated forms can be combined with any of
the type declarations above.
=back
=head2 $class-E<gt>main()
Perform your tool's task. Your implementation should call MT::Tool's
implementation to parse your options and handle the standard options such as
C<--help>. MT::Tool's implementation will return the level of verbosity
requested by the user (that is, how many times the C<-v> option was used).
=head2 $tool-E<gt>set_up_app()
This helper method creates a MT instance and configures it to look like
a L<MT::App> instance (although, it isn't), and invokes the 'init_app'
callback using this instance.
=head2 $class-E<gt>show_help
Displays command-line help provided by the C<MT::Tool> subclass L<help>
method.
=head2 $class-E<gt>show_usage
Displays commnad-line usage instructions provided by the C<MT::Tool>
subclass L<usage> method.
=head1 SEE ALSO
Getopt::Long
=cut
|