/stdhome

To get this branch, use:
bzr branch http://bzr.ed.am/stdhome

« back to all changes in this revision

Viewing changes to lib/stdhome/stdhome.py

  • Committer: Tim Marston
  • Date: 2013-12-08 19:28:11 UTC
  • Revision ID: tim@ed.am-20131208192811-r20qj7cgmn4duw11
initial commit; basic app startup and initial command-line processing

Show diffs side-by-side

added added

removed removed

1
 
# program.py
 
1
# stdhome.py
2
2
#
3
3
# Copyright (C) 2013 Tim Marston <tim@edm.am>
4
4
#
19
19
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
20
 
21
21
 
22
 
import os, sys, getopt
23
 
import the
24
 
 
25
 
 
26
 
class Program:
 
22
import sys, os
 
23
import getopt
 
24
 
 
25
 
 
26
class Stdhome:
27
27
 
28
28
 
29
29
        def __init__( self, version ):
30
 
                self.name = os.path.basename( sys.argv[ 0 ] )
31
30
                self.version = version
32
 
 
33
 
 
34
 
        def die( self, error_message ):
35
 
                prefix = self.name + ( ' ' + the.command if the.command else '' )
36
 
                print >> sys.stderr, '%s: %s' % ( prefix, error_message )
 
31
                self.program = os.path.basename( sys.argv[ 0 ] )
 
32
 
 
33
 
 
34
        def print_usage( self, error_message ):
 
35
                print >> sys.stderr, self.program + ": " + error_message
 
36
                print >> sys.stderr, "Try '" + self.program + " --help' for more information."
37
37
                exit( 1 )
38
38
 
39
39
 
40
 
        def print_usage( self, error_message ):
41
 
                suffix = ' ' + the.command if the.command else ''
42
 
                self.die( error_message + \
43
 
                                  "\nTry '%s%s --help' for more information." % \
44
 
                                  ( self.name, suffix ) )
45
 
 
46
 
 
47
40
        def print_help( self ):
48
 
                print "Usage: " + self.name + " COMMAND [OPTION]..."
 
41
                print "Usage: " + self.program + " COMMAND [OPTION]..."
49
42
                print
50
43
                #      01234567890123456789012345678901234567890123456789012345678901234567890123456789
51
44
                print "Manage your home directories, across multiple computers, similar to how you"
70
63
                print
71
64
                print "For help about a particular command (including the additional options that the"
72
65
                print "command accepts) try typing:"
73
 
                print "  $ " + self.name + " COMMAND --help"
 
66
                print "  $ " + self.program + " COMMAND --help"
74
67
                exit( 0 )
75
68
 
76
69
 
104
97
                         'stage-commit' ].count( command ) == 1:
105
98
                        return command
106
99
 
107
 
                # resolve aliases
 
100
                # aliases
108
101
                elif command == 'up':
109
102
                        return 'update'
110
103
                elif command == 'rm':
130
123
                        args = args[ 1 : ]
131
124
                return None
132
125
 
133
 
 
134
126
        def run( self ):
135
127
                # make an initial attempt to parse the command line, looking only for
136
128
                # --help and --version, so that they have the chance to run without a
140
132
                                sys.argv[ 1: ], "",
141
133
                                [ "help", "version" ] )
142
134
 
143
 
                        for opt, optarg in opts:
 
135
                        for opt, optargs in opts:
144
136
                                # we only show help if there are no non-option arguments (e.g.,
145
137
                                # a command) specified.  If a command has been specified it will
146
138
                                # have to be parsed and --help will be handled by it, instead)
150
142
                                        self.print_version()
151
143
 
152
144
                except getopt.GetoptError as e:
153
 
                        # ignore errors -- we aren't parsing the command line properly yet
 
145
                        # ignore any errors -- we aren't parsing the command line properly
154
146
                        pass
155
147
 
156
148
                # find the first non-option argument (the command)
157
 
                the.command = self.get_command_argument( sys.argv[ 1: ] )
158
 
                if the.command == None:
 
149
                self.command = self.get_command_argument( sys.argv[ 1: ] )
 
150
                if self.command == None:
159
151
                        self.print_usage( "missing command" )
160
152
 
161
153
                # check command is valid
162
 
                the.command = self.check_command( the.command )
163
 
                if the.command == None:
 
154
                self.command = self.check_command( self.command )
 
155
                if self.command == None:
164
156
                        self.print_usage( "bad command" )
165
157
 
166
158
                # calculate class name
167
 
                bits = the.command.split( '-' )
 
159
                bits = self.command.split( '-' )
168
160
                class_name = 'Command'
169
161
                for bit in bits:
170
162
                        class_name += bit[ 0 ].upper() + bit[ 1 : ]
171
163
 
172
 
                # instantiate the command class
173
 
                module = __import__( 'stdhome.command_' + the.command,
174
 
                                                         fromlist = [ class_name ] )
175
 
                instance = getattr( module, class_name )()
176
 
 
177
 
                # run it
178
 
                try:
179
 
                        instance.parse_command_line()
180
 
                        instance.run()
181
 
                except ( getopt.GetoptError, self.UsageError ) as e:
182
 
                        self.print_usage( e.msg )
183
 
                except self.FatalError as e:
184
 
                        message = e.msg
185
 
                        if the.verbose and e.output:
186
 
                                message += '\n\nOUTPUT:\n' + e.output
187
 
                        self.die( message )
188
 
 
189
 
 
190
 
        class UsageError( Exception ):
191
 
 
192
 
                def __init__( self, error_message ):
193
 
                        self.msg = error_message
194
 
 
195
 
 
196
 
        class FatalError( Exception ):
197
 
 
198
 
                def __init__( self, message, output = None ):
199
 
                        self.msg = message
200
 
                        self.output = output
 
164
                # instantiate and run the command class
 
165
                module = __import__( 'stdhome.command_' + self.command )
 
166
                the_class = getattr( module, class_name )
 
167
                instance = the_class()
 
168
                instance.run( self )