3
# Copyright (C) 2013 Tim Marston <tim@edm.am>
5
# This file is part of stdhome (hereafter referred to as "this program").
6
# See http://ed.am/dev/stdhome for more information.
8
# This program is free software: you can redistribute it and/or modify
9
# it under the terms of the GNU General Public License as published by
10
# the Free Software Foundation, either version 3 of the License, or
11
# (at your option) any later version.
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU General Public License for more details.
18
# You should have received a copy of the GNU General Public License
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
29
def __init__( self, version ):
30
self.version = version
31
self.program = os.path.basename( sys.argv[ 0 ] )
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."
40
def print_help( self ):
41
print "Usage: " + self.program + " COMMAND [OPTION]..."
43
# 01234567890123456789012345678901234567890123456789012345678901234567890123456789
44
print "Manage your home directories, across multiple computers, similar to how you"
45
print "would software under version control."
47
print "Global options (for all commands):"
48
print " --help display help and exit"
49
print " --version output version information and exit"
52
print " init initialise a local copy of your repositories"
53
print " update update files in your home directory"
54
print " resolve try to finish an update (that had conflicts)"
55
print " add add local files/changes to the repository"
56
print " remove remove a local file from the repository"
57
print " revert undo changes made to a local file"
58
print " stage-add stage local files/changes"
59
print " stage-remove stage the removal of files"
60
print " stage-revert revert staged changes"
61
print " stage-status show status of staging area"
62
print " stage-commit commit staged changes to repository"
64
print "For help about a particular command (including the additional options that the"
65
print "command accepts) try typing:"
66
print " $ " + self.program + " COMMAND --help"
70
def print_version( self ):
71
print "stdhome " + self.version
73
print "Copyright (C) 2013 Tim Marston"
75
# 01234567890123456789012345678901234567890123456789012345678901234567890123456789
76
print "This program is free software, and you may use, modify and redistribute it"
77
print "under the terms of the GNU General Public License version 3 or later. This"
78
print "program comes with ABSOLUTELY NO WARRANTY, to the extent permitted by law."
80
print "For more information, including documentation, please see the project website"
81
print "at http://ed.am/dev/stdhome."
83
print "Please report bugs to <tim@ed.am>."
87
def check_command( self, command ):
89
Check that the given command is valid and return the full name of the command.
92
- `command`: the given command
95
if [ 'init', 'update', 'resolve', 'add', 'remove', 'revert',
96
'stage-add', 'stage-remove', 'stage-revert', 'stage-status',
97
'stage-commit' ].count( command ) == 1:
101
elif command == 'up':
103
elif command == 'rm':
111
def get_command_argument( self, args ):
113
Find the first program argument what isn't an option argument.
116
- `args`: the program arguments
119
if args[ 0 ] == '--':
120
return args[ 1 ] if len( args ) > 1 else None
121
if args[ 0 ][ 0 : 1 ] != '-':
127
# make an initial attempt to parse the command line, looking only for
128
# --help and --version, so that they have the chance to run without a
129
# command being specified
131
opts, args = getopt.gnu_getopt(
133
[ "help", "version" ] )
135
for opt, optargs in opts:
136
# we only show help if there are no non-option arguments (e.g.,
137
# a command) specified. If a command has been specified it will
138
# have to be parsed and --help will be handled by it, instead)
139
if opt == "--help" and len( args ) == 0:
141
elif opt == "--version":
144
except getopt.GetoptError as e:
145
# ignore any errors -- we aren't parsing the command line properly
148
# find the first non-option argument (the command)
149
self.command = self.get_command_argument( sys.argv[ 1: ] )
150
if self.command == None:
151
self.print_usage( "missing command" )
153
# check command is valid
154
self.command = self.check_command( self.command )
155
if self.command == None:
156
self.print_usage( "bad command" )
158
# calculate class name
159
bits = self.command.split( '-' )
160
class_name = 'Command'
162
class_name += bit[ 0 ].upper() + bit[ 1 : ]
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()