Qc @sdZddkZddkZddkZddkZddklZddkZei Z de fdYZ da hahadZddZdZd Zd Zd Zd Zd ZdefdYZdefdYZddZdZdZdddZdefdYZdZ dZ!ddddde"dZ#dZ$dZ%dZ&dZ'ed eddddd!Z(e)d"jo e'ndS(#stThis module is the base for programs that provide multiple commands. This provides command line tools that have a few shared global flags, followed by a command name, followed by command specific flags, then by arguments. That is: tool [--global_flags] command [--command_flags] [args] The module is built on top of app.py and 'overrides' a bit of it. However the interface is mostly the same. The main difference is that your main is supposed to register commands and return without further execution of the commands; pre checking is of course welcome! Also your global initialization should call appcommands.Run() rather than app.run(). To register commands use AddCmd() or AddCmdFunc(). AddCmd() is used for commands that derive from class Cmd and the AddCmdFunc() is used to wrap simple functions. This module itself registers the command 'help' that allows users to retrieve help for all or specific commands. Example: from mx import DateTime class CmdDate(appcommands.Cmd): """This docstring contains the help for the date command.""" def Run(self, argv): print DateTime.now() def main(argv): appcommands.AddCmd('date', CmdDate, command_aliases=['data_now']) if __name__ == '__main__': appcommands.Run() In the above example the name of the registered command on the command line is 'date'. Thus, to get the date you would execute: tool date The above example also added the command alias 'data_now' which allows to replace 'tool date' with 'tool data_now'. To get a list of available commands run: tool help For help with a specific command, you would execute: tool help date For help on flags run one of the following: tool --help Note that 'tool --help' gives you information on global flags, just like for applications that do not use appcommand. Likewise 'tool --helpshort' and the other help-flags from app.py are also available. The above example also demonstrates that you only have to call appcommands.Run() and register your commands in main() to initialize your program with appcommands (and app). Handling of flags: Flags can be registered just as with any other google tool using flags.py. In addition you can also provide command specific flags. To do so simply add flags registering code into the __init__ function of your Cmd classes passing parameter flag_values to any flags registering calls. These flags will get copied to the global flag list, so that once the command is detected they behave just like any other flag. That means these flags won't be available for other commands. Note that it is possible to register flags with more than one command. Getting help: This module activates formatting and wrapping to help output. That is the main difference to help created from app.py. So just as with app.py, appcommands.py will create help from the main modules main __doc__. But it adds the new 'help' command that allows you to get a list of all available commands. Each command's help will be followed by the registered command specific flags along with their defaults and help. After help for all commands there will also be a list of all registered global flags with their defaults and help. The text for the command's help can best be supplied by overwriting the __doc__ property of the Cmd classes for commands registered with AddCmd() or the __doc__ property of command functions registered AddCmdFunc(). Inner working: This module interacts with app.py by replacing its inner start dispatcher. The replacement version basically does the same, registering help flags, checking whether help flags were present, and calling the main module's main function. However unlike app.py, this module epxpects main() to only register commands and then to return. After having all commands registered appcommands.py will then parse the remaining arguments for any registered command. If one is found it will get executed. Otherwise a short usage info will be displayed. Each provided command must be an instance of Cmd. If commands get registered from global functions using AddCmdFunc() then the helper class _FunctionalCmd will be used in the registering process. iN(tapptAppCommandsErrorcBseZdZRS(s$The base class for all flags errors.(t__name__t __module__t__doc__(((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pyRscCstiitidS(s2Returns the friendly basename of this application.i(tostpathtbasenametsystargv(((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pytGetAppBasenamescCsZtii|dj otiid|ntiidttiddS(sDisplay optional message, followed by a note on how to get help, then exit. Args: message: optional message to display s%s sRun '%s help' to get help iN(RtstdouttflushtNonetstderrtwriteR texit(tmessage((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pytShortHelpAndExits   cCstS(s#Return list of registered commands.(t _cmd_list(((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pytGetCommandListscCstS(s*Return list of registered command aliases.(t_cmd_alias_list(((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pytGetCommandAliasListscCsFtt}x0tiD]\}}|i|||] To retrieve help with global flags: %(prog)s --help To retrieve help with flags only from the main module: %(prog)s --helpshort [] tprog(R RMRN(R,RORPtcmd_help((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pyRQsN(RRRR0R RQ(((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pyRhs cCs dtS(sQGet synopsis for program. Returns: Synopsis including program basename. s6%s [--global_flags] [--command_flags] [args](R (((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pyt GetSynopsis$scCsg}| pt|djo|idtn| pt|ttjo|idtn|dj o-|o|idn|id|ndi|S(s$Output a footer at the end of usage or help output. Args: detailed_error: additional detail about why usage info was presented. cmd_names: list of command names for which help was shown or None. Returns: Generated footer that contains 'Run..' messages if appropriate. is4Run '%s help' to see the list of available commands.s2Run '%s help ' to get help for .ts%ss N(R#tappendR RR tjoin(R8RPtfooter((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pyt _UsageFooter.s  $  icCs8|o ti}n ti}ditd}tidi}|oRti|i dti d} |i ti | ti |i dn| p|iddjoCdt} |i ti | ti d d|i dnttd jo g} n|djp |d johti} | i|i d d i| }|i ti |ti d|i dn|dj o |g} n?tiptip|o g} nti} | ix| D]} t| } | itd| }|i}d i| g| ipg}t|d t|jp| o6|i ti |ti |i d|}n|itd}|o6|i ti |ti |||i dn|i dt| d jo\| i}|i oB|i d|| f|i |i!|d|i dqqqW|i d|oO|i d|o|i ti"n|i ti!|i dn|i dt#|i dt$|| |dj oti%|ndS(s$Output usage or help information. Extracts the __doc__ string from the __main__ module and writes it to stderr. If that string contains a '%s' then that is replaced by the command pathname. Otherwise a default usage string is being generated. The output varies depending on the following: - FLAGS.help - FLAGS.helpshort - show_cmd - show_global_flags Args: shorthelp: print only command and main module flags, rather than all. writeto_stdout: write help message to stdout, rather than to stderr. detailed_error: additional details about why usage info was presented. exitcode: if set, exit with this status code after writing help. show_cmd: show help for this command only (name of command). show_global_flags: show help for global flags. Rmit__main__s%sis isUSAGE: s ithelpsAny of the following commands: s, s RPs s s%sFlags for %s: sGlobal flags: s-Run '%s --help' to get help for global flags.s %s N(&RR RtrjustR%tmodulesRRMRNtreplaceR RtTextWrapt GetHelpWidthtfindRlR#RR tkeystsortRoR:Rst helpshortRRQR!tstripRRtljustR)tRegisteredFlagstGetHelptMainModuleHelpR RqR(R6R7R8R1R2R3tstdfiletprefixtdocthelp_msgtsynopsisRPRtcommandRkt all_namestprefix1t cmd_flags((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pyR4Es~  "     "      #%           cCsAyt|atSWn&tij o}td|nXdS(sParse the flags, exiting (after printing usage) if they are unparseable. Args: argv: command line arguments Returns: remaining command line arguments after parsing flags sFATAL Flags parsing error: %sN(R:R RMt FlagsErrorR(R RI((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pyR=s  cCswttattdjo|otdndSttd}|djotdtdntd=|S(spGet the command or return None (or issue an error) if there is none. Args: command_required: whether to issue an error if no command is present Returns: command or None, if command_required is True then return value is a valid command or the program will exit. The program also exits if a command was specified but that command does not exist. is%FATAL Command expected but none givenisFATAL Command '%s' unknownN(R=R R#RR R(tcommand_requiredR((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pyt GetCommands  cCstiytiditWnQtj o}ti|in.t j o!}t i t d|nXt tdjotdt}n td}ti|itdS(sMain initialization. This initializes flag values, and calls __main__.main(). Only non-flag arguments are passed to main(). The return value of main() is used as the exit status. Rrs FATAL error in main: %siRRsN(RtRegisterAndParseFlagsWithUsageRRutmainR!t SystemExitRtcodet Exceptiont tracebackt print_excRR#RR5RRK(teRIR((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pyt_CommandsStarts   cCs%tt_tt_tt_tiS(sThis must be called from __main__ modules main, instead of app.run(). app.run will base its actions on its stacktrace. Returns: app.run() (R=Rtparse_flags_with_usageRt really_startt_ReplacementAppUsageR<trun(((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pyR0s   Rsc Cs&t|||d|dddtdS(NR1R2R3(R4R R5(R6R7R8R1((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pyRsRr(*RRR?RRtgoogle.apputilsRtgflagsRMR:RRR R RRR RRRRRR!R%tobjectR&RSR]RZRfRgRhRlRqRiR4R=RRR0RR(((sc/Users/riccardo/git/gcloud/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.pytssP            >    2  i