Commit 4810a966 authored by maruel@chromium.org's avatar maruel@chromium.org

Deprecate gcl.GetSVNStatus() for gclient.CaptureSVNStatus() and fix some...

Deprecate gcl.GetSVNStatus() for gclient.CaptureSVNStatus() and fix some status information that was lost.
This was breaking gclient revert on unversioned files.

TEST=ran "for %a in (tests\*test.py) do python %a" and all tests succeeded.
Review URL: http://codereview.chromium.org/115264

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@15894 0039d316-1c4b-4281-b951-d872f2087c98
parent 46a94109
......@@ -76,78 +76,14 @@ def GetSVNFileProperty(file, property_name):
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 = {
'': ' ',
'added': 'A',
'conflicted': 'C',
'deleted': 'D',
'ignored': 'I',
'missing': '!',
'modified': 'M',
'normal': ' ',
'replaced': 'R',
'unversioned': '?',
# TODO(maruel): Find the corresponding strings for X, ~
}
output = RunShell(command)
dom = gclient.ParseXML(output)
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] == '?']
return [item[1] for item in gclient.CaptureSVNStatus(extra_args)
if item[0][0] == '?']
def GetRepositoryRoot():
......@@ -488,7 +424,7 @@ def LoadChangelistInfo(changename, fail_on_not_found=True,
if update_status:
for file in files:
filename = os.path.join(GetRepositoryRoot(), file[1])
status_result = GetSVNStatus(filename)
status_result = gclient.CaptureSVNStatus(filename)
if not status_result or not status_result[0][0]:
# File has been reverted.
save = True
......@@ -547,7 +483,7 @@ def GetModifiedFiles():
files_in_cl[filename] = change_info.name
# Get all the modified files.
status_result = GetSVNStatus(None)
status_result = gclient.CaptureSVNStatus(None)
for line in status_result:
status = line[0]
filename = line[1]
......
......@@ -612,30 +612,39 @@ def CaptureSVNHeadRevision(url):
return int(dom.getElementsByTagName('entry')[0].getAttribute('revision'))
class FileStatus:
def __init__(self, path, text_status, props, lock, history):
self.path = path
self.text_status = text_status
self.props = props
self.lock = lock
self.history = history
def CaptureSVNStatus(files):
"""Returns the svn 1.5 svn status emulated output.
def __str__(self):
# Emulate svn status 1.5 output.
return (self.text_status + self.props + self.lock + self.history + ' ' +
self.path)
def CaptureSVNStatus(path):
"""Runs 'svn status' on an existing path.
Args:
path: The directory to run svn status.
@files can be a string (one file) or a list of files.
Returns:
An array of FileStatus corresponding to the emulated output of 'svn status'
version 1.5."""
dom = ParseXML(CaptureSVN(["status", "--xml"], path))
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 = ParseXML(CaptureSVN(command))
results = []
if dom:
# /status/target/entry/(wc-status|commit|author|date)
......@@ -649,18 +658,8 @@ def CaptureSVNStatus(path):
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 xml_item_status in ('incomplete', 'missing'):
statuses[0] = '!'
elif not xml_item_status:
pass
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)
......@@ -682,8 +681,7 @@ def CaptureSVNStatus(path):
# Col 3
if wc_status[0].getAttribute('copied') == 'true':
statuses[3] = '+'
item = FileStatus(file, statuses[0], statuses[1], statuses[2],
statuses[3])
item = (''.join(statuses), file)
results.append(item)
return results
......@@ -856,10 +854,10 @@ class SCMWrapper(object):
# Batch the command.
files_to_revert = []
for file in files:
file_path = os.path.join(path, file.path)
file_path = os.path.join(path, file[1])
print(file_path)
# Unversioned file or unexpected unversioned file.
if file.text_status in ('?', '~'):
if file[0][0] in ('?', '~'):
# Remove extraneous file. Also remove unexpected unversioned
# directories. svn won't touch them but we want to delete these.
file_list.append(file_path)
......@@ -868,10 +866,10 @@ class SCMWrapper(object):
except EnvironmentError:
RemoveDirectory(file_path)
if file.text_status != '?':
if file[0][0] != '?':
# For any other status, svn revert will work.
file_list.append(file_path)
files_to_revert.append(file.path)
files_to_revert.append(file[1])
# Revert them all at once.
if files_to_revert:
......
......@@ -48,7 +48,7 @@ class GclUnittest(GclTestsBase):
'ErrorExit', 'GenerateChangeName', 'GenerateDiff', 'GetCLs',
'GetChangelistInfoFile', 'GetCodeReviewSetting', 'GetEditor',
'GetFilesNotInCL', 'GetInfoDir', 'GetIssueDescription',
'GetModifiedFiles', 'GetRepositoryRoot', 'GetSVNStatus',
'GetModifiedFiles', 'GetRepositoryRoot',
'GetSVNFileProperty', 'Help', 'IGNORE_PATHS', 'IsSVNMoved', 'IsTreeOpen',
'Lint', 'LoadChangelistInfo', 'LoadChangelistInfoForMultiple',
'MISSING_TEST_MSG', 'Opened', 'PresubmitCL', 'ReadFile',
......@@ -62,70 +62,6 @@ class GclUnittest(GclTestsBase):
# If this test fails, you should add the relevant test.
self.compareMembers(gcl, members)
def testGetSVNStatus(self):
def RunShellMock(command):
return r"""<?xml version="1.0"?>
<status>
<target path=".">
<entry path="unversionned_file.txt">
<wc-status props="none" item="unversioned"></wc-status>
</entry>
<entry path="build\internal\essential.vsprops">
<wc-status props="normal" item="modified" revision="14628">
<commit revision="13818">
<author>ajwong@chromium.org</author>
<date>2009-04-16T00:42:06.872358Z</date>
</commit>
</wc-status>
</entry>
<entry path="chrome\app\d">
<wc-status props="none" copied="true" tree-conflicted="true" item="added">
</wc-status>
</entry>
<entry path="chrome\app\DEPS">
<wc-status props="modified" item="modified" revision="14628">
<commit revision="1279">
<author>brettw@google.com</author>
<date>2008-08-23T17:16:42.090152Z</date>
</commit>
</wc-status>
</entry>
<entry path="scripts\master\factory\gclient_factory.py">
<wc-status props="normal" item="conflicted" revision="14725">
<commit revision="14633">
<author>nsylvain@chromium.org</author>
<date>2009-04-27T19:37:17.977400Z</date>
</commit>
</wc-status>
</entry>
</target>
</status>
"""
# GclTestsBase.tearDown will restore the original.
gcl.RunShell = RunShellMock
info = gcl.GetSVNStatus('.')
expected = [
('? ', 'unversionned_file.txt'),
('M ', 'build\\internal\\essential.vsprops'),
('A + ', 'chrome\\app\\d'),
('MM ', 'chrome\\app\\DEPS'),
('C ', 'scripts\\master\\factory\\gclient_factory.py'),
]
self.assertEquals(sorted(info), sorted(expected))
def testGetSVNStatusEmpty(self):
def RunShellMock(command):
return r"""<?xml version="1.0"?>
<status>
<target
path="perf">
</target>
</status>
"""
# GclTestsBase.tearDown will restore the original.
gcl.RunShell = RunShellMock
info = gcl.GetSVNStatus(None)
self.assertEquals(info, [])
def testHelp(self):
old_stdout = sys.stdout
......
......@@ -1159,8 +1159,8 @@ class SCMWrapperTestCase(GClientBaseTestCase):
gclient.os.path.isdir = self.mox.CreateMockAnything()
gclient.os.path.isdir(base_path).AndReturn(True)
items = [
gclient.FileStatus('a', 'M', ' ', ' ', ' '),
gclient.FileStatus('b', 'A', ' ', ' ', ' '),
('M ', 'a'),
('A ', 'b'),
]
gclient.CaptureSVNStatus(base_path).AndReturn(items)
......@@ -1387,6 +1387,73 @@ class SubprocessCallAndCaptureTestCase(BaseTestCase):
self.assertEquals(capture_list, ['cc', 'dd'])
self.mox.VerifyAll()
def testCaptureSVNStatus(self):
x = self
def CaptureSVNMock(command):
x.assertEquals(['status', '--xml', '.'], command)
return r"""<?xml version="1.0"?>
<status>
<target path=".">
<entry path="unversionned_file.txt">
<wc-status props="none" item="unversioned"></wc-status>
</entry>
<entry path="build\internal\essential.vsprops">
<wc-status props="normal" item="modified" revision="14628">
<commit revision="13818">
<author>ajwong@chromium.org</author>
<date>2009-04-16T00:42:06.872358Z</date>
</commit>
</wc-status>
</entry>
<entry path="chrome\app\d">
<wc-status props="none" copied="true" tree-conflicted="true" item="added">
</wc-status>
</entry>
<entry path="chrome\app\DEPS">
<wc-status props="modified" item="modified" revision="14628">
<commit revision="1279">
<author>brettw@google.com</author>
<date>2008-08-23T17:16:42.090152Z</date>
</commit>
</wc-status>
</entry>
<entry path="scripts\master\factory\gclient_factory.py">
<wc-status props="normal" item="conflicted" revision="14725">
<commit revision="14633">
<author>nsylvain@chromium.org</author>
<date>2009-04-27T19:37:17.977400Z</date>
</commit>
</wc-status>
</entry>
</target>
</status>
"""
gclient.CaptureSVN = CaptureSVNMock
info = gclient.CaptureSVNStatus('.')
expected = [
('? ', 'unversionned_file.txt'),
('M ', 'build\\internal\\essential.vsprops'),
('A + ', 'chrome\\app\\d'),
('MM ', 'chrome\\app\\DEPS'),
('C ', 'scripts\\master\\factory\\gclient_factory.py'),
]
self.assertEquals(sorted(info), sorted(expected))
def testCaptureSVNStatusEmpty(self):
x = self
def CaptureSVNMock(command):
x.assertEquals(['status', '--xml'], command)
return r"""<?xml version="1.0"?>
<status>
<target
path="perf">
</target>
</status>
"""
gclient.CaptureSVN = CaptureSVNMock
info = gclient.CaptureSVNStatus(None)
self.assertEquals(info, [])
if __name__ == '__main__':
unittest.main()
......
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