Commit 46a94109 authored by maruel@chromium.org's avatar maruel@chromium.org

Deprecate gcl.GetSVNFileInfo() for gclient.CaptureSVNInfo().

Review URL: http://codereview.chromium.org/113290

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@15891 0039d316-1c4b-4281-b951-d872f2087c98
parent 5c3a2ff6
...@@ -18,6 +18,8 @@ import upload ...@@ -18,6 +18,8 @@ import upload
import urllib2 import urllib2
import xml.dom.minidom import xml.dom.minidom
# gcl now depends on gclient.
import gclient
__version__ = '1.0' __version__ = '1.0'
...@@ -44,61 +46,16 @@ MISSING_TEST_MSG = "Change contains new or modified methods, but no new tests!" ...@@ -44,61 +46,16 @@ MISSING_TEST_MSG = "Change contains new or modified methods, but no new tests!"
read_gcl_info = False 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 ### SVN Functions
def IsSVNMoved(filename): def IsSVNMoved(filename):
"""Determine if a file has been added through svn mv""" """Determine if a file has been added through svn mv"""
info = GetSVNFileInfo(filename) info = gclient.CaptureSVNInfo(filename)
return (info.get('Copied From URL') and return (info.get('Copied From URL') and
info.get('Copied From Rev') and info.get('Copied From Rev') and
info.get('Schedule') == 'add') info.get('Schedule') == 'add')
def GetSVNFileInfo(file):
"""Returns a dictionary from the svn info output for the given file."""
output = RunShell(["svn", "info", "--xml", file])
dom = ParseXML(output)
result = {}
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
def GetSVNFileProperty(file, property_name): def GetSVNFileProperty(file, property_name):
"""Returns the value of an SVN property for the given file. """Returns the value of an SVN property for the given file.
...@@ -145,7 +102,7 @@ def GetSVNStatus(file): ...@@ -145,7 +102,7 @@ def GetSVNStatus(file):
# TODO(maruel): Find the corresponding strings for X, ~ # TODO(maruel): Find the corresponding strings for X, ~
} }
output = RunShell(command) output = RunShell(command)
dom = ParseXML(output) dom = gclient.ParseXML(output)
results = [] results = []
if dom: if dom:
# /status/target/entry/(wc-status|commit|author|date) # /status/target/entry/(wc-status|commit|author|date)
...@@ -200,14 +157,16 @@ def GetRepositoryRoot(): ...@@ -200,14 +157,16 @@ def GetRepositoryRoot():
""" """
global repository_root global repository_root
if not repository_root: if not repository_root:
cur_dir_repo_root = GetSVNFileInfo(os.getcwd()).get("Repository Root") infos = gclient.CaptureSVNInfo(os.getcwd(), print_error=False)
cur_dir_repo_root = infos.get("Repository Root")
if not cur_dir_repo_root: if not cur_dir_repo_root:
raise Exception("gcl run outside of repository") raise Exception("gcl run outside of repository")
repository_root = os.getcwd() repository_root = os.getcwd()
while True: while True:
parent = os.path.dirname(repository_root) parent = os.path.dirname(repository_root)
if GetSVNFileInfo(parent).get("Repository Root") != cur_dir_repo_root: if (gclient.CaptureSVNInfo(parent).get("Repository Root") !=
cur_dir_repo_root):
break break
repository_root = parent repository_root = parent
return repository_root return repository_root
...@@ -230,7 +189,7 @@ def GetCodeReviewSetting(key): ...@@ -230,7 +189,7 @@ def GetCodeReviewSetting(key):
cached_settings_file = os.path.join(GetInfoDir(), CODEREVIEW_SETTINGS_FILE) cached_settings_file = os.path.join(GetInfoDir(), CODEREVIEW_SETTINGS_FILE)
if (not os.path.exists(cached_settings_file) or if (not os.path.exists(cached_settings_file) or
os.stat(cached_settings_file).st_mtime > 60*60*24*3): os.stat(cached_settings_file).st_mtime > 60*60*24*3):
dir_info = GetSVNFileInfo(".") dir_info = gclient.CaptureSVNInfo(".")
repo_root = dir_info["Repository Root"] repo_root = dir_info["Repository Root"]
url_path = dir_info["URL"] url_path = dir_info["URL"]
settings = "" settings = ""
...@@ -753,7 +712,7 @@ def GenerateDiff(files, root=None): ...@@ -753,7 +712,7 @@ def GenerateDiff(files, root=None):
for file in files: for file in files:
# Use svn info output instead of os.path.isdir because the latter fails # Use svn info output instead of os.path.isdir because the latter fails
# when the file is deleted. # when the file is deleted.
if GetSVNFileInfo(file).get("Node Kind") in ("dir", "directory"): if gclient.CaptureSVNInfo(file).get("Node Kind") in ("dir", "directory"):
continue continue
# If the user specified a custom diff command in their svn config file, # If the user specified a custom diff command in their svn config file,
# then it'll be used when we do svn diff, which we don't want to happen # then it'll be used when we do svn diff, which we don't want to happen
......
...@@ -32,6 +32,7 @@ import urllib2 # Exposed through the API. ...@@ -32,6 +32,7 @@ import urllib2 # Exposed through the API.
# TODO(joi) Would be cleaner to factor out utils in gcl to separate module, but # TODO(joi) Would be cleaner to factor out utils in gcl to separate module, but
# for now it would only be a couple of functions so hardly worth it. # for now it would only be a couple of functions so hardly worth it.
import gcl import gcl
import gclient
import presubmit_canned_checks import presubmit_canned_checks
...@@ -207,7 +208,7 @@ class InputApi(object): ...@@ -207,7 +208,7 @@ class InputApi(object):
Remember to check for the None case and show an appropriate error! Remember to check for the None case and show an appropriate error!
""" """
local_path = gcl.GetSVNFileInfo(depot_path).get('Path') local_path = gclient.CaptureSVNInfo(depot_path).get('Path')
if not local_path: if not local_path:
return None return None
else: else:
...@@ -223,7 +224,7 @@ class InputApi(object): ...@@ -223,7 +224,7 @@ class InputApi(object):
Returns: Returns:
The depot path (SVN URL) of the file if mapped, otherwise None. The depot path (SVN URL) of the file if mapped, otherwise None.
""" """
depot_path = gcl.GetSVNFileInfo(local_path).get('URL') depot_path = gclient.CaptureSVNInfo(local_path).get('URL')
if not depot_path: if not depot_path:
return None return None
else: else:
...@@ -331,7 +332,7 @@ class AffectedFile(object): ...@@ -331,7 +332,7 @@ class AffectedFile(object):
Returns the empty string if the file does not exist in SCM. Returns the empty string if the file does not exist in SCM.
""" """
return gcl.GetSVNFileInfo(self.AbsoluteLocalPath()).get('URL', '') return gclient.CaptureSVNInfo(self.AbsoluteLocalPath()).get('URL', '')
def LocalPath(self): def LocalPath(self):
"""Returns the path of this file on the local disk relative to client root. """Returns the path of this file on the local disk relative to client root.
...@@ -350,7 +351,8 @@ class AffectedFile(object): ...@@ -350,7 +351,8 @@ class AffectedFile(object):
# subversion, especially on Windows. # subversion, especially on Windows.
return os.path.isdir(self.path) return os.path.isdir(self.path)
else: else:
return gcl.GetSVNFileInfo(self.path).get('Node Kind') == 'directory' return gclient.CaptureSVNInfo(self.path).get('Node Kind') in ('dir',
'directory')
def SvnProperty(self, property_name): def SvnProperty(self, property_name):
"""Returns the specified SVN property of this file, or the empty string """Returns the specified SVN property of this file, or the empty string
......
...@@ -48,53 +48,20 @@ class GclUnittest(GclTestsBase): ...@@ -48,53 +48,20 @@ class GclUnittest(GclTestsBase):
'ErrorExit', 'GenerateChangeName', 'GenerateDiff', 'GetCLs', 'ErrorExit', 'GenerateChangeName', 'GenerateDiff', 'GetCLs',
'GetChangelistInfoFile', 'GetCodeReviewSetting', 'GetEditor', 'GetChangelistInfoFile', 'GetCodeReviewSetting', 'GetEditor',
'GetFilesNotInCL', 'GetInfoDir', 'GetIssueDescription', 'GetFilesNotInCL', 'GetInfoDir', 'GetIssueDescription',
'GetModifiedFiles', 'GetNamedNodeText', 'GetNodeNamedAttributeText', 'GetModifiedFiles', 'GetRepositoryRoot', 'GetSVNStatus',
'GetRepositoryRoot', 'GetSVNFileInfo', 'GetSVNStatus',
'GetSVNFileProperty', 'Help', 'IGNORE_PATHS', 'IsSVNMoved', 'IsTreeOpen', 'GetSVNFileProperty', 'Help', 'IGNORE_PATHS', 'IsSVNMoved', 'IsTreeOpen',
'Lint', 'LoadChangelistInfo', 'LoadChangelistInfoForMultiple', 'Lint', 'LoadChangelistInfo', 'LoadChangelistInfoForMultiple',
'MISSING_TEST_MSG', 'Opened', 'ParseXML', 'PresubmitCL', 'ReadFile', 'MISSING_TEST_MSG', 'Opened', 'PresubmitCL', 'ReadFile',
'RunShell', 'RunShell',
'RunShellWithReturnCode', 'SEPARATOR', 'SendToRietveld', 'TryChange', 'RunShellWithReturnCode', 'SEPARATOR', 'SendToRietveld', 'TryChange',
'UnknownFiles', 'UploadCL', 'Warn', 'WriteFile', 'gcl_info_dir', 'UnknownFiles', 'UploadCL', 'Warn', 'WriteFile', 'gclient',
'getpass', 'main', 'os', 'random', 're', 'read_gcl_info', 'gcl_info_dir', 'getpass', 'main', 'os', 'random', 're', 'read_gcl_info',
'repository_root', 'string', 'subprocess', 'sys', 'tempfile', 'upload', 'repository_root', 'string', 'subprocess', 'sys', 'tempfile', 'upload',
'urllib2', 'xml', 'urllib2', 'xml',
] ]
# If this test fails, you should add the relevant test. # If this test fails, you should add the relevant test.
self.compareMembers(gcl, members) self.compareMembers(gcl, members)
def testGetSVNFileInfo(self):
def RunShellMock(command):
return r"""<?xml version="1.0"?>
<info>
<entry kind="file" path="%s" revision="14628">
<url>http://src.chromium.org/svn/trunk/src/chrome/app/d</url>
<repository><root>http://src.chromium.org/svn</root></repository>
<wc-info>
<schedule>add</schedule>
<depth>infinity</depth>
<copy-from-url>http://src.chromium.org/svn/trunk/src/chrome/app/DEPS</copy-from-url>
<copy-from-rev>14628</copy-from-rev>
<checksum>369f59057ba0e6d9017e28f8bdfb1f43</checksum>
</wc-info>
</entry>
</info>
""" % command[3]
# GclTestsBase.tearDown will restore the original.
gcl.RunShell = RunShellMock
filename = os.path.join('app', 'd')
info = gcl.GetSVNFileInfo(filename)
expected = {
'URL': 'http://src.chromium.org/svn/trunk/src/chrome/app/d',
'Repository Root': 'http://src.chromium.org/svn',
'Schedule': 'add',
'Copied From URL': 'http://src.chromium.org/svn/trunk/src/chrome/app/DEPS',
'Copied From Rev': '14628',
'Path': filename,
'Node Kind': 'file',
}
self.assertEquals(sorted(info.items()), sorted(expected.items()))
def testGetSVNStatus(self): def testGetSVNStatus(self):
def RunShellMock(command): def RunShellMock(command):
return r"""<?xml version="1.0"?> return r"""<?xml version="1.0"?>
......
...@@ -11,6 +11,7 @@ import unittest ...@@ -11,6 +11,7 @@ import unittest
# Local imports # Local imports
import gcl import gcl
import gclient
import presubmit import presubmit
import presubmit_canned_checks import presubmit_canned_checks
...@@ -24,8 +25,8 @@ class PresubmitTestsBase(unittest.TestCase): ...@@ -24,8 +25,8 @@ class PresubmitTestsBase(unittest.TestCase):
return dir.endswith('haspresubmit') or dir == '' return dir.endswith('haspresubmit') or dir == ''
os.path.isfile = MockIsFile os.path.isfile = MockIsFile
self.original_GetSVNFileInfo = gcl.GetSVNFileInfo self.original_CaptureSVNInfo = gclient.CaptureSVNInfo
def MockGetSVNFileInfo(path): def MockCaptureSVNInfo(path):
if path.count('notfound'): if path.count('notfound'):
return {} return {}
results = { results = {
...@@ -37,7 +38,7 @@ class PresubmitTestsBase(unittest.TestCase): ...@@ -37,7 +38,7 @@ class PresubmitTestsBase(unittest.TestCase):
else: else:
results['Node Kind'] = 'file' results['Node Kind'] = 'file'
return results return results
gcl.GetSVNFileInfo = MockGetSVNFileInfo gclient.CaptureSVNInfo = MockCaptureSVNInfo
self.original_GetSVNFileProperty = gcl.GetSVNFileProperty self.original_GetSVNFileProperty = gcl.GetSVNFileProperty
def MockGetSVNFileProperty(path, property_name): def MockGetSVNFileProperty(path, property_name):
...@@ -81,7 +82,7 @@ class PresubmitTestsBase(unittest.TestCase): ...@@ -81,7 +82,7 @@ class PresubmitTestsBase(unittest.TestCase):
def tearDown(self): def tearDown(self):
os.path.isfile = self.original_IsFile os.path.isfile = self.original_IsFile
gcl.GetSVNFileInfo = self.original_GetSVNFileInfo gclient.CaptureSVNInfo = self.original_CaptureSVNInfo
gcl.GetSVNFileProperty = self.original_GetSVNFileProperty gcl.GetSVNFileProperty = self.original_GetSVNFileProperty
gcl.ReadFile = self.original_ReadFile gcl.ReadFile = self.original_ReadFile
gcl.GetRepositoryRoot = self.original_GetRepositoryRoot gcl.GetRepositoryRoot = self.original_GetRepositoryRoot
...@@ -111,8 +112,8 @@ class PresubmitUnittest(PresubmitTestsBase): ...@@ -111,8 +112,8 @@ class PresubmitUnittest(PresubmitTestsBase):
'ListRelevantPresubmitFiles', 'Main', 'NotImplementedException', 'ListRelevantPresubmitFiles', 'Main', 'NotImplementedException',
'OutputApi', 'ParseFiles', 'PresubmitExecuter', 'SPECIAL_KEYS', 'OutputApi', 'ParseFiles', 'PresubmitExecuter', 'SPECIAL_KEYS',
'ScanSubDirs', 'cPickle', 'cStringIO', 'exceptions', 'ScanSubDirs', 'cPickle', 'cStringIO', 'exceptions',
'fnmatch', 'gcl', 'glob', 'marshal', 'normpath', 'optparse', 'os', 'fnmatch', 'gcl', 'gclient', 'glob', 'marshal', 'normpath', 'optparse',
'pickle', 'presubmit_canned_checks', 're', 'subprocess', 'sys', 'os', 'pickle', 'presubmit_canned_checks', 're', 'subprocess', 'sys',
'tempfile', 'types', 'urllib2', 'tempfile', 'types', 'urllib2',
] ]
# If this test fails, you should add the relevant test. # If this test fails, you should add the relevant test.
......
...@@ -20,6 +20,7 @@ import traceback ...@@ -20,6 +20,7 @@ import traceback
import urllib import urllib
import gcl import gcl
import gclient
__version__ = '1.1' __version__ = '1.1'
...@@ -132,7 +133,7 @@ class SVN(SCM): ...@@ -132,7 +133,7 @@ class SVN(SCM):
for file in files: for file in files:
# Use svn info output instead of os.path.isdir because the latter fails # Use svn info output instead of os.path.isdir because the latter fails
# when the file is deleted. # when the file is deleted.
if gcl.GetSVNFileInfo(file).get("Node Kind") == "directory": if gclient.CaptureSVNInfo(file).get("Node Kind") in ("dir", "directory"):
continue continue
# If the user specified a custom diff command in their svn config file, # If the user specified a custom diff command in their svn config file,
# then it'll be used when we do svn diff, which we don't want to happen # then it'll be used when we do svn diff, which we don't want to happen
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment