Пример #1
0
    def create(self, ebuild_path=None):
        """Write ebuild and update it after unpacking and examining ${S}"""
        # Need to write the ebuild first so we can unpack it and check for $S
        if ebuild_path:
            self.ebuild_path = ebuild_path

        if self.write(overwrite=self.options.overwrite):
            if self.unpacked_dir is None:
                PortageUtils.unpack_ebuild(self.ebuild_path)
            self.update_with_s()
            self.post_unpack()

            # Write ebuild again after unpacking and adding ${S}
            self.write(overwrite=True)

            if self.options.command != 'echo':
                # apply workflows
                Metadata(self.options, os.path.dirname(self.ebuild_path))()
                Echangelog(self.options, os.path.dirname(self.ebuild_path))()
                Repoman(self.options, os.path.dirname(self.ebuild_path))()

                log.info("Your ebuild is here: " + self.ebuild_path)

        # TODO: If ebuild already exists, we don't unpack and get dependencies
        # because they must exist.
        # We should add an option to force creating dependencies or should
        # overwrite be used?
        return self.requires
Пример #2
0
    def update_with_s(self):
        """Add ${:term:`S`} to ebuild if needed."""
        log.debug("Trying to determine ${S}, unpacking...")
        if self.unpacked_dir is None:
            unpacked_dir = PortageUtils.find_s_dir(self['p'], self.options.category)
            if unpacked_dir == "":
                self["s"] = "${WORKDIR}"

            self.unpacked_dir = os.path.join(PortageUtils.get_workdir(self['p'],
                self.options.category), unpacked_dir)

        if self.get('my_p', None):
            self["s"] = "${WORKDIR}/${MY_P}"
        else:
            pass  # ${WORKDIR}/${P}
Пример #3
0
    def write(self, overwrite=False):
        """Write ebuild file

        :param overwrite: Overwrite ebuild if it already exists.
        :type overwrite: bool

        """

        # get ebuild path
        if not self.ebuild_path:
            overlay_name = self.options.overlay
            overlay_path = PortageUtils.get_overlay_path(overlay_name)
            self.ebuild_path = self.find_path_to_ebuild(overlay_path)

        log.debug('Ebuild.write: build_path(%s)', self.ebuild_path)

        # see if we want to overwrite
        if (not self.options.command == 'echo') and os.path.exists(self.ebuild_path) and not overwrite:
            log.warn("Ebuild exists (use -o to overwrite), skipping: %s" % self.ebuild_path)
            return False

        # write ebuild
        out = open(self.ebuild_path, "w")
        try:
            out.write(self.render())
        finally:
            out.close()
        return True
Пример #4
0
 def find_path_to_ebuild(self, overlay_path):
     """"""
     ebuild_dir = PortageUtils.make_ebuild_dir(self.options.category,
         self['pn'], overlay_path)
     if not os.path.isdir(ebuild_dir or ""):
         raise GPyPiCouldNotCreateEbuildPath('Couldn not create ebuild directory %s' % ebuild_dir)
     return os.path.join(ebuild_dir, self['p'] + ".ebuild")
Пример #5
0
    def sync(self):
        """"""
        pypi = CheeseShop()
        for package in pypi.list_packages():
            (pn, vers) = pypi.query_versions_pypi(package)
            for version in vers:
                # TODO: parse_* will not return anything for correct atoms
                atom = Enamer.construct_atom(Enamer.parse_pn(pn)[0], self.config.category, Enamer.parse_pv(version[0]))

                # we skip existing ebuilds
                if PortageUtils.ebuild_exists(atom):
                    continue
                try:
                    url = pypi.get_download_urls(pn, version)[0]
                    # TODO: use setuptools way also
                except IndexError:
                    log.warn('Skipping %s, no download url', atom)
                else:
                    try:
                        self.config.configs['argparse']['uri'] = url
                        self.config.configs['argparse']['up_pn'] = pn
                        self.config.configs['argparse']['up_pv'] = version
                        gpypi = GPyPI(pn, version, self.config)
                        gpypi.create_ebuilds()
                    except KeyboardInterrupt:
                        raise
                    except:
                        log.exception('Unexpected error occured during ebuild creation:')
