diff options
author | Philip Thiem <ptthiem@gmail.com> | 2014-02-15 14:56:16 -0600 |
---|---|---|
committer | Philip Thiem <ptthiem@gmail.com> | 2014-02-15 14:56:16 -0600 |
commit | 0daefd2b07a5435b0795f3dd0c3d102352611343 (patch) | |
tree | ce8c5f1763b67b93af93554e41ea1097f272f2c4 /setuptools/svn_utils.py | |
parent | d2d40d0c30f6b5178851e79a0bca116492b63898 (diff) | |
download | external_python_setuptools-0daefd2b07a5435b0795f3dd0c3d102352611343.tar.gz external_python_setuptools-0daefd2b07a5435b0795f3dd0c3d102352611343.tar.bz2 external_python_setuptools-0daefd2b07a5435b0795f3dd0c3d102352611343.zip |
Fixed Issue #125: setuptools leaves a ~/.subversion dir laying around
after it completes
This is the best that can probably be done. Temporary directories are used
for get the svn binary version and to get the initial directory info (for
determining if one is, in fact, in a svn working directory)
ALSO: The check for SVN was not right. Decided on files to only check for
.svn/entries because missing properties just leaves out the external refs.
And then incorporated a test on the code to make sure that svn info completed.
Test passed on CPytonh 2.x and 2.3 on windows, travis-ci, and travis-ci/mac.
Note: There seems to be an issue with pypy and a test.
Diffstat (limited to 'setuptools/svn_utils.py')
-rw-r--r-- | setuptools/svn_utils.py | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/setuptools/svn_utils.py b/setuptools/svn_utils.py index a9bdc5c3..e1d336e2 100644 --- a/setuptools/svn_utils.py +++ b/setuptools/svn_utils.py @@ -4,6 +4,8 @@ import sys from distutils import log
import xml.dom.pulldom
import shlex
+import shutil
+import tempfile
import locale
import codecs
import unicodedata
@@ -27,6 +29,25 @@ from subprocess import Popen as _Popen, PIPE as _PIPE # http://stackoverflow.com/questions/5658622/
# python-subprocess-popen-environment-path
+class TempDir(object):
+ """"
+ Very simple temporary directory context manager.
+ Will try to delete afterward, but will also ignore OS and similar
+ errors on deletion.
+ """
+ def __init__(self):
+ self.path = None
+
+ def __enter__(self):
+ self.path = tempfile.mkdtemp()
+ return self
+
+ def __exit__(self, exctype, excvalue, exctrace):
+ try:
+ shutil.rmtree(self.path, True)
+ except OSError: #removal errors are not the only possible
+ pass
+ self.path = None
def _run_command(args, stdout=_PIPE, stderr=_PIPE, encoding=None, stream=0):
#regarding the shell argument, see: http://bugs.python.org/issue8557
@@ -231,7 +252,16 @@ class SvnInfo(object): @staticmethod
def get_svn_version():
- code, data = _run_command(['svn', '--version', '--quiet'])
+ # Temp config directory should be enough to check for repository
+ # This is needed because .svn always creates .subversion and
+ # some operating systems do not handle dot directory correctly.
+ # Real queries in real svn repos with be concerned with it creation
+ with TempDir() as tempdir:
+ code, data = _run_command(['svn',
+ '--config-dir', tempdir.path,
+ '--version',
+ '--quiet'])
+
if code == 0 and data:
return data.strip()
else:
@@ -247,13 +277,22 @@ class SvnInfo(object): @classmethod
def load(cls, dirname=''):
normdir = os.path.normpath(dirname)
- code, data = _run_command(['svn', 'info', normdir])
+
+ # Temp config directory should be enough to check for repository
+ # This is needed because .svn always creates .subversion and
+ # some operating systems do not handle dot directory correctly.
+ # Real queries in real svn repos with be concerned with it creation
+ with TempDir() as tempdir:
+ code, data = _run_command(['svn',
+ '--config-dir', tempdir.path,
+ 'info', normdir])
+
# Must check for some contents, as some use empty directories
- # in testcases
+ # in testcases, however only enteries is needed also the info
+ # command above MUST have worked
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')))
+ is_svn_wd = (not code or
+ os.path.isfile(os.path.join(svn_dir, 'entries')))
svn_version = tuple(cls.get_svn_version().split('.'))
@@ -262,7 +301,8 @@ class SvnInfo(object): except ValueError:
base_svn_version = tuple()
- if not has_svn:
+ if not is_svn_wd:
+ #return an instance of this NO-OP class
return SvnInfo(dirname)
if code or not base_svn_version or base_svn_version < (1, 3):
|