Add support for composer.
This commit is contained in:
parent
f75d4b6cb3
commit
0688a0cbba
4 changed files with 97 additions and 8 deletions
|
@ -40,6 +40,7 @@ from .requirements import (
|
||||||
CargoCrateRequirement,
|
CargoCrateRequirement,
|
||||||
RPackageRequirement,
|
RPackageRequirement,
|
||||||
OctavePackageRequirement,
|
OctavePackageRequirement,
|
||||||
|
PhpPackageRequirement,
|
||||||
)
|
)
|
||||||
from .fix_build import run_with_build_fixers
|
from .fix_build import run_with_build_fixers
|
||||||
from .session import which
|
from .session import which
|
||||||
|
@ -98,6 +99,16 @@ class BuildSystem(object):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def xmlparse_simplify_namespaces(path, namespaces):
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
namespaces = ['{%s}' % ns for ns in namespaces]
|
||||||
|
tree = ET.iterparse(path)
|
||||||
|
for _, el in tree:
|
||||||
|
for namespace in namespaces:
|
||||||
|
el.tag = el.tag.replace(namespace, '')
|
||||||
|
return tree.root
|
||||||
|
|
||||||
|
|
||||||
class Pear(BuildSystem):
|
class Pear(BuildSystem):
|
||||||
|
|
||||||
name = "pear"
|
name = "pear"
|
||||||
|
@ -130,6 +141,32 @@ class Pear(BuildSystem):
|
||||||
self.setup(resolver)
|
self.setup(resolver)
|
||||||
run_with_build_fixers(session, ["pear", "install", self.path], fixers)
|
run_with_build_fixers(session, ["pear", "install", self.path], fixers)
|
||||||
|
|
||||||
|
def get_declared_dependencies(self, session, fixers=None):
|
||||||
|
path = os.path.join(self.path, "package.xml")
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
try:
|
||||||
|
root = xmlparse_simplify_namespaces(path, [
|
||||||
|
'http://pear.php.net/dtd/package-2.0',
|
||||||
|
'http://pear.php.net/dtd/package-2.1'])
|
||||||
|
except ET.ParseError as e:
|
||||||
|
logging.warning('Unable to parse package.xml: %s', e)
|
||||||
|
return
|
||||||
|
assert root.tag == 'package', 'root tag is %r' % root.tag
|
||||||
|
dependencies_tag = root.find('dependencies')
|
||||||
|
if dependencies_tag is not None:
|
||||||
|
required_tag = root.find('dependencies')
|
||||||
|
if required_tag is not None:
|
||||||
|
for package_tag in root.findall('package'):
|
||||||
|
name = package_tag.find('name').text
|
||||||
|
min_tag = package_tag.find('min')
|
||||||
|
max_tag = package_tag.find('max')
|
||||||
|
channel_tag = package_tag.find('channel')
|
||||||
|
yield "core", PhpPackageRequirement(
|
||||||
|
name,
|
||||||
|
channel=(channel_tag.text if channel_tag else None),
|
||||||
|
min_version=(min_tag.text if min_tag else None),
|
||||||
|
max_version=(max_tag.text if max_tag else None))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def probe(cls, path):
|
def probe(cls, path):
|
||||||
if os.path.exists(os.path.join(path, "package.xml")):
|
if os.path.exists(os.path.join(path, "package.xml")):
|
||||||
|
@ -1214,6 +1251,23 @@ class Cabal(BuildSystem):
|
||||||
return cls(os.path.join(path, "Setup.hs"))
|
return cls(os.path.join(path, "Setup.hs"))
|
||||||
|
|
||||||
|
|
||||||
|
class Composer(BuildSystem):
|
||||||
|
|
||||||
|
name = "composer"
|
||||||
|
|
||||||
|
def __init__(self, path):
|
||||||
|
self.path = path
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "%s(%r)" % (type(self).__name__, self.path)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def probe(cls, path):
|
||||||
|
if os.path.exists(os.path.join(path, "composer.json")):
|
||||||
|
logging.debug("Found composer.json, assuming composer package.")
|
||||||
|
return cls(path)
|
||||||
|
|
||||||
|
|
||||||
class PerlBuildTiny(BuildSystem):
|
class PerlBuildTiny(BuildSystem):
|
||||||
|
|
||||||
name = "perl-build-tiny"
|
name = "perl-build-tiny"
|
||||||
|
@ -1254,7 +1308,7 @@ BUILDSYSTEM_CLSES = [
|
||||||
Pear, SetupPy, Npm, Waf, Cargo, Meson, Cabal, Gradle, Maven,
|
Pear, SetupPy, Npm, Waf, Cargo, Meson, Cabal, Gradle, Maven,
|
||||||
DistZilla, Gem, PerlBuildTiny, Golang, R, Octave,
|
DistZilla, Gem, PerlBuildTiny, Golang, R, Octave,
|
||||||
# Make is intentionally at the end of the list.
|
# Make is intentionally at the end of the list.
|
||||||
Make, RunTests]
|
Make, Composer, RunTests]
|
||||||
|
|
||||||
|
|
||||||
def scan_buildsystems(path):
|
def scan_buildsystems(path):
|
||||||
|
|
|
@ -69,21 +69,34 @@ def run_detecting_problems(session: Session, args: List[str], **kwargs):
|
||||||
def run_with_build_fixers(session: Session, args: List[str], fixers: List[BuildFixer], **kwargs):
|
def run_with_build_fixers(session: Session, args: List[str], fixers: List[BuildFixer], **kwargs):
|
||||||
fixed_errors = []
|
fixed_errors = []
|
||||||
while True:
|
while True:
|
||||||
|
to_resolve = []
|
||||||
try:
|
try:
|
||||||
run_detecting_problems(session, args, **kwargs)
|
run_detecting_problems(session, args, **kwargs)
|
||||||
except DetailedFailure as e:
|
except DetailedFailure as e:
|
||||||
|
to_resolve.append(e)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
while to_resolve:
|
||||||
|
e = to_resolve.pop(-1)
|
||||||
logging.info("Identified error: %r", e.error)
|
logging.info("Identified error: %r", e.error)
|
||||||
if e.error in fixed_errors:
|
if e.error in fixed_errors:
|
||||||
logging.warning(
|
logging.warning(
|
||||||
"Failed to resolve error %r, it persisted. Giving up.", e.error
|
"Failed to resolve error %r, it persisted. Giving up.", e.error
|
||||||
)
|
)
|
||||||
raise DetailedFailure(e.retcode, args, e.error)
|
raise e
|
||||||
|
try:
|
||||||
if not resolve_error(e.error, None, fixers=fixers):
|
if not resolve_error(e.error, None, fixers=fixers):
|
||||||
logging.warning("Failed to find resolution for error %r. Giving up.", e.error)
|
logging.warning("Failed to find resolution for error %r. Giving up.", e.error)
|
||||||
raise DetailedFailure(e.retcode, args, e.error)
|
raise e
|
||||||
fixed_errors.append(e.error)
|
except DetailedFailure as n:
|
||||||
|
logging.info('New error %r while resolving %r', n, e)
|
||||||
|
if n in to_resolve:
|
||||||
|
raise
|
||||||
|
to_resolve.append(e)
|
||||||
|
to_resolve.append(n)
|
||||||
else:
|
else:
|
||||||
return
|
fixed_errors.append(e.error)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def resolve_error(error, phase, fixers):
|
def resolve_error(error, phase, fixers):
|
||||||
|
|
|
@ -80,6 +80,22 @@ class PythonPackageRequirement(Requirement):
|
||||||
return p.returncode == 0
|
return p.returncode == 0
|
||||||
|
|
||||||
|
|
||||||
|
class PhpPackageRequirement(Requirement):
|
||||||
|
|
||||||
|
def __init__(self, package: str, channel: Optional[str] = None,
|
||||||
|
min_version: Optional[str] = None,
|
||||||
|
max_version: Optional[str] = None):
|
||||||
|
self.package = package
|
||||||
|
self.channel = channel
|
||||||
|
self.min_version = min_version
|
||||||
|
self.max_version = max_version
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "%s(%r, %r, %r, %r)" % (
|
||||||
|
type(self).__name__, self.package, self.channel,
|
||||||
|
self.min_version, self.max_version)
|
||||||
|
|
||||||
|
|
||||||
class BinaryRequirement(Requirement):
|
class BinaryRequirement(Requirement):
|
||||||
|
|
||||||
binary_name: str
|
binary_name: str
|
||||||
|
|
|
@ -41,6 +41,7 @@ from ..requirements import (
|
||||||
GoPackageRequirement,
|
GoPackageRequirement,
|
||||||
DhAddonRequirement,
|
DhAddonRequirement,
|
||||||
PhpClassRequirement,
|
PhpClassRequirement,
|
||||||
|
PhpPackageRequirement,
|
||||||
RPackageRequirement,
|
RPackageRequirement,
|
||||||
NodeModuleRequirement,
|
NodeModuleRequirement,
|
||||||
NodePackageRequirement,
|
NodePackageRequirement,
|
||||||
|
@ -315,6 +316,10 @@ def resolve_php_class_req(apt_mgr, req):
|
||||||
return find_reqs_simple(apt_mgr, [path])
|
return find_reqs_simple(apt_mgr, [path])
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_php_package_req(apt_mgr, req):
|
||||||
|
return [AptRequirement.simple('php-%s' % req.package, minimum_version=req.min_version)]
|
||||||
|
|
||||||
|
|
||||||
def resolve_r_package_req(apt_mgr, req):
|
def resolve_r_package_req(apt_mgr, req):
|
||||||
paths = [posixpath.join("/usr/lib/R/site-library/.*/R/%s$" % re.escape(req.package))]
|
paths = [posixpath.join("/usr/lib/R/site-library/.*/R/%s$" % re.escape(req.package))]
|
||||||
return find_reqs_simple(apt_mgr, paths, regex=True)
|
return find_reqs_simple(apt_mgr, paths, regex=True)
|
||||||
|
@ -560,6 +565,7 @@ APT_REQUIREMENT_RESOLVERS = [
|
||||||
(GoPackageRequirement, resolve_go_package_req),
|
(GoPackageRequirement, resolve_go_package_req),
|
||||||
(DhAddonRequirement, resolve_dh_addon_req),
|
(DhAddonRequirement, resolve_dh_addon_req),
|
||||||
(PhpClassRequirement, resolve_php_class_req),
|
(PhpClassRequirement, resolve_php_class_req),
|
||||||
|
(PhpPackageRequirement, resolve_php_package_req),
|
||||||
(RPackageRequirement, resolve_r_package_req),
|
(RPackageRequirement, resolve_r_package_req),
|
||||||
(NodeModuleRequirement, resolve_node_module_req),
|
(NodeModuleRequirement, resolve_node_module_req),
|
||||||
(NodePackageRequirement, resolve_node_package_req),
|
(NodePackageRequirement, resolve_node_package_req),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue