예제 #1
0
def apply_single_patch(repo, patchfile, options):
    """Apply a single patch onto the pq branch"""
    current = repo.get_branch()
    if not is_pq_branch(current, options):
        switch_to_pq_branch(repo, current, options)
    patch = Patch(patchfile)
    apply_and_commit_patch(repo, patch, fallback_author=None)
    def test_topic(self):
        """Test if setting a topic works"""
        patch = gbp.patch_series.Patch(_patch_path('foo.patch'))

        pq.apply_and_commit_patch(self.repo, patch, None, topic='foobar')
        info = self.repo.get_commit_info('HEAD')
        self.assertIn('Gbp-Pq-Topic: foobar', info['body'])
예제 #3
0
    def test_debian_missing_author(self):
        """
        Check if we parse the author from debian control
        if it's missing in the patch.
        """
        def _check_log(msg):
            self.assertEqual(msg, "Patch 'foo.patch' has no authorship "
                             "information, using 'Guido Günther <*****@*****.**>'")

        patch = gbp.patch_series.Patch(_patch_path('foo.patch'))

        # Overwrite data parsed from patch:
        patch.author
        patch.info['author'] = None
        patch.info['email'] = None

        # Fake a control file
        self.add_file("debian/control",
                      "Maintainer: Guido Günther <*****@*****.**>")

        maintainer = pq.get_maintainer_from_control(self.repo)
        orig_warn = gbp.log.warn
        gbp.log.warn = _check_log
        pq.apply_and_commit_patch(self.repo, patch, maintainer)
        gbp.log.warn = orig_warn
        info = self.repo.get_commit_info('HEAD')
        self.assertEqual(info['author'].email, '*****@*****.**')
        self.assertIn('foo', self.repo.list_files())
예제 #4
0
    def test_name(self):
        """Test if setting a name works"""
        patch = gbp.patch_series.Patch(_patch_path('foo.patch'))

        pq.apply_and_commit_patch(self.repo, patch, None, name='foobar')
        info = self.repo.get_commit_info('HEAD')
        self.assertIn('Gbp-Pq: Name foobar', info['body'])
예제 #5
0
def import_spec_patches(repo, spec, dirs):
    """
    Import patches from a spec file to the current branch
    """
    queue = spec.patchseries()
    if len(queue) == 0:
        return

    gbp.log.info("Importing patches to '%s' branch" % repo.get_branch())
    tmpdir = tempfile.mkdtemp(dir=dirs['tmp_base'], prefix='import_')
    orig_head = repo.rev_parse("HEAD")
    packager = get_packager(spec)

    # Put patches in a safe place
    queue = safe_patches(queue, tmpdir)
    for patch in queue:
        gbp.log.debug("Applying %s" % patch.path)
        try:
            apply_and_commit_patch(repo, patch, packager)
        except (GbpError, GitRepositoryError):
            repo.force_head(orig_head, hard=True)
            raise PatchImportError("Patch(es) didn't apply, you need apply "
                                   "and commit manually")

    # Remove patches from spec and packaging directory
    gbp.log.info("Removing imported patch files from spec and packaging dir")
    rm_patch_files(spec)
    try:
        spec.update_patches([], {})
        spec.write_spec_file()
    except GbpError:
        repo.force_head('HEAD', hard=True)
        raise PatchImportError("Unable to update spec file, you need to edit"
                               "and commit it  manually")
    repo.commit_all(msg=PATCH_AUTODELETE_COMMIT_MSG % spec.specfile)
예제 #6
0
    def test_topic(self):
        """Test if setting a topic works"""
        patch = gbp.patch_series.Patch(_patch_path('foo.patch'))

        pq.apply_and_commit_patch(self.repo, patch, None, topic='foobar')
        info = self.repo.get_commit_info('HEAD')
        self.assertIn('Gbp-Pq-Topic: foobar', info['body'])
예제 #7
0
    def test_apply_and_commit_patch(self):
        """Test applying a single patch"""
        patch = gbp.patch_series.Patch(
            os.path.join(os.path.abspath(os.path.curdir),
                         'tests/data/foo.patch'))

        pq.apply_and_commit_patch(self.repo, patch, None)
        self.assertIn('foo', self.repo.list_files())
    def test_apply_and_commit_patch_preserve_subject(self):
        """Test applying a patch preserves the subject"""
        patch = gbp.patch_series.Patch(_patch_path('brackets-in-subject.patch'))

        pq.apply_and_commit_patch(self.repo, patch, None)
        self.assertIn(b'foo', self.repo.list_files())
        info = self.repo.get_commit_info('HEAD')
        self.assertEquals('[text] foobar', info['subject'])
