Commit e9175087 authored by Jason R. Coombs's avatar Jason R. Coombs

Merged in philip_thiem/setuptools (pull request #24)

Issue #101 and tweak legacy fallback
parents bc18704d d01db08c
...@@ -219,7 +219,13 @@ class SvnInfo(object): ...@@ -219,7 +219,13 @@ class SvnInfo(object):
def load(cls, dirname=''): def load(cls, dirname=''):
normdir = os.path.normpath(dirname) normdir = os.path.normpath(dirname)
code, data = _run_command(['svn', 'info', normdir]) code, data = _run_command(['svn', 'info', normdir])
has_svn = os.path.isdir(os.path.join(normdir, '.svn')) # Must check for some contents, as some use empty directories
# in testcases
svn_dir = os.path.join(normdir, '.svn')
has_svn = (os.path.isfile(os.path.join(svn_dir, 'entries')) or
os.path.isfile(os.path.join(svn_dir, 'dir-props')) or
os.path.isfile(os.path.join(svn_dir, 'dir-prop-base')))
svn_version = tuple(cls.get_svn_version().split('.')) svn_version = tuple(cls.get_svn_version().split('.'))
try: try:
...@@ -229,7 +235,6 @@ class SvnInfo(object): ...@@ -229,7 +235,6 @@ class SvnInfo(object):
if has_svn and (code or not base_svn_version if has_svn and (code or not base_svn_version
or base_svn_version < (1, 3)): or base_svn_version < (1, 3)):
log.warn('Fallback onto .svn parsing')
warnings.warn(("No SVN 1.3+ command found: falling back " warnings.warn(("No SVN 1.3+ command found: falling back "
"on pre 1.7 .svn parsing"), DeprecationWarning) "on pre 1.7 .svn parsing"), DeprecationWarning)
return SvnFileInfo(dirname) return SvnFileInfo(dirname)
......
...@@ -5,6 +5,9 @@ import tempfile ...@@ -5,6 +5,9 @@ import tempfile
import unittest import unittest
import shutil import shutil
import stat import stat
import unicodedata
from subprocess import Popen as _Popen, PIPE as _PIPE
def _extract(self, member, path=None, pwd=None): def _extract(self, member, path=None, pwd=None):
...@@ -25,6 +28,7 @@ def _extract_from_zip(self, name, dest_path): ...@@ -25,6 +28,7 @@ def _extract_from_zip(self, name, dest_path):
finally: finally:
dest_file.close() dest_file.close()
def _extract_member(self, member, targetpath, pwd): def _extract_member(self, member, targetpath, pwd):
"""for zipfile py2.5 borrowed from cpython""" """for zipfile py2.5 borrowed from cpython"""
# build the destination pathname, replacing # build the destination pathname, replacing
...@@ -102,3 +106,53 @@ class ZippedEnvironment(unittest.TestCase): ...@@ -102,3 +106,53 @@ class ZippedEnvironment(unittest.TestCase):
#sigh? #sigh?
pass pass
def _which_dirs(cmd):
result = set()
for path in os.environ.get('PATH', '').split(os.pathsep):
filename = os.path.join(path, cmd)
if os.access(filename, os.X_OK):
result.add(path)
return result
def run_setup_py(cmd, pypath=None, path=None,
data_stream=0, env=None):
"""
Execution command for tests, separate from those used by the
code directly to prevent accidental behavior issues
"""
if env is None:
env = dict()
for envname in os.environ:
env[envname] = os.environ[envname]
#override the python path if needed
if pypath is not None:
env["PYTHONPATH"] = pypath
#overide the execution path if needed
if path is not None:
env["PATH"] = path
if not env.get("PATH", ""):
env["PATH"] = _which_dirs("tar").union(_which_dirs("gzip"))
env["PATH"] = os.pathsep.join(env["PATH"])
cmd = [sys.executable, "setup.py"] + list(cmd)
#regarding the shell argument, see: http://bugs.python.org/issue8557
try:
proc = _Popen(cmd, stdout=_PIPE, stderr=_PIPE,
shell=(sys.platform == 'win32'), env=env)
data = proc.communicate()[data_stream]
except OSError:
return 1, ''
#decode the console string if needed
if hasattr(data, "decode"):
data = data.decode() # should use the preffered encoding
data = unicodedata.normalize('NFC', data)
#communciate calls wait()
return proc.returncode, data
import os import os
import sys import sys
import tempfile import tempfile
...@@ -5,12 +6,15 @@ import shutil ...@@ -5,12 +6,15 @@ import shutil
import unittest import unittest
import pkg_resources import pkg_resources
import warnings
from setuptools.command import egg_info from setuptools.command import egg_info
from setuptools.tests import environment
from setuptools import svn_utils from setuptools import svn_utils
ENTRIES_V10 = pkg_resources.resource_string(__name__, 'entries-v10') ENTRIES_V10 = pkg_resources.resource_string(__name__, 'entries-v10')
"An entries file generated with svn 1.6.17 against the legacy Setuptools repo" "An entries file generated with svn 1.6.17 against the legacy Setuptools repo"
class TestEggInfo(unittest.TestCase): class TestEggInfo(unittest.TestCase):
def setUp(self): def setUp(self):
...@@ -37,7 +41,7 @@ class TestEggInfo(unittest.TestCase): ...@@ -37,7 +41,7 @@ class TestEggInfo(unittest.TestCase):
#to ensure I return using svnversion what would had been returned #to ensure I return using svnversion what would had been returned
version_str = svn_utils.SvnInfo.get_svn_version() version_str = svn_utils.SvnInfo.get_svn_version()
version = [int(x) for x in version_str.split('.')[:2]] version = [int(x) for x in version_str.split('.')[:2]]
if version != [1,6]: if version != [1, 6]:
if hasattr(self, 'skipTest'): if hasattr(self, 'skipTest'):
self.skipTest('') self.skipTest('')
else: else:
...@@ -61,14 +65,104 @@ class TestEggInfo(unittest.TestCase): ...@@ -61,14 +65,104 @@ class TestEggInfo(unittest.TestCase):
old_path = os.environ[path_variable] old_path = os.environ[path_variable]
os.environ[path_variable] = '' os.environ[path_variable] = ''
#catch_warnings not available until py26
warning_filters = warnings.filters
warnings.filters = warning_filters[:]
try: try:
warnings.simplefilter("ignore", DeprecationWarning)
self._write_entries(ENTRIES_V10) self._write_entries(ENTRIES_V10)
rev = egg_info.egg_info.get_svn_revision() rev = egg_info.egg_info.get_svn_revision()
finally: finally:
#restore the warning filters
warnings.filters = warning_filters
#restore the os path
os.environ[path_variable] = old_path os.environ[path_variable] = old_path
self.assertEqual(rev, '89000') self.assertEqual(rev, '89000')
DUMMY_SOURCE_TXT = """CHANGES.txt
CONTRIBUTORS.txt
HISTORY.txt
LICENSE
MANIFEST.in
README.txt
setup.py
dummy/__init__.py
dummy/test.txt
dummy.egg-info/PKG-INFO
dummy.egg-info/SOURCES.txt
dummy.egg-info/dependency_links.txt
dummy.egg-info/top_level.txt"""
class TestSvnDummy(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 = "dummy%i%i" % self.base_version
self.datafile = os.path.join('setuptools', 'tests',
'svn_data', self.dataname + ".zip")
super(TestSvnDummy, self).setUp()
def test_sources(self):
code, data = environment.run_setup_py(["sdist"],
pypath=self.old_cwd,
data_stream=1)
if code:
raise AssertionError(data)
sources = os.path.join('dummy.egg-info', 'SOURCES.txt')
infile = open(sources, 'r')
try:
read_contents = infile.read()
finally:
infile.close()
del infile
self.assertEqual(DUMMY_SOURCE_TXT, read_contents)
return data
class TestSvnDummyLegacy(environment.ZippedEnvironment):
def setUp(self):
self.base_version = (1, 6)
self.dataname = "dummy%i%i" % self.base_version
self.datafile = os.path.join('setuptools', 'tests',
'svn_data', self.dataname + ".zip")
super(TestSvnDummyLegacy, self).setUp()
def test_sources(self):
code, data = environment.run_setup_py(["sdist"],
pypath=self.old_cwd,
path="",
data_stream=1)
if code:
raise AssertionError(data)
sources = os.path.join('dummy.egg-info', 'SOURCES.txt')
infile = open(sources, 'r')
try:
read_contents = infile.read()
finally:
infile.close()
del infile
self.assertEqual(DUMMY_SOURCE_TXT, read_contents)
return data
def test_suite(): def test_suite():
return unittest.defaultTestLoader.loadTestsFromName(__name__) return unittest.defaultTestLoader.loadTestsFromName(__name__)
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""sdist tests""" """sdist tests"""
from __future__ import with_statement
import locale import locale
import os import os
import shutil import shutil
...@@ -401,81 +400,73 @@ class TestSdistTest(unittest.TestCase): ...@@ -401,81 +400,73 @@ class TestSdistTest(unittest.TestCase):
self.assertTrue(filename in cmd.filelist.files) self.assertTrue(filename in cmd.filelist.files)
def soruce_test(self): class TestDummyOutput(environment.ZippedEnvironment):
code, data = svn_utils._run_command([sys.executable, "setup.py", "egg_info"], stream=1)
if code:
raise AssertionError(data)
sources = os.path.join('dummy.egg-info', 'SOURCES.txt')
contents = """CHANGES.txt
CONTRIBUTORS.txt
HISTORY.txt
LICENSE
MANIFEST.in
README.txt
setup.py
dummy/__init__.py
dummy/test.txt
dummy.egg-info/PKG-INFO
dummy.egg-info/SOURCES.txt
dummy.egg-info/dependency_links.txt
dummy.egg-info/top_level.txt"""
with open(sources, 'r') as infile:
read_contents = infile.read()
self.assertEqual(contents, read_contents)
class TestSvnDummy(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 = "dummy%i%i" % self.base_version
self.datafile = os.path.join('setuptools', 'tests',
'svn_data', self.dataname + ".zip")
super(TestSvnDummy, self).setUp()
def test_sources(self):
soruce_test(self)
class TestSvnDummyLegacy(environment.ZippedEnvironment):
def setUp(self): def setUp(self):
self.base_version = (1,6)
self.path_variable = None
for env in os.environ:
if env.lower() == 'path':
self.path_variable = env
self.old_path = os.environ[self.path_variable]
os.environ[self.path_variable] = ''
if self.path_variable is None:
self.skipTest('Cannot figure out how to modify path')
self.dataname = "dummy%i%i" % self.base_version
self.datafile = os.path.join('setuptools', 'tests', self.datafile = os.path.join('setuptools', 'tests',
'svn_data', self.dataname + ".zip") 'svn_data', "dummy.zip")
super(TestSvnDummyLegacy, self).setUp() self.dataname = "dummy"
super(TestDummyOutput, self).setUp()
def tearDown(self):
os.environ[self.path_variable] = self.old_path def _run(self):
super(TestSvnDummyLegacy, self).tearDown() code, data = environment.run_setup_py(["sdist"],
pypath=self.old_cwd,
data_stream=0)
if code:
info = "DIR: " + os.path.abspath('.')
info += "\n SDIST RETURNED: %i\n\n" % code
info += data
raise AssertionError(info)
datalines = data.splitlines()
possible = (
"running sdist",
"running egg_info",
"creating dummy\.egg-info",
"writing dummy\.egg-info",
"writing top-level names to dummy\.egg-info",
"writing dependency_links to dummy\.egg-info",
"writing manifest file 'dummy\.egg-info",
"reading manifest file 'dummy\.egg-info",
"reading manifest template 'MANIFEST\.in'",
"writing manifest file 'dummy\.egg-info",
"creating dummy-0.1.1",
"making hard links in dummy-0\.1\.1",
"copying files to dummy-0\.1\.1",
"copying \S+ -> dummy-0\.1\.1",
"copying dummy",
"copying dummy\.egg-info",
"hard linking \S+ -> dummy-0\.1\.1",
"hard linking dummy",
"hard linking dummy\.egg-info",
"Writing dummy-0\.1\.1",
"creating dist",
"creating 'dist",
"Creating tar archive",
"running check",
"adding 'dummy-0\.1\.1",
"tar .+ dist/dummy-0\.1\.1\.tar dummy-0\.1\.1",
"gzip .+ dist/dummy-0\.1\.1\.tar",
"removing 'dummy-0\.1\.1' \\(and everything under it\\)",
)
print(" DIR: " + os.path.abspath('.'))
for line in datalines:
found = False
for pattern in possible:
if re.match(pattern, line):
print(" READ: " + line)
found = True
break
if not found:
raise AssertionError("Unexpexected: %s\n-in-\n%s"
% (line, data))
return data
def test_sources(self): def test_sources(self):
soruce_test(self) self._run()
class TestSvn(environment.ZippedEnvironment): class TestSvn(environment.ZippedEnvironment):
...@@ -486,11 +477,11 @@ class TestSvn(environment.ZippedEnvironment): ...@@ -486,11 +477,11 @@ class TestSvn(environment.ZippedEnvironment):
if not self.base_version: if not self.base_version:
raise ValueError('No SVN tools installed') raise ValueError('No SVN tools installed')
elif self.base_version < (1,3): elif self.base_version < (1, 3):
raise ValueError('Insufficient SVN Version %s' % version) raise ValueError('Insufficient SVN Version %s' % version)
elif self.base_version >= (1,9): elif self.base_version >= (1, 9):
#trying the latest version #trying the latest version
self.base_version = (1,8) self.base_version = (1, 8)
self.dataname = "svn%i%i_example" % self.base_version self.dataname = "svn%i%i_example" % self.base_version
self.datafile = os.path.join('setuptools', 'tests', self.datafile = os.path.join('setuptools', 'tests',
...@@ -498,7 +489,7 @@ class TestSvn(environment.ZippedEnvironment): ...@@ -498,7 +489,7 @@ class TestSvn(environment.ZippedEnvironment):
super(TestSvn, self).setUp() super(TestSvn, self).setUp()
def test_walksvn(self): def test_walksvn(self):
if self.base_version >= (1,6): if self.base_version >= (1, 6):
folder2 = 'third party2' folder2 = 'third party2'
folder3 = 'third party3' folder3 = 'third party3'
else: else:
...@@ -520,7 +511,7 @@ class TestSvn(environment.ZippedEnvironment): ...@@ -520,7 +511,7 @@ class TestSvn(environment.ZippedEnvironment):
os.path.join('folder', folder2, 'Changes.txt'), os.path.join('folder', folder2, 'Changes.txt'),
os.path.join('folder', folder2, 'MD5SUMS'), os.path.join('folder', folder2, 'MD5SUMS'),
os.path.join('folder', folder2, 'WatashiNiYomimasu.txt'), os.path.join('folder', folder2, 'WatashiNiYomimasu.txt'),
os.path.join( 'folder', folder3, 'Changes.txt'), os.path.join('folder', folder3, 'Changes.txt'),
os.path.join('folder', folder3, 'fin'), os.path.join('folder', folder3, 'fin'),
os.path.join('folder', folder3, 'MD5SUMS'), os.path.join('folder', folder3, 'MD5SUMS'),
os.path.join('folder', folder3, 'oops'), os.path.join('folder', folder3, 'oops'),
...@@ -529,11 +520,11 @@ class TestSvn(environment.ZippedEnvironment): ...@@ -529,11 +520,11 @@ class TestSvn(environment.ZippedEnvironment):
os.path.join('folder', 'third_party', 'WatashiNiYomimasu.txt'), os.path.join('folder', 'third_party', 'WatashiNiYomimasu.txt'),
os.path.join('folder', 'lalala.txt'), os.path.join('folder', 'lalala.txt'),
os.path.join('folder', 'quest.txt'), os.path.join('folder', 'quest.txt'),
#The example will have a deleted file (or should) but shouldn't return it # The example will have a deleted file
# (or should) but shouldn't return it
]) ])
self.assertEqual(set(x for x in walk_revctrl()), expected) self.assertEqual(set(x for x in walk_revctrl()), expected)
def test_suite(): def test_suite():
return unittest.defaultTestLoader.loadTestsFromName(__name__) 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