Esempio n. 1
0
    def _validateConfiguration(self):
        """
        Validate the configuration, possibly altering/completing it.
        """

        if self.EXECUTABLE:
            from os import getenv, pathsep
            from os.path import isabs, exists, join
            from sys import platform
            from vcpx.config import ConfigurationError

            if isabs(self.EXECUTABLE):
                ok = exists(self.EXECUTABLE)
            else:
                ok = False
                mswindows = (platform == "win32")
                for path in getenv('PATH').split(pathsep):
                    if exists(join(path, self.EXECUTABLE)):
                        ok = True
                    elif mswindows:
                        for ext in ['.exe', '.bat']:
                            if exists(join(path, self.EXECUTABLE + ext)):
                                self.EXECUTABLE += ext
                                ok = True
                                break
                    if ok:
                        break
            if not ok:
                self.log.critical("Cannot find external command %r",
                                  self.EXECUTABLE)
                raise ConfigurationError("The command %r used "
                                         "by %r does not exist in %r!" %
                                         (self.EXECUTABLE, self.name,
                                          getenv('PATH')))
Esempio n. 2
0
    def __call__(self):
        from shwrap import ExternalCommand
        from target import SynchronizableTargetWorkingDir
        from changes import Changeset

        def pconfig(option, raw=False):
            return self.config.get(self.name, option, raw=raw)

        ExternalCommand.DEBUG = pconfig('debug')

        pname_format = pconfig('patch-name-format', raw=True)
        if pname_format is not None:
            SynchronizableTargetWorkingDir.PATCH_NAME_FORMAT = pname_format.strip(
            )
        SynchronizableTargetWorkingDir.REMOVE_FIRST_LOG_LINE = pconfig(
            'remove-first-log-line')
        Changeset.REFILL_MESSAGE = pconfig('refill-changelogs')

        try:
            if not self.exists():
                self.bootstrap()
                if pconfig('start-revision') == 'HEAD':
                    return
            self.update()
        except (UnicodeDecodeError, UnicodeEncodeError), exc:
            raise ConfigurationError(
                '%s: it seems that the encoding '
                'used by either the source ("%s") or the '
                'target ("%s") repository '
                'cannot properly represent at least one '
                'of the characters in the upstream '
                'changelog. You need to use a wider '
                'character set, using "encoding" option, '
                'or even "encoding-errors-policy".' %
                (exc, self.source.encoding, self.target.encoding))
Esempio n. 3
0
    def _load(self, project):
        Repository._load(self, project)
        self.EXECUTABLE = project.config.get(self.name, 'git-command', 'git')
        self.overwrite_tags = project.config.get(self.name, 'overwrite-tags',
                                                 False)
        self.parent_repo = project.config.get(self.name, 'parent-repo')
        self.branch_point = project.config.get(self.name, 'branchpoint',
                                               'HEAD')
        self.branch_name = project.config.get(self.name, 'branch')
        if self.branch_name:
            self.branch_name = 'refs/heads/' + self.branch_name

        if self.repository and self.parent_repo:
            self.log.critical(
                'Cannot make sense of both "repository" and "parent-repo" parameters'
            )
            raise ConfigurationError(
                'Must specify only one of "repository" and "parent-repo"')

        if self.branch_name and not self.repository:
            self.log.critical(
                'Cannot make sense of "branch" if "repository" is not set')
            raise ConfigurationError(
                'Missing "repository" to make use o "branch"')

        self.env = {}

        # The git storage directory can track both the repository and
        # the working directory.  If the repository directory is
        # specified, make sure git stores its repository there by
        # setting $GIT_DIR.  However, this repository will typically be
        # a "bare" repository that can't directly track a working
        # directory.  As such, it is necessary to tell it where to find
        # the working directory and index through $GIT_WORK_TREE and
        # $GIT_INDEX_FILE.

        if self.repository:
            from os.path import join
            self.storagedir = self.repository
            self.env['GIT_DIR'] = self.storagedir
            self.env['GIT_INDEX_FILE'] = join(self.METADIR, 'index')
            self.env['GIT_WORK_TREE'] = self.basedir
        else:
            self.storagedir = self.METADIR
