123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- import json
- import re
- from functools import cmp_to_key
- from .semver import Version, VersionRange
- class ErmJsonLite(object):
- """
- Basic implementation to read `erm-packages.json`.
- It doesn't use any models, works with only raw JSON types: lists, dicts, strings
- """
- class ResourceType(object):
- NPM_PACKAGE = "NPM_PACKAGE"
- NODE_JS = "NODE_JS"
- data = None
- @staticmethod
- def get_versions_of(er_resource):
- # type: (dict) -> list[Version]
- """
- Return all versions of the resource in ASC order (from older to latest)
- """
- unsorted = er_resource.get("versions").keys()
- # We have to sort because in python 2 the order of keys in a dict is not guaranteed
- versions = sorted(unsorted, key=cmp_to_key(Version.cmp))
- return [Version.from_str(v) for v in versions]
- @classmethod
- def load(cls, path):
- # type: (str) -> ErmJsonLite
- erm_json = cls()
- with open(path, encoding='utf-8') as f:
- erm_json.data = dict()
- for k, v in json.load(f).items():
- # Ignore comments (when key starts with `_`), used for banner
- if not k.startswith("_"):
- erm_json.data[k] = v
- return erm_json
- @staticmethod
- def canonize_name(resource_name):
- # type: (str) -> str
- """
- Canonize resource name
- For example:
- hermione -> hermione
- super-package -> super_package
- @yatool/nots -> yatool_nots
- """
- return re.sub(r"\W+", "_", resource_name).strip("_")
- def get_resource(self, resource_name):
- # type: (str) -> dict
- """
- Return resource by his name
- """
- er_resource = self.data.get(resource_name)
- if not er_resource:
- raise Exception("Requested resource {} is not a toolchain item".format(resource_name))
- return er_resource
- def get_sb_resources(self, resource_name, version):
- # type: (str, Version) -> list[dict]
- """
- Return a list of SB resources for ER version
- """
- er_resource = self.get_resource(resource_name)
- return er_resource.get("versions").get(str(version)).get("resources")
- def is_resource_multiplatform(self, resource_name):
- # type: (str) -> bool
- """
- Return True if resource is multiplatform, False otherwise
- """
- er_resource = self.get_resource(resource_name)
- return er_resource.get("multiplatform", False)
- def list_npm_packages(self):
- # type: () -> list[str]
- """
- Returns a list of the names of the npm tools used in the toolchain
- """
- result = []
- for resource_name, resource in self.data.items():
- if resource.get("type") == self.ResourceType.NPM_PACKAGE:
- result.append(resource_name)
- return result
- def select_version_of(self, resource_name, range_str=None):
- # type: (str, str|None) -> Version|None
- er_resource = self.get_resource(resource_name)
- if range_str is None:
- return Version.from_str(er_resource.get("default"))
- version_range = VersionRange.from_str(range_str)
- # assuming the version list is sorted from the lowest to the highest version,
- # we stop the loop as early as possible and hence return the lowest compatible version
- for version in self.get_versions_of(er_resource):
- if version_range.is_satisfied_by(version):
- return version
- return None
- def use_resource_directly(self, resource_name):
- # type: (str) -> bool
- er_resource = self.get_resource(resource_name)
- return er_resource.get("useDirectly", False)
|