def revisions(self, paths=None, start=0, stop=0,
                  chunk_size=common.chunk_size):
        """Load the history of this repo.

        This is LAZY. It returns a generator, and fetches a small number
        of revisions at a time.

        The reason this is lazy is so that you can use the same repo object
        to perform RA calls to get deltas.
        """
        if paths is None:
            paths = ['']
        if not stop:
            stop = self.HEAD
        while stop > start:
            def callback(paths, revnum, props, haschildren):
                if paths is None:
                    return
                r = common.Revision(revnum,
                             props.get(properties.PROP_REVISION_AUTHOR),
                             props.get(properties.PROP_REVISION_LOG),
                             props.get(properties.PROP_REVISION_DATE),
                             dict([(_forceutf8(k), PathAdapter(*v))
                                   for k, v in paths.iteritems()]),
                             strip_path=_forceutf8(self.subdir))
                revisions.append(r)
            # we only access revisions in a FIFO manner
            revisions = collections.deque()

            revprops = [properties.PROP_REVISION_AUTHOR,
                        properties.PROP_REVISION_DATE,
                        properties.PROP_REVISION_LOG]
            try:
                # TODO: using min(start + chunk_size, stop) may be preferable;
                #       ra.get_log(), even with chunk_size set, takes a while
                #       when converting the 65k+ rev. in LLVM.
                self.remote.get_log(paths=paths, revprops=revprops,
                                    start=start + 1, end=stop, limit=chunk_size,
                                    discover_changed_paths=True,
                                    callback=callback)
            except SubversionException, e:
                if e.args[1] == ERR_FS_NOT_FOUND:
                    msg = ('%s not found at revision %d!'
                           % (self.subdir.rstrip('/'), stop))
                    raise common.SubversionConnectionException(msg)
                elif e.args[1] == subvertpy.ERR_FS_NO_SUCH_REVISION:
                    raise common.SubversionConnectionException(e.args[0])
                else:
                    raise

            while len(revisions) > 1:
                yield revisions.popleft()

            if len(revisions) == 0:
                # exit the loop; there is no history for the path.
                break
            else:
                r = revisions.popleft()
                start = r.revnum
                yield r
Beispiel #2
0
    def revisions(self, paths=None, start=0, stop=0,
                  chunk_size=common.chunk_size):
        """Load the history of this repo.

        This is LAZY. It returns a generator, and fetches a small number
        of revisions at a time.

        The reason this is lazy is so that you can use the same repo object
        to perform RA calls to get deltas.
        """
        if paths is None:
            paths = ['']
        if not stop:
            stop = self.HEAD
        while stop > start:
            def callback(paths, revnum, author, date, message, pool):
                r = common.Revision(revnum, author, message, date, paths,
                                    strip_path=self.subdir)
                revisions.append(r)
            # we only access revisions in a FIFO manner
            revisions = collections.deque()

            try:
                # TODO: using min(start + chunk_size, stop) may be preferable;
                #       ra.get_log(), even with chunk_size set, takes a while
                #       when converting the 65k+ rev. in LLVM.
                ra.get_log(self.ra,
                           paths,
                           start + 1,
                           stop,
                           chunk_size, # limit of how many log messages to load
                           True, # don't need to know changed paths
                           True, # stop on copies
                           callback,
                           self.pool)
            except core.SubversionException, e:
                if e.apr_err == core.SVN_ERR_FS_NOT_FOUND:
                    msg = ('%s not found at revision %d!'
                           % (self.subdir.rstrip('/'), stop))
                    raise common.SubversionConnectionException(msg)
                elif e.apr_err == core.SVN_ERR_FS_NO_SUCH_REVISION:
                    raise common.SubversionConnectionException(e.message)
                else:
                    raise

            while len(revisions) > 1:
                yield revisions.popleft()

            if len(revisions) == 0:
                # exit the loop; there is no history for the path.
                break
            else:
                r = revisions.popleft()
                start = r.revnum
                yield r
            self.init_ra_and_client()
