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,
|
||||
RPackageRequirement,
|
||||
OctavePackageRequirement,
|
||||
PhpPackageRequirement,
|
||||
)
|
||||
from .fix_build import run_with_build_fixers
|
||||
from .session import which
|
||||
|
@ -98,6 +99,16 @@ class BuildSystem(object):
|
|||
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):
|
||||
|
||||
name = "pear"
|
||||
|
@ -130,6 +141,32 @@ class Pear(BuildSystem):
|
|||
self.setup(resolver)
|
||||
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
|
||||
def probe(cls, path):
|
||||
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"))
|
||||
|
||||
|
||||
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):
|
||||
|
||||
name = "perl-build-tiny"
|
||||
|
@ -1254,7 +1308,7 @@ BUILDSYSTEM_CLSES = [
|
|||
Pear, SetupPy, Npm, Waf, Cargo, Meson, Cabal, Gradle, Maven,
|
||||
DistZilla, Gem, PerlBuildTiny, Golang, R, Octave,
|
||||
# Make is intentionally at the end of the list.
|
||||
Make, RunTests]
|
||||
Make, Composer, RunTests]
|
||||
|
||||
|
||||
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):
|
||||
fixed_errors = []
|
||||
while True:
|
||||
to_resolve = []
|
||||
try:
|
||||
run_detecting_problems(session, args, **kwargs)
|
||||
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)
|
||||
if e.error in fixed_errors:
|
||||
logging.warning(
|
||||
"Failed to resolve error %r, it persisted. Giving up.", e.error
|
||||
)
|
||||
raise DetailedFailure(e.retcode, args, e.error)
|
||||
if not resolve_error(e.error, None, fixers=fixers):
|
||||
logging.warning("Failed to find resolution for error %r. Giving up.", e.error)
|
||||
raise DetailedFailure(e.retcode, args, e.error)
|
||||
fixed_errors.append(e.error)
|
||||
else:
|
||||
return
|
||||
raise e
|
||||
try:
|
||||
if not resolve_error(e.error, None, fixers=fixers):
|
||||
logging.warning("Failed to find resolution for error %r. Giving up.", e.error)
|
||||
raise e
|
||||
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:
|
||||
fixed_errors.append(e.error)
|
||||
|
||||
|
||||
|
||||
def resolve_error(error, phase, fixers):
|
||||
|
|
|
@ -80,6 +80,22 @@ class PythonPackageRequirement(Requirement):
|
|||
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):
|
||||
|
||||
binary_name: str
|
||||
|
|
|
@ -41,6 +41,7 @@ from ..requirements import (
|
|||
GoPackageRequirement,
|
||||
DhAddonRequirement,
|
||||
PhpClassRequirement,
|
||||
PhpPackageRequirement,
|
||||
RPackageRequirement,
|
||||
NodeModuleRequirement,
|
||||
NodePackageRequirement,
|
||||
|
@ -315,6 +316,10 @@ def resolve_php_class_req(apt_mgr, req):
|
|||
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):
|
||||
paths = [posixpath.join("/usr/lib/R/site-library/.*/R/%s$" % re.escape(req.package))]
|
||||
return find_reqs_simple(apt_mgr, paths, regex=True)
|
||||
|
@ -560,6 +565,7 @@ APT_REQUIREMENT_RESOLVERS = [
|
|||
(GoPackageRequirement, resolve_go_package_req),
|
||||
(DhAddonRequirement, resolve_dh_addon_req),
|
||||
(PhpClassRequirement, resolve_php_class_req),
|
||||
(PhpPackageRequirement, resolve_php_package_req),
|
||||
(RPackageRequirement, resolve_r_package_req),
|
||||
(NodeModuleRequirement, resolve_node_module_req),
|
||||
(NodePackageRequirement, resolve_node_package_req),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue