#!/usr/bin/env python
__version__ = "1.0.0"
__author__ = "Kevin C. Krinke"
import os, sys, re
from optparse import OptionParser
RV_OK = 0
RV_ERR = 1
RV_WTF = 255
O_PARSER = OptionParser( usage = "usage: %prog [options]
[path2 [...]]",
version = "%prog " + __version__
)
SVN_ST_NORMAL = 'Normal'
SVN_ST_ADDED = 'Added'
SVN_ST_CONFLICTED = 'Conflicted'
SVN_ST_DELETED = 'Deleted'
SVN_ST_IGNORED = 'Ignored'
SVN_ST_MODIFIED = 'Modified'
SVN_ST_REPLACED = 'Replaced'
SVN_ST_UNKNOWN = 'Unknown'
SVN_ST_MISSING = 'Missing'
SVN_ST_OBSTRUCTED = 'Obstructed'
SVN_STATES = {
' ': SVN_ST_NORMAL,
'A': SVN_ST_ADDED,
'C': SVN_ST_CONFLICTED,
'D': SVN_ST_DELETED,
'I': SVN_ST_IGNORED,
'M': SVN_ST_MODIFIED,
'R': SVN_ST_REPLACED,
'?': SVN_ST_UNKNOWN,
'!': SVN_ST_MISSING,
'~': SVN_ST_OBSTRUCTED,
}
ACT_ADD = 'add'
ACT_REMOVE = 'remove'
ACT_REVERT = 'revert'
ACTIONS = [
ACT_ADD,
ACT_REMOVE,
ACT_REVERT
]
OP_ADDED = SVN_ST_ADDED.lower()
OP_DELETED = SVN_ST_DELETED.lower()
OP_MODIFIED = SVN_ST_MODIFIED.lower()
OP_UNKNOWN = SVN_ST_UNKNOWN.lower()
OP_MISSING = SVN_ST_MISSING.lower()
OPERATIONS = [
OP_ADDED,
OP_DELETED,
OP_MODIFIED,
OP_UNKNOWN,
OP_MISSING,
]
class SubversionStatusItem(object):
raw_status = None
path = None
def __init__(self,st_line):
m = re.match( r'^([ ACDIMRX?!~])[ CM][ L][ SX][ KOTB][ C][* ]+(.+?)\s*$', st_line )
if m != None:
self.raw_status = m.group(1)
self.path = m.group(2)
else:
raise Exception, "SubversionStatusItem: Unable to parse contructor line: " + st_line
def __str__(self):
return self.path
def get_status(self):
if self.raw_status in SVN_STATES.keys():
return SVN_STATES[ self.raw_status ]
return None
status = property( get_status, None, None, 'Access the current status as a constant.' )
def subversion(command,paths):
if isinstance(paths,basestring):
paths = [ paths ]
for line in os.popen("svn "+command+' "'+('" "'.join(paths))+'"').readlines():
print line.rstrip()
return None
def svn_status(path):
for line in os.popen("svn status").readlines():
yield SubversionStatusItem(line)
def main(act,op,paths):
targets = []
for path in paths:
for item in svn_status( path ):
if item.status.lower() == op:
targets.append( item.path )
continue
continue
continue
if len(targets):
print "Found the following:"
for tgt in targets: print "\t"+tgt
sys.stdout.write( 'Really ' + act + ' the above? [yN] ' )
answer = sys.stdin.readline()
if len(answer):
answer = answer.lower()
if answer[0] == 'y':
subversion( act, targets )
return RV_OK
print "No action performed."
return RV_OK
def validate(act,op):
if act.lower() in ACTIONS:
act = act.lower()
else:
return 'Invalid action (' + act + ')'
if op.lower() in OPERATIONS:
op = op.lower()
else:
return 'Invalid operate (' + op + ')'
if act == ACT_ADD and op != OP_UNKNOWN:
return 'Can not add ' + op + ' items; can only add unknown.'
elif act == ACT_REMOVE and op == OP_UNKNOWN:
return 'Can not remove unknown items.'
elif act == ACT_REVERT and op == OP_UNKNOWN:
return 'Can not revert unknown items.'
return None
if __name__ == '__main__':
(options, args) = O_PARSER.parse_args()
if len(args) >= 3:
(act, op) = args[0:2]
error = validate(act,op)
if error != None:
O_PARSER.error( error )
sys.exit( RV_ERR )
sys.exit(main(act,op,args[2:]))
else:
O_PARSER.print_usage()
sys.exit(RV_ERR)