/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/program.py

  • Committer: Tim Marston
  • Date: 2014-02-12 21:51:08 UTC
  • Revision ID: tim@ed.am-20140212215108-stk5z0nlvgpi4oa8
added bzr as a vcs backend; finished init command; implemented deployment

Show diffs side-by-side

added added

removed removed

21
21
 
22
22
import os, sys, getopt
23
23
import the
24
 
from config import Config
25
 
from vcs.vcs import Vcs
26
24
 
27
25
 
28
26
class Program:
62
60
                print "  init          initialise a local copy of your repositories"
63
61
                print "  update        update files in your home directory"
64
62
                print "  resolve       try to finish an update (that had conflicts)"
65
 
#               print "  add           add local files/changes to the repository"
66
 
#               print "  remove        remove a local file from the repository"
 
63
                print "  add           add local files/changes to the repository"
 
64
                print "  remove        remove a local file from the repository"
67
65
                print "  status        list files that have changed locally"
68
66
                print "  diff          shows changes made to local files"
69
 
                print "  revert        undo changes made to local files"
70
 
#               print "  stage-add     add (but don't commit) files/changes to local repository"
71
 
#               print "  stage-remove  delete *but don't comit) files from the local repository"
72
 
                print "  stage-revert  revert changes in the local repository"
73
 
#               print "  stage-status  show status of local repository"
74
 
#               print "  stage-diff    shows changes in local repository"
75
 
#               print "  stage-commit  commit changes in the local repository"
 
67
                print "  revert        undo changes made to a local file"
 
68
                print "  stage-add     stage local files/changes"
 
69
                print "  stage-remove  stage the removal of files"
 
70
                print "  stage-revert  revert staged changes"
 
71
                print "  stage-status  show status of staging area"
 
72
                print "  stage-diff    shows staged changes"
 
73
                print "  stage-commit  commit staged changes to repository"
76
74
                print
77
75
                print "For help about a particular command (including the additional options that the"
78
76
                print "command accepts) try typing:"
83
81
        def print_version( self ):
84
82
                print "stdhome " + self.version
85
83
                print
86
 
                print "Copyright (C) 2013 to 2014 Tim Marston"
 
84
                print "Copyright (C) 2013 Tim Marston"
87
85
                print
88
86
                #      01234567890123456789012345678901234567890123456789012345678901234567890123456789
89
87
                print "This program is free software, and you may use, modify and redistribute it"
112
110
                        return command
113
111
 
114
112
                # resolve aliases
115
 
                alias = {
116
 
                        'up': 'update',
117
 
                        'rm': 'remove',
118
 
                        'st': 'status',
119
 
                        'co': 'init',
120
 
                }.get( command, False )
121
 
                if alias: return alias
 
113
                elif command == 'up':
 
114
                        return 'update'
 
115
                elif command == 'rm':
 
116
                        return 'remove'
122
117
 
123
118
                # invalid
 
119
                else:
 
120
                        return None
 
121
 
 
122
 
 
123
        def get_command_argument( self, args ):
 
124
                """
 
125
                Find the first program argument what isn't an option argument.
 
126
 
 
127
        Arguments:
 
128
        - `args`: the program arguments
 
129
        """
 
130
                while args:
 
131
                        if args[ 0 ] == '--':
 
132
                                return args[ 1 ] if len( args ) > 1 else None
 
133
                        if args[ 0 ][ 0 : 1 ] != '-':
 
134
                                return args[ 0 ]
 
135
                        args = args[ 1 : ]
124
136
                return None
125
137
 
126
138
 
146
158
                        # ignore errors -- we aren't parsing the command line properly yet
147
159
                        pass
148
160
 
149
 
                # read program configuration
150
 
                the.config = Config()
151
 
 
152
 
                # the first argument should be the command
153
 
                the.command = sys.argv[ 1 ] if len( sys.argv ) > 1 else None
 
161
                # find the first non-option argument (the command)
 
162
                the.command = self.get_command_argument( sys.argv[ 1: ] )
154
163
                if the.command == None:
155
164
                        self.print_usage( "missing command" )
156
165
 
160
169
                        self.print_usage( "bad command" )
161
170
 
162
171
                # calculate module and class name
163
 
                class_name = module_name = ''
164
172
                bits = the.command.split( '-' )
 
173
                class_name = 'Command'
 
174
                module_name = 'command'
165
175
                for bit in bits:
166
176
                        class_name += bit[ 0 ].upper() + bit[ 1 : ]
167
 
                        if module_name: module_name += '_'
168
 
                        module_name += bit
169
 
                class_name += 'Command'
 
177
                        module_name += '_' + bit
170
178
 
171
179
                # import module and instantiate the class
172
 
                module = __import__( 'stdhome.command.' + module_name,
 
180
                module = __import__( 'stdhome.' + module_name,
173
181
                                                         fromlist = [ class_name ] )
174
182
                instance = getattr( module, class_name )()
175
183
 
176
 
                # fully parse the command line, as per the command
 
184
                # run the command
177
185
                try:
178
186
                        instance.parse_command_line()
179
 
                except( getopt.GetoptError, self.UsageError ) as e:
 
187
                        instance.run()
 
188
                except ( getopt.GetoptError, self.UsageError ) as e:
180
189
                        self.print_usage( e.msg )
181
190
                except self.FatalError as e:
182
 
                        self.die( e.msg )
183
 
 
184
 
                # do late initialisation
185
 
                the.late_init()
186
 
 
187
 
                # run the command
188
 
                try:
189
 
                        instance.run()
190
 
                except Vcs.VcsError as e:
191
191
                        message = e.msg.rstrip()
192
 
                        if the.verbose >= 1:
 
192
                        if the.verbose and hasattr( e, 'output' ) and e.output:
193
193
                                message += '\n\nOUTPUT:\n' + e.output.rstrip()
194
194
                        self.die( message )
195
 
                except self.FatalError as e:
196
 
                        self.die( e.msg )
197
195
 
198
196
 
199
197
        class UsageError( Exception ):
204
202
 
205
203
        class FatalError( Exception ):
206
204
 
207
 
                def __init__( self, message ):
 
205
                def __init__( self, message, output = None ):
208
206
                        self.msg = message
 
207
                        self.output = output