Exemple #1
0
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 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)()
Exemple #3
0
    def version_to_tag(cls, format, version):
        """Generate a tag from a given format and a version

        %(version)s provides a clean version that works as a git tag.

        %(hversion)s provides the same thing, but with '.' replaced with '-'.
        hversion is useful for upstreams with tagging policies that prohibit .
        characters.

        %(version%A%B)s provides %(version)s with string 'A' replaced by 'B'.
        This way, simple version mangling is possible via substitution.
        Inside the substition string, '%' needs to be escaped. See the
        examples below.

        >>> DebianGitRepository.version_to_tag("debian/%(version)s", "0:0~0")
        'debian/0%0_0'
        >>> DebianGitRepository.version_to_tag("libfoo-%(hversion)s", "1.8.1")
        'libfoo-1-8-1'
        >>> DebianGitRepository.version_to_tag("v%(version%.%_)s", "1.2.3")
        'v1_2_3'
        >>> DebianGitRepository.version_to_tag("%(version%-%\%)s", "0-1.2.3")
        '0%1.2.3'
        """
        f, v = cls._mangle_version(format, version)
        return format_str(f, dict(version=cls._sanitize_version(v),
                                  hversion=cls._sanitize_version(v).replace('.', '-')))
Exemple #4
0
    def version_to_tag(cls, format, version):
        """Generate a tag from a given format and a version

        %(version)s provides a clean version that works as a git tag.

        %(hversion)s provides the same thing, but with '.' replaced with '-'.
        hversion is useful for upstreams with tagging policies that prohibit .
        characters.

        %(version%A%B)s provides %(version)s with string 'A' replaced by 'B'.
        This way, simple version mangling is possible via substitution.
        Inside the substition string, '%' needs to be escaped. See the
        examples below.

        >>> DebianGitRepository.version_to_tag("debian/%(version)s", "0:0~0")
        'debian/0%0_0'
        >>> DebianGitRepository.version_to_tag("libfoo-%(hversion)s", "1.8.1")
        'libfoo-1-8-1'
        >>> DebianGitRepository.version_to_tag("v%(version%.%_)s", "1.2.3")
        'v1_2_3'
        >>> DebianGitRepository.version_to_tag("%(version%-%\%)s", "0-1.2.3")
        '0%1.2.3'
        """
        f, v = cls._mangle_version(format, version)
        return format_str(f, dict(version=cls._sanitize_version(v),
                                  hversion=cls._sanitize_version(v).replace('.', '-')))
Exemple #5
0
    def version_subst(cls, format, version, sanitizer=lambda arg: arg):
        """Generate a string from a given format and a version. The extracted
        version can be passed through the sanitizer function argument before
        being formatted into a string.

        %(version)s provides a clean version.

        %(hversion)s provides the same thing, but with '.' replaced with '-'.
        hversion is useful for upstreams with tagging policies that prohibit .
        characters.

        %(version%A%B)s provides %(version)s with string 'A' replaced by 'B'.
        This way, simple version mangling is possible via substitution.
        Inside the substition string, '%' needs to be escaped. See the
        examples below.

        >>> PkgPolicy.version_subst("debian/%(version)s", "0:0~0")
        'debian/0:0~0'
        >>> PkgPolicy.version_subst("libfoo-%(hversion)s", "1.8.1")
        'libfoo-1-8-1'
        >>> PkgPolicy.version_subst("v%(version%.%_)s", "1.2.3")
        'v1_2_3'
        >>> PkgPolicy.version_subst(r'%(version%-%\\%)s', "0-1.2.3")
        '0%1.2.3'
        """
        r = re.search(cls.version_mangle_re, format)
        if r:
            format = re.sub(cls.version_mangle_re, "%(version)s", format)
            version = version.replace(r.group('M'), r.group('R').replace(r'\%', '%'))
        return format_str(format, dict(version=sanitizer(version),
                                       hversion=sanitizer(version).replace('.', '-')))
def packaging_tag_data(repo, commit, name, version, options):
    """Compose packaging tag name and msg"""
    version_dict = dict(version, version=rpm.compose_version_str(version))

    # Compose tag name and message
    tag_name_fields = dict(version_dict, vendor=options.vendor.lower())
    tag_name = repo.version_to_tag(options.packaging_tag, tag_name_fields)

    tag_msg = format_str(options.packaging_tag_msg,
                         dict(version_dict, pkg=name, vendor=options.vendor))
    return (tag_name, tag_msg)
