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