Commit b4ba3389 authored by Philip Thiem's avatar Philip Thiem

Additional Tests, Various fixes, and encoding dealings

--HG--
extra : rebase_source : 2734e79e08e194923eab8c70f92cb77bce7daccf
parent 411379b7
......@@ -217,7 +217,7 @@ class egg_info(Command):
@staticmethod
def get_svn_revision():
return str(svn_utils.parse_revision(os.curdir))
return str(svn_utils.SvnInfo.load(os.curdir).get_revision())
......
......@@ -8,73 +8,58 @@ from setuptools import svn_utils
READMES = ('README', 'README.rst', 'README.txt')
entities = [
("&lt;","<"), ("&gt;", ">"), ("&quot;", '"'), ("&apos;", "'"),
("&amp;", "&")
]
def unescape(data):
for old,new in entities:
data = data.replace(old,new)
return data
def walk_revctrl(dirname=''):
"""Find all files under revision control"""
for ep in pkg_resources.iter_entry_points('setuptools.file_finders'):
for item in ep.load()(dirname):
yield item
#TODO will need test case
class re_finder(object):
def re_finder(pattern, postproc=None):
def find(dirname, filename):
def __init__(self, path, pattern, postproc=None):
self.pattern = pattern
self.postproc = postproc
self.path = convert_path(path)
def _finder(self, dirname, filename):
f = open(filename,'rU')
try:
data = f.read()
finally:
f.close()
for match in pattern.finditer(data):
for match in self.pattern.finditer(data):
path = match.group(1)
if postproc:
#postproc used to be used when the svn finder
#was an re_finder for calling unescape
path = postproc(path)
yield joinpath(dirname,path)
return find
def joinpath(prefix,suffix):
if not prefix:
return suffix
return os.path.join(prefix,suffix)
yield svn_utils.joinpath(dirname,path)
def __call__(self, dirname=''):
path = svn_utils.joinpath(dirname, self.path)
def walk_revctrl(dirname=''):
"""Find all files under revision control"""
for ep in pkg_resources.iter_entry_points('setuptools.file_finders'):
for item in ep.load()(dirname):
yield item
def _default_revctrl(dirname=''):
for path, finder in finders:
path = joinpath(dirname,path)
if os.path.isfile(path):
for path in finder(dirname,path):
for path in self._finder(dirname,path):
if os.path.isfile(path):
yield path
elif os.path.isdir(path):
for item in _default_revctrl(path):
for item in self.find(path):
yield item
def entries_externals_finder(dirname, filename):
for record in svn_utils.parse_dir_entries(dirname):
yield joinpath(dirname, record)
for name in svn_utils.parse_externals(dirname):
yield joinpath(dirname, name)
def _default_revctrl(dirname=''):
'Primary svn_cvs entry point'
for finder in finders:
for item in finder(dirname):
yield item
finders = [
(convert_path('CVS/Entries'),
re_finder(re.compile(r"^\w?/([^/]+)/", re.M))),
#combined externals due to common interface
#combined externals and enteries due to lack of dir_props in 1.7
(convert_path('.svn/entries'), entries_externals_finder),
re_finder('CVS/Entries', re.compile(r"^\w?/([^/]+)/", re.M)),
svn_utils.svn_finder,
]
......@@ -88,6 +73,7 @@ finders = [
class sdist(_sdist):
"""Smart sdist that finds anything supported by revision control"""
......
......@@ -26,6 +26,7 @@ if sys.version_info[0] < 3:
reduce = reduce
unichr = unichr
unicode = unicode
bytes = str
from urllib import url2pathname
import urllib2
from urllib2 import urlopen, HTTPError, URLError, unquote, splituser
......@@ -69,6 +70,7 @@ else:
from functools import reduce
unichr = chr
unicode = str
bytes = bytes
from urllib.error import HTTPError, URLError
import urllib.request as urllib2
from urllib.request import urlopen, url2pathname
......
import os
import re
import sys
import codecs
from distutils import log
import xml.dom.pulldom
import shlex
import locale
import unicodedata
from setuptools.compat import unicode, bytes
try:
import urlparse
except ImportError:
import urllib.parse as urlparse
#requires python >= 2.4
from subprocess import Popen as _Popen, PIPE as _PIPE
#NOTE: Use of the command line options
# require SVN 1.3 or newer (December 2005)
# and SVN 1.3 hsan't been supported by the
# developers since mid 2008.
#svnversion return values (previous implementations return max revision)
# 4123:4168 mixed revision working copy
# 4168M modified working copy
# 4123S switched working copy
# 4123:4168MS mixed revision, modified, switched working copy
_SVN_VER_RE = re.compile(r'(?:([\-0-9]+):)?(\d+)([a-z]*)\s*$', re.I)
#NOTE: Use of the command line options require SVN 1.3 or newer (December 2005)
# and SVN 1.3 hasn't been supported by the developers since mid 2008.
#subprocess is called several times with shell=(sys.platform=='win32')
#see the follow for more information:
......@@ -35,6 +26,7 @@ _SVN_VER_RE = re.compile(r'(?:([\-0-9]+):)?(\d+)([a-z]*)\s*$', re.I)
def _run_command(args, stdout=_PIPE, stderr=_PIPE):
#regarding the shell argument, see: http://bugs.python.org/issue8557
try:
args = [fsdecode(x) for x in args]
proc = _Popen(args, stdout=stdout, stderr=stderr,
shell=(sys.platform == 'win32'))
......@@ -42,20 +34,12 @@ def _run_command(args, stdout=_PIPE, stderr=_PIPE):
except OSError:
return 1, ''
#TODO: this is probably NOT always utf-8
try:
data = unicode(data, encoding='utf-8')
except NameError:
data = str(data, encoding='utf-8')
data = consoledecode(data)
#communciate calls wait()
return proc.returncode, data
def _get_entry_name(entry):
return entry.getAttribute('path')
def _get_entry_schedule(entry):
schedule = entry.getElementsByTagName('schedule')[0]
return "".join([t.nodeValue
......@@ -63,105 +47,283 @@ def _get_entry_schedule(entry):
if t.nodeType == t.TEXT_NODE])
def parse_revision(path):
code, data = _run_command(['svnversion', '-c', path])
def _get_target_property(target):
property_text = target.getElementsByTagName('property')[0]
return "".join([t.nodeValue
for t in property_text.childNodes
if t.nodeType == t.TEXT_NODE])
if code:
log.warn("svnversion failed")
return 0
def _get_xml_data(decoded_str):
if sys.version_info < (3, 0):
#old versions want an encoded string
data = decoded_str.encode('utf-8')
else:
log.warn('Version: %s' % data.strip())
data = decoded_str
return data
parsed = _SVN_VER_RE.match(data)
if parsed:
try:
#No max needed this command summarizes working copy since 1.0
return int(parsed.group(2))
except ValueError:
#This should only happen if the revision is WAY too big.
pass
return 0
#TODO: Need to do this with the -R because only root has .svn in 1.7.x
def parse_dir_entries(path):
code, data = _run_command(['svn', 'info',
'--depth', 'immediates', '--xml', path])
def joinpath(prefix, suffix):
if not prefix or prefix == '.':
return suffix
return os.path.join(prefix, suffix)
if code:
log.warn("svn info failed")
return []
data = codecs.encode(data, 'UTF-8')
def fsencode(path):
"Path must be unicode or in file system encoding already"
encoding = sys.getfilesystemencoding()
if isinstance(path, unicode):
path = path.encode()
elif not isinstance(path, bytes):
raise TypeError('%s is not a string or byte type'
% type(path).__name__)
doc = xml.dom.pulldom.parseString(data)
#getfilessystemencoding doesn't have the mac-roman issue
if encoding == 'utf-8' and sys.platform == 'darwin':
path = path.decode('utf-8')
path = unicodedata.normalize('NFD', path)
path = path.encode('utf-8')
return path
def fsdecode(path):
"Path must be unicode or in file system encoding already"
encoding = sys.getfilesystemencoding()
if isinstance(path, bytes):
path = path.decode(encoding)
elif not isinstance(path, unicode):
raise TypeError('%s is not a byte type'
% type(path).__name__)
return unicodedata.normalize('NFC', path)
def consoledecode(text):
encoding = locale.getpreferredencoding()
return text.decode(encoding)
def parse_dir_entries(decoded_str):
'''Parse the entries from a recursive info xml'''
doc = xml.dom.pulldom.parseString(_get_xml_data(decoded_str))
entries = list()
for event, node in doc:
if event == 'START_ELEMENT' and node.nodeName == 'entry':
doc.expandNode(node)
entries.append(node)
if entries:
return [
_get_entry_name(element)
for element in entries[1:]
if _get_entry_schedule(element).lower() != 'deleted'
]
else:
return []
if not _get_entry_schedule(node).startswith('delete'):
entries.append((node.getAttribute('path'),
node.getAttribute('kind')))
return entries[1:] # do not want the root directory
#--xml wasn't supported until 1.5.x need to do -R
#TODO: -R looks like directories are seperated by blank lines
# with dir - prepened to first directory
# what about directories with spaces?
# put quotes around them
# what about the URL's?
# same
# convert to UTF-8 and use csv
# delimiter = space
#
#-R without --xml parses a bit funny
def parse_externals(path):
try:
code, lines = _run_command(['svn',
'propget', 'svn:externals', path])
if code:
log.warn("svn propget failed")
return []
def parse_externals_xml(decoded_str, prefix=''):
'''Parse a propget svn:externals xml'''
prefix = os.path.normpath(prefix)
doc = xml.dom.pulldom.parseString(_get_xml_data(decoded_str))
externals = list()
for event, node in doc:
if event == 'START_ELEMENT' and node.nodeName == 'target':
doc.expandNode(node)
path = os.path.normpath(node.getAttribute('path'))
if os.path.normcase(path).startswith(prefix):
path = path[len(prefix)+1:]
data = _get_target_property(node)
for external in parse_external_prop(data):
externals.append(joinpath(path, external))
lines = [line for line in lines.splitlines() if line]
except ValueError:
lines = []
return externals # do not want the root directory
def parse_external_prop(lines):
"""
Parse the value of a retrieved svn:externals entry.
possible token setups (with quotng and backscaping in laters versions)
URL[@#] EXT_FOLDERNAME
[-r#] URL EXT_FOLDERNAME
EXT_FOLDERNAME [-r#] URL
"""
externals = []
for line in lines:
line = line.split()
for line in lines.splitlines():
line = line.lstrip() #there might be a "\ "
if not line:
continue
if sys.version_info < (3, 0):
#shlex handles NULLs just fine and shlex in 2.7 tries to encode
#as ascii automatiically
line = line.encode('utf-8')
line = shlex.split(line)
if sys.version_info < (3, 0):
line = [x.decode('utf-8') for x in line]
#EXT_FOLDERNAME is either the first or last depending on where
#the URL falls
if urlparse.urlsplit(line[-1])[0]:
externals.append(line[0])
external = line[0]
else:
externals.append(line[-1])
external = line[-1]
externals.append(os.path.normpath(external))
return externals
def get_svn_tool_version():
_, data = _run_command(['svn', '--version', '--quiet'])
if data:
return data.strip()
class SvnInfo(object):
'''
Generic svn_info object. No has little knowledge of how to extract
information. Use cls.load to instatiate according svn version.
Paths are not filesystem encoded.
'''
@staticmethod
def get_svn_version():
code, data = _run_command(['svn', '--version', '--quiet'])
if code == 0 and data:
return unicode(data).strip()
else:
return unicode('')
#svnversion return values (previous implementations return max revision)
# 4123:4168 mixed revision working copy
# 4168M modified working copy
# 4123S switched working copy
# 4123:4168MS mixed revision, modified, switched working copy
revision_re = re.compile(r'(?:([\-0-9]+):)?(\d+)([a-z]*)\s*$', re.I)
@classmethod
def load(cls, dirname=''):
code, data = _run_command(['svn', 'info', os.path.normpath(dirname)])
svn_version = tuple(cls.get_svn_version().split('.'))
base_svn_version = tuple(int(x) for x in svn_version[:2])
if code and base_svn_version:
#Not an SVN repository or compatible one
return SvnInfo(dirname)
elif base_svn_version < (1, 3):
log.warn('Insufficent version of SVN found')
return SvnInfo(dirname)
elif base_svn_version < (1, 5):
return Svn13Info(dirname)
else:
return ''
return Svn15Info(dirname)
if __name__ == '__main__':
def entries_externals_finder(dirname):
for record in parse_dir_entries(dirname):
yield os.path.join(dirname, record)
def __init__(self, path=''):
self.path = path
self._entries = None
self._externals = None
for name in parse_externals(dirname):
yield os.path.join(dirname, name)
def get_revision(self):
'Retrieve the directory revision informatino using svnversion'
code, data = _run_command(['svnversion', '-c', self.path])
if code:
log.warn("svnversion failed")
return 0
for name in entries_externals_finder(sys.argv[1]):
parsed = self.revision_re.match(data)
if parsed:
return int(parsed.group(2))
else:
return 0
@property
def entries(self):
if self._entries is None:
self._entries = self.get_entries()
return self._entries
@property
def externals(self):
if self._externals is None:
self._externals = self.get_externals()
return self._externals
def iter_externals(self):
'''
Iterate over the svn:external references in the repository path.
'''
for item in self.externals:
yield item
def iter_files(self):
'''
Iterate over the non-deleted file entries in the repository path
'''
for item, kind in self.entries:
if kind.lower()=='file':
yield item
def iter_dirs(self, include_root=True):
'''
Iterate over the non-deleted file entries in the repository path
'''
if include_root:
yield self.path
for item, kind in self.entries:
if kind.lower()=='dir':
yield item
def get_entries(self):
return []
def get_externals(self):
return []
class Svn13Info(SvnInfo):
def get_entries(self):
code, data = _run_command(['svn', 'info', '-R', '--xml', self.path])
if code:
log.debug("svn info failed")
return []
return parse_dir_entries(data)
def get_externals(self):
#Previous to 1.5 --xml was not supported for svn propget and the -R
#output format breaks the shlex compatible semantics.
cmd = ['svn', 'propget', 'svn:externals']
result = []
for folder in self.iter_dirs():
code, lines = _run_command(cmd + [folder])
if code != 0:
log.warn("svn propget failed")
return []
for external in parse_external_prop(lines):
if folder:
external = os.path.join(folder, external)
result.append(os.path.normpath(external))
return result
class Svn15Info(Svn13Info):
def get_externals(self):
cmd = ['svn', 'propget', 'svn:externals', self.path, '-R', '--xml']
code, lines = _run_command(cmd)
if code:
log.debug("svn propget failed")
return []
return parse_externals_xml(lines, prefix=os.path.abspath(self.path))
def svn_finder(dirname=''):
#combined externals due to common interface
#combined externals and entries due to lack of dir_props in 1.7
info = SvnInfo.load(dirname)
for path in info.iter_files():
yield fsencode(path)
for path in info.iter_externals():
sub_info = SvnInfo.load(path)
for sub_path in sub_info.iter_files():
yield fsencode(sub_path)
if __name__ == '__main__':
for name in svn_finder(sys.argv[1]):
print(name)
\ No newline at end of file
import os
import zipfile
import sys
import tempfile
import unittest
import shutil
import stat
def _extract(self, member, path=None, pwd=None):
"""for zipfile py2.5 borrowed from cpython"""
if not isinstance(member, zipfile.ZipInfo):
member = self.getinfo(member)
if path is None:
path = os.getcwd()
return _extract_member(self, member, path, pwd)
def _extract_from_zip(self, name, dest_path):
dest_file = open(dest_path, 'wb')
try:
dest_file.write(self.read(name))
finally:
dest_file.close()
def _extract_member(self, member, targetpath, pwd):
"""for zipfile py2.5 borrowed from cpython"""
# build the destination pathname, replacing
# forward slashes to platform specific separators.
# Strip trailing path separator, unless it represents the root.
if (targetpath[-1:] in (os.path.sep, os.path.altsep)
and len(os.path.splitdrive(targetpath)[1]) > 1):
targetpath = targetpath[:-1]
# don't include leading "/" from file name if present
if member.filename[0] == '/':
targetpath = os.path.join(targetpath, member.filename[1:])
else:
targetpath = os.path.join(targetpath, member.filename)
targetpath = os.path.normpath(targetpath)
# Create all upper directories if necessary.
upperdirs = os.path.dirname(targetpath)
if upperdirs and not os.path.exists(upperdirs):
os.makedirs(upperdirs)
if member.filename[-1] == '/':
if not os.path.isdir(targetpath):
os.mkdir(targetpath)
return targetpath
_extract_from_zip(self, member.filename, targetpath)
return targetpath
def _remove_dir(target):
#on windows this seems to a problem
for dir_path, dirs, files in os.walk(target):
os.chmod(dir_path, stat.S_IWRITE)
for filename in files:
os.chmod(os.path.join(dir_path, filename), stat.S_IWRITE)
shutil.rmtree(target)
class ZippedEnvironment(unittest.TestCase):
datafile = None
dataname = None
old_cwd = None
def setUp(self):
if not os.path.isfile(self.datafile):
self.old_cwd = None
return
self.old_cwd = os.getcwd()
self.temp_dir = tempfile.mkdtemp()
zip_file, source, target = [None, None, None]
try:
zip_file = zipfile.ZipFile(self.datafile)
for files in zip_file.namelist():
_extract(zip_file, files, self.temp_dir)
finally:
if zip_file:
zip_file.close()
del zip_file
os.chdir(os.path.join(self.temp_dir, self.dataname))
def tearDown(self):
try:
if self.old_cwd:
os.chdir(self.old_cwd)
_remove_dir(self.temp_dir)
except OSError:
#sigh?
pass
third_party3 file:///C:/development/svn_example/repos/svn13/extra1
third_party2 -r3 file:///C:/development/svn_example/repos/svn13/extra1
third_party -r1 file:///C:/development/svn_example/repos/svn13/extra1
<?xml version="1.0" encoding="utf-8"?>
<info>
<entry
kind="dir"
path="svn13_example"
revision="6">
<url>file:///C:/development/svn_example/repos/svn13/main</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn13/main</root>
<uuid>d2996769-47b0-9946-b618-da1aa3eceda3</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<prop-updated>2013-07-13T15:33:23.187500Z</prop-updated>
</wc-info>
<commit
revision="6">
<author>ptt</author>
<date>2013-07-13T15:33:28.359375Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn13_example\a file"
revision="6">
<url>file:///C:/development/svn_example/repos/svn13/main/a%20file</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn13/main</root>
<uuid>d2996769-47b0-9946-b618-da1aa3eceda3</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<text-updated>2013-07-13T15:33:21.109375Z</text-updated>
<checksum>a6166e5e98a5a503089cde9bc8031293</checksum>
</wc-info>
<commit
revision="3">
<author>ptt</author>
<date>2013-07-13T15:33:21.312500Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn13_example\to_delete"
revision="6">
<url>file:///C:/development/svn_example/repos/svn13/main/to_delete</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn13/main</root>
<uuid>d2996769-47b0-9946-b618-da1aa3eceda3</uuid>
</repository>
<wc-info>
<schedule>delete</schedule>
<text-updated>2013-07-13T15:33:28.140625Z</text-updated>
<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
</wc-info>
<commit
revision="6">
<author>ptt</author>
<date>2013-07-13T15:33:28.359375Z</date>
</commit>
</entry>
<entry
kind="dir"
path="svn13_example\folder"
revision="6">
<url>file:///C:/development/svn_example/repos/svn13/main/folder</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn13/main</root>
<uuid>d2996769-47b0-9946-b618-da1aa3eceda3</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<prop-updated>2013-07-13T15:33:26.187500Z</prop-updated>
</wc-info>
<commit
revision="5">
<author>ptt</author>
<date>2013-07-13T15:33:26.312500Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn13_example\folder\quest.txt"
revision="6">
<url>file:///C:/development/svn_example/repos/svn13/main/folder/quest.txt</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn13/main</root>
<uuid>d2996769-47b0-9946-b618-da1aa3eceda3</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<text-updated>2013-07-13T15:33:20.109375Z</text-updated>
<checksum>795240c6a830c14f83961e57e07dad12</checksum>
</wc-info>
<commit
revision="2">
<author>ptt</author>
<date>2013-07-13T15:33:20.312500Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn13_example\folder\lalala.txt"
revision="6">
<url>file:///C:/development/svn_example/repos/svn13/main/folder/lalala.txt</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn13/main</root>
<uuid>d2996769-47b0-9946-b618-da1aa3eceda3</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<text-updated>2013-07-13T15:33:19.375000Z</text-updated>
<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
</wc-info>
<commit
revision="1">
<author>ptt</author>
<date>2013-07-13T15:33:19.609375Z</date>
</commit>
</entry>
</info>
third_party3 file:///C:/development/svn_example/repos/svn13/extra1
third_party2 -r3 file:///C:/development/svn_example/repos/svn13/extra1
third_party -r1 file:///C:/development/svn_example/repos/svn13/extra1
<?xml version="1.0"?>
<info>
<entry
kind="dir"
path="svn14_example"
revision="6">
<url>file:///C:/development/svn_example/repos/svn14/main</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn14/main</root>
<uuid>c75942e5-8b7a-354d-b1cf-73dee23fa94f</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
</wc-info>
<commit
revision="6">
<author>ptt</author>
<date>2013-07-13T15:34:14.406250Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn14_example\a file"
revision="6">
<url>file:///C:/development/svn_example/repos/svn14/main/a%20file</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn14/main</root>
<uuid>c75942e5-8b7a-354d-b1cf-73dee23fa94f</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<text-updated>2013-07-13T15:34:08.109375Z</text-updated>
<checksum>a6166e5e98a5a503089cde9bc8031293</checksum>
</wc-info>
<commit
revision="3">
<author>ptt</author>
<date>2013-07-13T15:34:08.390625Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn14_example\to_delete"
revision="6">
<url>file:///C:/development/svn_example/repos/svn14/main/to_delete</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn14/main</root>
<uuid>c75942e5-8b7a-354d-b1cf-73dee23fa94f</uuid>
</repository>
<wc-info>
<schedule>delete</schedule>
<text-updated>2013-07-13T15:34:14.125000Z</text-updated>
<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
</wc-info>
<commit
revision="6">
<author>ptt</author>
<date>2013-07-13T15:34:14.406250Z</date>
</commit>
</entry>
<entry
kind="dir"
path="svn14_example\folder"
revision="6">
<url>file:///C:/development/svn_example/repos/svn14/main/folder</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn14/main</root>
<uuid>c75942e5-8b7a-354d-b1cf-73dee23fa94f</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
</wc-info>
<commit
revision="5">
<author>ptt</author>
<date>2013-07-13T15:34:12.390625Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn14_example\folder\quest.txt"
revision="6">
<url>file:///C:/development/svn_example/repos/svn14/main/folder/quest.txt</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn14/main</root>
<uuid>c75942e5-8b7a-354d-b1cf-73dee23fa94f</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<text-updated>2013-07-13T15:34:07.109375Z</text-updated>
<checksum>795240c6a830c14f83961e57e07dad12</checksum>
</wc-info>
<commit
revision="2">
<author>ptt</author>
<date>2013-07-13T15:34:07.390625Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn14_example\folder\lalala.txt"
revision="6">
<url>file:///C:/development/svn_example/repos/svn14/main/folder/lalala.txt</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn14/main</root>
<uuid>c75942e5-8b7a-354d-b1cf-73dee23fa94f</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<text-updated>2013-07-13T15:34:06.250000Z</text-updated>
<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
</wc-info>
<commit
revision="1">
<author>ptt</author>
<date>2013-07-13T15:34:06.531250Z</date>
</commit>
</entry>
</info>
third_party3 file:///C:/development/svn_example/repos/svn15/extra1
-r3 file:///C:/development/svn_example/repos/svn15/extra1 third_party2
file:///C:/development/svn_example/repos/svn15/extra1@r1 third_party
<?xml version="1.0"?>
<properties>
<target
path="C:/development/svn_example/svn15_example/folder">
<property
name="svn:externals">third_party3 file:///C:/development/svn_example/repos/svn15/extra2
-r3 file:///C:/development/svn_example/repos/svn15/extra2 third_party2
file:///C:/development/svn_example/repos/svn15/extra2@r1 third_party大介
</property>
</target>
<target
path="C:/development/svn_example/svn15_example">
<property
name="svn:externals">third_party3 file:///C:/development/svn_example/repos/svn15/extra1
-r3 file:///C:/development/svn_example/repos/svn15/extra1 third_party2
file:///C:/development/svn_example/repos/svn15/extra1@r1 third_party大介
</property>
</target>
</properties>
<?xml version="1.0"?>
<info>
<entry
kind="dir"
path="svn15_example"
revision="6">
<url>file:///C:/development/svn_example/repos/svn15/main</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn15/main</root>
<uuid>4eab6983-54fe-384b-a282-9306f52d948f</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<depth>infinity</depth>
</wc-info>
<commit
revision="6">
<author>ptt</author>
<date>2013-07-13T15:34:49.562500Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn15_example\a file"
revision="6">
<url>file:///C:/development/svn_example/repos/svn15/main/a%20file</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn15/main</root>
<uuid>4eab6983-54fe-384b-a282-9306f52d948f</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<depth>infinity</depth>
<text-updated>2013-07-13T15:34:43.109375Z</text-updated>
<checksum>a6166e5e98a5a503089cde9bc8031293</checksum>
</wc-info>
<commit
revision="3">
<author>ptt</author>
<date>2013-07-13T15:34:43.484375Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn15_example\to_delete"
revision="6">
<url>file:///C:/development/svn_example/repos/svn15/main/to_delete</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn15/main</root>
<uuid>4eab6983-54fe-384b-a282-9306f52d948f</uuid>
</repository>
<wc-info>
<schedule>delete</schedule>
<depth>infinity</depth>
<text-updated>2013-07-13T15:34:49.125000Z</text-updated>
<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
</wc-info>
<commit
revision="6">
<author>ptt</author>
<date>2013-07-13T15:34:49.562500Z</date>
</commit>
</entry>
<entry
kind="dir"
path="svn15_example\folder"
revision="6">
<url>file:///C:/development/svn_example/repos/svn15/main/folder</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn15/main</root>
<uuid>4eab6983-54fe-384b-a282-9306f52d948f</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<depth>infinity</depth>
</wc-info>
<commit
revision="5">
<author>ptt</author>
<date>2013-07-13T15:34:47.515625Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn15_example\folder\quest.txt"
revision="6">
<url>file:///C:/development/svn_example/repos/svn15/main/folder/quest.txt</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn15/main</root>
<uuid>4eab6983-54fe-384b-a282-9306f52d948f</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<depth>infinity</depth>
<text-updated>2013-07-13T15:34:42.109375Z</text-updated>
<checksum>795240c6a830c14f83961e57e07dad12</checksum>
</wc-info>
<commit
revision="2">
<author>ptt</author>
<date>2013-07-13T15:34:42.484375Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn15_example\folder\lalala.txt"
revision="6">
<url>file:///C:/development/svn_example/repos/svn15/main/folder/lalala.txt</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn15/main</root>
<uuid>4eab6983-54fe-384b-a282-9306f52d948f</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<depth>infinity</depth>
<text-updated>2013-07-13T15:34:41.375000Z</text-updated>
<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
</wc-info>
<commit
revision="1">
<author>ptt</author>
<date>2013-07-13T15:34:41.734375Z</date>
</commit>
</entry>
</info>
"third party3" file:///C:/development/svn_example/repos/svn16/extra1
'third party3b' file:///C:/development/svn_example/repos/svn16/extra1
-r3 file:///C:/development/svn_example/repos/svn16/extra1 third\ party2
file:///C:/development/svn_example/repos/svn16/extra1@r1 third_party
<?xml version="1.0"?>
<properties>
<target
path="C:/development/svn_example/svn16_example/folder">
<property
name="svn:externals">"third party3" file:///C:/development/svn_example/repos/svn16/extra2
-r3 file:///C:/development/svn_example/repos/svn16/extra2 third\ party2
file:///C:/development/svn_example/repos/svn16/extra2@r1 third_party大介
</property>
</target>
<target
path="C:/development/svn_example/svn16_example">
<property
name="svn:externals">"third party3" file:///C:/development/svn_example/repos/svn16/extra1
-r3 file:///C:/development/svn_example/repos/svn16/extra1 third\ party2
file:///C:/development/svn_example/repos/svn16/extra1@r1 third_party大介
</property>
</target>
</properties>
<?xml version="1.0"?>
<info>
<entry
kind="dir"
path="svn16_example"
revision="6">
<url>file:///C:/development/svn_example/repos/svn16/main</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn16/main</root>
<uuid>bd8d2cfc-1a74-de45-b166-262010c17c0a</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<depth>infinity</depth>
</wc-info>
<commit
revision="6">
<author>ptt</author>
<date>2013-07-13T15:35:17.390625Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn16_example\a file"
revision="6">
<url>file:///C:/development/svn_example/repos/svn16/main/a%20file</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn16/main</root>
<uuid>bd8d2cfc-1a74-de45-b166-262010c17c0a</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<depth>infinity</depth>
<text-updated>2013-07-13T15:35:14.578125Z</text-updated>
<checksum>a6166e5e98a5a503089cde9bc8031293</checksum>
</wc-info>
<commit
revision="3">
<author>ptt</author>
<date>2013-07-13T15:35:14.906250Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn16_example\to_delete"
revision="6">
<url>file:///C:/development/svn_example/repos/svn16/main/to_delete</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn16/main</root>
<uuid>bd8d2cfc-1a74-de45-b166-262010c17c0a</uuid>
</repository>
<wc-info>
<schedule>delete</schedule>
<depth>infinity</depth>
<text-updated>2013-07-13T15:35:17.046875Z</text-updated>
<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
</wc-info>
<commit
revision="6">
<author>ptt</author>
<date>2013-07-13T15:35:17.390625Z</date>
</commit>
</entry>
<entry
kind="dir"
path="svn16_example\folder"
revision="6">
<url>file:///C:/development/svn_example/repos/svn16/main/folder</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn16/main</root>
<uuid>bd8d2cfc-1a74-de45-b166-262010c17c0a</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<depth>infinity</depth>
</wc-info>
<commit
revision="5">
<author>ptt</author>
<date>2013-07-13T15:35:16.406250Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn16_example\folder\quest.txt"
revision="6">
<url>file:///C:/development/svn_example/repos/svn16/main/folder/quest.txt</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn16/main</root>
<uuid>bd8d2cfc-1a74-de45-b166-262010c17c0a</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<depth>infinity</depth>
<text-updated>2013-07-13T15:35:14.078125Z</text-updated>
<checksum>795240c6a830c14f83961e57e07dad12</checksum>
</wc-info>
<commit
revision="2">
<author>ptt</author>
<date>2013-07-13T15:35:14.421875Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn16_example\folder\lalala.txt"
revision="6">
<url>file:///C:/development/svn_example/repos/svn16/main/folder/lalala.txt</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn16/main</root>
<uuid>bd8d2cfc-1a74-de45-b166-262010c17c0a</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<depth>infinity</depth>
<text-updated>2013-07-13T15:35:12.171875Z</text-updated>
<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
</wc-info>
<commit
revision="1">
<author>ptt</author>
<date>2013-07-13T15:35:13.906250Z</date>
</commit>
</entry>
</info>
"third party3" file:///C:/development/svn_example/repos/svn17/extra1
'third party3b' file:///C:/development/svn_example/repos/svn17/extra1
-r3 file:///C:/development/svn_example/repos/svn17/extra1 third\ party2
file:///C:/development/svn_example/repos/svn17/extra1@r1 third_party
<?xml version="1.0" encoding="UTF-8"?>
<properties>
<target
path="C:/development/svn_example/svn17_example">
<property
name="svn:externals">"third party3" file:///C:/development/svn_example/repos/svn16/extra1
-r3 file:///C:/development/svn_example/repos/svn16/extra1 third\ party2
file:///C:/development/svn_example/repos/svn16/extra1@r1 third_party大介
</property>
</target>
<target
path="C:/development/svn_example/svn17_example/folder">
<property
name="svn:externals">"third party3" file:///C:/development/svn_example/repos/svn17/extra2
-r3 file:///C:/development/svn_example/repos/svn17/extra2 third\ party2
file:///C:/development/svn_example/repos/svn17/extra2@r1 third_party大介
</property>
</target>
</properties>
<?xml version="1.0" encoding="UTF-8"?>
<info>
<entry
kind="dir"
path="svn17_example"
revision="6">
<url>file:///C:/development/svn_example/repos/svn17/main</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn17/main</root>
<uuid>5ba45434-5197-164e-afab-81923f4744f5</uuid>
</repository>
<wc-info>
<wcroot-abspath>C:/development/svn_example/svn17_example</wcroot-abspath>
<schedule>normal</schedule>
<depth>infinity</depth>
</wc-info>
<commit
revision="6">
<author>ptt</author>
<date>2013-07-13T15:35:36.171875Z</date>
</commit>
</entry>
<entry
path="svn17_example\folder"
revision="6"
kind="dir">
<url>file:///C:/development/svn_example/repos/svn17/main/folder</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn17/main</root>
<uuid>5ba45434-5197-164e-afab-81923f4744f5</uuid>
</repository>
<wc-info>
<wcroot-abspath>C:/development/svn_example/svn17_example</wcroot-abspath>
<schedule>normal</schedule>
<depth>infinity</depth>
</wc-info>
<commit
revision="5">
<author>ptt</author>
<date>2013-07-13T15:35:34.859375Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn17_example\folder\quest.txt"
revision="6">
<url>file:///C:/development/svn_example/repos/svn17/main/folder/quest.txt</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn17/main</root>
<uuid>5ba45434-5197-164e-afab-81923f4744f5</uuid>
</repository>
<wc-info>
<wcroot-abspath>C:/development/svn_example/svn17_example</wcroot-abspath>
<schedule>normal</schedule>
<depth>infinity</depth>
<text-updated>2013-07-13T15:35:32.812500Z</text-updated>
<checksum>bc80eba9e7a10c0a571a4678c520bc9683f3bac2</checksum>
</wc-info>
<commit
revision="2">
<author>ptt</author>
<date>2013-07-13T15:35:33.109375Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn17_example\folder\lalala.txt"
revision="6">
<url>file:///C:/development/svn_example/repos/svn17/main/folder/lalala.txt</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn17/main</root>
<uuid>5ba45434-5197-164e-afab-81923f4744f5</uuid>
</repository>
<wc-info>
<wcroot-abspath>C:/development/svn_example/svn17_example</wcroot-abspath>
<schedule>normal</schedule>
<depth>infinity</depth>
<text-updated>2013-07-13T15:35:32.343750Z</text-updated>
<checksum>da39a3ee5e6b4b0d3255bfef95601890afd80709</checksum>
</wc-info>
<commit
revision="1">
<author>ptt</author>
<date>2013-07-13T15:35:32.687500Z</date>
</commit>
</entry>
<entry
path="svn17_example\a file"
revision="6"
kind="file">
<url>file:///C:/development/svn_example/repos/svn17/main/a%20file</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn17/main</root>
<uuid>5ba45434-5197-164e-afab-81923f4744f5</uuid>
</repository>
<wc-info>
<wcroot-abspath>C:/development/svn_example/svn17_example</wcroot-abspath>
<schedule>normal</schedule>
<depth>infinity</depth>
<text-updated>2013-07-13T15:35:33.187500Z</text-updated>
<checksum>43785ab4b1816b49f242990883292813cd4f486c</checksum>
</wc-info>
<commit
revision="3">
<author>ptt</author>
<date>2013-07-13T15:35:33.515625Z</date>
</commit>
</entry>
<entry
path="svn17_example\to_delete"
revision="6"
kind="file">
<url>file:///C:/development/svn_example/repos/svn17/main/to_delete</url>
<repository>
<root>file:///C:/development/svn_example/repos/svn17/main</root>
<uuid>5ba45434-5197-164e-afab-81923f4744f5</uuid>
</repository>
<wc-info>
<wcroot-abspath>C:/development/svn_example/svn17_example</wcroot-abspath>
<schedule>delete</schedule>
<depth>infinity</depth>
<checksum>da39a3ee5e6b4b0d3255bfef95601890afd80709</checksum>
</wc-info>
<commit
revision="6">
<author>ptt</author>
<date>2013-07-13T15:35:36.171875Z</date>
</commit>
</entry>
</info>
"third party3" file:///C:/development/svn_example/repos/svn18/extra1
'third party3b' file:///C:/development/svn_example/repos/svn18/extra1
-r3 file:///C:/development/svn_example/repos/svn18/extra1 third\ party2
file:///C:/development/svn_example/repos/svn18/extra1@r1 third_party
<?xml version="1.0" encoding="UTF-8"?>
<properties>
<target
path="C:/development/svn_example/svn18_example">
<property
name="svn:externals">"third party3" file:///C:/development/svn_example/repos/svn16/extra1
-r3 file:///C:/development/svn_example/repos/svn16/extra1 third\ party2
file:///C:/development/svn_example/repos/svn16/extra1@r1 third_party大介
</property>
</target>
<target
path="C:/development/svn_example/svn18_example/folder">
<property
name="svn:externals">"third party3" file:///C:/development/svn_example/repos/svn18/extra2
-r3 file:///C:/development/svn_example/repos/svn18/extra2 third\ party2
file:///C:/development/svn_example/repos/svn18/extra2@r1 third_party大介
</property>
</target>
</properties>
<?xml version="1.0" encoding="UTF-8"?>
<info>
<entry
path="svn18_example"
revision="6"
kind="dir">
<url>file:///C:/development/svn_example/repos/svn18/main</url>
<relative-url>^/</relative-url>
<repository>
<root>file:///C:/development/svn_example/repos/svn18/main</root>
<uuid>3c5e3929-c92b-7045-9ba9-5e65d3dd1ee9</uuid>
</repository>
<wc-info>
<wcroot-abspath>C:/development/svn_example/svn18_example</wcroot-abspath>
<schedule>normal</schedule>
<depth>infinity</depth>
</wc-info>
<commit
revision="6">
<author>ptt</author>
<date>2013-07-13T15:35:57.796875Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn18_example\a file"
revision="6">
<url>file:///C:/development/svn_example/repos/svn18/main/a%20file</url>
<relative-url>^/a%20file</relative-url>
<repository>
<root>file:///C:/development/svn_example/repos/svn18/main</root>
<uuid>3c5e3929-c92b-7045-9ba9-5e65d3dd1ee9</uuid>
</repository>
<wc-info>
<wcroot-abspath>C:/development/svn_example/svn18_example</wcroot-abspath>
<schedule>normal</schedule>
<depth>infinity</depth>
<text-updated>2013-07-13T15:35:54.906250Z</text-updated>
<checksum>43785ab4b1816b49f242990883292813cd4f486c</checksum>
</wc-info>
<commit
revision="3">
<author>ptt</author>
<date>2013-07-13T15:35:55.265625Z</date>
</commit>
</entry>
<entry
kind="file"
path="svn18_example\to_delete"
revision="6">
<url>file:///C:/development/svn_example/repos/svn18/main/to_delete</url>
<relative-url>^/to_delete</relative-url>
<repository>
<root>file:///C:/development/svn_example/repos/svn18/main</root>
<uuid>3c5e3929-c92b-7045-9ba9-5e65d3dd1ee9</uuid>
</repository>
<wc-info>
<wcroot-abspath>C:/development/svn_example/svn18_example</wcroot-abspath>
<schedule>delete</schedule>
<depth>infinity</depth>
<checksum>da39a3ee5e6b4b0d3255bfef95601890afd80709</checksum>
</wc-info>
<commit
revision="6">
<author>ptt</author>
<date>2013-07-13T15:35:57.796875Z</date>
</commit>
</entry>
<entry
kind="dir"
path="svn18_example\folder"
revision="6">
<url>file:///C:/development/svn_example/repos/svn18/main/folder</url>
<relative-url>^/folder</relative-url>
<repository>
<root>file:///C:/development/svn_example/repos/svn18/main</root>
<uuid>3c5e3929-c92b-7045-9ba9-5e65d3dd1ee9</uuid>
</repository>
<wc-info>
<wcroot-abspath>C:/development/svn_example/svn18_example</wcroot-abspath>
<schedule>normal</schedule>
<depth>infinity</depth>
</wc-info>
<commit
revision="5">
<author>ptt</author>
<date>2013-07-13T15:35:56.750000Z</date>
</commit>
</entry>
<entry
path="svn18_example\folder\quest.txt"
revision="6"
kind="file">
<url>file:///C:/development/svn_example/repos/svn18/main/folder/quest.txt</url>
<relative-url>^/folder/quest.txt</relative-url>
<repository>
<root>file:///C:/development/svn_example/repos/svn18/main</root>
<uuid>3c5e3929-c92b-7045-9ba9-5e65d3dd1ee9</uuid>
</repository>
<wc-info>
<wcroot-abspath>C:/development/svn_example/svn18_example</wcroot-abspath>
<schedule>normal</schedule>
<depth>infinity</depth>
<text-updated>2013-07-13T15:35:54.484375Z</text-updated>
<checksum>bc80eba9e7a10c0a571a4678c520bc9683f3bac2</checksum>
</wc-info>
<commit
revision="2">
<author>ptt</author>
<date>2013-07-13T15:35:54.843750Z</date>
</commit>
</entry>
<entry
path="svn18_example\folder\lalala.txt"
revision="6"
kind="file">
<url>file:///C:/development/svn_example/repos/svn18/main/folder/lalala.txt</url>
<relative-url>^/folder/lalala.txt</relative-url>
<repository>
<root>file:///C:/development/svn_example/repos/svn18/main</root>
<uuid>3c5e3929-c92b-7045-9ba9-5e65d3dd1ee9</uuid>
</repository>
<wc-info>
<wcroot-abspath>C:/development/svn_example/svn18_example</wcroot-abspath>
<schedule>normal</schedule>
<depth>infinity</depth>
<text-updated>2013-07-13T15:35:54.015625Z</text-updated>
<checksum>da39a3ee5e6b4b0d3255bfef95601890afd80709</checksum>
</wc-info>
<commit
revision="1">
<author>ptt</author>
<date>2013-07-13T15:35:54.375000Z</date>
</commit>
</entry>
</info>
import os
import sys
import tempfile
import shutil
import unittest
import pkg_resources
from setuptools.command import egg_info
from setuptools import svn_utils
ENTRIES_V10 = pkg_resources.resource_string(__name__, 'entries-v10')
"An entries file generated with svn 1.6.17 against the legacy Setuptools repo"
......@@ -31,6 +33,17 @@ class TestEggInfo(unittest.TestCase):
def test_version_10_format(self):
"""
"""
#keeping this set for 1.6 is a good check on the get_svn_revision
#to ensure I return using svnversion what would had been returned
version_str = svn_utils.SvnInfo.get_svn_version()
version = [int(x) for x in version_str.split('.')[:2]]
if version != [1,6]:
if hasattr(self, 'skipTest'):
self.skipTest('')
else:
sys.stderr.write('\n Skipping due to SVN Version\n')
return
self._write_entries(ENTRIES_V10)
rev = egg_info.egg_info.get_svn_revision()
self.assertEqual(rev, '89000')
......
......@@ -8,12 +8,14 @@ import sys
import tempfile
import unittest
import unicodedata
from setuptools.tests import environment
from setuptools.compat import StringIO, unicode
from setuptools.command.sdist import sdist
from setuptools.command.sdist import sdist, walk_revctrl
from setuptools.command.egg_info import manifest_maker
from setuptools.dist import Distribution
from setuptools import svn_utils
from setuptools.svn_utils import fsencode
SETUP_ATTRS = {
'name': 'sdist_test',
......@@ -395,6 +397,64 @@ class TestSdistTest(unittest.TestCase):
self.assertTrue(filename in cmd.filelist.files)
class TestSvn(environment.ZippedEnvironment):
def setUp(self):
version = svn_utils.SvnInfo.get_svn_version()
self.base_version = tuple([int(x) for x in version.split('.')][:2])
if not self.base_version:
raise ValueError('No SVN tools installed')
elif self.base_version < (1,3):
raise ValueError('Insufficient SVN Version %s' % version)
elif self.base_version >= (1,9):
#trying the latest version
self.base_version = (1,8)
self.dataname = "svn%i%i_example" % self.base_version
self.datafile = os.path.join('setuptools', 'tests',
'svn_data', self.dataname + ".zip")
super(TestSvn, self).setUp()
def test_walksvn(self):
if self.base_version >= (1,6):
folder2 = 'third party2'
folder3 = 'third party3'
else:
folder2 = 'third_party2'
folder3 = 'third_party3'
#TODO is this right
expected = set([
os.path.join('a file'),
os.path.join(folder2, 'Changes.txt'),
os.path.join(folder2, 'MD5SUMS'),
os.path.join(folder2, 'README.txt'),
os.path.join(folder3, 'Changes.txt'),
os.path.join(folder3, 'MD5SUMS'),
os.path.join(folder3, 'README.txt'),
os.path.join(folder3, 'TODO.txt'),
os.path.join(folder3, 'fin'),
os.path.join('third_party', 'README.txt'),
os.path.join('folder', folder2, 'Changes.txt'),
os.path.join('folder', folder2, 'MD5SUMS'),
os.path.join('folder', folder2, 'WatashiNiYomimasu.txt'),
os.path.join( 'folder', folder3, 'Changes.txt'),
os.path.join('folder', folder3, 'fin'),
os.path.join('folder', folder3, 'MD5SUMS'),
os.path.join('folder', folder3, 'oops'),
os.path.join('folder', folder3, 'WatashiNiYomimasu.txt'),
os.path.join('folder', folder3, 'ZuMachen.txt'),
os.path.join('folder', 'third_party', 'WatashiNiYomimasu.txt'),
os.path.join('folder', 'lalala.txt'),
os.path.join('folder', 'quest.txt'),
#The example will have a deleted file (or should) but shouldn't return it
])
expected = set(fsencode(x) for x in expected)
self.assertEqual(set(x for x in walk_revctrl()), expected)
def test_suite():
return unittest.defaultTestLoader.loadTestsFromName(__name__)
......@@ -3,77 +3,20 @@
import os
import zipfile
import sys
import tempfile
import unittest
import shutil
import stat
import codecs
from setuptools.tests import environment
from setuptools.svn_utils import fsencode
from setuptools.compat import unicode, unichr
from setuptools import svn_utils
from setuptools.command import egg_info
from setuptools.command import sdist
#requires python >= 2.4
from subprocess import call as _call
def _extract(self, member, path=None, pwd=None):
"""for zipfile py2.5 borrowed from cpython"""
if not isinstance(member, zipfile.ZipInfo):
member = self.getinfo(member)
from distutils import log
if path is None:
path = os.getcwd()
return _extract_member(self, member, path, pwd)
def _extract_from_zip(self, name, dest_path):
dest_file = open(dest_path, 'wb')
try:
dest_file.write(self.read(name))
finally:
dest_file.close()
def _extract_member(self, member, targetpath, pwd):
"""for zipfile py2.5 borrowed from cpython"""
# build the destination pathname, replacing
# forward slashes to platform specific separators.
# Strip trailing path separator, unless it represents the root.
if (targetpath[-1:] in (os.path.sep, os.path.altsep)
and len(os.path.splitdrive(targetpath)[1]) > 1):
targetpath = targetpath[:-1]
# don't include leading "/" from file name if present
if member.filename[0] == '/':
targetpath = os.path.join(targetpath, member.filename[1:])
else:
targetpath = os.path.join(targetpath, member.filename)
targetpath = os.path.normpath(targetpath)
# Create all upper directories if necessary.
upperdirs = os.path.dirname(targetpath)
if upperdirs and not os.path.exists(upperdirs):
os.makedirs(upperdirs)
if member.filename[-1] == '/':
if not os.path.isdir(targetpath):
os.mkdir(targetpath)
return targetpath
_extract_from_zip(self, member.filename, targetpath)
return targetpath
def _remove_dir(target):
#on windows this seems to a problem
for dir_path, dirs, files in os.walk(target):
os.chmod(dir_path, stat.S_IWRITE)
for filename in files:
os.chmod(os.path.join(dir_path, filename), stat.S_IWRITE)
shutil.rmtree(target)
class TestSvnVersion(unittest.TestCase):
......@@ -90,81 +33,207 @@ class TestSvnVersion(unittest.TestCase):
old_path = os.environ[path_variable]
os.environ[path_variable] = ''
try:
version = svn_utils.get_svn_tool_version()
version = svn_utils.SvnInfo.get_svn_version()
self.assertEqual(version, '')
finally:
os.environ[path_variable] = old_path
def test_svn_should_exist(self):
version = svn_utils.get_svn_tool_version()
version = svn_utils.SvnInfo.get_svn_version()
self.assertNotEqual(version, '')
def _read_utf8_file(path):
fileobj = None
try:
fileobj = codecs.open(path, 'r', 'utf-8')
data = fileobj.read()
return data
finally:
if fileobj:
fileobj.close()
class TestSvn_1_7(unittest.TestCase):
def setUp(self):
version = svn_utils.get_svn_tool_version()
ver_list = [int(x) for x in version.split('.')]
if ver_list < [1,7,0]:
self.version_err = 'Insufficent Subversion (%s)' % version
class ParserInfoXML(unittest.TestCase):
def parse_tester(self, svn_name, ext_spaces):
path = os.path.join('setuptools', 'tests',
'svn_data', svn_name + '_info.xml')
#Remember these are pre-generated to test XML parsing
# so these paths might not valid on your system
example_base = "%s_example" % svn_name
data = _read_utf8_file(path)
if ext_spaces:
folder2 = 'third party2'
folder3 = 'third party3'
else:
self.version_err = None
folder2 = 'third_party2'
folder3 = 'third_party3'
expected = set([
("\\".join((example_base, 'a file')), 'file'),
("\\".join((example_base, 'folder')), 'dir'),
("\\".join((example_base, 'folder', 'lalala.txt')), 'file'),
("\\".join((example_base, 'folder', 'quest.txt')), 'file'),
])
self.assertEqual(set(x for x in svn_utils.parse_dir_entries(data)),
expected)
def test_svn13(self):
self.parse_tester('svn13', False)
self.temp_dir = tempfile.mkdtemp()
zip_file, source, target = [None, None, None]
try:
zip_file = zipfile.ZipFile(os.path.join('setuptools', 'tests',
'svn17_example.zip'))
for files in zip_file.namelist():
_extract(zip_file, files, self.temp_dir)
finally:
if zip_file:
zip_file.close()
del zip_file
def test_svn14(self):
self.parse_tester('svn14', False)
self.old_cwd = os.getcwd()
os.chdir(os.path.join(self.temp_dir, 'svn17_example'))
def test_svn15(self):
self.parse_tester('svn15', False)
def tearDown(self):
try:
os.chdir(self.old_cwd)
_remove_dir(self.temp_dir)
except OSError:
#sigh?
pass
def _chk_skip(self):
if self.version_err is not None:
if hasattr(self, 'skipTest'):
self.skipTest(self.version_err)
else:
sys.stderr.write(self.version_error + "\n")
return True
return False
def test_svn16(self):
self.parse_tester('svn16', True)
def test_svn17(self):
self.parse_tester('svn17', True)
def test_svn18(self):
self.parse_tester('svn18', True)
def test_egg_info(self):
if self._chk_skip:
return
class ParserExternalXML(unittest.TestCase):
rev = egg_info.egg_info.get_svn_revision()
self.assertEqual(rev, '4')
def parse_tester(self, svn_name, ext_spaces):
path = os.path.join('setuptools', 'tests',
'svn_data', svn_name + '_ext_list.xml')
example_base = svn_name + '_example'
data = _read_utf8_file(path)
def test_iterator(self):
if self._chk_skip:
return
if ext_spaces:
folder2 = 'third party2'
folder3 = 'third party3'
else:
folder2 = 'third_party2'
folder3 = 'third_party3'
expected = set([
os.path.join('.', 'readme.txt'),
os.path.join('.', 'other'),
os.path.join('.', 'third_party'),
os.path.join('.', 'third_party2'),
os.path.join('.', 'third_party3'),
"\\".join((example_base, folder2)),
"\\".join((example_base, folder3)),
#third_party大介
"\\".join((example_base,
unicode('third_party') +
unichr(0x5927) + unichr(0x4ecb))),
"\\".join((example_base, 'folder', folder2)),
"\\".join((example_base, 'folder', folder3)),
"\\".join((example_base, 'folder',
unicode('third_party') +
unichr(0x5927) + unichr(0x4ecb))),
])
self.assertEqual(set(x for x
in sdist.entries_externals_finder('.', '')),
dir_base = r'c:\development\svn_example'
self.assertEqual(set(x for x \
in svn_utils.parse_externals_xml(data, dir_base)), expected)
def test_svn15(self):
self.parse_tester('svn15', False)
def test_svn16(self):
self.parse_tester('svn16', True)
def test_svn17(self):
self.parse_tester('svn17', True)
def test_svn18(self):
self.parse_tester('svn18', True)
class ParseExternal(unittest.TestCase):
def parse_tester(self, svn_name, ext_spaces):
path = os.path.join('setuptools', 'tests',
'svn_data', svn_name + '_ext_list.txt')
example_base = svn_name + '_example'
data = _read_utf8_file(path)
if ext_spaces:
expected = set(['third party2', 'third party3',
'third party3b', 'third_party'])
else:
expected = set(['third_party2', 'third_party3', 'third_party'])
self.assertEqual(set(x for x in svn_utils.parse_external_prop(data)),
expected)
def test_svn13(self):
self.parse_tester('svn13', False)
def test_svn14(self):
self.parse_tester('svn14', False)
def test_svn15(self):
self.parse_tester('svn15', False)
def test_svn16(self):
self.parse_tester('svn16', True)
def test_svn17(self):
self.parse_tester('svn17', True)
def test_svn18(self):
self.parse_tester('svn18', True)
class TestSvn(environment.ZippedEnvironment):
def setUp(self):
version = svn_utils.SvnInfo.get_svn_version()
self.base_version = tuple([int(x) for x in version.split('.')[:2]])
if not self.base_version:
raise ValueError('No SVN tools installed')
elif self.base_version < (1,3):
raise ValueError('Insufficient SVN Version %s' % version)
elif self.base_version >= (1,9):
#trying the latest version
self.base_version = (1,8)
self.dataname = "svn%i%i_example" % self.base_version
self.datafile = os.path.join('setuptools', 'tests',
'svn_data', self.dataname + ".zip")
super(TestSvn, self).setUp()
def test_revision(self):
rev = svn_utils.SvnInfo.load('.').get_revision()
self.assertEqual(rev, 6)
def test_entries(self):
expected = set([
(os.path.join('a file'), 'file'),
(os.path.join('folder'), 'dir'),
(os.path.join('folder', 'lalala.txt'), 'file'),
(os.path.join('folder', 'quest.txt'), 'file'),
#The example will have a deleted file (or should)
#but shouldn't return it
])
info = svn_utils.SvnInfo.load('.')
self.assertEqual(set(x for x in info.entries), expected)
def test_externals(self):
if self.base_version >= (1,6):
folder2 = 'third party2'
folder3 = 'third party3'
else:
folder2 = 'third_party2'
folder3 = 'third_party3'
expected = set([
os.path.join(folder2),
os.path.join(folder3),
os.path.join('third_party'),
os.path.join('folder', folder2),
os.path.join('folder', folder3),
os.path.join('folder', 'third_party'),
])
info = svn_utils.SvnInfo.load('.')
self.assertEqual(set([x for x in info.externals]), expected)
def test_suite():
return unittest.defaultTestLoader.loadTestsFromName(__name__)
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