def __init__(self, path):
        self.name = None
        self.version = None
        self.component = None

        self._commit = None
        self._linked = False
        self._pristine_orig = None
        self._source = OrigUpstreamSource(path)
        self._tag = None
        self._tmpdir = None
def find_source(use_uscan, args):
    """Find the tarball to import - either via uscan or via command line argument
    @return: upstream source filename or None if nothing to import
    @rtype: string
    @raise GbpError: raised on all detected errors

    >>> find_source(False, ['too', 'much'])
    Traceback (most recent call last):
    ...
    GbpError: More than one archive specified. Try --help.
    >>> find_source(False, [])
    Traceback (most recent call last):
    ...
    GbpError: No archive to import specified. Try --help.
    >>> find_source(True, ['tarball'])
    Traceback (most recent call last):
    ...
    GbpError: you can't pass both --uscan and a filename.
    >>> find_source(False, ['tarball']).path
    'tarball'
    """
    if use_uscan:
        if args:
            raise GbpError("you can't pass both --uscan and a filename.")

        uscan = Uscan()
        gbp.log.info("Launching uscan...")
        try:
            uscan.scan()
        except UscanError as e:
            raise GbpError("%s" % e)

        if not uscan.uptodate:
            if uscan.tarball:
                gbp.log.info("using %s" % uscan.tarball)
                args.append(uscan.tarball)
            else:
                raise GbpError("uscan didn't download anything, and no source was found in ../")
        else:
            gbp.log.info("package is up to date, nothing to do.")
            return None
    if len(args) > 1: # source specified
        raise GbpError("More than one archive specified. Try --help.")
    elif len(args) == 0:
        raise GbpError("No archive to import specified. Try --help.")
    else:
        archive = OrigUpstreamSource(args[0])
        return archive
class SourceImportManager(object):
    """Object to manage the import of an upstream source."""
    def __init__(self, path):
        self.name = None
        self.version = None
        self.component = None

        self._commit = None
        self._linked = False
        self._pristine_orig = None
        self._source = OrigUpstreamSource(path)
        self._tag = None
        self._tmpdir = None


    def detect_name_version_and_component(self, repo, options):
        # Guess defaults for the package name, version, and component from the
        # original tarball.
        (guessed_package, guessed_version, guessed_component) = self._source.guess_version() or ('', '', '')

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

        self.name = sourcepackage
        self.version = version
        self.component = guessed_component

    def unpack_or_repack_as_necessary(self, options):
        if not self._source.is_dir():
            self._tmpdir = tempfile.mkdtemp(dir='../')
            self._source.unpack(self._tmpdir, options.filters, self.component == '')
            gbp.log.debug("Unpacked '%s' to '%s'" % (self._source.path, self._source.unpacked))

        if self._source.needs_repack(options):
            gbp.log.debug("Filter pristine-tar: repacking '%s' from '%s'" % (self._source.path, self._source.unpacked))
            (self._source, self._tmpdir)  = repack_source(self._source, self.name, self.version, self.component, self._tmpdir, options.filters)

        # Don't mess up our repo with git metadata from an upstream tarball
        try:
            if os.path.isdir(os.path.join(self._source.unpacked, '.git/')):
                raise GbpError("The orig tarball contains .git metadata - giving up.")
        except OSError:
            pass

    def import_into_upstream_branch(self, repo, options):
        self._prepare_pristine_tar()

        try:
            upstream_branch = options.upstream_branch
            if self.component:
                upstream_branch += '-' + self.component

            filter_msg = ["", " (filtering out %s)"
                              % options.filters][len(options.filters) > 0]
            gbp.log.info("Importing '%s' to branch '%s'%s..." % (self._source.path,
                                                                 upstream_branch,
                                                                 filter_msg))
            gbp.log.info("Source package is %s" % self.name)
            gbp.log.info("Upstream version is %s" % self.version)

            msg = upstream_import_commit_msg(options, self.version)

            if options.vcs_tag:
                parents = [repo.rev_parse("%s^{}" % options.vcs_tag)]
            else:
                parents = None

            self._commit = repo.commit_dir(self._source.unpacked,
                                           msg=msg,
                                           branch=upstream_branch,
                                           other_parents=parents,
                                           create_missing_branch=True,
                                           )

            if options.pristine_tar:
                if self._pristine_orig:
                    repo.pristine_tar.commit(self._pristine_orig, upstream_branch)
                else:
                    gbp.log.warn("'%s' not an archive, skipping pristine-tar" % self._source.path)

            tagcomponent = ''
            if self.component:
                tagcomponent = '-' + self.component

            self._tag = repo.version_to_tag(options.upstream_tag, self.version, tagcomponent)
            repo.create_tag(name=self._tag,
                            msg="Upstream version %s" % self.version,
                            commit=self._commit,
                            sign=options.sign_tags,
                            keyid=options.keyid)
        except GitRepositoryError as err:
            msg = err.__str__() if len(err.__str__()) else ''
            raise GbpError("Import of %s failed: %s" % (source.path, msg))


    def merge_into_debian_branch(self, repo, options):
        try:
            if not repo.has_branch(options.debian_branch):
                repo.create_branch(options.debian_branch, rev=self._commit)
                repo.force_head(options.debian_branch, hard=True)
            else:
                gbp.log.info("Merging '%s' to '%s'" % ( self._tag, options.debian_branch ))
                repo.set_branch(options.debian_branch)
                try:
                    repo.merge(self._tag)
                except GitRepositoryError:
                    raise GbpError("Merge failed, please resolve.")
        except GitRepositoryError as err:
            msg = err.__str__() if len(err.__str__()) else ''
            raise GbpError("Import of %s failed: %s" % (source.path, msg))


    def cleanup(self, options):
        if self._pristine_orig and self._linked and not options.symlink_orig:
            os.unlink(self._pristine_orig)

        if self._tmpdir:
            cleanup_tmp_tree(self._tmpdir)


    def _prepare_pristine_tar(self):
        """
        Prepare the upstream source for pristine tar import.

        This checks if the upstream source is actually a tarball
        and creates a symlink from I{archive}
        to I{<pkg>_<version>.orig.tar.<ext>} so pristine-tar will
        see the correct basename.
        """
        if os.path.isdir(self._source.path):
            return

        ext = os.path.splitext(self._source.path)[1]
        if ext in ['.tgz', '.tbz2', '.tlz', '.txz' ]:
            ext = ".%s" % ext[2:]

        if not self.component:
            link = "../%s_%s.orig.tar%s" % (self.name, self.version, ext)
        else:
            link = "../%s_%s.orig-%s.tar%s" % ( self.name, self.version, self.component, ext)

        if os.path.basename(self._source.path) != os.path.basename(link):
            try:
                if not is_link_target(self._source.path, link):
                    os.symlink(os.path.abspath(self._source.path), link)
                    self._linked = True
            except OSError as err:
                    raise GbpError("Cannot symlink '%s' to '%s': %s" % (self._source.path, link, err[1]))
            self._pristine_orig = link
        else:
            self._pristine_orig = self._source.path