aboutsummaryrefslogtreecommitdiffstats
path: root/setuptools/svn_utils.py
diff options
context:
space:
mode:
authorPhilip Thiem <ptthiem@gmail.com>2013-06-30 00:13:56 -0500
committerPhilip Thiem <ptthiem@gmail.com>2013-06-30 00:13:56 -0500
commit89e84d11a149696aab37645db0b9c4f50fded1f7 (patch)
treefc5ed00a75ccaeeeae99ad83fc182818ea22a467 /setuptools/svn_utils.py
parent0f89549e4bfdbc404deaf1f62fe8d95f5220416d (diff)
downloadexternal_python_setuptools-89e84d11a149696aab37645db0b9c4f50fded1f7.tar.gz
external_python_setuptools-89e84d11a149696aab37645db0b9c4f50fded1f7.tar.bz2
external_python_setuptools-89e84d11a149696aab37645db0b9c4f50fded1f7.zip
Added a class for getting SVN information with a cmd.
Using XML because the regular output is probably internationalized. Need to inspect setuptools/command/egg_info.py setuptools/command/sdist.py setuptools/package_index.py to see how used again to see if we will every be parsing a raw XML file or if always from .svn/enteries, if so looks like we can just replace the whole of the file parsing. --HG-- extra : rebase_source : 5e10e3b43fbe12f890d09923c1050f8384db7f84
Diffstat (limited to 'setuptools/svn_utils.py')
-rw-r--r--setuptools/svn_utils.py116
1 files changed, 100 insertions, 16 deletions
diff --git a/setuptools/svn_utils.py b/setuptools/svn_utils.py
index 2a200fdf..ad3b5f15 100644
--- a/setuptools/svn_utils.py
+++ b/setuptools/svn_utils.py
@@ -1,6 +1,10 @@
import os
import re
+#requires python >= 2.4
+from subprocess import Popen as _Popen, PIPE as _PIPE
+
+
def get_entries_files(base, recurse=True):
for base,dirs,files in os.walk(os.curdir):
if '.svn' not in dirs:
@@ -12,6 +16,17 @@ def get_entries_files(base, recurse=True):
f.close()
class SVNEntries(object):
+ known_svn_versions = {
+ '1.4.x': 8,
+ '1.5.x': 9,
+ '1.6.x': 10,
+ #11 didn't exist (maybe 1.7-dev)
+ #12 is the number in the file there is another
+ #number in .svn/wb.db that is at larger so
+ #looks like they won't be updating it any longer.
+ '1.7.x+': 12,
+ }
+
def __init__(self, data):
self.data = data
@@ -26,8 +41,27 @@ class SVNEntries(object):
@classmethod
def read(class_, file):
data = file.read()
- is_xml = data.startswith('<?xml')
- class_ = [SVNEntriesText, SVNEntriesXML][is_xml]
+
+ if data.startswith('<?xml'):
+ #entries were originally xml so pre-1.4.x
+ return SVNEntriesXML(data)
+ else:
+ try:
+ eol = data.index('\n')
+ svn_version = int(data[:eol])
+ data = data[eol+1:] # remove the revision number and newline
+ except ValueError:
+ log.warn('Unable to parse SVN entries file starting with %r' % data[:20])
+ svn_version = None
+
+ version_known = svn_version in class_.known_svn_versions
+ if version_known and svn_version <= 10:
+ return SVNEntriesText(data)
+ else:
+ if not version_known:
+ log.warn("Unknown subversion verson %d", svn_version)
+ class_ = SVNEntriesCmd
+
return class_(data)
def parse_revision(self):
@@ -35,11 +69,6 @@ class SVNEntries(object):
return max(all_revs)
class SVNEntriesText(SVNEntries):
- known_svn_versions = {
- '1.4.x': 8,
- '1.5.x': 9,
- '1.6.x': 10,
- }
def __get_cached_sections(self):
return self.sections
@@ -47,15 +76,7 @@ class SVNEntriesText(SVNEntries):
def get_sections(self):
SECTION_DIVIDER = '\f\n'
sections = self.data.split(SECTION_DIVIDER)
- sections = map(str.splitlines, sections)
- try:
- # remove the SVN version number from the first line
- svn_version = int(sections[0].pop(0))
- if not svn_version in self.known_svn_versions.values():
- log.warn("Unknown subversion verson %d", svn_version)
- except ValueError:
- return
- self.sections = sections
+ self.sections = map(str.splitlines, sections)
self.get_sections = self.__get_cached_sections
return self.sections
@@ -108,3 +129,66 @@ class SVNEntriesXML(SVNEntries):
]
return results
+
+class SVNEntriesCMD(SVNEntries):
+ entrypathre = re.compile(r'<entry\s+[^>]*path="(\.+)">', re.I)
+ entryre = re.compile(r'<entry.*?</entry>', re.M or re.I)
+ urlre = re.compile('<root>(.*?)</root>', re.I)
+ revre = re.compile('<commit\s+[^>]*revision="(\d+)"', re.I)
+ namere = re.compile('<name>(.*?)</name>', re.I)
+
+ def __get_cached_dir_data(self):
+ return self.dir_data
+
+ def __get_cached_entries(self):
+ return self.entries
+
+ def is_valid(self):
+ return bool(self.get_dir_data())
+
+ def get_dir_data(self):
+ #regard the shell argument, see: http://bugs.python.org/issue8557
+ # and http://stackoverflow.com/questions/5658622/python-subprocess-popen-environment-path
+ proc = _Popen(['svn', 'info', '--xml', self.path],
+ stdout=_PIPE, shell=(sys.platform=='win32'))
+ data = unicode(proc.communicate()[0], encoding='utf-8')
+ self.dir_data = self.entryre.findall(data)
+ self.get_dir_data = self.__get_cached_dir_data
+ return self.dir_data
+
+ def get_entries(self):
+ #regard the shell argument, see: http://bugs.python.org/issue8557
+ # and http://stackoverflow.com/questions/5658622/python-subprocess-popen-environment-path
+ proc = _Popen(['svn', 'list', '--xml', self.path],
+ stdout=_PIPE, shell=(sys.platform=='win32'))
+ data = unicode(proc.communicate()[0], encoding='utf-8')
+ self.dir_data = self.entryre.findall(data)
+ self.get_dir_data = self.__get_cached_dir_data
+ return self.dir_data
+
+ def get_url(self):
+ "Get repository URL"
+ return self.urlre.search(self.get_sections()[0]).group(1)
+
+ def parse_revision_numbers(self):
+ #NOTE: if one has recently commited, the new revision doesn't get updated until svn update
+ if not self.is_valid():
+ return list()
+ else:
+ return [
+ int(m.group(1))
+ for entry in self.get_enteries()
+ for m in self.revre.finditer(entry)
+ ]
+
+ def get_undeleted_records(self):
+ #NOTE: Need to pars enteries?
+ if not self.is_valid():
+ return list()
+ else:
+ return [
+ m.group(1))
+ for entry in self.get_enteries()
+ for m in self.namere.finditer(entry)
+ ]
+