Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Unified Diff: gcl.py

Issue 100095: Convert gcl.GetSVNFileInfo() to xml format. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools/
Patch Set: '' Created 11 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | revert.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gcl.py
===================================================================
--- gcl.py (revision 14731)
+++ gcl.py (working copy)
@@ -16,6 +16,7 @@
import tempfile
import upload
import urllib2
+import xml.dom.minidom
__version__ = '1.0'
@@ -47,6 +48,32 @@
read_gcl_info = False
+### Simplified XML processing functions.
+
+def ParseXML(output):
+ try:
+ return xml.dom.minidom.parseString(output)
+ except xml.parsers.expat.ExpatError:
+ return None
+
+def GetNamedNodeText(node, node_name):
+ child_nodes = node.getElementsByTagName(node_name)
+ if not child_nodes:
+ return None
+ assert len(child_nodes) == 1 and child_nodes[0].childNodes.length == 1
+ return child_nodes[0].firstChild.nodeValue
+
+
+def GetNodeNamedAttributeText(node, node_name, attribute_name):
+ child_nodes = node.getElementsByTagName(node_name)
+ if not child_nodes:
+ return None
+ assert len(child_nodes) == 1
+ return child_nodes[0].getAttribute(attribute_name)
+
+
+### SVN Functions
+
def IsSVNMoved(filename):
"""Determine if a file has been added through svn mv"""
info = GetSVNFileInfo(filename)
@@ -57,13 +84,21 @@
def GetSVNFileInfo(file):
"""Returns a dictionary from the svn info output for the given file."""
- output = RunShell(["svn", "info", file])
+ dom = ParseXML(RunShell(["svn", "info", "--xml", file]))
result = {}
- re_key_value_pair = re.compile('^(.*)\: (.*)$')
- for line in output.splitlines():
- key_value_pair = re_key_value_pair.match(line)
- if key_value_pair:
- result[key_value_pair.group(1)] = key_value_pair.group(2)
+ if dom:
+ # /info/entry/
+ # url
+ # reposityory/(root|uuid)
+ # wc-info/(schedule|depth)
+ # commit/(author|date)
+ result['Node Kind'] = GetNodeNamedAttributeText(dom, 'entry', 'kind')
+ result['Repository Root'] = GetNamedNodeText(dom, 'root')
+ result['Schedule'] = GetNamedNodeText(dom, 'schedule')
+ result['URL'] = GetNamedNodeText(dom, 'url')
+ result['Path'] = GetNodeNamedAttributeText(dom, 'entry', 'path')
+ result['Copied From URL'] = GetNamedNodeText(dom, 'copy-from-url')
+ result['Copied From Rev'] = GetNamedNodeText(dom, 'copy-from-rev')
return result
@@ -87,6 +122,77 @@
return output
+def GetSVNStatus(file):
+ """Returns the svn 1.5 svn status emulated output.
+
+ @file can be a string (one file) or a list of files."""
+ command = ["svn", "status", "--xml"]
+ if file is None:
+ pass
+ elif isinstance(file, basestring):
+ command.append(file)
+ else:
+ command.extend(file)
+
+ status_letter = {
+ '': ' ',
+ 'unversioned': '?',
+ 'modified': 'M',
+ 'added': 'A',
+ 'conflicted': 'C',
+ 'deleted': 'D',
+ 'ignored': 'I',
+ 'replaced': 'R',
+ # TODO(maruel): Find the corresponding strings for X, !, ~
+ }
+ dom = ParseXML(RunShell(command))
+ 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 in status_letter:
+ statuses[0] = status_letter[xml_item_status]
+ 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 = (''.join(statuses), file)
+ results.append(item)
+ return results
+
+
+def UnknownFiles(extra_args):
+ """Runs svn status and prints unknown files.
+
+ Any args in |extra_args| are passed to the tool to support giving alternate
+ code locations.
+ """
+ return [item[1] for item in GetSVNStatus(extra_args) if item[0][0] == '?']
+
+
def GetRepositoryRoot():
"""Returns the top level directory of the current repository.
@@ -418,8 +524,9 @@
if update_status:
for file in files:
filename = os.path.join(GetRepositoryRoot(), file[1])
- status = RunShell(["svn", "status", filename])[:7]
- if not status: # File has been reverted.
+ status_result = GetSVNStatus(filename)
+ if not status_result or not status_result[0][0]:
+ # File has been reverted.
save = True
files.remove(file)
elif status != file[0]:
@@ -474,12 +581,12 @@
files_in_cl[filename] = change_info.name
# Get all the modified files.
- status = RunShell(["svn", "status"])
- for line in status.splitlines():
- if not len(line) or line[0] == "?":
+ status_result = GetSVNStatus(None)
+ for line in status_result:
+ status = line[0]
+ filename = line[1]
+ if status[0] == "?":
continue
- status = line[:7]
- filename = line[7:].strip()
if dir_prefix:
filename = os.path.join(dir_prefix, filename)
change_list_name = ""
@@ -530,30 +637,6 @@
return SendToRietveld("/" + issue + "/description")
-def UnknownFiles(extra_args):
- """Runs svn status and prints unknown files.
-
- Any args in |extra_args| are passed to the tool to support giving alternate
- code locations.
- """
- args = ["svn", "status"]
- args += extra_args
- p = subprocess.Popen(args, stdout = subprocess.PIPE,
- stderr = subprocess.STDOUT, shell = use_shell)
- while 1:
- line = p.stdout.readline()
- if not line:
- break
- if line[0] != '?':
- continue # Not an unknown file to svn.
- # The lines look like this:
- # "? foo.txt"
- # and we want just "foo.txt"
- print line[7:].strip()
- p.wait()
- p.stdout.close()
-
-
def Opened():
"""Prints a list of modified files in the current directory down."""
files = GetModifiedFiles()
« no previous file with comments | « no previous file | revert.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698