From c342ec7f274a93efdd26d93def589780d13f7b41 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Dec 05 2017 06:36:23 +0000 Subject: Issue #28: Remove dependency on DNF This skips looking anything up in the metadata of the system running `fedmod`, and hence also removes the runtime dependency on `dnf`. The summary and description are now *never* copied from the underlying SRPM, and the content licenses field is always empty (even when only a single package reference is given). --- diff --git a/README.md b/README.md index f3a34b1..fadf515 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Python installation. Some dependencies aren't currently available from PyPI, and hence need to be installed system-wide: - $ sudo dnf install python3-dnf python3-solv + $ sudo dnf install python3-solv ### Additional development dependencies diff --git a/src/_fedmod/module_generator.py b/src/_fedmod/module_generator.py index 5b33dfd..7d5e7f2 100644 --- a/src/_fedmod/module_generator.py +++ b/src/_fedmod/module_generator.py @@ -3,7 +3,6 @@ from __future__ import absolute_import import sys import modulemd import logging -import dnf from . import _depchase, _repodata def _name_only(rpm_name): @@ -25,12 +24,13 @@ class ModuleGenerator(object): def __init__(self, pkgs): self.pkgs = pkgs - self.pkg = None + self.core_srpm = None self.mmd = modulemd.ModuleMetadata() + self._pool = _depchase.make_pool("x86_64") def _calculate_dependencies(self, build_deps_iterations): pkgs = self.pkgs - pool = _depchase.make_pool("x86_64") + pool = self._pool self.api_srpms = {_name_only(_depchase.get_srpm_for_rpm(pool, dep)) for dep in pkgs} run_deps = _depchase.ensure_installable(pool, pkgs) module_run_deps, rpm_run_deps = _categorise_deps(run_deps) @@ -65,33 +65,19 @@ class ModuleGenerator(object): self.build_and_run_srpms = run_srpm_names & build_srpm_names self.unresolved_build_rpms = {n for n in build_deps} - - def _get_pkg_info(self): - """Function loads package from dnf""" - # TODO: Get this from the _depchase metadata, not the system metadata - logging.info("Getting package info from DNF") - b = dnf.Base() - b.read_all_repos() - b.fill_sack() - q = b.sack.query().filter(name=self.pkgs, reponame='fedora', latest=True) - if len(q) > 1: - raise ValueError('Name of package is not unique') - if len(q) == 0: - raise ValueError('No package found in repo') - self.pkg = q[0] + def _set_core_srpm(self): + """Set core SRPM based on first listed package""" + pool = self._pool + pkg = self.pkgs[0] + self.core_srpm = _name_only(_depchase.get_srpm_for_rpm(pool, pkg)) def _save_module_md(self, output_fname): """ Function writes modulemd to either stdout or the given filename :return: """ - - if len(self.pkgs) == 1: - file_name = self.pkgs[0] + '.yaml' - else: - file_name = "modulemd-output.yaml" if output_fname is not None: - self.mmd.dump(file_name) + self.mmd.dump(output_fname) print('Generated modulemd file: %r' % output_fname) else: print(self.mmd.dumps()) @@ -105,14 +91,12 @@ class ModuleGenerator(object): """ self.mmd.add_module_license("MIT") - if len(self.pkgs) == 1: - self.mmd.summary = str(self.pkg.summary) - self.mmd.description = str(self.pkg.description) - - # Default license for the module metadata, same as default Fedora - # content license. + if self.core_srpm is not None: + self.mmd.summary = f"Generated module for {self.core_srpm}" + else: + self.mmd.summary = f"Generated module for {self.pkgs}" - self.mmd.add_content_license(str(self.pkg.license)) + self.mmd.description = "Module auto-generated by fedmod" # Declare the public API for pkg in self.api_srpms: @@ -139,6 +123,8 @@ class ModuleGenerator(object): # See https://pagure.io/modulemd/issue/54 for discussion self.mmd.filter.add_rpm(pkg) + # TODO: Always set content licenses appropriately + # TODO: Emit something for non-empty self.unresolved_build_rpms # rather than relying solely on the warnings emitted on stderr @@ -151,7 +137,7 @@ class ModuleGenerator(object): def run(self, output_fname, build_deps_iterations): if len(self.pkgs) == 1: - self._get_pkg_info() + self._set_core_srpm() self._calculate_dependencies(build_deps_iterations) self._update_module_md() self._save_module_md(output_fname) diff --git a/tests/test_module_generator.py b/tests/test_module_generator.py index f413575..5c2f66c 100644 --- a/tests/test_module_generator.py +++ b/tests/test_module_generator.py @@ -27,17 +27,12 @@ class TestSinglePackageInput(object): modmd = _generate_modulemd(input_rpms) # Expected description for 'grep' - assert modmd.summary == "Pattern matching utilities" - assert modmd.description == ( - "The GNU versions of commonly used grep utilities. Grep searches through\n" - "textual input for lines which contain a match to a specified pattern and then\n" - "prints the matching lines. GNU\'s grep utilities include grep, egrep and fgrep.\n\n" - "GNU grep is needed by many scripts, so it shall be installed on every system." - ) + assert modmd.summary == "Generated module for grep" + assert modmd.description == "Module auto-generated by fedmod" # Expected licenses for 'grep' assert modmd.module_licenses == {'MIT'} - assert modmd.content_licenses == {'GPLv3+'} + assert modmd.content_licenses == set() # Only given modules are listed in the public API assert sorted(modmd.api.rpms) == sorted(input_rpms) @@ -57,8 +52,8 @@ class TestMultiplePackageInput(object): modmd = _generate_modulemd(input_rpms) # Can't generate descriptive metadata when given multiple RPMs - assert modmd.summary == "" - assert modmd.description == "" + assert modmd.summary == "Generated module for ('grep', 'haproxy')" + assert modmd.description == "Module auto-generated by fedmod" # Expected licenses for grep + haproxy assert modmd.module_licenses == {'MIT'} @@ -83,18 +78,12 @@ class TestRecursiveBuildDeps(object): modmd = _generate_modulemd(input_rpms, 100) # Descriptive metadata - assert modmd.summary == "A community developed branch of MySQL" - assert modmd.description == ( - "MariaDB is a community developed branch of MySQL.\n" - "MariaDB is a multi-user, multi-threaded SQL database server.\n" - "It is a client/server implementation consisting of a server daemon (mysqld)\n" - "and many different client programs and libraries. The base package\n" - "contains the standard MariaDB/MySQL client programs and generic MySQL files." - ) + assert modmd.summary == "Generated module for mariadb" + assert modmd.description == "Module auto-generated by fedmod" # Expected licenses assert modmd.module_licenses == {'MIT'} - assert modmd.content_licenses == {'GPLv2 with exceptions and LGPLv2 and BSD'} + assert modmd.content_licenses == set() # Only given modules are listed in the public API assert sorted(modmd.api.rpms) == sorted(input_rpms) @@ -139,22 +128,12 @@ class TestNonRecursiveBuildDeps(object): modmd = _generate_modulemd(input_rpms) # Descriptive metadata - assert modmd.summary == "A Django web application for enterprise scalable realtime graphing" - assert modmd.description == ( - "Graphite consists of a storage backend and a web-based visualization frontend.\n" - "Client applications send streams of numeric time-series data to the Graphite\n" - "backend (called carbon), where it gets stored in fixed-size database files\n" - "similar in design to RRD. The web frontend provides user interfaces\n" - "for visualizing this data in graphs as well as a simple URL-based API for\n" - "direct graph generation.\n\n" - "Graphite's design is focused on providing simple interfaces (both to users and\n" - "applications), real-time visualization, high-availability, and enterprise\n" - "scalability." - ) + assert modmd.summary == "Generated module for graphite-web" + assert modmd.description == "Module auto-generated by fedmod" # Expected licenses assert modmd.module_licenses == {'MIT'} - assert modmd.content_licenses == {'ASL 2.0'} + assert modmd.content_licenses == set() # Only given modules are listed in the public API assert sorted(modmd.api.rpms) == sorted(input_rpms)