django-triager-bot / djangotriager / wc / subversion.py

from subprocess import PIPE
from subprocess import Popen
from xml.dom.minidom import parseString

from djangotriager.wc.general import WorkingCopy

class Subversion(WorkingCopy):
    """
    VC-specific implementation for SVN
    """
    RESULT_ALIASES = {
        "unversioned" : "added",
        "missing" : "deleted",
    }

    def __init__(self, dir):
        super(Subversion, self).__init__(dir)
        self._curr_rev = None

    def get_changes_from_xml(self, xml):
        result = {
            "modified" : [],
            "added" : [],
            "deleted" : [],
        }

        doc = parseString(xml).documentElement
        for entry in doc.getElementsByTagName("entry"):
            status = entry.getElementsByTagName("wc-status")[0].getAttribute("item")
            path = entry.getAttribute("path")

            if status in result:
                result[status].append(path)
            elif status in self.RESULT_ALIASES:
                result[self.RESULT_ALIASES[status]].append(path)
            else:
                raise ValueError("File %s with unexpected status %s" % (path, status))
        return result

    def get_revision_from_xml(self, xml):
        doc = parseString(xml).documentElement
        entries = doc.getElementsByTagName("entry")
        if len(entries) == 1:
            entry = entries[0]
            if entry.attributes.has_key(u"revision"):
                return entry.attributes[u'revision'].value

    def update(self):
        proc = Popen(["svn", "up"], cwd=self.dir, stdout=PIPE, stderr=PIPE)
        proc.communicate()
        self._curr_rev = None

    def get_revision(self):
        if self._curr_rev is not None:
            return self._curr_rev
        proc = Popen(["svn", "info", "--xml"], cwd=self.dir, stdout=PIPE, stderr=PIPE)
        stdout, stderr = proc.communicate()
        if proc.returncode != 0:
            raise ValueError("Status returned code %s" % proc.returncode)
        self._curr_rev = self.get_revision_from_xml(stdout)
        return self._curr_rev

    def get_changes(self):
        proc = Popen(["svn", "status", "--xml"], cwd=self.dir, stdout=PIPE, stderr=PIPE)
        stdout, stderr = proc.communicate()
        if proc.returncode != 0:
            raise ValueError("Status returned code %s" % proc.returncode)
        
        return self.get_changes_from_xml(stdout)

    def revert_files(self, files):
        proc = Popen(
            ["svn", "revert"] +  files, cwd=self.dir, stdout=PIPE, stderr=PIPE)
        stdout, stderr = proc.communicate()
        if proc.returncode != 0:
            raise ValueError("Revert returned code %s" % proc.returncode)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.