예제 #1
0
def main(argv):
    retval = 0
    prefix = "git-"
    source = None
    branch = None

    options, gbp_args, dpkg_args = parse_args(argv, prefix)

    if not options:
        return 1

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

    try:
        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.")

        try:
            branch = repo.get_branch()
        except GitRepositoryError:
            # Not being on any branch is o.k. with --git-ignore-branch
            if not options.ignore_branch:
                raise

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

        tree = write_tree(repo, options)
        source = source_vfs(repo, options, tree)
        if not options.tag_only:
            output_dir = prepare_output_dir(options.export_dir)
            tarball_dir = options.tarball_dir or output_dir

            # Get/build the upstream tarball if necessary. We delay this in
            # case of a postexport hook so the hook gets a chance to modify the
            # sources and create different tarballs (#640382)
            # We don't delay it in general since we want to fail early if the
            # tarball is missing.
            if not source.is_native(repo.has_upstream_tag(options.upstream_tag)):
                if options.postexport:
                    gbp.log.info("Postexport hook set, delaying tarball creation")
                else:
                    prepare_upstream_tarball(repo, source.changelog, options, tarball_dir,
                                             output_dir)

            # Export to another build dir if requested:
            if options.export_dir:
                tmp_dir = os.path.join(output_dir, "%s-tmp" % source.sourcepkg)
                export_source(repo, tree, source, options, tmp_dir, output_dir)

                # Run postexport hook
                if options.postexport:
                    RunAtCommand(options.postexport, shell=True,
                                 extra_env={'GBP_GIT_DIR': repo.git_dir,
                                            'GBP_TMP_DIR': tmp_dir})(dir=tmp_dir)

                major = (source.changelog.upstream_version if source.changelog.has_upstream_version()
                         else source.changelog.debian_version)
                export_dir = os.path.join(output_dir, "%s-%s" % (source.sourcepkg, major))
                gbp.log.info("Moving '%s' to '%s'" % (tmp_dir, export_dir))
                move_old_export(export_dir)
                os.rename(tmp_dir, export_dir)

                # Delayed tarball creation in case a postexport hook is used:
                if not source.is_native(repo.has_upstream_tag(options.upstream_tag)) and options.postexport:
                    prepare_upstream_tarball(repo, source.changelog, options, tarball_dir,
                                             output_dir)

            if options.export_dir:
                build_dir = export_dir
            else:
                build_dir = repo_dir

            if options.prebuild:
                RunAtCommand(options.prebuild, shell=True,
                             extra_env={'GBP_GIT_DIR': repo.git_dir,
                                        'GBP_BUILD_DIR': build_dir})(dir=build_dir)

            setup_pbuilder(options)
            # Finally build the package:
            RunAtCommand(options.builder, dpkg_args, shell=True,
                         extra_env={'GBP_BUILD_DIR': build_dir})(dir=build_dir)
            if options.postbuild:
                changes = os.path.abspath("%s/../%s_%s_%s.changes" %
                                          (build_dir,
                                           source.sourcepkg,
                                           source.changelog.noepoch,
                                           changes_file_suffix(dpkg_args)))
                gbp.log.debug("Looking for changes file %s" % changes)
                Command(options.postbuild, shell=True,
                        extra_env={'GBP_CHANGES_FILE': changes,
                                   'GBP_BUILD_DIR': build_dir})()
        if options.tag or options.tag_only:
            gbp.log.info("Tagging %s" % source.changelog.version)
            tag = repo.version_to_tag(options.debian_tag, source.changelog.version)
            if options.retag and repo.has_tag(tag):
                repo.delete_tag(tag)
            repo.create_tag(name=tag,
                            msg="%s Debian release %s" % (source.sourcepkg,
                                                          source.changelog.version),
                            sign=options.sign_tags, keyid=options.keyid)
            if options.posttag:
                sha = repo.rev_parse("%s^{}" % tag)
                Command(options.posttag, shell=True,
                        extra_env={'GBP_TAG': tag,
                                   'GBP_BRANCH': branch or '(no branch)',
                                   'GBP_SHA1': sha})()
    except CommandExecFailed:
        retval = 1
    except (GbpError, GitRepositoryError) as err:
        if len(err.__str__()):
            gbp.log.err(err)
        retval = 1
    except DebianSourceError as err:
        gbp.log.err(err)
        source = None
        retval = 1
    finally:
        drop_index()

    if not options.tag_only:
        if options.export_dir and options.purge and not retval:
            RemoveTree(export_dir)()

        if source and not gbp.notifications.notify(source.changelog,
                                                   not retval,
                                                   options.notify):
            gbp.log.err("Failed to send notification")
            retval = 1

    return retval