def packaging_tag_data(repo, commit, name, version, options):
    """Compose packaging tag name and msg"""
    version_dict = dict(version, version=rpm.compose_version_str(version))

    # Compose tag name and message
    tag_name_fields = dict(version_dict, vendor=options.vendor.lower())
    tag_name = repo.version_to_tag(options.packaging_tag, tag_name_fields)

    tag_msg = format_str(options.packaging_tag_msg,
                         dict(version_dict, pkg=name,
                              vendor=options.vendor))
    return (tag_name, tag_msg)
Exemple #8
0
    def version_to_tag(format, version):
        """Generate a tag from a given format and a version

        %(version)s provides a clean version that works as a git tag.

        %(hversion)s provides the same thing, but with '.' replaced with '-'.
        hversion is useful for upstreams with tagging policies that prohibit .
        characters.

        >>> DebianGitRepository.version_to_tag("debian/%(version)s", "0:0~0")
        'debian/0%0_0'
        >>> DebianGitRepository.version_to_tag("libfoo-%(hversion)s", "1.8.1")
        'libfoo-1-8-1'

        """
        return format_str(format, dict(version=DebianGitRepository._sanitize_version(version),
                                       hversion=DebianGitRepository._sanitize_version(version).replace('.','-')))
Exemple #9
0
    def version_to_tag(format, version):
        """Generate a tag from a given format and a version

        %(version)s provides a clean version that works as a git tag.

        %(hversion)s provides the same thing, but with '.' replaced with '-'.
        hversion is useful for upstreams with tagging policies that prohibit .
        characters.

        >>> DebianGitRepository.version_to_tag("debian/%(version)s", "0:0~0")
        'debian/0%0_0'
        >>> DebianGitRepository.version_to_tag("libfoo-%(hversion)s", "1.8.1")
        'libfoo-1-8-1'

        """
        return format_str(format, dict(version=DebianGitRepository._sanitize_version(version),
                                       hversion=DebianGitRepository._sanitize_version(version).replace('.','-')))
Exemple #10
0
def create_debian_tag(repo, source, commit, options):
    """
    Create the debian tag

    returns: the created tag
    """
    tag = repo.version_to_tag(options.debian_tag, source.version)
    gbp.log.info("Tagging %s as %s" % (source.version, tag))
    if options.retag and repo.has_tag(tag):
        repo.delete_tag(tag)
    tag_msg = format_str(options.debian_tag_msg,
                         dict(pkg=source.sourcepkg, version=source.version))
    repo.create_tag(name=tag,
                    msg=tag_msg,
                    sign=options.sign_tags,
                    commit=commit,
                    keyid=options.keyid)
    return tag
Exemple #11
0
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)()
Exemple #12
0
    def version_to_tag(format, str_fields):
        """
        Generate a tag from a given format and a version

        @param format: tag pattern
        @type format: C{str}
        @param str_fields: arguments for format string ('upstreamversion', 'release', 'vendor'...)
        @type str_fields: C{dict} of C{str}
        @return: version tag

        >>> RpmGitRepository.version_to_tag("packaging/%(version)s", dict(epoch='0', upstreamversion='0~0'))
        'packaging/0%0_0'
        >>> RpmGitRepository.version_to_tag("%(vendor)s/v%(version)s", dict(upstreamversion='1.0', release='2', vendor="myvendor"))
        'myvendor/v1.0-2'
        """
        version_tag = format_str(
            format, dict(str_fields, version=compose_version_str(str_fields)))
        return RpmGitRepository._sanitize_tag(version_tag)
Exemple #13
0
    def version_to_tag(format, str_fields):
        """
        Generate a tag from a given format and a version

        @param format: tag pattern
        @type format: C{str}
        @param str_fields: arguments for format string ('upstreamversion', 'release', 'vendor'...)
        @type str_fields: C{dict} of C{str}
        @return: version tag

        >>> RpmGitRepository.version_to_tag("packaging/%(version)s", dict(epoch='0', upstreamversion='0~0'))
        'packaging/0%0_0'
        >>> RpmGitRepository.version_to_tag("%(vendor)s/v%(version)s", dict(upstreamversion='1.0', release='2', vendor="myvendor"))
        'myvendor/v1.0-2'
        """
        version_tag = format_str(format,
                                 dict(str_fields,
                                      version=compose_version_str(str_fields)))
        return RpmGitRepository._sanitize_tag(version_tag)
