RSS
 

svn-act-op

#!/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)
Share

Leave a Reply