예제 #9
0
    def test_apply_and_commit_patch_preserve_subject(self):
        """Test applying a patch preserves the subject"""
        patch = gbp.patch_series.Patch(
            _patch_path('brackets-in-subject.patch'))

        pq.apply_and_commit_patch(self.repo, patch, None)
        self.assertIn(b'foo', self.repo.list_files())
        info = self.repo.get_commit_info('HEAD')
        self.assertEquals('[text] foobar', info['subject'])
예제 #10
0
def import_bb_patches(cfg, repo, options):
    """Apply a series of patches in a recipe to branch onto a pq branch"""
    current = repo.get_branch()

    if is_pq_branch(current, options):
        base = pq_branch_base(current, options)
        raise GbpError("Already on a patch-queue branch '%s' - doing "
                       "nothing." % current)
    else:
        bbfile = parse_bb(cfg, options, repo)
        base = current
    upstream_commit = find_upstream_commit(repo, bbfile, options.upstream_tag)
    pq_branch = pq_branch_name(base, options, pkg_version(bbfile))

    # Create pq-branch
    if repo.has_branch(pq_branch) and not options.force:
        raise GbpError("Patch-queue branch '%s' already exists. "
                       "Try 'rebase' instead." % pq_branch)
    try:
        if repo.get_branch() == pq_branch:
            repo.force_head(upstream_commit, hard=True)
        else:
            repo.create_branch(pq_branch, upstream_commit, force=True)
    except GitRepositoryError as err:
        raise GbpError("Cannot create patch-queue branch '%s': %s" %
                       (pq_branch, err))

    # Put patches in a safe place
    in_queue = bb_to_patch_series(bbfile)
    queue = safe_patches(in_queue, options.tmp_dir)
    # Do import
    try:
        gbp.log.info("Switching to branch '%s'" % pq_branch)
        repo.set_branch(pq_branch)
        import_extra_files(repo, base, options.import_files)

        if not queue:
            return
        gbp.log.info("Trying to apply patches from branch '%s' onto '%s'" %
                     (base, upstream_commit))
        for patch in queue:
            gbp.log.debug("Applying %s" % patch.path)
            apply_and_commit_patch(repo, patch, fallback_author=None)
    except (GbpError, GitRepositoryError) as err:
        gbp.log.err('Import failed: %s' % err)
        repo.force_head('HEAD', hard=True)
        repo.set_branch(base)
        repo.delete_branch(pq_branch)
        raise

    recipe_fn = os.path.basename(bbfile.getVar('FILE', True))
    gbp.log.info("Patches listed in '%s' imported on '%s'" %
                 (recipe_fn, pq_branch))
예제 #11
0
    def test_debian_missing_author(self):
        """
        Check if we parse the author from debian control
        if it's missing.
        """
        patch = gbp.patch_series.Patch(
            os.path.join(os.path.abspath(os.path.curdir),
                         'tests/data/foo.patch'))

        # Overwrite data parsed from patch:
        patch.author
        patch.info['author'] = None
        patch.info['email'] = None

        # Fake a control file
        self.add_file("debian/control",
                      "Maintainer: Guido Günther <*****@*****.**>")

        c = pq.get_maintainer_from_control
        pq.apply_and_commit_patch(self.repo, patch, c)
        info = self.repo.get_commit_info('HEAD')
        self.assertEqual(info['author'].email, '*****@*****.**')
        self.assertIn('foo', self.repo.list_files())