Пример #6
0
    def sync(self):
        """"""
        pypi = CheeseShop()
        for package in pypi.list_packages():
            (pn, vers) = pypi.query_versions_pypi(package)
            for version in vers:
                # TODO: parse_* will not return anything for correct atoms
                atom = Enamer.construct_atom(
                    Enamer.parse_pn(pn)[0], self.config.category,
                    Enamer.parse_pv(version[0]))

                # we skip existing ebuilds
                if PortageUtils.ebuild_exists(atom):
                    continue
                try:
                    url = pypi.get_download_urls(pn, version)[0]
                    # TODO: use setuptools way also
                except IndexError:
                    log.warn('Skipping %s, no download url', atom)
                else:
                    try:
                        self.config.configs['argparse']['uri'] = url
                        self.config.configs['argparse']['up_pn'] = pn
                        self.config.configs['argparse']['up_pv'] = version
                        gpypi = GPyPI(pn, version, self.config)
                        gpypi.create_ebuilds()
                    except KeyboardInterrupt:
                        raise
                    except:
                        log.exception(
                            'Unexpected error occured during ebuild creation:')
Пример #7
0
    def __init__(self, options):
        self.setup_keywords = {}
        self.metadata = {}
        self.unpacked_dir = None
        self.ebuild_path = None
        self.requires = set()
        self.has_tests = None
        self.options = options

        # init stuff
        self.env = Environment(
            loader=PackageLoader(self.EBUILD_TEMPLATE_PACKAGE, 'templates'),
            trim_blocks=True)
        self.template = self.env.get_template(self.EBUILD_TEMPLATE)

        # Variables that will be passed to the Jinja template
        d = {
            'python_modname': None,
            'rdepend': set(),
            'depend': set(),
            'use': set(),
            'warnings': set(),
            'slot': '0',
            's': '',
            'tests_method': '',
            'inherit': set(['distutils']),
            'gpypi_version': __version__,
            'year': date.today().year,
            'gentoo_keywords': PortageUtils.get_keyword(),
        }
        super(Ebuild, self).__init__(d)
        # TODO: use Config rather
        self.options.configs['setup_py'] = self
        self.set_ebuild_vars()
Пример #8
0
    def is_valid_portage_license(cls, license):
        """
        Check if license string matches a valid one in ${PORTDIR}/licenses

        :param license: Portage license name
        :type license: string
        :returns: True if license is valid/exists
        :rtype: bool

        **Example:**

        >>> Enamer.is_valid_portage_license("KQEMU")
        True
        >>> Enamer.is_valid_portage_license("foobar")
        False

        """
        return os.path.exists(os.path.join(PortageUtils.get_portdir(), "licenses", license))
Пример #9
0
    def is_valid_portage_license(cls, license):
        """
        Check if license string matches a valid one in ${PORTDIR}/licenses

        :param license: Portage license name
        :type license: string
        :returns: True if license is valid/exists
        :rtype: bool

        **Example:**

        >>> Enamer.is_valid_portage_license("KQEMU")
        True
        >>> Enamer.is_valid_portage_license("foobar")
        False

        """
        return os.path.exists(
            os.path.join(PortageUtils.get_portdir(), "licenses", license))