예제 #2
0
def main(argv):
    ret = 0
    changelog = 'debian/changelog'
    until = 'HEAD'
    found_snapshot_banner = False
    version_change = {}
    branch = None

    try:
        parser = GbpOptionParserDebian(command=os.path.basename(argv[0]), prefix='',
                                       usage='%prog [options] paths')
    except ConfigParser.ParsingError as err:
        gbp.log.err(err)
        return 1
    range_group = GbpOptionGroup(parser, "commit range options",
                                 "which commits to add to the changelog")
    version_group = GbpOptionGroup(parser, "release & version number options",
                                   "what version number and release to use")
    commit_group = GbpOptionGroup(parser, "commit message formatting",
                                  "howto format the changelog entries")
    naming_group = GbpOptionGroup(parser, "branch and tag naming",
                                  "branch names and tag formats")
    custom_group = GbpOptionGroup(parser, "customization",
                                  "options for customization")
    parser.add_option_group(range_group)
    parser.add_option_group(version_group)
    parser.add_option_group(commit_group)
    parser.add_option_group(naming_group)
    parser.add_option_group(custom_group)

    parser.add_boolean_config_file_option(option_name = "ignore-branch", dest="ignore_branch")
    naming_group.add_config_file_option(option_name="debian-branch", dest="debian_branch")
    naming_group.add_config_file_option(option_name="upstream-tag", dest="upstream_tag")
    naming_group.add_config_file_option(option_name="debian-tag", dest="debian_tag")
    naming_group.add_config_file_option(option_name="snapshot-number", dest="snapshot_number",
                      help="expression to determine the next snapshot number, default is '%(snapshot-number)s'")
    parser.add_config_file_option(option_name="git-log", dest="git_log",
                      help="options to pass to git-log, default is '%(git-log)s'")
    parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False,
                      help="verbose command execution")
    parser.add_config_file_option(option_name="color", dest="color", type='tristate')
    parser.add_config_file_option(option_name="color-scheme",
                                  dest="color_scheme")
    range_group.add_option("-s", "--since", dest="since", help="commit to start from (e.g. HEAD^^^, debian/0.4.3)")
    range_group.add_option("-a", "--auto", action="store_true", dest="auto", default=False,
                      help="autocomplete changelog from last snapshot or tag")
    version_group.add_option("-R", "--release", action="store_true", dest="release", default=False,
                      help="mark as release")
    version_group.add_option("-S", "--snapshot", action="store_true", dest="snapshot", default=False,
                      help="mark as snapshot build")
    version_group.add_option("-D", "--distribution", dest="distribution", help="Set distribution")
    version_group.add_option("--force-distribution", action="store_true", dest="force_distribution", default=False,
                      help="Force the provided distribution to be used, even if it doesn't match the list of known distributions")
    version_group.add_option("-N", "--new-version", dest="new_version",
                      help="use this as base for the new version number")
    version_group.add_option("-U", "--urgency", dest="urgency", help="Set urgency level")
    version_group.add_option("--bpo", dest="bpo", action="store_true", default=False,
                      help="Increment the Debian release number for an upload to backports, and add a backport upload changelog comment.")
    version_group.add_option("--nmu", dest="nmu", action="store_true", default=False,
                      help="Increment the Debian release number for a non-maintainer upload")
    version_group.add_option("--qa", dest="qa", action="store_true", default=False,
                      help="Increment the Debian release number for a Debian QA Team upload, and add a QA upload changelog comment.")
    version_group.add_option("--team", dest="team", action="store_true", default=False,
                      help="Increment the Debian release number for a Debian Team upload, and add a Team upload changelog comment.")
    version_group.add_option("--security", dest="security", action="store_true", default=False,
                      help="Increment the Debian release number for a security upload and add a security upload changelog comment.")
    version_group.add_boolean_config_file_option(option_name="git-author", dest="git_author")
    commit_group.add_boolean_config_file_option(option_name="meta", dest="meta")
    commit_group.add_config_file_option(option_name="meta-closes", dest="meta_closes",
                      help="Meta tags for the bts close commands, default is '%(meta-closes)s'")
    commit_group.add_boolean_config_file_option(option_name="full", dest="full")
    commit_group.add_config_file_option(option_name="id-length", dest="idlen",
                      help="include N digits of the commit id in the changelog entry, default is '%(id-length)s'",
                      type="int", metavar="N")
    commit_group.add_config_file_option(option_name="ignore-regex", dest="ignore_regex",
                      help="Ignore commit lines matching regex, default is '%(ignore-regex)s'")
    commit_group.add_boolean_config_file_option(option_name="multimaint", dest="multimaint")
    commit_group.add_boolean_config_file_option(option_name="multimaint-merge", dest="multimaint_merge")
    commit_group.add_config_file_option(option_name="spawn-editor", dest="spawn_editor")
    parser.add_config_file_option(option_name="commit-msg",
                      dest="commit_msg")
    parser.add_option("-c", "--commit", action="store_true", dest="commit", default=False,
                      help="commit changelog file after generating")

    help_msg = ('Load Python code from CUSTOMIZATION_FILE.  At the moment,'
                ' the only useful thing the code can do is define a custom'
                ' format_changelog_entry() function.')
    custom_group.add_config_file_option(option_name="customizations",
                                        dest="customization_file",
                                        help=help_msg)

    (options, args) = parser.parse_args(argv[1:])
    gbp.log.setup(options.color, options.verbose, options.color_scheme)
    dch_options = process_options(options, parser)
    editor_cmd = process_editor_option(options)

    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.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 = source.changelog

        if options.since:
            since = options.since
        else:
            since = ''
            if options.auto:
                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)
            else: # Fallback: continue from last tag
                since = repo.find_version(options.debian_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

        has_upstream_tag = repo.has_upstream_tag(options.upstream_tag)
        if add_section and not version_change and not source.is_native(has_upstream_tag):
            # 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, git_author=options.git_author, options=options,
                      dch_options=dch_options)

        if options.release:
            do_release(changelog, repo, cp, git_author=options.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