def CaptureSVNLog(args): command = ['log', '--xml'] if args: command += args output = gclient_scm.CaptureSVN(command) dom = gclient_utils.ParseXML(output) entries = [] if dom: # /log/logentry/ # @revision # author|date # paths/ # path (@kind&@action) for node in dom.getElementsByTagName('logentry'): paths = [] for path in node.getElementsByTagName('path'): item = { 'kind': path.getAttribute('kind'), 'action': path.getAttribute('action'), 'path': path.firstChild.nodeValue, } paths.append(item) entry = { 'revision': int(node.getAttribute('revision')), 'author': gclient_utils.GetNamedNodeText(node, 'author'), 'date': gclient_utils.GetNamedNodeText(node, 'date'), 'paths': paths, } entries.append(entry) return entries
def CaptureInfo(relpath, in_directory=None, print_error=True): """Returns a dictionary from the svn info output for the given file. Args: relpath: The directory where the working copy resides relative to the directory given by in_directory. in_directory: The directory where svn is to be run. """ output = SVN.Capture(["info", "--xml", relpath], in_directory, print_error) dom = gclient_utils.ParseXML(output) result = {} if dom: GetNamedNodeText = gclient_utils.GetNamedNodeText GetNodeNamedAttributeText = gclient_utils.GetNodeNamedAttributeText def C(item, f): if item is not None: return f(item) # /info/entry/ # url # reposityory/(root|uuid) # wc-info/(schedule|depth) # commit/(author|date) # str() the results because they may be returned as Unicode, which # interferes with the higher layers matching up things in the deps # dictionary. # TODO(maruel): Fix at higher level instead (!) result['Repository Root'] = C(GetNamedNodeText(dom, 'root'), str) result['URL'] = C(GetNamedNodeText(dom, 'url'), str) result['UUID'] = C(GetNamedNodeText(dom, 'uuid'), str) result['Revision'] = C( GetNodeNamedAttributeText(dom, 'entry', 'revision'), int) result['Node Kind'] = C( GetNodeNamedAttributeText(dom, 'entry', 'kind'), str) # Differs across versions. if result['Node Kind'] == 'dir': result['Node Kind'] = 'directory' result['Schedule'] = C(GetNamedNodeText(dom, 'schedule'), str) result['Path'] = C(GetNodeNamedAttributeText(dom, 'entry', 'path'), str) result['Copied From URL'] = C( GetNamedNodeText(dom, 'copy-from-url'), str) result['Copied From Rev'] = C( GetNamedNodeText(dom, 'copy-from-rev'), str) return result
def CaptureStatus(files): """Returns the svn 1.5 svn status emulated output. @files can be a string (one file) or a list of files. Returns an array of (status, file) tuples.""" command = ["status", "--xml"] if not files: pass elif isinstance(files, basestring): command.append(files) else: command.extend(files) status_letter = { None: ' ', '': ' ', 'added': 'A', 'conflicted': 'C', 'deleted': 'D', 'external': 'X', 'ignored': 'I', 'incomplete': '!', 'merged': 'G', 'missing': '!', 'modified': 'M', 'none': ' ', 'normal': ' ', 'obstructed': '~', 'replaced': 'R', 'unversioned': '?', } dom = gclient_utils.ParseXML(SVN.Capture(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_path = entry.getAttribute('path') wc_status = entry.getElementsByTagName('wc-status') assert len(wc_status) == 1 # Emulate svn 1.5 status ouput... statuses = [' '] * 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 2 if wc_status[0].getAttribute('wc-locked') == 'true': statuses[2] = 'L' # Col 3 if wc_status[0].getAttribute('copied') == 'true': statuses[3] = '+' # Col 4 if wc_status[0].getAttribute('switched') == 'true': statuses[4] = 'S' # TODO(maruel): Col 5 and 6 item = (''.join(statuses), file_path) results.append(item) return results