예제 #12
0
def import_spec_patches(repo, options):
    """
    apply a series of patches in a spec/packaging dir to branch
    the patch-queue branch for 'branch'

    @param repo: git repository to work on
    @param options: command options
    """
    current = repo.get_branch()
    # Get spec and related information
    if is_pq_branch(current):
        base = pq_branch_base(current)
        if options.force:
            spec = parse_spec(options, repo, base)
            spec_treeish = base
        else:
            raise GbpError("Already on a patch-queue branch '%s' - doing "
                           "nothing." % current)
    else:
        spec = parse_spec(options, repo)
        spec_treeish = None
        base = current
    upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag)
    packager = get_packager(spec)
    pq_branch = pq_branch_name(base)

    # Create pq-branch
    if repo.has_branch(pq_branch) and not options.force:
        raise GbpError("Patch-queue branch '%s' already exists. "
                       "Try 'switch' instead." % pq_branch)
    try:
        if repo.get_branch() == pq_branch:
            repo.force_head(upstream_commit, hard=True)
        else:
            repo.create_branch(pq_branch, upstream_commit, force=True)
    except GitRepositoryError as err:
        raise GbpError("Cannot create patch-queue branch '%s': %s" %
                       (pq_branch, err))

    # Put patches in a safe place
    if spec_treeish:
        packaging_tmp = tempfile.mkdtemp(prefix='dump_')
        packaging_tree = '%s:%s' % (spec_treeish, options.packaging_dir)
        dump_tree(repo,
                  packaging_tmp,
                  packaging_tree,
                  with_submodules=False,
                  recursive=False)
        spec.specdir = packaging_tmp
    in_queue = spec.patchseries()
    queue = safe_patches(in_queue)
    # Do import
    try:
        gbp.log.info("Switching to branch '%s'" % pq_branch)
        repo.set_branch(pq_branch)

        if not queue:
            return
        gbp.log.info("Trying to apply patches from branch '%s' onto '%s'" %
                     (base, upstream_commit))
        for patch in queue:
            gbp.log.debug("Applying %s" % patch.path)
            apply_and_commit_patch(repo, patch, packager)
    except (GbpError, GitRepositoryError) as err:
        repo.set_branch(base)
        repo.delete_branch(pq_branch)
        raise GbpError('Import failed: %s' % err)

    gbp.log.info("%d patches listed in '%s' imported on '%s'" %
                 (len(queue), spec.specfile, pq_branch))
예제 #13
0
def import_quilt_patches(repo, branch, series, tries, force):
    """
    apply a series of quilt patches in the series file 'series' to branch
    the patch-queue branch for 'branch'

    @param repo: git repository to work on
    @param branch: branch to base pqtch queue on
    @param series; series file to read patches from
    @param tries: try that many times to apply the patches going back one
                  commit in the branches history after each failure.
    @param force: import the patch series even if the branch already exists
    """
    tmpdir = None

    if is_pq_branch(branch):
        if force:
            branch = pq_branch_base(branch)
            pq_branch = pq_branch_name(branch)
            repo.checkout(branch)
        else:
            gbp.log.err("Already on a patch-queue branch '%s' - doing nothing." % branch)
            raise GbpError
    else:
        pq_branch = pq_branch_name(branch)

    if repo.has_branch(pq_branch):
        if force:
            drop_pq(repo, branch)
        else:
            raise GbpError("Patch queue branch '%s'. already exists. Try 'rebase' instead."
                           % pq_branch)

    maintainer = get_maintainer_from_control(repo)
    commits = repo.get_commits(num=tries, first_parent=True)
    # If we go back in history we have to safe our pq so we always try to apply
    # the latest one
    if len(commits) > 1:
        tmpdir, series = safe_patches(series)

    queue = PatchSeries.read_series_file(series)

    i = len(commits)
    for commit in commits:
        if len(commits) > 1:
            gbp.log.info("%d %s left" % (i, 'tries' if i > 1 else 'try'))
        try:
            gbp.log.info("Trying to apply patches at '%s'" % commit)
            repo.create_branch(pq_branch, commit)
        except GitRepositoryError:
            raise GbpError("Cannot create patch-queue branch '%s'." % pq_branch)

        repo.set_branch(pq_branch)
        for patch in queue:
            gbp.log.debug("Applying %s" % patch.path)
            try:
                apply_and_commit_patch(repo, patch, maintainer, patch.topic)
            except (GbpError, GitRepositoryError):
                gbp.log.err("Failed to apply '%s'" % patch.path)
                repo.set_branch(branch)
                repo.delete_branch(pq_branch)
                break
        else:
            # All patches applied successfully
            break
        i-=1
    else:
        raise GbpError("Couldn't apply patches")

    if tmpdir:
        gbp.log.debug("Remove temporary patch safe '%s'" % tmpdir)
        shutil.rmtree(tmpdir)
