Index: gclient.py |
=================================================================== |
--- gclient.py (revision 14731) |
+++ gclient.py (working copy) |
@@ -78,19 +78,7 @@ |
import xml.dom.minidom |
import urllib |
-def getText(nodelist): |
- """ |
- Return the concatenated text for the children of a list of DOM nodes. |
- """ |
- rc = [] |
- for node in nodelist: |
- if node.nodeType == node.TEXT_NODE: |
- rc.append(node.data) |
- else: |
- rc.append(getText(node.childNodes)) |
- return ''.join(rc) |
- |
SVN_COMMAND = "svn" |
@@ -271,6 +259,26 @@ |
## Generic utils |
+def getText(nodelist): |
+ """ |
+ Return the concatenated text for the children of a list of DOM nodes. |
+ """ |
+ rc = [] |
+ for node in nodelist: |
+ if node.nodeType == node.TEXT_NODE: |
+ rc.append(node.data) |
+ else: |
+ rc.append(getText(node.childNodes)) |
+ return ''.join(rc) |
+ |
+ |
+def ParseXML(output): |
+ try: |
+ return xml.dom.minidom.parseString(output) |
+ except xml.parsers.expat.ExpatError: |
+ return None |
+ |
+ |
class Error(Exception): |
"""gclient exception class.""" |
pass |
@@ -584,20 +592,15 @@ |
class FileStatus: |
- def __init__(self, path, text_status, props, locked, history, switched, |
- repo_locked, out_of_date): |
- self.path = path.strip() |
+ def __init__(self, path, text_status, props, history): |
+ self.path = path |
self.text_status = text_status |
self.props = props |
- self.locked = locked |
self.history = history |
- self.switched = switched |
- self.repo_locked = repo_locked |
- self.out_of_date = out_of_date |
def __str__(self): |
- return (self.text_status + self.props + self.locked + self.history + |
- self.switched + self.repo_locked + self.out_of_date + |
+ # Emulate svn status 1.5 output. |
+ return (self.text_status + self.props + ' ' + self.history + ' ' + |
self.path) |
@@ -608,18 +611,53 @@ |
path: The directory to run svn status. |
Returns: |
- An array of FileStatus corresponding to the output of 'svn status' |
- """ |
- info = CaptureSVN(options, ["status"], path) |
- result = [] |
- if not info: |
- return result |
- for line in info.splitlines(): |
- if line: |
- new_item = FileStatus(line[7:], line[0:1], line[1:2], line[2:3], |
- line[3:4], line[4:5], line[5:6], line[6:7]) |
- result.append(new_item) |
- return result |
+ An array of FileStatus corresponding to the emulated output of 'svn status' |
+ version 1.5.""" |
+ dom = ParseXML(CaptureSVN(options, ["status", "--xml"], path)) |
+ results = [] |
+ if dom: |
+ # /status/target/entry/(wc-status|commit|author|date) |
+ for target in dom.getElementsByTagName('target'): |
+ base_path = target.getAttribute('path') |
+ for entry in target.getElementsByTagName('entry'): |
+ file = entry.getAttribute('path') |
+ wc_status = entry.getElementsByTagName('wc-status') |
+ assert len(wc_status) == 1 |
+ # Emulate svn 1.5 status ouput... |
+ statuses = [' ' for i in range(7)] |
+ # Col 0 |
+ xml_item_status = wc_status[0].getAttribute('item') |
+ if xml_item_status == 'unversioned': |
+ statuses[0] = '?' |
+ elif xml_item_status == 'modified': |
+ statuses[0] = 'M' |
+ elif xml_item_status == 'added': |
+ statuses[0] = 'A' |
+ elif xml_item_status == 'conflicted': |
+ statuses[0] = 'C' |
+ elif not xml_item_status: |
+ pass |
+ else: |
+ raise Exception('Unknown item status "%s"; please implement me!' % |
+ xml_item_status) |
+ # Col 1 |
+ xml_props_status = wc_status[0].getAttribute('props') |
+ if xml_props_status == 'modified': |
+ statuses[1] = 'M' |
+ elif xml_props_status == 'conflicted': |
+ statuses[1] = 'C' |
+ elif (not xml_props_status or xml_props_status == 'none' or |
+ xml_props_status == 'normal'): |
+ pass |
+ else: |
+ raise Exception('Unknown props status "%s"; please implement me!' % |
+ xml_props_status) |
+ # Col 3 |
+ if wc_status[0].getAttribute('copied') == 'true': |
+ statuses[3] = '+' |
+ item = FileStatus(file, statuses[0], statuses[1], statuses[3]) |
+ results.append(item) |
+ return results |
### SCM abstraction layer |
@@ -638,10 +676,10 @@ |
self.url = url |
self._root_dir = root_dir |
if self._root_dir: |
- self._root_dir = self._root_dir.replace('/', os.sep).strip() |
+ self._root_dir = self._root_dir.replace('/', os.sep) |
self.relpath = relpath |
if self.relpath: |
- self.relpath = self.relpath.replace('/', os.sep).strip() |
+ self.relpath = self.relpath.replace('/', os.sep) |
def FullUrlForRelativeUrl(self, url): |
# Find the forth '/' and strip from there. A bit hackish. |