Beispiel #3
0
    def init_ra_and_client(self):
        """Initializes the RA and client layers, because sometimes getting
        unified diffs runs the remote server out of open files.
        """
        # while we're in here we'll recreate our pool
        self.pool = core.Pool()
        if self.username:
            core.svn_auth_set_parameter(self.auth_baton,
                                        core.SVN_AUTH_PARAM_DEFAULT_USERNAME,
                                        self.username)
        if self.password:
            core.svn_auth_set_parameter(self.auth_baton,
                                        core.SVN_AUTH_PARAM_DEFAULT_PASSWORD,
                                        self.password)
        self.client_context = client.create_context()

        self.client_context.auth_baton = self.auth_baton
        self.client_context.config = svn_config
        callbacks = RaCallbacks()
        callbacks.auth_baton = self.auth_baton
        self.callbacks = callbacks
        try:
            self.ra = ra.open2(self.svn_url, callbacks, svn_config, self.pool)
        except SubversionException, e:
            # e.child contains a detailed error messages
            msglist = []
            svn_exc = e
            while svn_exc:
                if svn_exc.args[0]:
                    msglist.append(svn_exc.args[0])
                svn_exc = svn_exc.child
            msg = '\n'.join(msglist)
            raise common.SubversionConnectionException(msg)
    def init_ra_and_client(self):
        """Initializes the RA and client layers, because sometimes getting
        unified diffs runs the remote server out of open files.
        """
        # while we're in here we'll recreate our pool
        self.pool = core.Pool()
        if self.username:
            core.svn_auth_set_parameter(self.auth_baton,
                                        core.SVN_AUTH_PARAM_DEFAULT_USERNAME,
                                        self.username)
        if self.password:
            core.svn_auth_set_parameter(self.auth_baton,
                                        core.SVN_AUTH_PARAM_DEFAULT_PASSWORD,
                                        self.password)
        self.client_context = client.create_context()

        self.client_context.auth_baton = self.auth_baton
        self.client_context.config = svn_config
        callbacks = RaCallbacks()
        callbacks.auth_baton = self.auth_baton
        self.callbacks = callbacks
        try:
            self.ra = ra.open2(self.svn_url, callbacks, svn_config, self.pool)
        except SubversionException, e:
            if e.apr_err == core.SVN_ERR_RA_SERF_SSL_CERT_UNTRUSTED:
                msg = (
                    'Subversion does not trust the SSL certificate for this '
                    'site; please try running \'svn ls %s\' first.' %
                    self.svn_url)
            elif e.apr_err == core.SVN_ERR_RA_DAV_REQUEST_FAILED:
                msg = ('Failed to open Subversion repository; please try '
                       'running \'svn ls %s\' for details.' % self.svn_url)
            else:
                msg = e.args[0]
                for k, v in vars(core).iteritems():
                    if k.startswith('SVN_ERR_') and v == e.apr_err:
                        msg = '%s (%s)' % (msg, k)
                        break
            raise common.SubversionConnectionException(msg)
    def init_ra_and_client(self):
        """
        Initializes the RA and client layers.

        With the SWIG bindings, getting unified diffs runs the remote server
        sometimes runs out of open files. It is not known whether the Subvertpy
        is affected by this.
        """
        def getclientstring():
            return 'hgsubversion'

        def simple(realm, username, may_save):
            return _prompt.simple(realm, username, may_save)

        def username(realm, may_save):
            return _prompt.username(realm, may_save)

        def ssl_client_cert(realm, may_save):
            return _prompt.ssl_client_cert(realm, may_save)

        def ssl_client_cert_pw(realm, may_save):
            return _prompt.ssl_client_cert_pw(realm, may_save)

        def ssl_server_trust(realm, failures, cert_info, may_save):
            creds = _prompt.ssl_server_trust(realm, failures, cert_info, may_save)
            if creds is None:
                # We need to reject the certificate, but subvertpy doesn't
                # handle None as a return value here, and requires
                # we instead return a tuple of (int, bool). Because of that,
                # we return (0, False) instead.
                creds = (0, False)
            return creds

        providers = ra.get_platform_specific_client_providers()
        providers += [
            ra.get_simple_provider(),
            ra.get_username_provider(),
            ra.get_ssl_client_cert_file_provider(),
            ra.get_ssl_client_cert_pw_file_provider(),
            ra.get_ssl_server_trust_file_provider(),
        ]
        if _prompt:
            providers += [
                ra.get_simple_prompt_provider(simple, 2),
                ra.get_username_prompt_provider(username, 2),
                ra.get_ssl_client_cert_prompt_provider(ssl_client_cert, 2),
                ra.get_ssl_client_cert_pw_prompt_provider(ssl_client_cert_pw, 2),
                ra.get_ssl_server_trust_prompt_provider(ssl_server_trust),
            ]

        auth = ra.Auth(providers)
        if self.username:
            auth.set_parameter(subvertpy.AUTH_PARAM_DEFAULT_USERNAME, self.username)
        if self.password:
            auth.set_parameter(subvertpy.AUTH_PARAM_DEFAULT_PASSWORD, self.password)

        try:
            self.remote = ra.RemoteAccess(url=self.svn_url,
                                          client_string_func=getclientstring,
                                          auth=auth)
        except SubversionException, e:
            # e.child contains a detailed error messages
            msglist = []
            svn_exc = e
            while svn_exc:
                if svn_exc.args[0]:
                    msglist.append(svn_exc.args[0])
                svn_exc = svn_exc.child
            msg = '\n'.join(msglist)
            raise common.SubversionConnectionException(msg)