Пример #10
0
    def get_vars(cls, uri, up_pn, up_pv, pn="", pv="", my_pn=None, my_pv=None):
        """
        Determine P* and MY_* ebuild variables

        :param uri: HTTP URL to download link for a package
        :param up_pn: Upstream package name
        :param up_pv: Upstream package version
        :param pn: Converted package name
        :param pv: Converted package version
        :param my_pn: Bash substitution for upstream package name
        :param my_pv: Bash substitution for upstream package version
        :type uri: string
        :type up_pn: string
        :type up_pv: string
        :type pn: string
        :type pv: string
        :type my_pn: list
        :type my_pv: list
        :raises: :exc:`GPyPiInvalidAtom` if version/name could not be parsed correctly
        :returns:
            * pn -- Ebuild Gentoo package name
            * pv -- Ebuild Gentoo package version
            * p -- Ebuild Gentoo package name + version
            * my_p -- Upstream whole package name (name + version)
            * my_pn -- Bash substitution for upstream package name
            * my_pv -- Bash substitution for upstream package version
            * my_p_raw -- my_p extracted from SRC_URI
            * src_uri -- Ebuild SRC_URI with MY_P variable
        :rtype: dict

        **Examples of what it can detect/convert** (see test_enamer.py for full capabilities)

        http://www.foo.com/pkgfoo-1.0.tbz2

        * PN="pkgfoo"
        * PV="1.0"
        * Ebuild name: pkgfoo-1.0.ebuild
        * SRC_URI="http://www.foo.com/${P}.tbz2"

        http://www.foo.com/PkgFoo-1.0.tbz2

        * PN="pkgfoo"
        * PV="1.0"
        * Ebuild name: pkgfoo-1.0.ebuild
        * MY_P="PkgFoo-${PV}"
        * SRC_URI="http://www.foo.com/${MY_P}.tbz2"

        http://www.foo.com/pkgfoo_1.0.tbz2

        * PN="pkgfoo"
        * PV="1.0"
        * Ebuild name: pkgfoo-1.0.ebuild
        * MY_P="${PN}_${PV}"
        * SRC_URI="http://www.foo.com/${MY_P}.tbz2"

        http://www.foo.com/PKGFOO_1.0.tbz2

        * PN="pkgfoo"
        * PV="1.0"
        * Ebuild name: pkgfoo-1.0.ebuild
        * MY_P="PKGFOO_${PV}"
        * SRC_URI="http://www.foo.com/${MY_P}.tbz2"

        http://www.foo.com/pkg-foo-1.0_beta1.tbz2

        * PN="pkg-foo"
        * PV="1.0_beta1"
        * Ebuild name: pkg-foo-1.0_beta1.ebuild
        * SRC_URI="http://www.foo.com/${P}.tbz2"

        **Example:**

        >>> d = Enamer.get_vars('http://www.foo.com/pkg.foo-1.0b1.tbz2', 'pkg.foo', '1.0b1')
        >>> assert d['pn'] == 'pkg-foo'
        >>> assert d['pv'] == '1.0_beta1'
        >>> assert d['p'] == 'pkg-foo-1.0_beta1'
        >>> assert d['my_pv'] == ['${PV/_beta/b}']
        >>> assert d['my_pn'] == ['${PN/-/.}']
        >>> assert d['my_p'] == '${MY_PN}-${MY_PV}'
        >>> assert d['my_p_raw'] == 'pkg.foo-1.0b1'
        >>> assert d['src_uri'] == 'http://www.foo.com/${MY_P}.tbz2'
        >>> assert len(d) == 8

        """
        log.debug("get_vars: %r" % locals())
        my_pn = my_pn or []
        my_pv = my_pv or []
        my_p = ""
        INVALID_VERSION = False
        uri = cls.sanitize_uri(uri)

        # Test for PV with -r1234 suffix
        # Portage uses -r suffixes for it's own ebuild revisions so
        # We have to convert it to _pre or _alpha etc.
        tail = up_pv.split("-")[-1][0]
        if tail == "r":
            INVALID_VERSION = True
            log.debug("We have a version with a -r### suffix")

        portage_atom = "=dev-python/%s-%s" % (up_pn, up_pv)
        if not PortageUtils.is_valid_atom(portage_atom):
            INVALID_VERSION = True
            log.debug("%s is not valid portage atom", portage_atom)

        if INVALID_VERSION:
            pv, my_pv = cls.parse_pv(up_pv, pv, my_pv)
        pn, my_pn = cls.parse_pn(up_pn, pn, my_pn)

        # No PN or PV given on command-line, try upstream's name/version
        if not pn and not pv:
            log.debug("pn and pv not given, trying upstream")
            # Try to determine pn and pv from uri
            parts = cls.split_uri(uri)
            if parts:
                # pylint: disable-msg=W0612
                # unused variable 'rev'
                # The 'rev' is never used because these are
                # new ebuilds being created.
                pn, pv, rev = parts
            else:
                pn = up_pn
                pv = up_pv
        # Try upstream's version if it could't be determined from uri or cli option
        elif pn and not pv:
            pv = up_pv
        elif not pn and pv:
            pn = up_pn

        p = "%s-%s" % (pn, pv)
        log.debug("get_vars: p(%s)", p)

        # Make sure we have a valid P
        atom = "=dev-python/%s-%s" % (pn, pv)
        if not PortageUtils.is_valid_atom(atom):
            log.debug(locals())
            raise GPyPiInvalidAtom("%s is not a valid portage atom. "
                "We could not determine it from upstream pn(%s) and pv(%s)." %
                (atom, up_pn, up_pv))

        # Check if we need to use MY_P based on src's uri
        src_uri, my_p_raw = cls.get_my_p(uri)
        log.debug("getting SRC_URI with ${MY_P}: %s %s %s", src_uri, my_p, my_p_raw)
        if my_p_raw == p:
            my_pn = []
            my_p_raw = ''
            src_uri = src_uri.replace("${MY_P}", "${P}")
        elif not (my_pn or my_pv):
            src_uri, my_p, my_pn, my_p_raw = cls._get_src_uri(uri, my_pn)
            log.debug("getting SRC_URI: %s %s %s", src_uri, my_p, my_p_raw)

        log.debug("before MY_P guessing: %r", locals())
        if my_pn or my_pv:
            my_p = "%s-%s" % ("${MY_PN}" if my_pn else "${PN}",
                "${MY_PV}" if my_pv else "${PV}")

        return {
            'pn': pn,
            'pv': pv,
            'p': p,
            'my_p': my_p,
            'my_pn': my_pn,
            'my_pv': my_pv,
            'my_p_raw': my_p_raw,
            'src_uri': src_uri,
        }
