eggs/infrae.subversion-1.4.5-py2.6.egg/infrae/subversion/Native.py
changeset 69 c6bca38c1cbf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eggs/infrae.subversion-1.4.5-py2.6.egg/infrae/subversion/Native.py	Sat Jan 08 11:20:57 2011 +0530
@@ -0,0 +1,140 @@
+# Copyright (c) 2007-2008 Infrae. All rights reserved.
+# $Id: Native.py 33170 2009-01-21 15:46:45Z sylvain $
+
+from pysvn import wc_status_kind, opt_revision_kind, wc_notify_action
+import pysvn
+
+from Common import BaseRecipe, prepareURLs
+from Common import checkAddedPaths, checkExistPath, reportInvalidFiles
+
+import os
+import re
+import getpass
+
+
+def createSVNClient(recipe):
+    """Create a pysvn client, and setup some callback and options.
+    """
+
+    def callback_ssl(info):
+        print "-------- SECURITY WARNING --------"
+        print "There is no valid SSL certificat for %s." % info['realm']
+        print "Check that the files are correct after being fetched."
+        print "-------- SECURITY WARNING --------"
+        return True, 0, False
+
+    def callback_login(realm, username, may_save):
+        print 'Authentication realm: ' + realm
+        user = raw_input('Username: ')
+        password = getpass.getpass('Password for ' + "'" + user + "': ")
+        return True, user, password, True
+
+    def callback_notify(info):
+        if info['action'] == wc_notify_action.update_completed:
+            path = info['path']
+            url = recipe.urls.get(path, None)
+            if not (url is None):
+                recipe._updateRevisionInformation(url, path, info['revision'])
+
+    client = pysvn.Client()
+    client.set_interactive(True)
+    client.callback_ssl_server_trust_prompt = callback_ssl
+    client.callback_get_login = callback_login
+    if not (recipe is None):
+        client.callback_notify = callback_notify
+    return client
+
+
+class Recipe(BaseRecipe):
+    """infrae.subversion recipe.
+    """
+
+    def __init__(self, buildout, name, options):
+        super(Recipe, self).__init__(buildout, name, options)
+        if self.verbose:
+            print 'Using pysvn implementation.'
+        self.client = createSVNClient(self)
+        if not self.export:
+            self._updateAllRevisionInformation()
+        self._exportInformationToOptions()
+
+    def _updateRevisionInformation(self, link, path, revision=None):
+        """Update revision information on a path.
+        """
+        if revision is None:
+            if self.export:
+                return
+            info = self.client.info(path)
+            revision = info['revision']
+
+        assert (revision.kind == opt_revision_kind.number)
+        super(Recipe, self)._updateRevisionInformation(link, revision.number)
+
+    def _updatePath(self, link, path):
+        """Update a single path.
+        """
+        self.client.update(path)
+
+    def _parseRevisionInUrl(self, url):
+        """Parse URL to extract revision number. This is not done by
+        pysvn, so we have to do it by ourself.
+        """
+        num_release = re.compile('(.*)@([0-9]+)$')
+        match = num_release.match(url)
+        if match:
+            return (match.group(1),
+                    pysvn.Revision(opt_revision_kind.number,
+                                   int(match.group(2))))
+        return (url, pysvn.Revision(opt_revision_kind.head))
+
+    def _installPath(self, link, path):
+        """Checkout a single entry.
+        """
+        link, wanted_revision = self._parseRevisionInUrl(link)
+        if self.export:
+            method = self.client.export
+        else:
+            method = self.client.checkout
+        method(link, path, revision=wanted_revision, recurse=True)
+
+
+def uninstall(name, options):
+    r"""
+    This is an uninstallation hook for the 'infrae.subversion' recipe.
+
+    Its only job is to raise an exception when there are changes in a
+    subversion tree that a user might not want to lose.  This function
+    does *not* delete or otherwise touch any files.
+
+    The location of the path is passed as options['location'].
+    """
+    if bool(options.get('export', False)):
+        return                  # SVN Export, there is nothing to check.
+
+    if bool(options.get('ignore_verification', False)):
+        return                  # Verification disabled.
+
+    # XXX This makes the assumption that we're in the buildout
+    #     directory and that our part is in 'parts'.  We don't have
+    #     options['buildout'] available so no
+    #     'buildout:parts-directory'.
+    location = options.get('location', os.path.join('.', 'parts', name))
+    urls = prepareURLs(location, options['urls'])
+    client = createSVNClient(None)
+
+    bad_svn_status = [wc_status_kind.modified,
+                      wc_status_kind.missing,
+                      wc_status_kind.unversioned, ]
+
+    if not checkExistPath(location):
+        return
+
+    checkAddedPaths(location, urls)
+
+    for path in urls.keys():
+        if not checkExistPath(path):
+            continue
+
+        badfiles = filter(lambda e: e['text_status'] in bad_svn_status,
+                          client.status(path))
+        reportInvalidFiles(path, name, [file['path'] for file in badfiles])