Beispiel #1
0
def import_upstream_archive(repo, pkg_data, fetch_data, dirs, options):
    """Import upstream sources from archive"""
    # Unpack orig source archive
    path = fetch_data.localpath
    sources = RpmUpstreamSource(path)
    sources = sources.unpack(dirs['origsrc'], options.filters)

    tag_str_fields = dict(pkg_version(pkg_data), vendor=options.vendor.lower())
    tag = repo.version_to_tag(options.upstream_tag, tag_str_fields)
    if not repo.has_tag(tag):
        gbp.log.info("Tag %s not found, importing upstream sources" % tag)
        branch = options.upstream_branch

        msg = "Upstream version %s" % tag_str_fields['upstreamversion']
        if options.vcs_tag:
            parents = [repo.rev_parse("%s^{}" % options.vcs_tag)]
        else:
            parents = None
        commit = repo.commit_dir(sources.unpacked, "Imported %s" % msg,
                        branch, other_parents=parents,
                        create_missing_branch=options.create_missing_branches)
        repo.create_tag(name=tag, msg=msg, commit=commit,
                        sign=options.sign_tags, keyid=options.keyid)

        if options.pristine_tar:
            archive_fmt = parse_archive_filename(path)[1]
            if archive_fmt == 'tar':
                repo.pristine_tar.commit(path, 'refs/heads/%s' % branch)
            else:
                gbp.log.warn('Ignoring pristine-tar, %s archives '
                             'not supported' % archive_fmt)
    return repo.rev_parse('%s^0' % tag)
def drop_pq_bb(cfg, repo, options):
    """Remove pq branch"""
    current = repo.get_branch()
    if is_pq_branch(current, options):
        base = pq_branch_base(current, options)
        bbfile = parse_bb(cfg, options, repo, base)
    else:
        bbfile = parse_bb(cfg, options, repo)
    drop_pq(repo, current, options, pkg_version(bbfile))
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))
def switch_to_pq_branch(cfg, repo, branch, options):
    """
    Switch to patch-queue branch if not already there, create it if it
    doesn't exist yet
    """
    if is_pq_branch(branch, options):
        return

    bbfile = parse_bb(cfg, options, repo, branch)
    pq_branch = pq_branch_name(branch, options, pkg_version(bbfile))
    if not repo.has_branch(pq_branch):
        raise GbpError("Branch '%s' does not exist" % pq_branch)

    gbp.log.info("Switching to branch '%s'" % pq_branch)
    repo.set_branch(pq_branch)
def export_patches(cfg, repo, options):
    """Export patches from the pq branch into a packaging branch"""
    current = repo.get_branch()
    if is_pq_branch(current, options):
        base = pq_branch_base(current, options)
        gbp.log.info("On branch '%s', switching to '%s'" % (current, base))
        repo.set_branch(base)
        bbfile = parse_bb(cfg, options, repo)
        pq_branch = current
    else:
        bbfile = parse_bb(cfg, options, repo)
        pq_branch = pq_branch_name(current, options, pkg_version(bbfile))
    upstream_commit = find_upstream_commit(repo, bbfile, options.upstream_tag)

    export_treeish = options.export_rev if options.export_rev else pq_branch

    update_patch_series(repo, bbfile, upstream_commit, export_treeish, options)

    bb_dir = os.path.dirname(bbfile.getVar('FILE', True))
    GitCommand('status')(['--', bb_dir])
