From c13fcb830638184568b6cb5b9ea5c9d8e7f58094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jelmer=20Vernoo=C4=B3?= Date: Wed, 24 Feb 2021 02:54:18 +0000 Subject: [PATCH] Move more to resolver-apt. --- ognibuild/debian/fix_build.py | 135 +++++++++++----------------------- ognibuild/requirements.py | 27 ++++++- ognibuild/resolver/apt.py | 48 ++++++++++++ 3 files changed, 118 insertions(+), 92 deletions(-) diff --git a/ognibuild/debian/fix_build.py b/ognibuild/debian/fix_build.py index d72721f..0d9e0e2 100644 --- a/ognibuild/debian/fix_build.py +++ b/ognibuild/debian/fix_build.py @@ -133,6 +133,9 @@ from ..requirements import ( MavenArtifactRequirement, GnomeCommonRequirement, JDKFileRequirement, + PerlModuleRequirement, + PerlFileRequirement, + AutoconfMacroRequirement, ) from .build import attempt_build, DEFAULT_BUILDER @@ -506,6 +509,31 @@ def fix_missing_requirement(error, context): req = GnomeCommonRequirement() elif isinstance(error, MissingJDKFile): req = JDKFileRequirement(error.jdk_path, error.filename) + elif isinstance(error, MissingGnomeCommonDependency): + if error.package == "glib-gettext": + req = BinaryRequirement('glib-gettextize') + else: + logging.warning( + "No known command for gnome-common dependency %s", + error.package) + return None + elif isinstance(error, MissingXfceDependency): + if error.package == "gtk-doc": + req = BinaryRequirement("gtkdocize") + else: + logging.warning( + "No known command for xfce dependency %s", + error.package) + return None + elif isinstance(error, MissingPerlModule): + req = PerlModuleRequirement( + module=error.module, + filename=error.filename, + inc=error.inc) + elif isinstance(error, MissingPerlFile): + req = PerlFileRequirement(filename=error.filename) + elif isinstance(error, MissingAutoconfMacro): + req = AutoconfMacroRequirement(error.macro) else: return None @@ -519,42 +547,6 @@ def fix_missing_requirement(error, context): DEFAULT_PERL_PATHS = ["/usr/share/perl5"] -def fix_missing_perl_file(error, context): - - if ( - error.filename == "Makefile.PL" - and not context.tree.has_filename("Makefile.PL") - and context.tree.has_filename("dist.ini") - ): - # TODO(jelmer): add dist-zilla add-on to debhelper - raise NotImplementedError - - if error.inc is None: - if error.filename is None: - filename = error.module.replace("::", "/") + ".pm" - paths = [os.path.join(inc, filename) for inc in DEFAULT_PERL_PATHS] - elif not os.path.isabs(error.filename): - return False - else: - paths = [error.filename] - else: - paths = [os.path.join(inc, error.filename) for inc in error.inc] - package = context.apt.get_package_for_paths(paths, regex=False) - if package is None: - if getattr(error, "module", None): - logging.warning( - "no perl package found for %s (%r).", error.module, error.filename - ) - else: - logging.warning( - "perl file %s not found (paths searched for: %r).", - error.filename, - paths, - ) - return False - return context.add_dependency(package) - - def retry_apt_failure(error, context): return True @@ -593,30 +585,6 @@ def fix_missing_automake_input(error, context): return enable_dh_autoreconf(context) -def install_gnome_common_dep(error, context): - if error.package == "glib-gettext": - package = context.apt.get_package_for_paths(["/usr/bin/glib-gettextize"]) - else: - package = None - if package is None: - logging.warning("No debian package for package %s", error.package) - return False - return context.add_dependency( - package=package, minimum_version=error.minimum_version - ) - - -def install_xfce_dep(error, context): - if error.package == "gtk-doc": - package = context.apt.get_package_for_paths(["/usr/bin/gtkdocize"]) - else: - package = None - if package is None: - logging.warning("No debian package for package %s", error.package) - return False - return context.add_dependency(package=package) - - def fix_missing_config_status_input(error, context): autogen_path = "autogen.sh" rules_path = "debian/rules" @@ -648,19 +616,6 @@ def fix_missing_config_status_input(error, context): return True -def _find_aclocal_fun(macro): - # TODO(jelmer): Use the API for codesearch.debian.net instead? - defun_prefix = b"AC_DEFUN([%s]," % macro.encode("ascii") - for entry in os.scandir("/usr/share/aclocal"): - if not entry.is_file(): - continue - with open(entry.path, "rb") as f: - for line in f: - if line.startswith(defun_prefix): - return entry.path - raise KeyError - - def run_pgbuildext_updatecontrol(error, context): logging.info("Running 'pg_buildext updatecontrol'") # TODO(jelmer): run in the schroot @@ -674,17 +629,15 @@ def run_pgbuildext_updatecontrol(error, context): ) -def fix_missing_autoconf_macro(error, context): - try: - path = _find_aclocal_fun(error.macro) - except KeyError: - logging.info("No local m4 file found defining %s", error.macro) - return False - package = context.apt.get_package_for_paths([path]) - if package is None: - logging.warning("no package for macro file %s", path) - return False - return context.add_dependency(package) +def fix_missing_makefile_pl(error, context): + if ( + error.filename == "Makefile.PL" + and not context.tree.has_filename("Makefile.PL") + and context.tree.has_filename("dist.ini") + ): + # TODO(jelmer): add dist-zilla add-on to debhelper + raise NotImplementedError + return False VERSIONED_PACKAGE_FIXERS: List[ @@ -699,17 +652,17 @@ VERSIONED_PACKAGE_FIXERS: List[ APT_FIXERS: List[Tuple[Type[Problem], Callable[[Problem, DependencyContext], bool]]] = [ (MissingPythonModule, fix_missing_python_module), (MissingPythonDistribution, fix_missing_python_distribution), - (MissingPerlFile, fix_missing_perl_file), - (MissingPerlModule, fix_missing_perl_file), (AptFetchFailure, retry_apt_failure), - (MissingGnomeCommonDependency, install_gnome_common_dep), - (MissingXfceDependency, install_xfce_dep), - (MissingConfigStatusInput, fix_missing_config_status_input), - (MissingAutoconfMacro, fix_missing_autoconf_macro), + (MissingPerlFile, fix_missing_makefile_pl), (Problem, fix_missing_requirement), ] +GENERIC_FIXERS: List[Tuple[Type[Problem], Callable[[Problem, DependencyContext], bool]]] = [ + (MissingConfigStatusInput, fix_missing_config_status_input), +] + + def resolve_error(error, context, fixers): relevant_fixers = [] for error_cls, fixer in fixers: @@ -793,7 +746,7 @@ def build_incrementally( raise try: if not resolve_error( - e.error, context, VERSIONED_PACKAGE_FIXERS + APT_FIXERS + e.error, context, VERSIONED_PACKAGE_FIXERS + APT_FIXERS + GENERIC_FIXERS ): logging.warning("Failed to resolve error %r. Giving up.", e.error) raise diff --git a/ognibuild/requirements.py b/ognibuild/requirements.py index 98d929c..45c176a 100644 --- a/ognibuild/requirements.py +++ b/ognibuild/requirements.py @@ -43,10 +43,17 @@ class BinaryRequirement(UpstreamRequirement): class PerlModuleRequirement(UpstreamRequirement): module: str + filename: Optional[str] + inc: Optional[List[str]] - def __init__(self, module): + def __init__(self, module, filename=None, inc=None): super(PerlModuleRequirement, self).__init__('perl-module') self.module = module + self.filename = filename + self.inc = inc + + def relfilename(self): + return self.module.replace("::", "/") + ".pm" class NodePackageRequirement(UpstreamRequirement): @@ -244,3 +251,21 @@ class JDKFileRequirement(UpstreamRequirement): @property def path(self): return posixpath.join(self.jdk_path, self.filename) + + +class PerlFileRequirement(UpstreamRequirement): + + filename: str + + def __init__(self, filename: str): + super(PerlFileRequirement, self).__init__('perl-file') + self.filename = filename + + +class AutoconfMacroRequirement(UpstreamRequirement): + + macro: str + + def __init__(self, macro: str): + super(AutoconfMacroRequirement, self).__init__('autoconf-macro') + self.macro = macro diff --git a/ognibuild/resolver/apt.py b/ognibuild/resolver/apt.py index 7d8e444..6864119 100644 --- a/ognibuild/resolver/apt.py +++ b/ognibuild/resolver/apt.py @@ -44,6 +44,9 @@ from ..requirements import ( MavenArtifactRequirement, GnomeCommonRequirement, JDKFileRequirement, + PerlModuleRequirement, + PerlFileRequirement, + AutoconfMacroRequirement, ) @@ -308,6 +311,48 @@ def resolve_jdk_file_req(apt_mgr, req): return apt_mgr.get_package_for_paths([path], regex=True) +def resolve_perl_module_req(apt_mgr, req): + DEFAULT_PERL_PATHS = ["/usr/share/perl5"] + + if req.inc is None: + if req.filename is None: + paths = [posixpath.join(inc, req.relfilename) + for inc in DEFAULT_PERL_PATHS] + elif not posixpath.isabs(req.filename): + return False + else: + paths = [req.filename] + else: + paths = [posixpath.join(inc, req.filename) for inc in req.inc] + return apt_mgr.get_package_for_paths(paths, regex=False) + + +def resolve_perl_file_req(apt_mgr, req): + return apt_mgr.get_package_for_paths([req.filename], regex=False) + + +def _find_aclocal_fun(macro): + # TODO(jelmer): Use the API for codesearch.debian.net instead? + defun_prefix = b"AC_DEFUN([%s]," % macro.encode("ascii") + for entry in os.scandir("/usr/share/aclocal"): + if not entry.is_file(): + continue + with open(entry.path, "rb") as f: + for line in f: + if line.startswith(defun_prefix): + return entry.path + raise KeyError + + +def resolve_autoconf_macro_req(apt_mgr, req): + try: + path = _find_aclocal_fun(req.macro) + except KeyError: + logging.info("No local m4 file found defining %s", req.macro) + return None + return apt_mgr.get_package_for_paths([path]) + + APT_REQUIREMENT_RESOLVERS = [ (BinaryRequirement, resolve_binary_req), (PkgConfigRequirement, resolve_pkg_config_req), @@ -330,6 +375,9 @@ APT_REQUIREMENT_RESOLVERS = [ (MavenArtifactRequirement, resolve_maven_artifact_req), (GnomeCommonRequirement, resolve_gnome_common_req), (JDKFileRequirement, resolve_jdk_file_req), + (PerlModuleRequirement, resolve_perl_module_req), + (PerlFileRequirement, resolve_perl_file_req), + (AutoconfMacroRequirement, resolve_autoconf_macro_req), ]