Esempio n. 4
0
    def _validateConfiguration(self):
        from vcpx.config import ConfigurationError

        Repository._validateConfiguration(self)

        if not self.repository:
            self.log.critical('Missing repository information in %r',
                              self.name)
            raise ConfigurationError("Must specify the root of the "
                                     "Subversion repository used "
                                     "as %s with the option "
                                     "'repository'" % self.which)
        elif self.repository.endswith('/'):
            self.log.debug("Removing final slash from %r in %r",
                           self.repository, self.name)
            self.repository = self.repository.rstrip('/')

        if not self.module:
            self.log.critical('Missing module information in %r', self.name)
            raise ConfigurationError("Must specify the path within the "
                                     "Subversion repository as 'module'")

        if self.module == '.':
            self.log.warning("Replacing '.' with '/' in module name in %r",
                             self.name)
            self.module = '/'
        elif not self.module.startswith('/'):
            self.log.debug("Prepending '/' to module %r in %r", self.module,
                           self.name)
            self.module = '/' + self.module

        if not self.tags_path.startswith('/'):
            self.log.debug("Prepending '/' to svn-tags %r in %r",
                           self.tags_path, self.name)
            self.tags_path = '/' + self.tags_path

        if not self.branches_path.startswith('/'):
            self.log.debug("Prepending '/' to svn-branches %r in %r",
                           self.branches_path, self.name)
            self.branches_path = '/' + self.branches_path
Esempio n. 5
0
    def _load(self, project):
        Repository._load(self, project)
        self.EXECUTABLE = project.config.get(self.name, 'git-command', 'git')
        self.overwrite_tags = project.config.get(self.name, 'overwrite-tags', False)
        self.parent_repo = project.config.get(self.name, 'parent-repo')
        self.branch_point = project.config.get(self.name, 'branchpoint', 'HEAD')
        self.branch_name = project.config.get(self.name, 'branch')
        if self.branch_name:
            self.branch_name = 'refs/heads/' + self.branch_name

        if self.repository and self.parent_repo:
            self.log.critical('Cannot make sense of both "repository" and "parent-repo" parameters')
            raise ConfigurationError ('Must specify only one of "repository" and "parent-repo"')

        if self.branch_name and not self.repository:
            self.log.critical('Cannot make sense of "branch" if "repository" is not set')
            raise ConfigurationError ('Missing "repository" to make use o "branch"')

        self.env = {}

        # XXX: this seems plain wrong to me [who does not know git at
        # all!]: why storagedir gets set to repository here? and why
        # the need for the GIT_DIR envvar? I fail to see when
        # storagedir should be different from '.git', the default,
        # given how it's being used by this class! The same with
        # GIT_INDEX_FILE, that accordingly with the man page defaults
        # to ".git/index" anyway...
        #
        self.storagedir = self.METADIR
        if self.repository:
            from os.path import join

            #self.storagedir = self.repository
            #self.env['GIT_DIR'] = self.storagedir
            self.env['GIT_DIR'] = join(self.basedir, self.METADIR)
            self.env['GIT_INDEX_FILE'] = self.METADIR + '/index'
Esempio n. 6
0
    def _getUpstreamChangesets(self, sincerev):
        from os.path import join, exists
        from time import sleep

        from codecs import getreader

        try:
            reader = getreader(self.repository.encoding)
        except (ValueError, LookupError), err:
            raise ConfigurationError(
                'Encoding "%s" does not seem to be '
                'allowed on this system (%s): you '
                'may override the default with '
                'something like "encoding = ascii" in '
                'the %s config section' %
                (self.repository.encoding, err, self.repository.name))
Esempio n. 7
0
    def _validateConfiguration(self):
        from os.path import split
        from vcpx.config import ConfigurationError

        Repository._validateConfiguration(self)

        if not self.module and self.repository:
            self.module = split(self.repository)[1]

        if not self.module:
            self.log.critical('Missing module information in %r', self.name)
            raise ConfigurationError("Must specify a repository and maybe "
                                     "a module also")

        if self.module.endswith('/'):
            self.log.debug("Removing final slash from %r in %r", self.module,
                           self.name)
            self.module = self.module.rstrip('/')
