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:')
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:')
def set_ebuild_vars(self): """Calls :meth:`gpypi.enamer.Enamer.get_vars` and updates instance variables. """ d = Enamer.get_vars(self.options.uri, self.options.up_pn, self.options.up_pv) self.update(d) if filter(None, [src_uri.lower().endswith('.zip') for src_uri in self['src_uri']]): self.add_depend("app-arch/unzip")
def parse_metadata(self): """Extract :term:`DESCRIPTION`, :term:`HOMEPAGE`, :term:`LICENSE` ebuild variables from :term:`PyPi` metadata. """ # There doesn't seem to be any specification for case if 'summary' in self: self['description'] = self.get('summary', "") # Replace double quotes to keep bash syntax correct self['description'] = self['description'].replace('"', "'") my_license = Enamer.convert_license(self.get('classifiers', []), self.get('license', "")) if Enamer.is_valid_portage_license(my_license): self['license'] = my_license else: if 'license' in self: del self['license'] self.options.configs['setup_py'].update(self)
def run(self): """""" # late import because of setup.py from gpypi.enamer import Enamer from gpypi.ebuild import Ebuild from gpypi.config import Config, ConfigManager # TODO: configure logging (handlers and stuff) self.argparse_config.update({ 'up_pn': self.distribution.get_name(), 'up_pv': self.distribution.get_version(), }) mgr = ConfigManager.load_from_ini(self.config_file) mgr.configs['argparse'] = Config(self.argparse_config) mgr.configs['setup_py'] = Config.from_setup_py(Enamer.parse_setup_py(self.distribution)) ebuild = Ebuild(mgr) ebuild.unpacked_dir = os.getcwd() to = os.path.join(self.dist_dir, ebuild['p'] + '.ebuild') ebuild.create(to) print 'ebuild saved to %s' % to
def run(self): """""" # late import because of setup.py from gpypi.enamer import Enamer from gpypi.ebuild import Ebuild from gpypi.config import Config, ConfigManager # TODO: configure logging (handlers and stuff) self.argparse_config.update({ 'up_pn': self.distribution.get_name(), 'up_pv': self.distribution.get_version(), }) mgr = ConfigManager.load_from_ini(self.config_file) mgr.configs['argparse'] = Config(self.argparse_config) mgr.configs['setup_py'] = Config.from_setup_py( Enamer.parse_setup_py(self.distribution)) ebuild = Ebuild(mgr) ebuild.unpacked_dir = os.getcwd() to = os.path.join(self.dist_dir, ebuild['p'] + '.ebuild') ebuild.create(to) print 'ebuild saved to %s' % to
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))
def post_unpack(self): """Perform finalization tasks. Dynamically imports *setup.py* file and extracts it's kwargs. * determine if :term:`PYTHON_MODNAME` is not :term:`PN` -- We inspect `packages`, `py_module` and `package_dir` * get dependencies from `setup_requires`, `install_requires` and `extra_requires` * figure out if we need to :term:`DEPEND` / :term:`RDEPEND` on :mod:`setuptools` -- We inspect if `setup.py` imports :mod:`setuptools` or :mod:`pkg_resources` * calls :meth:`Ebuild.discover_docs_and_examples` and :meth:`Ebuild.discover_tests` * determines :term:`DEPEND` / :term:`RDEPEND` on :mod:`setuptools` :raises: :exc:`gpypi.exc.GPyPiNoSetupFile` :raises: :exc:`gpypi.exc.GPyPiNoDistribution` """ # save original functions to undo monkeypaching at the end temp_setup = setuptools.setup temp_distutils = distutils.core.setup # mock functions to get metadata self.setup_keywords = {} def wrapper(**kw): self.setup_keywords.update(kw) # monkeypatch setups setuptools.setup = wrapper distutils.core.setup = wrapper setup_file = os.path.join(self.unpacked_dir, "setup.py") if os.path.exists(self.unpacked_dir): if not os.path.exists(setup_file): raise GPyPiNoSetupFile("%s does not exists." % setup_file) else: # run setup file from unpacked_dir cwd = os.getcwdu() try: os.chdir(self.unpacked_dir) utils.import_path(setup_file) finally: os.chdir(cwd) else: raise GPyPiNoDistribution("Unpacked dir could not be found: %s"\ % self.unpacked_dir) # extract dependencies self.install_requires = self.setup_keywords.get('install_requires', '') self.setup_requires = self.setup_keywords.get('setup_requires', '') self.extras_require = self.setup_keywords.get('extras_require', {}) self.tests_require = self.setup_keywords.get('tests_require', '') # dependencies resolving self.get_dependencies(self.install_requires) self.get_dependencies(self.setup_requires) # TODO: handle setup as depend instead of rdepend for use_flag, dependency in self.extras_require.iteritems(): self.get_dependencies(dependency, if_use=use_flag) self.discover_docs_and_examples() self.discover_tests() # check dependency on setuptools with open(setup_file) as f: contents = f.read() if ('setuptools' in contents) or ('pkg_resources' in contents): self.add_depend('dev-python/setuptools') self.add_rdepend('dev-python/setuptools') # handle PYTHON_MODNAME module_names = [] module_names.extend(self.setup_keywords.get('packages', [])) module_names.extend(self.setup_keywords.get('py_modules', [])) module_names.extend(filter(None, self.setup_keywords.get('package_dir', {}).keys())) # set modname only if needed if len(module_names) == 1 and module_names[0] != self['pn']: self['python_modname'] = module_names # undo monkeypatching setuptools.setup = temp_setup distutils.core.setup = temp_distutils # extract metadata if 'setup_py' in self.options.use: d = distutils.core.Distribution(self.setup_keywords) metadata = Enamer.parse_setup_py(d) self.update(metadata)
def install(self): """""" self.create() package = Enamer.parse_pn(self.config.up_pn)[0] os.execvp('emerge', ['emerge', '-av', package or self.config.up_pn])