Package cliutils
[hide private]
[frames] | no frames]

Source Code for Package cliutils

  1  r""" 
  2  A collection of utilities easing the creation of command line scripts. 
  3   
  4  cliutils is pure Python with no dependencies. 
  5   
  6  At the moment, the module provides three disparate features: Process objects, a 
  7  command-line argument parsing decorator, and a logging decorator factory. 
  8   
  9  Process objects 
 10  =============== 
 11      Although it isn't very difficult to execute shell commands from a Python 
 12      script, there are several lines of overhead in the standard pattern. 
 13      Process objects reduce the entire pattern to a single line. In addition, 
 14      they are more flexible; they may be piped into each other, just as regular 
 15      processes may be on the bash command line. 
 16   
 17          >>> Process("echo 'spam and eggs'") 
 18          spam and eggs 
 19          >>> s = Process("echo 'spam and eggs'").stdout 
 20          >>> s 
 21          'spam and eggs' 
 22          >>> p = Process("echo 'spam and eggs'") | Process("wc -w") 
 23          >>> p.stdout 
 24          '3' 
 25   
 26      For convenience, a singleton object (L{sh}) is provided that is able to 
 27      create process objects from given attributes. 
 28   
 29          >>> sh.echo("spam and eggs") | sh.wc("-w") | sh.cat() 
 30          3 
 31   
 32      Arguments passed to Process objects are split using the C{shlex} module, so 
 33      most simple strings will work just fine. More complex arguments should be 
 34      passed in as lists: 
 35   
 36          >>> sh.echo(["spam", "and", "eggs"]) 
 37          spam and eggs 
 38   
 39  The L{cliargs} decorator 
 40  ======================== 
 41      A common pattern for shell scripts is:: 
 42           
 43          def main(): 
 44              parser = make_an_option_parser() 
 45              parser.parse(sys.argv[1:]) 
 46              do_some_stuff_with_options() 
 47   
 48          if __name__=="__main__": 
 49              main() 
 50   
 51      Creation of shell scripts using C{setuptools}' C{entry_points} results in a 
 52      similar pattern; a function is called with no arguments, and must do its 
 53      own command-line argument parsing. This makes sense in some cases, where 
 54      complex argument parsing is required. In simple cases, however, where 
 55      parsing of a few arguments or keywords is required, the L{cliargs} 
 56      decorator will be of use. It does a simple parse of C{sys.argv}, using a 
 57      parsing algorithm based on some code in C{getopt}, and calls the decorated 
 58      function with the results:: 
 59   
 60          @cliargs 
 61          def myScript(anarg, anotherarg, someval="default") 
 62              "Usage: myscript anarg anotherarg [--someval VALUE]" 
 63              print anarg anotherarg someval 
 64   
 65      When that function is called as a result of a command line script, such 
 66      as:: 
 67           
 68          $ myscript val1 val2 --someflag somevalue  
 69   
 70      L{cliargs} will parse C{sys.argv} and pass the results into myScript. If 
 71      improper arguments are passed such that a C{TypeError} is raised, the 
 72      docstring of the function will be printed; this makes that an ideal place 
 73      to include a usage string. 
 74   
 75      L{cliargs} is of course limited to very simple cases. More complex argument 
 76      parsing will require the use of the C{getopt} or C{optparse} modules. 
 77   
 78  L{log_decorator} 
 79  ================ 
 80      L{log_decorator} is an almost trivially simple decorator factory. When 
 81      called with a file-like object, it returns a decorator that redirects 
 82      C{sys.stdout} to that file for the duration of the execution of the 
 83      decorated function. 
 84   
 85          >>> from StringIO import StringIO 
 86          >>> logfile = StringIO() 
 87          >>> logger = log_decorator(logfile) 
 88          >>> @logger 
 89          ... def func(): 
 90          ...     print "ABCDEFGHIJK" 
 91          ...  
 92          >>> func() 
 93          >>> logfile.seek(0) 
 94          >>> logfile.read().strip() 
 95          'ABCDEFGHIJK' 
 96   
 97  """ 
 98  __version__="0.1" 
 99  __all__=["sh", "Process", "cliargs", "log_decorator"] 
100   
101  from process import sh, Process 
102  from decorators import cliargs, log_decorator 
103