diff --git a/ognibuild/__main__.py b/ognibuild/__main__.py index af14c31..3a40ef1 100644 --- a/ognibuild/__main__.py +++ b/ognibuild/__main__.py @@ -35,8 +35,8 @@ def get_necessary_declared_requirements(resolver, requirements, stages): return missing -def install_necessary_declared_requirements(resolver, buildsystem, stages): - missing = [] +def install_necessary_declared_requirements(session, resolver, buildsystem, stages): + relevant = [] try: declared_reqs = list(buildsystem.get_declared_dependencies()) except NotImplementedError: @@ -44,10 +44,18 @@ def install_necessary_declared_requirements(resolver, buildsystem, stages): "Unable to determine declared dependencies from %s", buildsystem ) else: - missing.extend( + relevant.extend( get_necessary_declared_requirements(resolver, declared_reqs, stages) ) - resolver.install(missing) + missing = [] + for req in relevant: + try: + if not req.met(session): + missing.append(req) + except NotImplementedError: + missing.append(req) + if missing: + resolver.install(missing) # Types of dependencies: @@ -141,7 +149,7 @@ def main(): # noqa: C901 if stages: logging.info("Checking that declared requirements are present") for bs in bss: - install_necessary_declared_requirements(resolver, bs, stages) + install_necessary_declared_requirements(session, resolver, bs, stages) fixers = determine_fixers(session, resolver) if args.subcommand == "dist": from .dist import run_dist diff --git a/ognibuild/buildlog.py b/ognibuild/buildlog.py index 8a8c1e3..33d51ed 100644 --- a/ognibuild/buildlog.py +++ b/ognibuild/buildlog.py @@ -120,7 +120,7 @@ def problem_to_upstream_requirement(problem): # noqa: C901 elif isinstance(problem, MissingJavaClass): return JavaClassRequirement(problem.classname) elif isinstance(problem, MissingHaskellDependencies): - return [HaskellPackageRequirement(dep) for dep in problem.deps] + return [HaskellPackageRequirement.from_string(dep) for dep in problem.deps] elif isinstance(problem, MissingMavenArtifacts): return [MavenArtifactRequirement(artifact) for artifact in problem.artifacts] elif isinstance(problem, MissingCSharpCompiler): diff --git a/ognibuild/buildsystem.py b/ognibuild/buildsystem.py index a951ee7..5291b4f 100644 --- a/ognibuild/buildsystem.py +++ b/ognibuild/buildsystem.py @@ -633,6 +633,9 @@ class Cabal(BuildSystem): def test(self, session, resolver, fixers): self._run(session, ["test"], fixers) + def dist(self, session, resolver, fixers, quiet=False): + self._run(session, ["sdist"], fixers) + def detect_buildsystems(path, trust_package=False): # noqa: C901 """Detect build systems.""" diff --git a/ognibuild/requirements.py b/ognibuild/requirements.py index 560ad29..2f3673f 100644 --- a/ognibuild/requirements.py +++ b/ognibuild/requirements.py @@ -17,6 +17,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import posixpath +import subprocess from typing import Optional, List, Tuple from . import Requirement @@ -55,6 +56,26 @@ class PythonPackageRequirement(Requirement): req = Requirement.parse(text) return cls(package=req.name, specs=req.specs) + def met(self, session): + if self.python_version == "cpython3": + cmd = "python3" + elif self.python_version == "cpython2": + cmd = "python2" + elif self.python_version == "pypy": + cmd = "pypy" + elif self.python_version == "pypy3": + cmd = "pypy3" + elif self.python_version is None: + cmd = "python3" + else: + raise NotImplementedError + text = self.package + ','.join([''.join(spec) for spec in self.specs]) + p = session.Popen( + [cmd, "-c", "import pkg_resources; pkg_resources.require(%r)" % text], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + p.communicate() + return p.returncode == 0 + class BinaryRequirement(Requirement): @@ -64,6 +85,13 @@ class BinaryRequirement(Requirement): super(BinaryRequirement, self).__init__("binary") self.binary_name = binary_name + def met(self, session): + p = session.Popen( + ["which", self.binary_name], stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL) + p.communicate() + return p.returncode == 0 + class PerlModuleRequirement(Requirement): @@ -250,9 +278,15 @@ class HaskellPackageRequirement(Requirement): package: str - def __init__(self, package: str): + def __init__(self, package: str, specs=None): super(HaskellPackageRequirement, self).__init__("haskell-package") self.package = package + self.specs = specs + + @classmethod + def from_string(cls, text): + parts = text.split() + return cls(parts[0], specs=parts[1:]) class MavenArtifactRequirement(Requirement): @@ -312,3 +346,22 @@ class PythonModuleRequirement(Requirement): super(PythonModuleRequirement, self).__init__("python-module") self.python_version = python_version self.minimum_version = minimum_version + + def met(self, session): + if self.python_version == "cpython3": + cmd = "python3" + elif self.python_version == "cpython2": + cmd = "python2" + elif self.python_version == "pypy": + cmd = "pypy" + elif self.python_version == "pypy3": + cmd = "pypy3" + elif self.python_version is None: + cmd = "python3" + else: + raise NotImplementedError + p = session.Popen( + [cmd, "-c", "import %s" % self.module], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + p.communicate() + return p.returncode == 0 diff --git a/ognibuild/resolver/__init__.py b/ognibuild/resolver/__init__.py index 8eca42c..0bd5c24 100644 --- a/ognibuild/resolver/__init__.py +++ b/ognibuild/resolver/__init__.py @@ -56,7 +56,6 @@ class CPANResolver(Resolver): # TODO(jelmer): Specify -T to skip tests? self.session.check_call( ["cpan", "-i", requirement.module], - user="root", env={"PERL_MM_USE_DEFAULT": "1"}, ) if missing: @@ -85,7 +84,7 @@ class HackageResolver(Resolver): missing.append(requirement) continue self.session.check_call( - ["cabal", "install", requirement.package], user="root" + ["cabal", "install", requirement.package] ) if missing: raise UnsatisfiedRequirements(missing)