Пример #11
0
    def get_dependencies(self, vanilla_requirements, if_use=None):
        """
        Generate :term:`DEPEND` / :term:`RDEPEND` strings.

        :param vanilla_requirements: **require_\*** contents from `setup.py`
        :param if_use: :term:`USE` flag that must be set
            to download dependencies
        :type vanilla_requirements: string or list
        :type if_use: string

        """
        # TODO: DOC: steps to acquire deps
        requirements = parse_requirements(vanilla_requirements)

        for req in requirements:
            extras = req.extras
            # TODO: extend configuration to support callable configs
            # TODO: pass metadata from the project_name
            #category = Enamer.convert_category(req.project_name, {})
            category = self.options.category
            pn = Enamer.parse_pn(req.project_name)[0] or req.project_name

            # add setuptools dependency for later dependency generating
            self.add_setuptools_depend(req)

            log.debug('get_dependencies: pn(%s) category(%s)', pn, category)

            if not len(req.specs):
                # No version of requirement was specified so we only add
                # dev-python/pn
                self.add_rdepend(Enamer.construct_atom(pn, category,
                    uses=extras, if_use=if_use))
            else:
                comparator, ver = req.specs[0]
                ver = Enamer.parse_pv(ver)[0] or ver
                log.debug('get_dependencies: pv(%s)' % ver)
                if len(req.specs) > 1:
                    # Some packages have more than one comparator, i.e. cherrypy
                    # for turbogears has cherrpy>=2.2,<3.0 which would translate
                    # to portage's =dev-python/cherrypy-2.2*
                    comparator1, ver1 = req.specs[0]
                    comparator2, ver2 = req.specs[1]
                    # TODO: this is a total mess, refactor
                    if comparator1.startswith(">") and \
                            comparator2.startswith("<"):
                        # we set blocker for <*
                        self.add_rdepend(Enamer.construct_atom(pn, category, ver1,
                            comparator1, uses=extras, if_use=if_use))
                        self.add_rdepend(Enamer.construct_atom(pn, category, ver2,
                            "!" + comparator2, uses=extras, if_use=if_use))
                    elif comparator2.startswith(">") and \
                            comparator1.startswith("<"):
                        self.add_rdepend(Enamer.construct_atom(pn, category, ver2,
                            comparator2, uses=extras, if_use=if_use))
                        self.add_rdepend(Enamer.construct_atom(pn, category, ver1,
                            "!" + comparator1, uses=extras, if_use=if_use))
                    else:
                        self['warnings'].add("Couldn't resolve requirements. "
                            "You will need to make sure the RDEPEND for %s is "
                            "correct." % req)
                        self.add_rdepend(Enamer.construct_atom(pn, category,
                            uses=extras, if_use=if_use))
                        self['warnings'].add("Could not determine dependency: %s" % req)
                    break
                # Requirement.specs is a list of (comparator,version) tuples
                if comparator == "==":
                    comparator = "="
                atom = Enamer.construct_atom(pn, category, ver, comparator,
                    uses=extras)
                if PortageUtils.is_valid_atom(atom):
                    self.add_rdepend(Enamer.construct_atom(pn, category, ver,
                        comparator, uses=extras, if_use=if_use))
                else:
                    log.debug("Invalid PV in dependency: (Requirement %s) %s",
                        req, atom)
                    installed_pv = PortageUtils.get_installed_ver(Enamer.\
                        construct_atom(pn, category, uses=extras, if_use=if_use))
                    if installed_pv:
                        # If we have it installed, use >= installed version
                        self.add_rdepend(Enamer.construct_atom(pn, category,
                            installed_pv, '>=', uses=extras, if_use=if_use))
                    else:
                        # If package has invalid version and we don't have
                        # an ebuild in portage, just add PN to DEPEND, no
                        # version.
                        self['warnings'].add("Could not determine dependency: %s" % req)
                        self.add_rdepend(Enamer.construct_atom(pn, category,
                            uses=extras, if_use=if_use))