Esempio n. 8
0
    def _checkoutUpstreamRevision(self, revision):
        """
        Concretely do the checkout of the upstream revision.
        """

        from os.path import join, exists

        # Verify that the we have the root of the repository: do that
        # iterating an "svn ls" over the hierarchy until one fails

        lastok = self.repository.repository
        if not self.repository.trust_root:
            # Use --non-interactive, so that it fails if credentials
            # are needed.
            cmd = self.repository.command("ls", "--non-interactive")
            svnls = ExternalCommand(command=cmd)

            # First verify that we have a valid repository
            svnls.execute(self.repository.repository)
            if svnls.exit_status:
                lastok = None
            else:
                # Then verify it really points to the root of the
                # repository: this is needed because later the svn log
                # parser needs to know the "offset".

                reporoot = lastok[:lastok.rfind('/')]

                # Even if it would be enough asserting that the uplevel
                # directory is not a repository, find the real root to
                # suggest it in the exception.  But don't go too far, that
                # is, stop when you hit schema://...
                while '//' in reporoot:
                    svnls.execute(reporoot)
                    if svnls.exit_status:
                        break
                    lastok = reporoot
                    reporoot = reporoot[:reporoot.rfind('/')]

        if lastok is None:
            raise ConfigurationError(
                "%r is not the root of a svn repository." %
                self.repository.repository)
        elif lastok <> self.repository.repository:
            module = self.repository.repository[len(lastok):]
            module += self.repository.module
            raise ConfigurationError(
                "Non-root svn repository %r. "
                "Please specify that as 'repository=%s' "
                "and 'module=%s'." %
                (self.repository.repository, lastok, module.rstrip('/')))

        if revision == 'INITIAL':
            initial = True
            cmd = self.repository.command("log", "--verbose", "--xml",
                                          "--non-interactive",
                                          "--stop-on-copy", "--revision",
                                          "1:HEAD")
            if self.repository.use_limit:
                cmd.extend(["--limit", "1"])
            svnlog = ExternalCommand(command=cmd)
            out, err = svnlog.execute(
                "%s%s" % (self.repository.repository, self.repository.module),
                stdout=PIPE,
                stderr=PIPE)

            if svnlog.exit_status:
                raise TargetInitializationFailure(
                    "%s returned status %d saying\n%s" %
                    (str(svnlog), svnlog.exit_status, err.read()))

            csets = changesets_from_svnlog(out, self.repository)
            last = csets.next()
            revision = last.revision
        else:
            initial = False

        if not exists(join(self.repository.basedir, self.repository.METADIR)):
            self.log.debug("Checking out a working copy")

            cmd = self.repository.command("co", "--quiet")
            if self.repository.ignore_externals:
                cmd.append("--ignore-externals")
            cmd.extend(["--revision", revision])
            svnco = ExternalCommand(command=cmd)

            out, err = svnco.execute(
                "%s%s@%s" %
                (self.repository.repository, self.repository.module, revision),
                self.repository.basedir,
                stdout=PIPE,
                stderr=PIPE)
            if svnco.exit_status:
                raise TargetInitializationFailure(
                    "%s returned status %s saying\n%s" %
                    (str(svnco), svnco.exit_status, err.read()))
        else:
            self.log.debug(
                "%r already exists, assuming it's "
                "a svn working dir", self.repository.basedir)

        if not initial:
            if revision == 'HEAD':
                revision = 'COMMITTED'
            cmd = self.repository.command("log", "--verbose", "--xml",
                                          "--non-interactive", "--revision",
                                          revision)
            svnlog = ExternalCommand(cwd=self.repository.basedir, command=cmd)
            out, err = svnlog.execute(stdout=PIPE, stderr=PIPE)

            if svnlog.exit_status:
                raise TargetInitializationFailure(
                    "%s returned status %d saying\n%s" %
                    (str(svnlog), svnlog.exit_status, err.read()))

            csets = changesets_from_svnlog(out, self.repository)
            last = csets.next()

        self.log.debug("Working copy up to svn revision %s", last.revision)

        return last