def main(argv):
    """Entry point for git-buildpackage-bb"""
    retval = 0
    prefix = "git-"
    bbfile = None
    dump_dir = None

    if not bb:
        return 1

    options, gbp_args, builder_args = parse_args(argv, prefix)
    if not options:
        return 1

    try:
        repo = RpmGitRepository(os.path.curdir)
    except GitRepositoryError:
        gbp.log.err("%s is not a git repository" % (os.path.abspath('.')))
        return 1

    # Determine tree-ish to be exported
    try:
        tree = get_tree(repo, options.export)
    except GbpError as err:
        gbp.log.err('Failed to determine export treeish: %s' % err)
        return 1
    # Re-parse config options with using the per-tree config file(s) from the
    # exported tree-ish
    options, gbp_args, builder_args = parse_args(argv, prefix, tree)

    branch = get_current_branch(repo)

    try:
        tinfoil = init_tinfoil(config_only=True)
        #bb_cfg_data = bb.data.createCopy(tinfoil.config_data)
    except GbpError:
        tinfoil = None

    # Use naive parsing because repository might only have .bb file
    gbp.log.info("Using naive standalone parsing of recipes in package repo.")
    bb_cfg_data = None

    try:
        tree = guess_export_params(repo, options)

        Command(options.cleaner, shell=True)()
        if not options.ignore_new:
            (ret, out) = repo.is_clean(options.ignore_untracked)
            if not ret:
                gbp.log.err("You have uncommitted changes in your source tree:")
                gbp.log.err(out)
                raise GbpError("Use --git-ignore-new or --git-ignore-untracked "
                               "to ignore.")

        if not options.ignore_new and not options.ignore_branch:
            if branch != options.packaging_branch:
                gbp.log.err("You are not on branch '%s' but on '%s'" %
                            (options.packaging_branch, branch))
                raise GbpError("Use --git-ignore-branch to ignore or "
                               "--git-packaging-branch to set the branch name.")

        if not options.tag_only:
            # Dump/parse meta to export dir
            if options.export_dir:
                export_dir = os.path.abspath(options.export_dir)
            else:
                export_dir = guess_export_dir(options, tinfoil, repo, tree)
            gbp.log.info("Dumping meta from tree '%s' to '%s'" %
                            (options.export, export_dir))
            bbfile = dump_meta(bb_cfg_data, options, repo, tree,
                                 export_dir)

            # Setup builder opts
            setup_builder(options, builder_args)

            if is_native(repo, options) and bbfile.getVar('SRCREV') == 'HEAD':
                # Update SRCREV for native packages that are exported from
                # pristine repository
                BBFile.set_var_val(bbfile.bb_path, 'SRCREV',
                                   repo.rev_parse(tree))

                # TODO: Re-design the handling of native packages. Updating
                #       SRCREV must probably be more explicit
            if options.patch_export:
                # Generate patches, if requested
                if options.patch_export_rev:
                    patch_tree = get_tree(repo, options.patch_export_rev)
                else:
                    patch_tree = tree
                export_patches(repo, bbfile, patch_tree, options)

            # Run postexport hook
            if options.postexport:
                RunAtCommand(options.postexport, shell=True,
                             extra_env={'GBP_GIT_DIR': repo.git_dir,
                                        'GBP_TMP_DIR': export_dir}
                             )(dir=export_dir)
            # Do actual build
            if not options.no_build:
                if options.prebuild:
                    RunAtCommand(options.prebuild, shell=True,
                                 extra_env={'GBP_GIT_DIR': repo.git_dir,
                                            'GBP_BUILD_DIR': export_dir}
                                 )(dir=export_dir)

                # Unlock cooker so that we are able to run external bitbake
                if options.builder == 'bitbake' and tinfoil:
                    bb.utils.unlockfile(tinfoil.cooker.lock)

                # Finally build the package:
                bb_path = bbfile.getVar('FILE', True)
                builder_args.extend(['-b', bb_path])
                RunAtCommand(options.builder, builder_args, shell=True,
                             extra_env={'GBP_BUILD_DIR': export_dir})()

                if options.postbuild:
                    Command(options.postbuild, shell=True,
                            extra_env={'GBP_BUILD_DIR': export_dir})()
        else:
            # Tag-only: we just need to parse the meta
            bbfile = parse_bb(bb_cfg_data, options, repo, tree)

        # Tag (note: tags the exported version)
        if options.tag or options.tag_only:
            version = pkg_version(bbfile)
            gbp.log.info("Tagging %s" %
                         RpmPkgPolicy.compose_full_version(version))
            commit_info = repo.get_commit_info(tree)
            tag = packaging_tag_name(repo, version, commit_info, options)
            if options.retag and repo.has_tag(tag):
                repo.delete_tag(tag)
            create_packaging_tag(repo, tag, commit=tree, version=version,
                                 options=options)
            vcs_info = get_vcs_info(repo, tag)
            if options.posttag:
                sha = repo.rev_parse("%s^{}" % tag)
                Command(options.posttag, shell=True,
                        extra_env={'GBP_TAG': tag,
                                   'GBP_BRANCH': branch,
                                   'GBP_SHA1': sha})()
        else:
            vcs_info = get_vcs_info(repo, tree)
        # TODO: Put VCS information to recipe
        if options.bb_vcs_info:
            raise GbpError("Injecting VCS info into recipe not yet supported")

    except CommandExecFailed:
        retval = 1
    except GitRepositoryError as err:
        gbp.log.err("Git command failed: %s" % err)
        retval = 1
    except GbpAutoGenerateError as err:
        if len(err.__str__()):
            gbp.log.err(err)
        retval = 2
    except GbpError, err:
        if len(err.__str__()):
            gbp.log.err(err)
        retval = 1
        gbp.log.err("Git command failed: %s" % err)
        retval = 1
    except GbpAutoGenerateError as err:
        if len(err.__str__()):
            gbp.log.err(err)
        retval = 2
    except GbpError, err:
        if len(err.__str__()):
            gbp.log.err(err)
        retval = 1
    finally:
        drop_index(repo)
        if dump_dir and os.path.exists(dump_dir):
            shutil.rmtree(dump_dir)

    if not options.tag_only:
        if bbfile and options.notify:
            summary = "GBP buildpackage-bb %s" % \
                        ["failed", "successful"][not retval]
            message = ("Build of %s %s %s" % (bbfile.getVar('PN', True),
                       RpmPkgPolicy.compose_full_version(pkg_version(bbfile)),
                       ["failed", "succeeded"][not retval]))
            if not gbp.notifications.notify(summary, message, options.notify):
                gbp.log.err("Failed to send notification")
                retval = 1

    return retval