Пример #12
0
    def get_vars(cls, uri, up_pn, up_pv, pn="", pv="", my_pn=None, my_pv=None):
        """
        Determine P* and MY_* ebuild variables

        :param uri: HTTP URL to download link for a package
        :param up_pn: Upstream package name
        :param up_pv: Upstream package version
        :param pn: Converted package name
        :param pv: Converted package version
        :param my_pn: Bash substitution for upstream package name
        :param my_pv: Bash substitution for upstream package version
        :type uri: string
        :type up_pn: string
        :type up_pv: string
        :type pn: string
        :type pv: string
        :type my_pn: list
        :type my_pv: list
        :raises: :exc:`GPyPiInvalidAtom` if version/name could not be parsed correctly
        :returns:
            * pn -- Ebuild Gentoo package name
            * pv -- Ebuild Gentoo package version
            * p -- Ebuild Gentoo package name + version
            * my_p -- Upstream whole package name (name + version)
            * my_pn -- Bash substitution for upstream package name
            * my_pv -- Bash substitution for upstream package version
            * my_p_raw -- my_p extracted from SRC_URI
            * src_uri -- Ebuild SRC_URI with MY_P variable
        :rtype: dict

        **Examples of what it can detect/convert** (see test_enamer.py for full capabilities)

        http://www.foo.com/pkgfoo-1.0.tbz2

        * PN="pkgfoo"
        * PV="1.0"
        * Ebuild name: pkgfoo-1.0.ebuild
        * SRC_URI="http://www.foo.com/${P}.tbz2"

        http://www.foo.com/PkgFoo-1.0.tbz2

        * PN="pkgfoo"
        * PV="1.0"
        * Ebuild name: pkgfoo-1.0.ebuild
        * MY_P="PkgFoo-${PV}"
        * SRC_URI="http://www.foo.com/${MY_P}.tbz2"

        http://www.foo.com/pkgfoo_1.0.tbz2

        * PN="pkgfoo"
        * PV="1.0"
        * Ebuild name: pkgfoo-1.0.ebuild
        * MY_P="${PN}_${PV}"
        * SRC_URI="http://www.foo.com/${MY_P}.tbz2"

        http://www.foo.com/PKGFOO_1.0.tbz2

        * PN="pkgfoo"
        * PV="1.0"
        * Ebuild name: pkgfoo-1.0.ebuild
        * MY_P="PKGFOO_${PV}"
        * SRC_URI="http://www.foo.com/${MY_P}.tbz2"

        http://www.foo.com/pkg-foo-1.0_beta1.tbz2

        * PN="pkg-foo"
        * PV="1.0_beta1"
        * Ebuild name: pkg-foo-1.0_beta1.ebuild
        * SRC_URI="http://www.foo.com/${P}.tbz2"

        **Example:**

        >>> d = Enamer.get_vars('http://www.foo.com/pkg.foo-1.0b1.tbz2', 'pkg.foo', '1.0b1')
        >>> assert d['pn'] == 'pkg-foo'
        >>> assert d['pv'] == '1.0_beta1'
        >>> assert d['p'] == 'pkg-foo-1.0_beta1'
        >>> assert d['my_pv'] == ['${PV/_beta/b}']
        >>> assert d['my_pn'] == ['${PN/-/.}']
        >>> assert d['my_p'] == '${MY_PN}-${MY_PV}'
        >>> assert d['my_p_raw'] == 'pkg.foo-1.0b1'
        >>> assert d['src_uri'] == 'http://www.foo.com/${MY_P}.tbz2'
        >>> assert len(d) == 8

        """
        log.debug("get_vars: %r" % locals())
        my_pn = my_pn or []
        my_pv = my_pv or []
        my_p = ""
        INVALID_VERSION = False
        uri = cls.sanitize_uri(uri)

        # Test for PV with -r1234 suffix
        # Portage uses -r suffixes for it's own ebuild revisions so
        # We have to convert it to _pre or _alpha etc.
        tail = up_pv.split("-")[-1][0]
        if tail == "r":
            INVALID_VERSION = True
            log.debug("We have a version with a -r### suffix")

        portage_atom = "=dev-python/%s-%s" % (up_pn, up_pv)
        if not PortageUtils.is_valid_atom(portage_atom):
            INVALID_VERSION = True
            log.debug("%s is not valid portage atom", portage_atom)

        if INVALID_VERSION:
            pv, my_pv = cls.parse_pv(up_pv, pv, my_pv)
        pn, my_pn = cls.parse_pn(up_pn, pn, my_pn)

        # No PN or PV given on command-line, try upstream's name/version
        if not pn and not pv:
            log.debug("pn and pv not given, trying upstream")
            # Try to determine pn and pv from uri
            parts = cls.split_uri(uri)
            if parts:
                # pylint: disable-msg=W0612
                # unused variable 'rev'
                # The 'rev' is never used because these are
                # new ebuilds being created.
                pn, pv, rev = parts
            else:
                pn = up_pn
                pv = up_pv
        # Try upstream's version if it could't be determined from uri or cli option
        elif pn and not pv:
            pv = up_pv
        elif not pn and pv:
            pn = up_pn

        p = "%s-%s" % (pn, pv)
        log.debug("get_vars: p(%s)", p)

        # Make sure we have a valid P
        atom = "=dev-python/%s-%s" % (pn, pv)
        if not PortageUtils.is_valid_atom(atom):
            log.debug(locals())
            raise GPyPiInvalidAtom(
                "%s is not a valid portage atom. "
                "We could not determine it from upstream pn(%s) and pv(%s)." %
                (atom, up_pn, up_pv))

        # Check if we need to use MY_P based on src's uri
        src_uri, my_p_raw = cls.get_my_p(uri)
        log.debug("getting SRC_URI with ${MY_P}: %s %s %s", src_uri, my_p,
                  my_p_raw)
        if my_p_raw == p:
            my_pn = []
            my_p_raw = ''
            src_uri = src_uri.replace("${MY_P}", "${P}")
        elif not (my_pn or my_pv):
            src_uri, my_p, my_pn, my_p_raw = cls._get_src_uri(uri, my_pn)
            log.debug("getting SRC_URI: %s %s %s", src_uri, my_p, my_p_raw)

        log.debug("before MY_P guessing: %r", locals())
        if my_pn or my_pv:
            my_p = "%s-%s" % ("${MY_PN}" if my_pn else "${PN}",
                              "${MY_PV}" if my_pv else "${PV}")

        return {
            'pn': pn,
            'pv': pv,
            'p': p,
            'my_p': my_p,
            'my_pn': my_pn,
            'my_pv': my_pv,
            'my_p_raw': my_p_raw,
            'src_uri': src_uri,
        }