def fixup_section(repo, use_git_author, options, dch_options): """ Fixup the changelog header and trailer's committer and email address It might otherwise point to the last git committer instead of the person creating the changelog This also applies --distribution and --urgency options passed to gbp dch """ author, email = get_author_email(repo, use_git_author) used_options = ['distribution', 'urgency'] opts = [] mainttrailer_opts = [ '--nomainttrailer', '--mainttrailer', '-t' ] # This must not be done for snapshots or snapshots changelog entries # will not be concatenated if not options.snapshot: for opt in used_options: val = getattr(options, opt) if val: gbp.log.debug("Set header option '%s' to '%s'" % (opt, val)) opts.append("--%s=%s" % (opt, val)) else: gbp.log.debug("Snapshot enabled: do not fixup options in header") if use_git_author: for opt in mainttrailer_opts: if opt in dch_options: break else: opts.append(mainttrailer_opts[0]) ChangeLog.spawn_dch(msg='', author=author, email=email, dch_options=dch_options+opts)
def debian_branch_merge(repo, tag, version, options): try: func = globals()["debian_branch_merge_by_%s" % options.merge_mode] except KeyError: raise GbpError("%s is not a valid merge mode" % options.merge_mode) func(repo, tag, version, options) if options.postimport: epoch = '' if os.access('debian/changelog', os.R_OK): # No need to check the changelog file from the # repository, since we're certain that we're on # the debian-branch cp = ChangeLog(filename='debian/changelog') if cp.has_epoch(): epoch = '%s:' % cp.epoch debian_version = "%s%s-1" % (epoch, version) info = {'version': debian_version} env = {'GBP_BRANCH': options.debian_branch, 'GBP_TAG': tag, 'GBP_UPSTREAM_VERSION': version, 'GBP_DEBIAN_VERSION': debian_version, } Hook('Postimport', format_str(options.postimport, info), extra_env=env)()
def fixup_section(repo, use_git_author, options, dch_options): """ Fixup the changelog header and trailer's committer and email address It might otherwise point to the last git committer instead of the person creating the changelog This also applies --distribution and --urgency options passed to gbp dch """ author, email = get_author_email(repo, use_git_author) used_options = ['distribution', 'urgency'] opts = [] mainttrailer_opts = ['--nomainttrailer', '--mainttrailer', '-t'] # This must not be done for snapshots or snapshots changelog entries # will not be concatenated if not options.snapshot: for opt in used_options: val = getattr(options, opt) if val: gbp.log.debug("Set header option '%s' to '%s'" % (opt, val)) opts.append("--%s=%s" % (opt, val)) else: gbp.log.debug("Snapshot enabled: do not fixup options in header") if use_git_author: for opt in mainttrailer_opts: if opt in dch_options: break else: opts.append(mainttrailer_opts[0]) ChangeLog.spawn_dch(msg='', author=author, email=email, dch_options=dch_options + opts)
def debian_branch_merge(repo, tag, version, options): try: func = globals()["debian_branch_merge_by_%s" % options.merge_mode] except KeyError: raise GbpError("%s is not a valid merge mode" % options.merge_mode) func(repo, tag, version, options) if options.postimport: epoch = '' if os.access('debian/changelog', os.R_OK): # No need to check the changelog file from the # repository, since we're certain that we're on # the debian-branch cp = ChangeLog(filename='debian/changelog') if cp.has_epoch(): epoch = '%s:' % cp.epoch debian_version = "%s%s-1" % (epoch, version) info = {'version': debian_version} env = { 'GBP_BRANCH': options.debian_branch, 'GBP_TAG': tag, 'GBP_UPSTREAM_VERSION': version, 'GBP_DEBIAN_VERSION': debian_version, } Hook('Postimport', format_str(options.postimport, info), extra_env=env)()
def test_broken_upstream_version(self, repo): cl = ChangeLog(filename='debian/changelog') cl.add_section(["broken versionnumber"], "unstable", version={'version': "3.0"}) ret = buildpackage(['argv0', '--git-ignore-new', '--git-builder=/bin/true', '--git-tarball-dir=../tarballs']) eq_(ret, 1) self._check_log(-1, "gbp:error: Non-native package 'hello-debhelper' has invalid version '3.0'")
def test_nul(self): """Test we remove NUL characters from strings when parsing (#981340)""" changes = """git-buildpackage (0.9.2) unstable; urgency=low * List of ch\0nges -- User N\0me <*****@*****.**> Sun, 12 Nov 2017 19:00:00 +0200 """ cl = ChangeLog(changes) self.assertEquals(cl.author, 'User Nme') self.assertEquals(cl.email, '*****@*****.**') self.assertEquals('\0' in cl.get_changes(), False)
def get_changes(dir, repo, is_empty, debian_branch): if is_empty: version = "0~" else: vfs = GitVfs(repo, debian_branch) try: with vfs.open('debian/changelog') as f: version = ChangeLog(contents=f.read()).version except IOError: version = "0~" # Use full history if debian branch has no changelog cl = ChangeLog(filename=os.path.join(dir, 'debian/changelog')) return cl.get_changes(version)
def get_changes(dir, repo, debian_branch): if repo.empty: version = "0~" else: vfs = GitVfs(repo, debian_branch) try: with vfs.open('debian/changelog') as f: version = ChangeLog(contents=f.read()).version except IOError: version = "0~" # Use full history if debian branch has no changelog cl = ChangeLog(filename=os.path.join(dir, 'debian/changelog')) return cl.get_changes(version)
def create_changelog(repo, source, options): try: name = source.control.name except DebianSourceError: raise GbpError("Did not find debian/changelog or debian/source. Is this a Debian package?") version = guess_version_from_upstream(repo, options.upstream_tag, options.upstream_branch, None) return ChangeLog.create(name, version)
def debian_branch_merge(repo, tag, version, options): try: func = globals()["debian_branch_merge_by_%s" % options.merge_mode] except KeyError: raise GbpError("%s is not a valid merge mode" % options.merge_mode) func(repo, tag, version, options) if options.postimport: epoch = '' if os.access('debian/changelog', os.R_OK): # No need to check the changelog file from the # repository, since we're certain that we're on # the debian-branch cp = ChangeLog(filename='debian/changelog') if cp.has_epoch(): epoch = '%s:' % cp.epoch info = {'version': "%s%s-1" % (epoch, version)} env = {'GBP_BRANCH': options.debian_branch} gbpc.Command(format_str(options.postimport, info), extra_env=env, shell=True)()
def get_author_from_changelog(dir): """ Get author from debian/changelog """ dch = ChangeLog(filename=os.path.join(dir, 'debian/changelog')) date = rfc822_date_to_git(dch.date, fuzzy=True) if not (dch.author or dch.email): gbp.log.warn("Failed to parse maintainer") return GitModifier(dch.author, dch.email, date)
def distribution(): """ Return the "distribution" (eg. "stable" or "xenial") from our most recent debian/changelog entry. :returns: ``str`` """ clog = ChangeLog(filename='debian/changelog') # clog['Distribution'] is from dpkg-parsechangelog. return clog['Distribution']
def changelog(self): """ Return the L{gbp.deb.ChangeLog} """ if not self._changelog: try: with self._vfs.open('debian/changelog', 'rb') as clf: self._changelog = ChangeLog(clf.read().decode('utf-8')) except IOError as err: raise DebianSourceError('Failed to read changelog: %s' % err) return self._changelog
def postimport_hook(repo, tag, version, options): if options.postimport: epoch = '' if os.access('debian/changelog', os.R_OK): # No need to check the changelog file from the # repository, since we're certain that we're on # the debian-branch cp = ChangeLog(filename='debian/changelog') if cp.has_epoch(): epoch = '%s:' % cp.epoch debian_version = "%s%s-1" % (epoch, version) info = {'version': debian_version} env = {'GBP_BRANCH': options.debian_branch, 'GBP_TAG': tag, 'GBP_UPSTREAM_VERSION': version, 'GBP_DEBIAN_VERSION': debian_version, } Hook('Postimport', format_str(options.postimport, info), extra_env=env)()
def postimport_hook(repo, tag, version, options): if options.postimport: epoch = '' if os.access('debian/changelog', os.R_OK): # No need to check the changelog file from the # repository, since we're certain that we're on # the debian-branch cp = ChangeLog(filename='debian/changelog') if cp.has_epoch(): epoch = '%s:' % cp.epoch debian_version = "%s%s-1" % (epoch, version) info = {'version': debian_version} env = { 'GBP_BRANCH': options.debian_branch, 'GBP_TAG': tag, 'GBP_UPSTREAM_VERSION': version, 'GBP_DEBIAN_VERSION': debian_version, } Hook('Postimport', format_str(options.postimport, info), extra_env=env)()
def test_comma(self): """Test we properly parse maitainers with comma #737623""" changes = """git-buildpackage (0.9.2) unstable; urgency=low * List of changes -- Guido Günther, aftercomma <*****@*****.**> Sun, 12 Nov 2017 19:00:00 +0200 """ cl = ChangeLog(changes) self.assertEquals(cl.author, 'Guido Günther, aftercomma') self.assertEquals(cl.email, '*****@*****.**')
def changelog(self): """ Return the L{gbp.deb.ChangeLog} """ if not self._changelog: try: clf = self._vfs.open('debian/changelog') self._changelog = ChangeLog(clf.read()) except IOError as err: raise DebianSourceError('Failed to read changelog: %s' % err) return self._changelog
def git_commit_message(): """ Return a Git commit message string from the most recent debian/changelog entry. """ clog = ChangeLog(filename='debian/changelog') template = """ debian: {version} {changes} """.lstrip("\n") return template.format(version=clog.version, changes=changes_string())
def fixup_section(repo, git_author, options, dch_options): """ Fixup the changelog header and trailer's comitter and email address It might otherwise point to the last git committer instead of the person creating the changelog This apply --distribution and --urgency options passed to git-dch """ author, email = get_author_email(repo, git_author) used_options = ["distribution", "urgency"] header_opts = [] # This must not be done for snapshots or snapshots changelog entries # will not be concatenated if not options.snapshot: for opt in used_options: val = getattr(options, opt) if val: gbp.log.debug("Set header option '%s' to '%s'" % (opt, val)) header_opts.append("--%s=%s" % (opt, val)) else: gbp.log.debug("Snapshot enabled: do not fixup options in header") ChangeLog.spawn_dch(msg="", author=author, email=email, dch_options=dch_options + header_opts)
def do_snapshot(changelog, repo, next_snapshot): """ Add new snapshot banner to most recent changelog section. The next snapshot number is calculated by eval()'ing next_snapshot. """ commit = repo.head cp = ChangeLog(filename=changelog) (release, snapshot) = snapshot_version(cp['Version']) snapshot = int(eval(next_snapshot)) suffix = "%d.gbp%s" % (snapshot, "".join(commit[0:6])) cp['MangledVersion'] = "%s~%s" % (release, suffix) mangle_changelog(changelog, cp, commit) return snapshot, commit
def detect_name_and_version(repo, source, options): # Guess defaults for the package name and version from the # original tarball. guessed_package, guessed_version = source.guess_version() # Try to find the source package name try: cp = ChangeLog(filename='debian/changelog') sourcepackage = cp['Source'] except NoChangeLogError: try: # Check the changelog file from the repository, in case # we're not on the debian-branch (but upstream, for # example). cp = parse_changelog_repo(repo, options.debian_branch, 'debian/changelog') sourcepackage = cp['Source'] except NoChangeLogError: if options.interactive: sourcepackage = ask_package_name( guessed_package, DebianPkgPolicy.is_valid_packagename, DebianPkgPolicy.packagename_msg) else: if guessed_package: sourcepackage = guessed_package else: raise GbpError( "Couldn't determine upstream package name. Use --interactive." ) # Try to find the version. if options.version: version = options.version else: if options.interactive: version = ask_package_version( guessed_version, DebianPkgPolicy.is_valid_upstreamversion, DebianPkgPolicy.upstreamversion_msg) else: if guessed_version: version = guessed_version else: raise GbpError( "Couldn't determine upstream version. Use '-u<version>' or --interactive." ) return (sourcepackage, version)
def parse_changelog_repo(repo, branch, filename): """ Parse the changelog file from given branch in the git repository. FIXME: this should use *Vfs methods """ try: # Note that we could just pass in the branch:filename notation # to show as well, but we want to check if the branch / filename # exists first, so we can give a separate error from other # repository errors. sha = repo.rev_parse("%s:%s" % (branch, filename)) except GitRepositoryError: raise NoChangeLogError("Changelog %s not found in branch %s" % (filename, branch)) return ChangeLog(repo.show(sha))
def changes_string(): """ Return the "Changes" (bulleted entries) from our most recent debian/changelog entry. :returns: single indented/bulleted/wrapped ``str`` """ clog = ChangeLog(filename='debian/changelog') # clog['Changes'] is from dpkg-parsechangelog. # First line is the section headers, and we're searching for the blank " ." # line after that one: section = clog['Changes'].find(" .\n") # Note: dpkg-parsechangelog (and therefore git-buildpackage) prefixes each # line here with an extraneous space (" ") that is not present in the # changelog file itself. Maybe we should dedent this string by one column # to be fully accurate? Python's textwrap's dedent can't do this trivially # so I'm kicking this down the road for now. return clog['Changes'][section + 3:]
def test_changelog_creation_full(self): cp = ChangeLog.create('package', '1.0') self.assertEquals(cp.name, 'package') self.assertEquals(cp.version, '1.0')
def __init__(self, version, changes = "a important change"): ChangeLog.__init__(self, contents=self.contents % (version, changes))
def main(argv): ret = 0 changelog = 'debian/changelog' until = 'HEAD' found_snapshot_banner = False version_change = {} branch = None options, args, dch_options, editor_cmd = parse_args(argv) try: try: repo = DebianGitRepository('.') except GitRepositoryError: raise GbpError("%s is not a git repository" % (os.path.abspath('.'))) try: branch = repo.get_branch() except GitRepositoryError: # Not being on any branch is o.k. with --ignore-branch if not options.ignore_branch: raise if options.packaging_branch != branch and not options.ignore_branch: gbp.log.err("You are not on branch '%s' but on '%s'" % (options.packaging_branch, branch)) raise GbpError("Use --ignore-branch to ignore or --debian-branch " "to set the branch name.") source = DebianSource('.') cp = source.changelog if options.since: since = options.since else: since = '' if options.auto: since = guess_documented_commit(cp, repo, options.packaging_tag) if since: msg = "Continuing from commit '%s'" % since else: msg = "Starting from first commit" gbp.log.info(msg) found_snapshot_banner = has_snapshot_banner(cp) else: # Fallback: continue from last tag since = repo.find_version(options.packaging_tag, cp['Version']) if not since: raise GbpError("Version %s not found" % cp['Version']) if args: gbp.log.info("Only looking for changes on '%s'" % " ".join(args)) commits = repo.get_commits(since=since, until=until, paths=args, options=options.git_log.split(" ")) commits.reverse() # add a new changelog section if: if (options.new_version or options.bpo or options.nmu or options.qa or options.team or options.security): if options.bpo: version_change['increment'] = '--bpo' elif options.nmu: version_change['increment'] = '--nmu' elif options.qa: version_change['increment'] = '--qa' elif options.team: version_change['increment'] = '--team' elif options.security: version_change['increment'] = '--security' else: version_change['version'] = options.new_version # the user wants to force a new version add_section = True elif cp['Distribution'] != "UNRELEASED" and not found_snapshot_banner and commits: # the last version was a release and we have pending commits add_section = True elif options.snapshot and not found_snapshot_banner: # the user want to switch to snapshot mode add_section = True else: add_section = False if add_section and not version_change and not source.is_native(): # Get version from upstream if none provided v = guess_version_from_upstream(repo, options.upstream_tag, cp) if v: version_change['version'] = v i = 0 for c in commits: i += 1 parsed = parse_commit(repo, c, options, last_commit=i == len(commits)) commit_msg, (commit_author, commit_email) = parsed if not commit_msg: # Some commits can be ignored continue if add_section: # Add a section containing just this message (we can't # add an empty section with dch) cp.add_section(distribution="UNRELEASED", msg=commit_msg, version=version_change, author=commit_author, email=commit_email, dch_options=dch_options) # Adding a section only needs to happen once. add_section = False else: cp.add_entry(commit_msg, commit_author, commit_email, dch_options) # Show a message if there were no commits (not even ignored # commits). if not commits: gbp.log.info("No changes detected from %s to %s." % (since, until)) if add_section: # If we end up here, then there were no commits to include, # so we put a dummy message in the new section. cp.add_section(distribution="UNRELEASED", msg=["UNRELEASED"], version=version_change, dch_options=dch_options) fixup_section(repo, use_git_author=options.use_git_author, options=options, dch_options=dch_options) if options.release: do_release(changelog, repo, cp, use_git_author=options.use_git_author, dch_options=dch_options) elif options.snapshot: (snap, version) = do_snapshot(changelog, repo, options.snapshot_number) gbp.log.info("Changelog has been prepared for snapshot #%d at %s" % (snap, version)) if editor_cmd: gbpc.Command(editor_cmd, ["debian/changelog"])() if options.commit: # Get the version from the changelog file (since dch might # have incremented it, there's no way we can already know # the version). version = ChangeLog(filename=changelog).version # Commit the changes to the changelog file msg = changelog_commit_msg(options, version) repo.commit_files([changelog], msg) gbp.log.info("Changelog has been committed for version %s" % version) except (gbpc.CommandExecFailed, GbpError, GitRepositoryError, DebianSourceError, NoChangeLogError) as err: if len(err.__str__()): gbp.log.err(err) ret = 1 return ret
def test_changelog_missing_dir(self): os.rmdir('debian/') with self.assertRaisesRegexp(CommandExecFailed, "Cannot find debian directory"): ChangeLog.create('package', '1.0')
def test_changelog_creation_package(self): cp = ChangeLog.create(package='package') self.assertEquals(cp.name, 'package') self.assertEquals(cp.version, 'unknown')
def __init__(self, version, changes="a important change"): ChangeLog.__init__(self, contents=self.contents % (version, changes))
def test_changelog_creation_version(self): cp = ChangeLog.create(version='1.0') self.assertEquals(cp.name, 'PACKAGE') self.assertEquals(cp.version, '1.0')
def __init__(self, version): ChangeLog.__init__(self, contents=self.contents % version)
def main(argv): ret = 0 changelog = 'debian/changelog' until = 'HEAD' found_snapshot_banner = False version_change = {} branch = None options, args, dch_options, editor_cmd = parse_args(argv) if not options: return ExitCodes.parse_error try: old_cwd = os.path.abspath(os.path.curdir) try: repo = DebianGitRepository('.', toplevel=False) os.chdir(repo.path) except GitRepositoryError: raise GbpError("%s is not a git repository" % (os.path.abspath('.'))) get_customizations(options.customization_file) try: branch = repo.get_branch() except GitRepositoryError: # Not being on any branch is o.k. with --ignore-branch if not options.ignore_branch: raise if options.debian_branch != branch and not options.ignore_branch: gbp.log.err("You are not on branch '%s' but on '%s'" % (options.debian_branch, branch)) raise GbpError( "Use --ignore-branch to ignore or --debian-branch to set the branch name." ) source = DebianSource('.') cp = maybe_create_changelog(repo, source, options) if options.since: since = options.since else: since = guess_documented_commit(cp, repo, options.debian_tag) if since: msg = "Continuing from commit '%s'" % since else: msg = "Starting from first commit" gbp.log.info(msg) found_snapshot_banner = has_snapshot_banner(cp) if args: gbp.log.info("Only looking for changes on '%s'" % " ".join(args)) commits = repo.get_commits(since=since, until=until, paths=args, options=options.git_log.split(" ")) commits.reverse() add_section = False # add a new changelog section if: if (options.new_version or options.bpo or options.nmu or options.qa or options.team or options.security or options.local_suffix): if options.bpo: version_change['increment'] = '--bpo' elif options.nmu: version_change['increment'] = '--nmu' elif options.qa: version_change['increment'] = '--qa' elif options.team: version_change['increment'] = '--team' elif options.security: version_change['increment'] = '--security' elif options.local_suffix: version_change[ 'increment'] = '--local=%s' % options.local_suffix else: version_change['version'] = options.new_version # the user wants to force a new version add_section = True elif cp['Distribution'] != "UNRELEASED" and not found_snapshot_banner: if commits: # the last version was a release and we have pending commits add_section = True if options.snapshot: # the user want to switch to snapshot mode add_section = True if add_section and not version_change and not source.is_native(): # Get version from upstream if none provided v = guess_version_from_upstream(repo, options.upstream_tag, options.upstream_branch, cp) if v: version_change['version'] = v i = 0 for c in commits: i += 1 parsed = parse_commit(repo, c, options, last_commit=(i == len(commits))) commit_msg, (commit_author, commit_email) = parsed if not commit_msg: # Some commits can be ignored continue if add_section: # Add a section containing just this message (we can't # add an empty section with dch) cp.add_section(distribution="UNRELEASED", msg=commit_msg, version=version_change, author=commit_author, email=commit_email, dch_options=dch_options) # Adding a section only needs to happen once. add_section = False else: cp.add_entry(commit_msg, commit_author, commit_email, dch_options) # Show a message if there were no commits (not even ignored # commits). if not commits: gbp.log.info("No changes detected from %s to %s." % (since, until)) if add_section: # If we end up here, then there were no commits to include, # so we put a dummy message in the new section. cp.add_section(distribution="UNRELEASED", msg=["UNRELEASED"], version=version_change, dch_options=dch_options) fixup_section(repo, use_git_author=options.use_git_author, options=options, dch_options=dch_options) if options.release: do_release(changelog, repo, cp, use_git_author=options.use_git_author, dch_options=dch_options) elif options.snapshot: (snap, commit, version) = do_snapshot(changelog, repo, options.snapshot_number) gbp.log.info("Changelog %s (snapshot #%d) prepared up to %s" % (version, snap, commit[:7])) if editor_cmd: gbpc.Command(editor_cmd, ["debian/changelog"])() if options.postedit: cp = ChangeLog(filename=changelog) Hook('Postimport', options.postedit, extra_env={'GBP_DEBIAN_VERSION': cp.version})() if options.commit: # Get the version from the changelog file (since dch might # have incremented it, there's no way we can already know # the version). version = ChangeLog(filename=changelog).version # Commit the changes to the changelog file msg = changelog_commit_msg(options, version) repo.commit_files([changelog], msg) gbp.log.info("Changelog committed for version %s" % version) except KeyboardInterrupt: ret = 1 gbp.log.err("Interrupted. Aborting.") except (gbpc.CommandExecFailed, GbpError, GitRepositoryError, DebianSourceError, NoChangeLogError) as err: if str(err): gbp.log.err(err) ret = 1 maybe_debug_raise() finally: os.chdir(old_cwd) return ret
def main(argv): ret = 0 tmpdir = '' pristine_orig = None linked = False (options, args) = parse_args(argv) if not options: return 1 try: source = find_source(options.uscan, args) if not source: return ret try: repo = DebianGitRepository('.') except GitRepositoryError: raise GbpError("%s is not a git repository" % (os.path.abspath('.'))) # an empty repo has now branches: initial_branch = repo.get_branch() is_empty = False if initial_branch else True if not repo.has_branch(options.upstream_branch) and not is_empty: raise GbpError(no_upstream_branch_msg % options.upstream_branch) (sourcepackage, version) = detect_name_and_version(repo, source, options) (clean, out) = repo.is_clean() if not clean and not is_empty: gbp.log.err("Repository has uncommitted changes, commit these first: ") raise GbpError(out) if repo.bare: set_bare_repo_options(options) if not source.is_dir(): tmpdir = tempfile.mkdtemp(dir='../') source.unpack(tmpdir, options.filters) gbp.log.debug("Unpacked '%s' to '%s'" % (source.path, source.unpacked)) if source.needs_repack(options): gbp.log.debug("Filter pristine-tar: repacking '%s' from '%s'" % (source.path, source.unpacked)) (source, tmpdir) = repack_source(source, sourcepackage, version, tmpdir, options.filters) (pristine_orig, linked) = prepare_pristine_tar(source.path, sourcepackage, version) # Don't mess up our repo with git metadata from an upstream tarball try: if os.path.isdir(os.path.join(source.unpacked, '.git/')): raise GbpError("The orig tarball contains .git metadata - giving up.") except OSError: pass try: upstream_branch = [ options.upstream_branch, 'master' ][is_empty] filter_msg = ["", " (filtering out %s)" % options.filters][len(options.filters) > 0] gbp.log.info("Importing '%s' to branch '%s'%s..." % (source.path, upstream_branch, filter_msg)) gbp.log.info("Source package is %s" % sourcepackage) gbp.log.info("Upstream version is %s" % version) import_branch = [ options.upstream_branch, None ][is_empty] msg = upstream_import_commit_msg(options, version) if options.vcs_tag: parents = [repo.rev_parse("%s^{}" % options.vcs_tag)] else: parents = None commit = repo.commit_dir(source.unpacked, msg=msg, branch=import_branch, other_parents=parents, ) if options.pristine_tar: if pristine_orig: repo.pristine_tar.commit(pristine_orig, upstream_branch) else: gbp.log.warn("'%s' not an archive, skipping pristine-tar" % source.path) tag = repo.version_to_tag(options.upstream_tag, version) repo.create_tag(name=tag, msg="Upstream version %s" % version, commit=commit, sign=options.sign_tags, keyid=options.keyid) if is_empty: repo.create_branch(options.upstream_branch, rev=commit) repo.force_head(options.upstream_branch, hard=True) elif options.merge: gbp.log.info("Merging to '%s'" % options.debian_branch) repo.set_branch(options.debian_branch) try: repo.merge(tag) except GitRepositoryError: raise GbpError("Merge failed, please resolve.") if options.postimport: epoch = '' if os.access('debian/changelog', os.R_OK): # No need to check the changelog file from the # repository, since we're certain that we're on # the debian-branch cp = ChangeLog(filename='debian/changelog') if cp.has_epoch(): epoch = '%s:' % cp.epoch info = { 'version': "%s%s-1" % (epoch, version) } env = { 'GBP_BRANCH': options.debian_branch } gbpc.Command(options.postimport % info, extra_env=env, shell=True)() # Update working copy and index if we've possibly updated the # checked out branch current_branch = repo.get_branch() if current_branch in [ options.upstream_branch, repo.pristine_tar_branch]: repo.force_head(current_branch, hard=True) except (gbpc.CommandExecFailed, GitRepositoryError) as err: msg = err.__str__() if len(err.__str__()) else '' raise GbpError("Import of %s failed: %s" % (source.path, msg)) except GbpError as err: if len(err.__str__()): gbp.log.err(err) ret = 1 if pristine_orig and linked and not options.symlink_orig: os.unlink(pristine_orig) if tmpdir: cleanup_tmp_tree(tmpdir) if not ret: gbp.log.info("Successfully imported version %s of %s" % (version, source.path)) return ret
def test_changelog_exists(self): with open('debian/changelog', 'w') as f: f.write('') with self.assertRaisesRegexp(CommandExecFailed, "File debian/changelog already exists"): ChangeLog.create('package', '1.0')
def main(argv): retval = 0 changelog = 'debian/changelog' cmd = [] try: options, args = parse_args(argv) except Exception as e: print("%s" % e, file=sys.stderr) return 1 gbp.log.setup(options.color, options.verbose, options.color_scheme) try: repo = DebianGitRepository(os.path.curdir) except GitRepositoryError: gbp.log.err("%s is not a git repository" % (os.path.abspath('.'))) return 1 try: branches = [] for branch in [ options.debian_branch, options.upstream_branch ]: if repo.has_branch(branch): branches += [ branch ] if repo.has_pristine_tar_branch() and options.pristine_tar: branches += [ repo.pristine_tar_branch ] try: cp = ChangeLog(filename=changelog) pkg = cp['Source'] except NoChangeLogError: pkg = None if not pkg: gbp.log.warn("Couldn't parse changelog, will use directory name.") pkg = os.path.basename(os.path.abspath(os.path.curdir)) pkg = os.path.splitext(pkg)[0] remote = parse_url(options.remote_url, options.name, pkg, options.template_dir) if repo.has_remote_repo(options.name): raise GbpError("You already have a remote name '%s' defined for this repository." % options.name) gbp.log.info("Shall I create a repository for '%(pkg)s' at '%(url)s' now? (y/n)?" % remote) if not read_yn(): raise GbpError("Aborted.") remote_script = build_remote_script(remote, branches[0]) if options.verbose: print(remote_script) cmd = build_cmd(remote) if options.verbose: print(cmd) proc = subprocess.Popen(cmd, stdin=subprocess.PIPE) proc.communicate(remote_script) if proc.returncode: raise GbpError("Error creating remote repository") push_branches(remote, branches) if options.track: setup_branch_tracking(repo, remote, branches) else: gbp.log.info("You can now add:") print_config(remote, branches) gbp.log.info("to your .git/config to 'gbp-pull' and 'git push' in the future.") except CommandExecFailed: retval = 1 except (GbpError, GitRepositoryError) as err: if str(err): gbp.log.err(err) retval = 1 return retval
def main(argv): ret = 0 (options, args) = parse_args(argv) try: sources = find_sources(options, args) if not sources: return ret except GbpError as err: if len(err.__str__()): gbp.log.err(err) return 1 try: try: repo = DebianGitRepository('.') except GitRepositoryError: raise GbpError("%s is not a git repository" % (os.path.abspath('.'))) # an empty repo has no branches: initial_branch = repo.get_branch() is_empty = False if initial_branch else True initial_head = None if is_empty else repo.rev_parse('HEAD', short=40) (clean, out) = repo.is_clean() if not clean and not is_empty: gbp.log.err("Repository has uncommitted changes, commit these first: ") raise GbpError(out) if repo.bare: set_bare_repo_options(options) # Collect upstream branches, ensuring they're unique and exist if appropriate upstream_branches = [] for source in sources: source.detect_name_version_and_component(repo, options) upstream_branch = options.upstream_branch if source.component: upstream_branch += '-' + source.component if upstream_branch in upstream_branches: raise GbpError("Duplicate component '%s'" % ( component, )) if not repo.has_branch(upstream_branch) and not is_empty: raise GbpError(no_upstream_branch_msg % upstream_branch) upstream_branches.append(upstream_branch) # Unpack/repack each source, ensuring that there's no git metadata present for source in sources: source.unpack_or_repack_as_necessary(options) # Import each source into the relevant upstream branch, and create tag for source in sources: source.import_into_upstream_branch(repo, options) # If merge has been requested, merge each upstream branch onto the debian branch # TODO: what happens if a merge fails? if options.merge: for source in sources: source.merge_into_debian_branch(repo, options) # If the repository is empty and master isn't the selected debian branch, merge onto master, too # TODO: what happens if a merge fails? if is_empty and options.debian_branch != 'master': options.debian_branch = 'master' for source in sources: source.merge_into_debian_branch(repo, options) # TODO: why is this conditional on merge? if options.merge and options.postimport: epoch = '' repo.set_branch(options.debian_branch) if os.access('debian/changelog', os.R_OK): # No need to check the changelog file from the # repository, since we're certain that we're on # the debian-branch cp = ChangeLog(filename='debian/changelog') if cp.has_epoch(): epoch = '%s:' % cp.epoch info = { 'version': "%s%s-1" % (epoch, sources[0].version) } env = { 'GBP_BRANCH': options.debian_branch } gbpc.Command(options.postimport % info, extra_env=env, shell=True)() if not is_empty: # Restore the working copy to the pre-import state current_head = repo.rev_parse('HEAD', short=40) if current_head != initial_head: repo.force_head(initial_head, hard=True) except (gbpc.CommandExecFailed, GbpError) as err: if len(err.__str__()): gbp.log.err(err) ret = 1 finally: for source in sources: source.cleanup(options) if not ret: gbp.log.info("Successfully imported version %s of %s" % (sources[0].version, sources[0].name)) return ret