Add basic support for octave forge.

This commit is contained in:
Jelmer Vernooij 2021-03-22 14:49:08 +00:00
parent 24e417650a
commit 7f55169fc6
No known key found for this signature in database
GPG key ID: 579C160D4C9E23E8
3 changed files with 97 additions and 4 deletions

View file

@ -36,6 +36,7 @@ from .requirements import (
NodePackageRequirement,
CargoCrateRequirement,
RPackageRequirement,
OctavePackageRequirement,
)
from .fix_build import run_with_build_fixers
@ -453,9 +454,7 @@ class Octave(BuildSystem):
@classmethod
def exists(cls, path):
if not (
os.path.exists(os.path.join(path, "DESCRIPTION")) and
os.path.exists(os.path.join(path, "COPYING"))):
if not os.path.exists(os.path.join(path, "DESCRIPTION")):
return False
# Urgh, isn't there a better way to see if this is an octave package?
for entry in os.scandir(path):
@ -471,9 +470,23 @@ class Octave(BuildSystem):
@classmethod
def probe(cls, path):
if cls.exists(path):
logging.debug("Found DESCRIPTION and COPYING, assuming octave package.")
logging.debug("Found DESCRIPTION, assuming octave package.")
return cls(path)
def _read_description(self):
path = os.path.join(self.path, 'DESCRIPTION')
from email.parser import BytesParser
with open(path, 'rb') as f:
return BytesParser().parse(f)
def get_declared_dependencies(self, session, fixers=None):
def parse_list(t):
return [s.strip() for s in t.split(',') if s.strip()]
description = self._read_description()
if 'Depends' in description:
for s in parse_list(description['Depends']):
yield "build", OctavePackageRequirement.from_str(s)
class Gradle(BuildSystem):

View file

@ -278,6 +278,41 @@ class RPackageRequirement(Requirement):
raise ValueError(text)
class OctavePackageRequirement(Requirement):
package: str
minimum_version: Optional[str]
def __init__(self, package: str, minimum_version: Optional[str] = None):
super(OctavePackageRequirement, self).__init__("octave-package")
self.package = package
self.minimum_version = minimum_version
def __repr__(self):
return "%s(%r, minimum_version=%r)" % (
type(self).__name__,
self.package,
self.minimum_version,
)
def __str__(self):
if self.minimum_version:
return "Octave package: %s (>= %s)" % (self.package, self.minimum_version)
else:
return "Octave package: %s" % (self.package,)
@classmethod
def from_str(cls, text):
# TODO(jelmer): More complex parser
m = re.fullmatch(r'(.*) \(>= (.*)\)', text)
if m:
return cls(m.group(1), m.group(2))
m = re.fullmatch(r'([^ ]+)', text)
if m:
return cls(m.group(1))
raise ValueError(text)
class LibraryRequirement(Requirement):
library: str

View file

@ -132,6 +132,50 @@ class RResolver(Resolver):
raise UnsatisfiedRequirements(missing)
class OctaveForgeResolver(Resolver):
def __init__(self, session, user_local=False):
self.session = session
self.user_local = user_local
def __str__(self):
return "octave-forge"
def __repr__(self):
return "%s(%r)" % (type(self).__name__, self.session)
def _cmd(self, req):
# TODO(jelmer: Handle self.user_local
return ["octave-cli", "--eval", "pkg install -forge %s" % req.package]
def explain(self, requirements):
from ..requirements import OctavePackageRequirement
rreqs = []
for requirement in requirements:
if not isinstance(requirement, OctavePackageRequirement):
continue
rreqs.append(requirement)
if rreqs:
yield ([self._cmd(req) for req in rreqs])
def install(self, requirements):
from ..requirements import OctavePackageRequirement
if self.user_local:
user = None
else:
user = "root"
missing = []
for requirement in requirements:
if not isinstance(requirement, OctavePackageRequirement):
missing.append(requirement)
continue
self.session.check_call(self._cmd(requirement), user=user)
if missing:
raise UnsatisfiedRequirements(missing)
class CRANResolver(RResolver):
def __init__(self, session, user_local=False):
@ -362,6 +406,7 @@ NATIVE_RESOLVER_CLS = [
HackageResolver,
CRANResolver,
BioconductorResolver,
OctaveForgeResolver,
]