From 97da5ea6bda42636f5c0e6802672dfea66f8b65c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jelmer=20Vernoo=C4=B3?= Date: Thu, 18 Mar 2021 14:59:57 +0000 Subject: [PATCH] Add R/CRAN support. --- README.md | 2 ++ ognibuild/buildsystem.py | 24 ++++++++++++++++++++- ognibuild/resolver/__init__.py | 39 ++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 39b2ddc..61dae9e 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ issues (or lack of support for a particular ecosystem), please file a bug. - Module::Build::Tiny - PHP Pear - Python - setup.py/setup.cfg/pyproject.toml +- R - Ruby gems - Waf @@ -69,6 +70,7 @@ The following "native" repositories are supported: - hackage - npm - cargo +- cran - golang\* As well one distribution repository: diff --git a/ognibuild/buildsystem.py b/ognibuild/buildsystem.py index b1a9320..fe245a9 100644 --- a/ognibuild/buildsystem.py +++ b/ognibuild/buildsystem.py @@ -363,6 +363,28 @@ class Gradle(BuildSystem): session, [self.executable, "installDist"], fixers) +class R(BuildSystem): + + name = "R" + + def __init__(self, path): + self.path = path + + def __repr__(self): + return "%s(%r)" % (type(self).__name__, self.path) + + def build(self, session, resolver, fixers): + run_with_build_fixers(session, ["R", "CMD", "build", "."], fixers) + + def test(self, session, resolver, fixers): + run_with_build_fixers(session, ["R", "CMD", "test", "."], fixers) + + @classmethod + def probe(cls, path): + if os.path.exists(os.path.join(path, 'DESCRIPTION')): + return cls(path) + + class Meson(BuildSystem): name = "meson" @@ -868,7 +890,7 @@ class PerlBuildTiny(BuildSystem): BUILDSYSTEM_CLSES = [ Pear, SetupPy, Npm, Waf, Cargo, Meson, Cabal, Gradle, Maven, - DistInkt, Gem, Make, PerlBuildTiny, Golang] + DistInkt, Gem, Make, PerlBuildTiny, Golang, R] def detect_buildsystems(path, trust_package=False): diff --git a/ognibuild/resolver/__init__.py b/ognibuild/resolver/__init__.py index 4dacd35..a0c0e71 100644 --- a/ognibuild/resolver/__init__.py +++ b/ognibuild/resolver/__init__.py @@ -76,6 +76,44 @@ class CPANResolver(Resolver): raise UnsatisfiedRequirements(missing) +class CRANResolver(Resolver): + def __init__(self, session, repos='"http://cran.r-project.org'): + self.session = session + self.repos = repos + + def __str__(self): + return "cran" + + def __repr__(self): + return "%s(%r, %r)" % (type(self).__name__, self.session, self.repos) + + def _cmd(self, req): + return ["R", "-e", "install.packages('%s', repos=%r)" % (req.package, self.repos)] + + def explain(self, requirements): + from ..requirements import RPackageRequirement + + rreqs = [] + for requirement in requirements: + if not isinstance(requirement, RPackageRequirement): + continue + rreqs.append(requirement) + if rreqs: + yield ([self._cmd(req) for req in rreqs]) + + def install(self, requirements): + from ..requirements import RPackageRequirement + + missing = [] + for requirement in requirements: + if not isinstance(requirement, RPackageRequirement): + missing.append(requirement) + continue + self.session.check_call(self._cmd(requirement)) + if missing: + raise UnsatisfiedRequirements(missing) + + class HackageResolver(Resolver): def __init__(self, session): self.session = session @@ -268,6 +306,7 @@ NATIVE_RESOLVER_CLS = [ NpmResolver, GoResolver, HackageResolver, + CRANResolver, ]