diff -r 5ff1fc726848 -r c6bca38c1cbf eggs/infrae.subversion-1.4.5-py2.6.egg/infrae/subversion/Common.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eggs/infrae.subversion-1.4.5-py2.6.egg/infrae/subversion/Common.py Sat Jan 08 11:20:57 2011 +0530 @@ -0,0 +1,244 @@ +# Copyright (c) 2007-2008 Infrae. All rights reserved. +# $Id: Common.py 33243 2009-01-29 10:59:47Z sylvain $ + +from sets import Set # For python 2.3 compatibility +import os.path +import os +import re + + +import zc.buildout + + +def ignoredFile(file): + """Return true if the file should be ignored while checking for + added/changed/modified files. + """ + for suffix in ['.pyc', '.pyo', '.egg-info']: + if file.endswith(suffix): + return True + return False + + +def reportInvalidFiles(path, name, badfiles): + """Report invalid files. + """ + badfiles = [file for file in badfiles if not ignoredFile(file)] + if not badfiles: + return + raise ValueError("""\ +In '%s': +local modifications detected while uninstalling %r: Uninstall aborted! + +Please check for local modifications and make sure these are checked +in. + +If you sure that these modifications can be ignored, remove the +checkout manually: + + rm -rf %s + +Or if applicable, add the file to the 'svn:ignore' property of the +file's container directory. Alternatively, add an ignore glob pattern +to your subversion client's 'global-ignores' configuration variable. +""" % (path, name, """ + rm -rf """.join(badfiles))) + + +def checkExistPath(path, warning=True): + """Check that a path exist. + """ + status = os.path.exists(path) + if not status and warning: + print "-------- WARNING --------" + print "Directory %s have been removed." % os.path.abspath(path) + print "Changes might be lost." + print "-------- WARNING --------" + return status + + +def checkAddedPaths(location, urls): + """Check that no path have been added to that location. + """ + current_paths = Set([os.path.join(location, s) for s in + os.listdir(location)]) + recipe_paths = Set(urls.keys()) + added_paths = list(current_paths - recipe_paths) + for path in added_paths[:]: + if path.endswith('.svn'): + added_paths.remove(path) + if added_paths: + msg = "New path have been added to the location: %s." + raise ValueError(msg % ', '.join(added_paths)) + + +def prepareURLs(location, urls): + """Given a list of urls/path, and a location, prepare a list of + tuple with url, full path. + """ + + def prepareEntry(line): + link, path = line.split() + return os.path.join(location, path), link + + return dict([prepareEntry(l) for l in urls.splitlines() if l.strip()]) + + +def extractNames(urls): + """Return just the target names of the urls (used for egg names)""" + + def extractName(line): + link, name = line.split() + return name + + return [extractName(line) for line in urls.splitlines() if line.strip()] + + +class BaseRecipe(object): + """infrae.subversion recipe. Base class. + """ + + def __init__(self, buildout, name, options): + self.buildout = buildout + self.name = name + self.options = options + # location is overridable if desired. + location = options.get('location', None) + if location: + self.location = os.path.abspath(os.path.join( + buildout['buildout']['directory'], location)) + else: + self.location = os.path.join( + buildout['buildout']['parts-directory'], self.name) + options['location'] = self.location + self.revisions = {} # Store revision information for each link + self.updated = [] # Store updated links + self.urls = prepareURLs(self.location, options['urls']) + self.export = options.get('export') + self.offline = buildout['buildout'].get('offline', 'false') == 'true' + self.eggify = options.get('as_eggs', False) + self.eggs = self.eggify and extractNames(options['urls']) or [] + self.newest = ( + not self.offline and + buildout['buildout'].get('newest', 'true') == 'true' + ) + self.verbose = buildout['buildout'].get('verbosity', 0) + self.warning = not (options.get('no_warnings', 'false') == 'true') + + def _exportInformationToOptions(self): + """Export revision and changed information to options. + + Options can only contains strings. + """ + if self.options.get('export_info', False): + self.options['updated'] = str('\n'.join(self.updated)) + str_revisions = ['%s %s' % r for r in self.revisions.items() + if r[1]] + self.options['revisions'] = str('\n'.join(sorted(str_revisions))) + # Always export egg list + self.options['eggs'] = '\n'.join(sorted(self.eggs)) + + def _updateAllRevisionInformation(self): + """Update all revision information for defined urls. + """ + for path, link in self.urls.items(): + if os.path.exists(path): + self._updateRevisionInformation(link, path) + + def _updateRevisionInformation(self, link, revision): + """Update revision information on a path. + """ + old_revision = self.revisions.get(link, None) + self.revisions[link] = revision + if not (old_revision is None): + self.updated.append(link) + + def _updatePath(self, link, path): + """Update a single path. + """ + raise NotImplementedError + + def _updateAllPaths(self): + """Update the checkouts. + """ + ignore = self.options.get('ignore_updates', False) or self.export + + num_release = re.compile('.*@[0-9]+$') + for path, link in self.urls.items(): + if not checkExistPath(path, warning=self.warning): + if self.verbose: + print "Entry %s missing, checkout a new version ..." % link + self._installPath(link, path) + continue + + if ignore: + continue + + if num_release.match(link): + if self.verbose: + print "Given num release for %s, skipping." % link + continue + + if self.verbose: + print "Updating %s" % path + self._updatePath(link, path) + + def update(self): + """Update the recipe. + + Does not update SVN path if the buildout is in offline mode, + but still eggify and export information. + """ + if self.newest: + self._updateAllPaths() + + if self.eggify: + self._eggify() + self._exportInformationToOptions() + return self.location + + def _installPath(self, link, path): + """Checkout a single entry. + """ + raise NotImplementedError + + def _installPathVerbose(self, link, path): + """Checkout a single entry with verbose. + """ + if self.verbose: + print "%s %s to %s" % (self.export and 'Export' or 'Fetch', + link, path) + self._installPath(link, path) + + def _eggify(self): + """Install everything as development eggs if eggs=true""" + if self.eggify: + target = self.buildout['buildout']['develop-eggs-directory'] + for path in self.urls.keys(): + # If we update the recipe, and we don't have newest, + # and that some path have been deleted, all of them + # might not be there. + if checkExistPath(path, warning=self.warning): + zc.buildout.easy_install.develop(path, target) + + def install(self): + """Checkout the checkouts. + + Fails if buildout is running in offline mode. + """ + + for path, link in self.urls.items(): + self._installPathVerbose(link, path) + installed = [self.location] + + if self.eggify: + self._eggify() + # And also return the develop-eggs/*.egg-link files that are + # ours so that an uninstall automatically zaps them. + dev_dir = self.buildout['buildout']['develop-eggs-directory'] + egg_links = ['%s.egg-link' % egg for egg in self.eggs] + egg_links = [os.path.join(dev_dir, link) for link in egg_links] + installed += egg_links + self._exportInformationToOptions() + + return installed