Exemple #14
0
def create_debian_tag(repo, source, commit, options):
    """
    Create the debian tag

    returns: the created tag
    """
    tag = repo.version_to_tag(options.debian_tag, source.version)
    gbp.log.info("Tagging Debian package %s as %s in git" % (source.version, tag))
    if options.retag and repo.has_tag(tag):
        repo.delete_tag(tag)
    tag_msg = format_str(options.debian_tag_msg,
                         dict(pkg=source.sourcepkg,
                              version=source.version))
    repo.create_tag(name=tag,
                    msg=tag_msg,
                    sign=options.sign_tags,
                    commit=commit,
                    keyid=options.keyid)
    return tag
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)()
Exemple #16
0
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)()
Exemple #17
0
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 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 ExitCodes.parse_error

    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))

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

            # 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))
                    comp = None
                    if spec.orig_src['compression']:
                        comp = Compressor(spec.orig_src['compression'],
                                          options.comp_level)
                        gbp.log.debug("Building source archive with "
                                      "compression '%s" % comp)
                    orig_prefix = spec.orig_src['prefix']
                    if not git_archive(repo, spec, source_dir, tree,
                                       orig_prefix, comp,
                                       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,
                             [pipes.quote(arg) for arg in 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)

        # Put 'VCS:' tag to .spec
        spec.set_tag('VCS', None, format_str(options.spec_vcs_tag, vcs_info))
        spec.write_spec_file()
    except KeyboardInterrupt:
        retval = 1
        gbp.log.err("Interrupted. Aborting.")
    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(repo)
        del_tmpdir()

    if not options.tag_only:
        if spec:
            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 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 ExitCodes.parse_error

    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))
                    comp = None
                    if spec.orig_src['compression']:
                        comp = Compressor(spec.orig_src['compression'],
                                          options.comp_level)
                        gbp.log.debug("Building source archive with "
                                      "compression '%s" % comp)
                    orig_prefix = spec.orig_src['prefix']
                    if not git_archive(repo, spec, source_dir, tree,
                                       orig_prefix, comp,
                                       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,
                             [pipes.quote(arg) for arg in 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)

        # Put 'VCS:' tag to .spec
        spec.set_tag('VCS', None, format_str(options.spec_vcs_tag, vcs_info))
        spec.write_spec_file()
    except KeyboardInterrupt:
        retval = 1
        gbp.log.err("Interrupted. Aborting.")
    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(repo)
        del_tmpdir()

    if not options.tag_only:
        if spec:
            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 main(argv):
    retval = 0
    prefix = "git-"
    source = None
    branch = None
    hook_env = {}

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

        head = repo.head
        tree = write_tree(repo, options)
        source = source_vfs(repo, options, tree)

        check_tag(options, repo, source)

        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():
                if options.postexport:
                    gbp.log.info("Postexport hook set, delaying tarball creation")
                else:
                    prepare_upstream_tarball(repo, source.changelog, options, tarball_dir,
                                             output_dir)

            build_env, hook_env = setup_pbuilder(options, repo, source.is_native())

            # 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:
                    Hook('Postexport', options.postexport,
                         extra_env=md(hook_env,
                                      {'GBP_GIT_DIR': repo.git_dir,
                                       'GBP_TMP_DIR': tmp_dir})
                         )(dir=tmp_dir)

                major = (source.changelog.debian_version if source.is_native()
                         else source.changelog.upstream_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() 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:
                Hook('Prebuild', options.prebuild,
                     extra_env=md(hook_env,
                                  {'GBP_GIT_DIR': repo.git_dir,
                                   'GBP_BUILD_DIR': build_dir})
                     )(dir=build_dir)

            # Finally build the package:
            RunAtCommand(options.builder, dpkg_args, shell=True,
                         extra_env=md(build_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)
                Hook('Postbuild', options.postbuild,
                     extra_env=md(hook_env,
                                  {'GBP_CHANGES_FILE': changes,
                                   'GBP_BUILD_DIR': build_dir})
                     )()
        if options.tag or options.tag_only:
            tag = repo.version_to_tag(options.debian_tag, source.changelog.version)
            gbp.log.info("Tagging %s as %s" % (source.changelog.version, tag))
            if options.retag and repo.has_tag(tag):
                repo.delete_tag(tag)
            tag_msg = format_str(options.debian_tag_msg,
                                 dict(pkg=source.sourcepkg,
                                      version=source.changelog.version))
            repo.create_tag(name=tag,
                            msg=tag_msg,
                            sign=options.sign_tags,
                            commit=head,
                            keyid=options.keyid)
            if options.posttag:
                sha = repo.rev_parse("%s^{}" % tag)
                Hook('Posttag', options.posttag,
                     extra_env=md(hook_env,
                                  {'GBP_TAG': tag,
                                   'GBP_BRANCH': branch or '(no branch)',
                                   'GBP_SHA1': sha})
                     )()
    except CommandExecFailed:
        retval = 1
    except (GbpError, GitRepositoryError) as err:
        if str(err):
            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:
            summary, msg = gbp.notifications.build_msg(source.changelog,
                                                       not retval)
            if not gbp.notifications.notify(summary, msg, options.notify):
                gbp.log.err("Failed to send notification")
                retval = 1

    return retval
Exemple #21
0
def main(argv):
    ret = 0
    tmpdir = ''
    pristine_orig = None
    linked = False

    (options, args) = parse_args(argv)
    if not options:
        return 1

    try:
        if options.download:
            source = download_orig(args[0])
        else:
            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 orig_needs_repack(source, 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^{}" %
                        repo.version_to_tag(options.vcs_tag, version))
                ]
            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(format_str(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 = str(err) or 'Unknown error, please report a bug'
            raise GbpError("Import of %s failed: %s" % (source.path, msg))
    except GbpError as err:
        if str(err):
            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 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.")

        head = repo.head
        tree = write_tree(repo, options)
        source = source_vfs(repo, options, tree)

        check_tag(options, repo, source)

        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.
            is_native = source.is_native()
            gbp.log.debug('Is the package Debian-native? %s' % (is_native,))
            if not is_native:
                if options.postexport:
                    gbp.log.info("Postexport hook set, delaying tarball creation")
                else:
                    gbp.log.info('Preparing upstream tarball (not delayed)...')
                    prepare_upstream_tarball(repo, source.changelog, options, tarball_dir,
                                             output_dir)

            # Export to another build dir if requested:
            if options.export_dir:
                gbp.log.debug('export_dir is set...')
                sourcepkg = source.sourcepkg
                assert sourcepkg is not None
                gbp.log.debug('sourcepkg = %s' % (sourcepkg,))
                tmp_dir = os.path.join(output_dir, "%s-tmp" % sourcepkg)
                export_source(repo, tree, source, options, tmp_dir, output_dir)

                # XXX: @KK:
                gbp.log.debug('Changing source to use tmp_dir=%s' % (tmp_dir,))
                source = DebianSource(tmp_dir)
                
                # Run postexport hook
                gbp.log.debug('running post-export hook...') 
                if options.postexport:
                    Hook('Postexport', options.postexport, shell=True,
                         extra_env={'GBP_GIT_DIR': repo.git_dir,
                                    'GBP_TMP_DIR': tmp_dir})(dir=tmp_dir)

                    # @KK: This is unnecessary because we are creating a new DebianSource object above now, anyhow.
                    assert source._changelog is None
                    # # XXX: Using source.sourcepkg causes debian/changelog to be parsed (and then
                    # # cached); but we want our post-export hook to be able to change it!
                    # source._changelog = None

                if source.changelog.upstream_version is None and not source.is_native():
                    raise GbpError('This package is not Debian-native (according to debian/source/format), but the '
                                   'last version number in debian/changelog does not seem to contain a dash (-) to  '
                                   'separate the Debian version from the upstream version.  (The raw version string '
                                   'is {!r}.)'.format(source.changelog.version))
                    
                major = (source.changelog.debian_version if source.is_native()
                         else source.changelog.upstream_version)
                if major is None:
                    raise GbpError('Cannot determine upstream version from changelog.')
                
                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() and options.postexport:
                    gbp.log.debug('Preparing upstream tarball (delayed)...')
                    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:
                Hook('Prebuild', options.prebuild, shell=True,
                     extra_env={'GBP_GIT_DIR': repo.git_dir,
                                'GBP_BUILD_DIR': build_dir,
                                'GBP_PBUILDER_DIST': get_pbuilder_dist(options,
                                                                       repo,
                                                                       source.is_native()),
                                })(dir=build_dir)

            setup_pbuilder(options, repo, source.is_native())
            # 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)
                Hook('Postbuild', options.postbuild, shell=True,
                     extra_env={'GBP_CHANGES_FILE': changes,
                                'GBP_BUILD_DIR': build_dir})()
        if options.tag or options.tag_only:
            tag = repo.version_to_tag(options.debian_tag, source.changelog.version)
            gbp.log.info("Tagging %s as %s" % (source.changelog.version, tag))
            if options.retag and repo.has_tag(tag):
                repo.delete_tag(tag)
            tag_msg = format_str(options.debian_tag_msg,
                                 dict(pkg=source.sourcepkg,
                                      version=source.changelog.version))
            repo.create_tag(name=tag,
                            msg=tag_msg,
                            sign=options.sign_tags,
                            commit=head,
                            keyid=options.keyid)
            if options.posttag:
                sha = repo.rev_parse("%s^{}" % tag)
                Hook('Posttag', 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 str(err):
            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:
            summary, msg = gbp.notifications.build_msg(source.changelog,
                                                       not retval)
            if not gbp.notifications.notify(summary, msg, options.notify):
                gbp.log.err("Failed to send notification")
                retval = 1

    return retval
Exemple #23
0
def main(argv):
    retval = 0
    prefix = "git-"
    source = None
    branch = None
    hook_env = {}

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

    if not options:
        return ExitCodes.parse_error

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

    try:
        clean_working_tree(options, repo)

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

        head = repo.head
        tree = write_tree(repo, options)
        source = source_vfs(repo, options, tree)

        check_tag(options, repo, source)

        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():
                if options.postexport:
                    gbp.log.info(
                        "Postexport hook set, delaying tarball creation")
                else:
                    prepare_upstream_tarball(repo, source, options,
                                             tarball_dir, output_dir)

            build_env, hook_env = setup_pbuilder(options, repo,
                                                 source.is_native())

            # 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:
                    Hook('Postexport',
                         options.postexport,
                         extra_env=Hook.md(hook_env, {
                             'GBP_GIT_DIR': repo.git_dir,
                             'GBP_TMP_DIR': tmp_dir
                         }))(dir=tmp_dir)

                major = (source.debian_version
                         if source.is_native() else source.upstream_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() and options.postexport:
                    prepare_upstream_tarball(repo, source, options,
                                             tarball_dir, output_dir)
                build_dir = export_dir
            else:
                build_dir = repo.path

            if options.prebuild:
                Hook('Prebuild',
                     options.prebuild,
                     extra_env=Hook.md(hook_env, {
                         'GBP_GIT_DIR': repo.git_dir,
                         'GBP_BUILD_DIR': build_dir
                     }))(dir=build_dir)

            # Finally build the package:
            RunAtCommand(
                options.builder, [pipes.quote(arg) for arg in dpkg_args],
                shell=True,
                extra_env=Hook.md(build_env,
                                  {'GBP_BUILD_DIR': build_dir}))(dir=build_dir)
            if options.postbuild:
                changes = os.path.abspath(
                    "%s/../%s_%s_%s.changes" %
                    (build_dir, source.changelog.name,
                     source.changelog.noepoch, changes_file_suffix(dpkg_args)))
                gbp.log.debug("Looking for changes file %s" % changes)
                Hook('Postbuild',
                     options.postbuild,
                     extra_env=Hook.md(hook_env, {
                         'GBP_CHANGES_FILE': changes,
                         'GBP_BUILD_DIR': build_dir
                     }))()
        if options.tag or options.tag_only:
            if is_pq_branch(branch):
                commit = repo.get_merge_base(branch, pq_branch_base(branch))
            else:
                commit = head

            tag = repo.version_to_tag(options.debian_tag, source.version)
            gbp.log.info("Tagging %s as %s" % (source.version, tag))
            if options.retag and repo.has_tag(tag):
                repo.delete_tag(tag)
            tag_msg = format_str(
                options.debian_tag_msg,
                dict(pkg=source.sourcepkg, version=source.version))
            repo.create_tag(name=tag,
                            msg=tag_msg,
                            sign=options.sign_tags,
                            commit=commit,
                            keyid=options.keyid)

            if options.posttag:
                sha = repo.rev_parse("%s^{}" % tag)
                Hook('Posttag',
                     options.posttag,
                     extra_env=Hook.md(
                         hook_env, {
                             'GBP_TAG': tag,
                             'GBP_BRANCH': branch or '(no branch)',
                             'GBP_SHA1': sha
                         }))()
    except KeyboardInterrupt:
        retval = 1
        gbp.log.err("Interrupted. Aborting.")
    except CommandExecFailed:
        retval = 1
    except (GbpError, GitRepositoryError) as err:
        if str(err):
            gbp.log.err(err)
        retval = 1
    except DebianSourceError as err:
        gbp.log.err(err)
        source = None
        retval = 1
    finally:
        drop_index(repo)

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

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

    return retval
def main(argv):
    ret = 0
    tmpdir = ''
    pristine_orig = None
    linked = False

    (options, args) = parse_args(argv)
    if not options:
        return 1

    try:
        if options.download:
            source = download_orig(args[0])
        else:
            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 orig_needs_repack(source, 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^{}" % repo.version_to_tag(options.vcs_tag, version))]
            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(format_str(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 = str(err) or 'Unknown error, please report a bug'
            raise GbpError("Import of %s failed: %s" % (source.path, msg))
    except GbpError as err:
        if str(err):
            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