if __name__ == '__main__':
    sys.exit(main(sys.argv))
Beispiel #8
0
def main(argv):
    """Main function of the gbp import-bb script"""
    dirs = dict(top=os.path.abspath(os.curdir))
    ret = 0
    skipped = False

    if not bb:
        return 1

    options, args = parse_args(argv)

    if len(args) == 0 or len(args) > 2:
        gbp.log.err("Need to give exactly one package to import. Try --help.")
        return 1

    try:
        dirs['tmp_base'] = tempfile.mkdtemp(dir=options.tmp_dir,
                                            prefix='import-bb')
        tinfoil = init_tinfoil()
        pkg_bb = guess_pkg(tinfoil, args[0])
        dirs['src'] = os.path.abspath(os.path.dirname(pkg_bb))
        gbp.log.info("Importing '%s' from '%s'" %
                     (os.path.basename(pkg_bb), dirs['src']))

        pkg_data = bb.cache.Cache.loadDataFull(pkg_bb, [], tinfoil.config_data)

        # Determine target repo dir
        target_dir = ''
        if len(args) == 2:
            target_dir = args[1]
        else:
            if 'BUILDDIR' in os.environ:
                target_dir = os.path.join(os.environ['BUILDDIR'], 'devel')
            target_dir = os.path.join(target_dir, pkg_data.getVar('PN', True))

        # Check the Git repository state
        repo = init_repo(target_dir)
        if repo.bare:
            set_bare_repo_options(options)
        if repo.is_empty():
            options.create_missing_branches = True
        os.chdir(repo.path)

        # Create more tempdirs
        dirs['origsrc'] = tempfile.mkdtemp(dir=dirs['tmp_base'],
                                           prefix='origsrc_')
        dirs['packaging_base'] = tempfile.mkdtemp(dir=dirs['tmp_base'],
                                                  prefix='packaging_')
        dirs['packaging'] = os.path.join(dirs['packaging_base'],
                                         options.meta_dir)

        # Copy (local) packaging files to tmp dir
        remote_srcs = bb_get_files(pkg_data, dirs['packaging'])

        version_dict = pkg_version(pkg_data)
        tag_str_fields = dict(version_dict, vendor=options.vendor.lower())
        ver_str = RpmPkgPolicy.compose_full_version(version_dict)

        # Check if the same version of the package is already imported
        if repo.find_version(options.packaging_tag, tag_str_fields):
            gbp.log.warn("Version %s already imported." % ver_str)
            if options.allow_same_version:
                gbp.log.info("Moving tag of version '%s' since import forced" %
                             ver_str)
                move_tag_stamp(repo, options.packaging_tag, tag_str_fields)
            else:
                raise SkipImport

        # Import upstream sources
        import_upstream_sources(repo, pkg_data, remote_srcs, dirs, options)

        # Import packaging files
        gbp.log.info("Importing local meta/packaging files")
        branch = options.packaging_branch
        if not repo.has_branch(branch):
            if options.create_missing_branches:
                gbp.log.info("Will create missing branch '%s'" % branch)
            else:
                gbp.log.err(NO_PACKAGING_BRANCH_MSG % branch + "\n"
                            "Also check the --create-missing-branches "
                            "option.")
                raise GbpError

        tag = repo.version_to_tag(options.packaging_tag, tag_str_fields)
        msg = "%s release %s" % (options.vendor, ver_str)

        commit = repo.commit_dir(dirs['packaging_base'],
                    "Imported %s" % msg,
                    branch,
                    create_missing_branch=options.create_missing_branches)

        # Create packaging tag
        repo.create_tag(name=tag,
                        msg=msg,
                        commit=commit,
                        sign=options.sign_tags,
                        keyid=options.keyid)

        force_to_branch_head(repo, options.packaging_branch)

    except KeyboardInterrupt:
        ret = 1
        gbp.log.err("Interrupted. Aborting.")
    except gbpc.CommandExecFailed:
        ret = 1
    except GitRepositoryError as err:
        gbp.log.err("Git command failed: %s" % err)
        ret = 1
    except GbpError as err:
        if len(err.__str__()):
            gbp.log.err(err)
        ret = 1
    except SkipImport:
        skipped = True
    finally:
        os.chdir(dirs['top'])
        gbpc.RemoveTree(dirs['tmp_base'])()

    if not ret and not skipped:
        gbp.log.info("Version '%s' imported under '%s'" %
                     (ver_str, repo.path))
    return ret