def convert_with_history(repo, upstream, commits, new_branch, spec_fn, options): """Auto-import packaging files and (auto-generated) patches""" # Dump and commit packaging files packaging_tree = '%s:%s' % (commits[0], options.packaging_dir) packaging_tmp = tempfile.mkdtemp(prefix='pack_', dir=options.tmp_dir) dump_packaging_dir = os.path.join(packaging_tmp, options.new_packaging_dir) dump_tree(repo, dump_packaging_dir, packaging_tree, with_submodules=False, recursive=False) msg = "Auto-import packaging files\n\n" \ "Imported initial packaging files from commit '%s'" % (commits[0]) new_tree = repo.create_tree(packaging_tmp) tip_commit = repo.commit_tree(new_tree, msg, []) # Generate initial patches spec = SpecFile(os.path.join(dump_packaging_dir, spec_fn)) update_patch_series(repo, spec, upstream, commits[0], options) # Commit updated packaging files only if something was changed new_tree = repo.create_tree(packaging_tmp) if new_tree != repo.rev_parse(tip_commit + ':'): msg = "Auto-generate patches\n\n" \ "Generated patches from\n'%s..%s'\n\n" \ "updating spec file and possibly removing old patches." \ % (upstream, commits[0]) tip_commit = repo.commit_tree(new_tree, msg, [tip_commit]) # Import rest of the commits for commit in commits[1:]: shutil.rmtree(dump_packaging_dir) packaging_tree = '%s:%s' % (commit, options.packaging_dir) dump_tree(repo, dump_packaging_dir, packaging_tree, with_submodules=False, recursive=False) try: spec = SpecFile(os.path.join(dump_packaging_dir, spec_fn)) update_patch_series(repo, spec, upstream, commit, options) except (NoSpecError, GbpError): gbp.log.warn("Failed to generate patches from '%s'" % commit) new_tree = repo.create_tree(packaging_tmp) if new_tree == repo.rev_parse(tip_commit + ':'): gbp.log.info("Skipping commit '%s' which generated no change" % commit) else: info = repo.get_commit_info(commit) msg = "%s\n\n%sAuto-imported by gbp from '%s'" % ( info['subject'], info['body'], commit) tip_commit = repo.commit_tree(new_tree, msg, [tip_commit]) repo.create_branch(new_branch, tip_commit) repo.set_branch(new_branch)
def bb_from_repo(cfg_data, repo, treeish, bb_path): """Get and parse a bb recipe from a Git treeish""" try: tmpdir = tempfile.mkdtemp(prefix='gbp-bb_') # Dump whole bb directory dump_tree(repo, tmpdir, '%s:%s' % (treeish, os.path.dirname(bb_path)), False) fpath = os.path.join(tmpdir, os.path.basename(bb_path)) return BBFile(fpath, cfg_data) except GitRepositoryError as err: raise GbpError("Git error: %s" % err) finally: shutil.rmtree(tmpdir)
def dump_meta(cfg_data, options, repo, treeish, dump_dir): """Parse and dump meta information from a treeish""" tmpdir = tempfile.mkdtemp(prefix='gbp-bb_') try: bb_path = guess_bb_path(options, repo, treeish, bbappend=True) # Dump whole meta directory dump_tree(repo, tmpdir, '%s:%s' % (treeish, os.path.dirname(bb_path)), False) # Parse recipe full_path = os.path.join(tmpdir, os.path.basename(bb_path)) bbfile = BBFile(full_path, cfg_data) bb_get_local_files(bbfile, dump_dir) except GitRepositoryError as err: raise GbpError("Git error: %s" % err) finally: shutil.rmtree(tmpdir) # Re-parse recipe from final location full_path = os.path.abspath(os.path.join(dump_dir, os.path.basename(bb_path))) return BBFile(full_path, cfg_data)
def export_source(repo, tree, cp, options, dest_dir, tarball_dir): """ Export a version of the source tree when building in a separate directory @param repo: the git repository to export from @type repo: L{gbp.git.GitRepository} @param cp: the package's changelog @param options: options to apply @param dest_dir: where to export the source to @param tarball_dir: where to fetch the tarball from in overlay mode @returns: the temporary directory """ # Extract orig tarball if git-overlay option is selected: if options.overlay: if cp.is_native(): raise GbpError("Cannot overlay Debian native package") extract_orig(os.path.join(tarball_dir, du.orig_file(cp, options.comp_type)), dest_dir) gbp.log.info("Exporting '%s' to '%s'" % (options.export, dest_dir)) if not dump_tree(repo, dest_dir, tree, options.with_submodules): raise GbpError
def export_source(repo, tree, source, options, dest_dir, tarball_dir): """ Export a version of the source tree when building in a separate directory @param repo: the git repository to export from @type repo: L{gbp.git.GitRepository} @param source: the source package @param options: options to apply @param dest_dir: where to export the source to @param tarball_dir: where to fetch the tarball from in overlay mode @returns: the temporary directory """ # Extract orig tarball if git-overlay option is selected: if options.overlay: if source.is_native(): raise GbpError("Cannot overlay Debian native package") overlay_extract_origs(source, tarball_dir, dest_dir, options) gbp.log.info("Exporting '%s' to '%s'" % (options.export, dest_dir)) if not dump_tree(repo, dest_dir, tree, options.with_submodules): raise GbpError
def main(argv): """Entry point for gbp-buildpackage-rpm""" retval = 0 prefix = "git-" spec = None 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: init_tmpdir(options.tmp_dir, prefix='buildpackage-rpm_') tree = get_tree(repo, options.export) spec = parse_spec(options, repo, treeish=tree) Command(options.cleaner, shell=True)() if not options.ignore_new: ret, out = repo.is_clean() if not ret: gbp.log.err("You have uncommitted changes in your source tree:") gbp.log.err(out) raise GbpError("Use --git-ignore-new 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.") # Dump from git to a temporary directory: packaging_tree = '%s:%s' % (tree, options.packaging_dir) dump_dir = tempfile.mkdtemp(prefix='packaging_') gbp.log.debug("Dumping packaging files to '%s'" % dump_dir) if not dump_tree(repo, dump_dir, packaging_tree, False, False): raise GbpError # Re-parse spec from dump dir to get version etc. spec = rpm.SpecFile(os.path.join(dump_dir, spec.specfile)) if not options.tag_only: # Setup builder opts setup_builder(options, builder_args) if options.use_mock: setup_mock(options) # Prepare final export dirs export_dir = makedir(options.export_dir) source_dir = makedir(os.path.join(export_dir, options.export_sourcedir)) spec_dir = makedir(os.path.join(export_dir, options.export_specdir)) # Move packaging files to final export dir gbp.log.debug("Exporting packaging files from '%s' to '%s'" % (dump_dir, export_dir)) for fname in os.listdir(dump_dir): src = os.path.join(dump_dir, fname) if fname == spec.specfile: dst = os.path.join(spec_dir, fname) else: dst = os.path.join(source_dir, fname) try: shutil.copy2(src, dst) except IOError as err: raise GbpError("Error exporting packaging files: %s" % err) spec.specdir = os.path.abspath(spec_dir) # Get/build the orig tarball if is_native(repo, options): if spec.orig_src and not options.no_create_orig: # Just build source archive from the exported tree gbp.log.info("Creating (native) source archive %s from '%s'" % (spec.orig_src['filename'], tree)) if spec.orig_src['compression']: gbp.log.debug("Building source archive with " "compression '%s -%s'" % (spec.orig_src['compression'], options.comp_level)) orig_prefix = spec.orig_src['prefix'] if not git_archive(repo, spec, source_dir, tree, orig_prefix, options.comp_level, options.with_submodules): raise GbpError("Cannot create source tarball at '%s'" % source_dir) # Non-native packages: create orig tarball from upstream elif spec.orig_src: prepare_upstream_tarball(repo, spec, options, source_dir) # 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 and not options.tag_only: if options.prebuild: RunAtCommand(options.prebuild, shell=True, extra_env={'GBP_GIT_DIR': repo.git_dir, 'GBP_BUILD_DIR': export_dir} )(dir=export_dir) # Finally build the package: if options.builder.startswith("rpmbuild"): builder_args.append(os.path.join(spec.specdir, spec.specfile)) else: builder_args.append(spec.specfile) RunAtCommand(options.builder, builder_args, shell=True, extra_env={'GBP_BUILD_DIR': export_dir} )(dir=export_dir) if options.postbuild: changes = os.path.abspath("%s/%s.changes" % (source_dir, spec.name)) gbp.log.debug("Looking for changes file %s" % changes) Command(options.postbuild, shell=True, extra_env={'GBP_CHANGES_FILE': changes, 'GBP_BUILD_DIR': export_dir})() # Tag (note: tags the exported version) if options.tag or options.tag_only: gbp.log.info("Tagging %s" % rpm.compose_version_str(spec.version)) tag = create_packaging_tag(repo, tree, spec.name, spec.version, 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) 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 as err: if len(err.__str__()): gbp.log.err(err) retval = 1 finally: drop_index() del_tmpdir() if not options.tag_only: if spec and options.notify: summary = "Gbp-rpm %s" % ["failed", "successful"][not retval] message = ("Build of %s %s %s" % (spec.name, rpm.compose_version_str(spec.version), ["failed", "succeeded"][not retval])) if not gbp.notifications.notify(summary, message, options.notify): gbp.log.err("Failed to send notification") retval = 1 return retval
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))
def main(argv): """Entry point for gbp-buildpackage-rpm""" retval = 0 prefix = "git-" spec = None 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: init_tmpdir(options.tmp_dir, prefix='buildpackage-rpm_') tree = get_tree(repo, options.export) spec = parse_spec(options, repo, treeish=tree) Command(options.cleaner, shell=True)() if not options.ignore_new: ret, out = repo.is_clean() if not ret: gbp.log.err( "You have uncommitted changes in your source tree:") gbp.log.err(out) raise GbpError("Use --git-ignore-new 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.") # Dump from git to a temporary directory: packaging_tree = '%s:%s' % (tree, options.packaging_dir) dump_dir = tempfile.mkdtemp(prefix='packaging_') gbp.log.debug("Dumping packaging files to '%s'" % dump_dir) if not dump_tree(repo, dump_dir, packaging_tree, False, False): raise GbpError # Re-parse spec from dump dir to get version etc. spec = rpm.SpecFile(os.path.join(dump_dir, spec.specfile)) if not options.tag_only: # Setup builder opts setup_builder(options, builder_args) if options.use_mock: setup_mock(options) # Prepare final export dirs export_dir = makedir(options.export_dir) source_dir = makedir( os.path.join(export_dir, options.export_sourcedir)) spec_dir = makedir(os.path.join(export_dir, options.export_specdir)) # Move packaging files to final export dir gbp.log.debug("Exporting packaging files from '%s' to '%s'" % (dump_dir, export_dir)) for fname in os.listdir(dump_dir): src = os.path.join(dump_dir, fname) if fname == spec.specfile: dst = os.path.join(spec_dir, fname) else: dst = os.path.join(source_dir, fname) try: shutil.copy2(src, dst) except IOError as err: raise GbpError("Error exporting packaging files: %s" % err) spec.specdir = os.path.abspath(spec_dir) # Get/build the orig tarball if is_native(repo, options): if spec.orig_src and not options.no_create_orig: # Just build source archive from the exported tree gbp.log.info( "Creating (native) source archive %s from '%s'" % (spec.orig_src['filename'], tree)) if spec.orig_src['compression']: gbp.log.debug( "Building source archive with " "compression '%s -%s'" % (spec.orig_src['compression'], options.comp_level)) orig_prefix = spec.orig_src['prefix'] if not git_archive(repo, spec, source_dir, tree, orig_prefix, options.comp_level, options.with_submodules): raise GbpError("Cannot create source tarball at '%s'" % source_dir) # Non-native packages: create orig tarball from upstream elif spec.orig_src: prepare_upstream_tarball(repo, spec, options, source_dir) # 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 and not options.tag_only: if options.prebuild: RunAtCommand(options.prebuild, shell=True, extra_env={ 'GBP_GIT_DIR': repo.git_dir, 'GBP_BUILD_DIR': export_dir })(dir=export_dir) # Finally build the package: if options.builder.startswith("rpmbuild"): builder_args.append( os.path.join(spec.specdir, spec.specfile)) else: builder_args.append(spec.specfile) RunAtCommand(options.builder, builder_args, shell=True, extra_env={'GBP_BUILD_DIR': export_dir})(dir=export_dir) if options.postbuild: changes = os.path.abspath("%s/%s.changes" % (source_dir, spec.name)) gbp.log.debug("Looking for changes file %s" % changes) Command(options.postbuild, shell=True, extra_env={ 'GBP_CHANGES_FILE': changes, 'GBP_BUILD_DIR': export_dir })() # Tag (note: tags the exported version) if options.tag or options.tag_only: gbp.log.info("Tagging %s" % rpm.compose_version_str(spec.version)) tag = create_packaging_tag(repo, tree, spec.name, spec.version, 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) 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 as err: if len(err.__str__()): gbp.log.err(err) retval = 1 finally: drop_index() del_tmpdir() if not options.tag_only: if spec and options.notify: summary = "Gbp-rpm %s" % ["failed", "successful"][not retval] message = ("Build of %s %s %s" % (spec.name, rpm.compose_version_str( spec.version), ["failed", "succeeded"][not retval])) if not gbp.notifications.notify(summary, message, options.notify): gbp.log.err("Failed to send notification") retval = 1 return retval
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))
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." # Dump from git to a temporary directory: dump_dir = tempfile.mkdtemp(dir=options.tmp_dir, prefix='dump_tree_') gbp.log.debug("Dumping tree '%s' to '%s'" % (options.export, dump_dir)) if not dump_tree(repo, dump_dir, tree, options.with_submodules): raise GbpError # Parse spec from dump dir to get version etc. spec = rpm.SpecFile(os.path.join(dump_dir, relative_spec_path)) if not options.tag_only: # Setup builder opts setup_builder(options, builder_args) # Generate patches, if requested if options.patch_export and not is_native(repo, options): if options.patch_export_rev: patch_tree = get_tree(repo, options.patch_export_rev) else: patch_tree = tree export_patches(repo, spec, patch_tree, options)