예제 #14
0
def import_quilt_patches(repo, branch, series, tries, force, pq_from,
                         upstream_tag):
    """
    apply a series of quilt patches in the series file 'series' to branch
    the patch-queue branch for 'branch'

    @param repo: git repository to work on
    @param branch: branch to base patch queue on
    @param series: series file to read patches from
    @param tries: try that many times to apply the patches going back one
                  commit in the branches history after each failure.
    @param force: import the patch series even if the branch already exists
    @param pq_from: what to use as the starting point for the pq branch.
                    DEBIAN indicates the current branch, TAG indicates that
                    the corresponding upstream tag should be used.
    @param upstream_tag: upstream tag template to use
    """
    tmpdir = None
    series = os.path.join(repo.path, series)

    if is_pq_branch(branch):
        if force:
            branch = pq_branch_base(branch)
            pq_branch = pq_branch_name(branch)
            repo.checkout(branch)
        else:
            raise GbpError(
                "Already on a patch-queue branch '%s' - doing nothing." %
                branch)
    else:
        pq_branch = pq_branch_name(branch)

    if repo.has_branch(pq_branch):
        if force:
            drop_pq(repo, branch)
        else:
            raise GbpError(
                "Patch queue branch '%s'. already exists. Try 'rebase' or 'switch' instead."
                % pq_branch)

    maintainer = get_maintainer_from_control(repo)
    if pq_on_upstream_tag(pq_from):
        commits = [find_upstream_commit(repo, branch, upstream_tag)]
    else:  # pq_from == 'DEBIAN'
        commits = repo.get_commits(num=tries, first_parent=True)
    # If we go back in history we have to safe our pq so we always try to apply
    # the latest one
    # If we are using the upstream_tag, we always need a copy of the patches
    if len(commits) > 1 or pq_on_upstream_tag(pq_from):
        if os.path.exists(series):
            tmpdir, series = safe_patches(series, repo)

    queue = PatchSeries.read_series_file(series)

    i = len(commits)
    for commit in commits:
        if len(commits) > 1:
            gbp.log.info("%d %s left" % (i, 'tries' if i > 1 else 'try'))
        try:
            gbp.log.info("Trying to apply patches at '%s'" % commit)
            repo.create_branch(pq_branch, commit)
        except GitRepositoryError:
            raise GbpError("Cannot create patch-queue branch '%s'." %
                           pq_branch)

        repo.set_branch(pq_branch)
        for patch in queue:
            gbp.log.debug("Applying %s" % patch.path)
            try:
                name = os.path.basename(patch.path)
                apply_and_commit_patch(repo, patch, maintainer, patch.topic,
                                       name)
            except (GbpError, GitRepositoryError) as e:
                gbp.log.err("Failed to apply '%s': %s" % (patch.path, e))
                repo.force_head('HEAD', hard=True)
                repo.set_branch(branch)
                repo.delete_branch(pq_branch)
                break
        else:
            # All patches applied successfully
            break
        i -= 1
    else:
        raise GbpError("Couldn't apply patches")

    if tmpdir:
        gbp.log.debug("Remove temporary patch safe '%s'" % tmpdir)
        shutil.rmtree(tmpdir)

    return len(queue)
예제 #15
0
    def test_apply_and_commit_patch(self):
        """Test applying a single patch"""
        patch = gbp.patch_series.Patch(_patch_path('foo.patch'))

        pq.apply_and_commit_patch(self.repo, patch, None)
        self.assertIn('foo', self.repo.list_files())
예제 #16
0
def import_quilt_patches(repo, branch, series, tries, force, pq_from,
                         upstream_tag):
    """
    apply a series of quilt patches in the series file 'series' to branch
    the patch-queue branch for 'branch'

    @param repo: git repository to work on
    @param branch: branch to base patch queue on
    @param series: series file to read patches from
    @param tries: try that many times to apply the patches going back one
                  commit in the branches history after each failure.
    @param force: import the patch series even if the branch already exists
    @param pq_from: what to use as the starting point for the pq branch.
                    DEBIAN indicates the current branch, TAG indicates that
                    the corresponding upstream tag should be used.
    @param upstream_tag: upstream tag template to use
    """
    tmpdir = None
    series = os.path.join(repo.path, series)

    if is_pq_branch(branch):
        if force:
            branch = pq_branch_base(branch)
            pq_branch = pq_branch_name(branch)
            repo.checkout(branch)
        else:
            raise GbpError("Already on a patch-queue branch '%s' - doing nothing." % branch)
    else:
        pq_branch = pq_branch_name(branch)

    if repo.has_branch(pq_branch):
        if force:
            drop_pq(repo, branch)
        else:
            raise GbpError("Patch queue branch '%s'. already exists. Try 'rebase' or 'switch' instead."
                           % pq_branch)

    maintainer = get_maintainer_from_control(repo)
    if pq_on_upstream_tag(pq_from):
        commits = [find_upstream_commit(repo, branch, upstream_tag)]
    else:  # pq_from == 'DEBIAN'
        commits = repo.get_commits(num=tries, first_parent=True)
    # If we go back in history we have to safe our pq so we always try to apply
    # the latest one
    # If we are using the upstream_tag, we always need a copy of the patches
    if len(commits) > 1 or pq_on_upstream_tag(pq_from):
        if os.path.exists(series):
            tmpdir, series = safe_patches(series, repo)

    queue = PatchSeries.read_series_file(series)

    i = len(commits)
    for commit in commits:
        if len(commits) > 1:
            gbp.log.info("%d %s left" % (i, 'tries' if i > 1 else 'try'))
        try:
            gbp.log.info("Trying to apply patches at '%s'" % commit)
            repo.create_branch(pq_branch, commit)
        except GitRepositoryError:
            raise GbpError("Cannot create patch-queue branch '%s'." % pq_branch)

        repo.set_branch(pq_branch)
        for patch in queue:
            gbp.log.debug("Applying %s" % patch.path)
            try:
                name = os.path.basename(patch.path)
                apply_and_commit_patch(repo, patch, maintainer, patch.topic, name)
            except (GbpError, GitRepositoryError) as e:
                gbp.log.err("Failed to apply '%s': %s" % (patch.path, e))
                repo.force_head('HEAD', hard=True)
                repo.set_branch(branch)
                repo.delete_branch(pq_branch)
                break
        else:
            # All patches applied successfully
            break
        i -= 1
    else:
        raise GbpError("Couldn't apply patches")

    if tmpdir:
        gbp.log.debug("Remove temporary patch safe '%s'" % tmpdir)
        shutil.rmtree(tmpdir)

    return len(queue)
예제 #17
0
def import_spec_patches(repo, options):
    """
    apply a series of patches in a spec/packaging dir to branch
    the patch-queue branch for 'branch'

    @param repo: git repository to work on
    @param options: command options
    """
    current = repo.get_branch()
    # Get spec and related information
    if is_pq_branch(current):
        base = pq_branch_base(current)
        if options.force:
            spec = parse_spec(options, repo, base)
            spec_treeish = base
        else:
            raise GbpError("Already on a patch-queue branch '%s' - doing "
                           "nothing." % current)
    else:
        spec = parse_spec(options, repo)
        spec_treeish = None
        base = current
    upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag)
    packager = get_packager(spec)
    pq_branch = pq_branch_name(base)

    # Create pq-branch
    if repo.has_branch(pq_branch) and not options.force:
        raise GbpError("Patch-queue branch '%s' already exists. "
                       "Try 'switch' instead." % pq_branch)
    try:
        if repo.get_branch() == pq_branch:
            repo.force_head(upstream_commit, hard=True)
        else:
            repo.create_branch(pq_branch, upstream_commit, force=True)
    except GitRepositoryError as err:
        raise GbpError("Cannot create patch-queue branch '%s': %s" %
                        (pq_branch, err))

    # Put patches in a safe place
    if spec_treeish:
        packaging_tmp = tempfile.mkdtemp(prefix='dump_', dir=options.tmp_dir)
        packaging_tree = '%s:%s' % (spec_treeish, options.packaging_dir)
        dump_tree(repo, packaging_tmp, packaging_tree, with_submodules=False,
                  recursive=False)
        spec.specdir = packaging_tmp
    in_queue = spec.patchseries()
    queue = safe_patches(in_queue, options.tmp_dir)
    # Do import
    try:
        gbp.log.info("Switching to branch '%s'" % pq_branch)
        repo.set_branch(pq_branch)

        if not queue:
            return
        gbp.log.info("Trying to apply patches from branch '%s' onto '%s'" %
                        (base, upstream_commit))
        for patch in queue:
            gbp.log.debug("Applying %s" % patch.path)
            apply_and_commit_patch(repo, patch, packager)
    except (GbpError, GitRepositoryError) as err:
        repo.set_branch(base)
        repo.delete_branch(pq_branch)
        raise GbpError('Import failed: %s' % err)

    gbp.log.info("Patches listed in '%s' imported on '%s'" % (spec.specfile,
                                                              pq_branch))