mirror of
https://github.com/platformio/platformio-core.git
synced 2025-07-30 10:07:14 +02:00
Add manifest parsers for platform.json and package.json
This commit is contained in:
@ -172,7 +172,12 @@ class DataModel(object):
|
|||||||
setattr(self, name, value)
|
setattr(self, name, value)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
raise NotImplementedError
|
assert isinstance(other, DataModel)
|
||||||
|
if self.get_field_names() != other.get_field_names():
|
||||||
|
return False
|
||||||
|
if len(self.get_exceptions()) != len(other.get_exceptions()):
|
||||||
|
return False
|
||||||
|
return self.as_dict() == other.as_dict()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
fields = []
|
fields = []
|
||||||
|
@ -79,6 +79,14 @@ class ManifestModel(DataModel):
|
|||||||
export = DataField(type=ExportModel)
|
export = DataField(type=ExportModel)
|
||||||
examples = DataField(type=DictOfType(ExampleModel))
|
examples = DataField(type=DictOfType(ExampleModel))
|
||||||
|
|
||||||
|
# platform.json specific
|
||||||
|
title = DataField(max_length=100)
|
||||||
|
|
||||||
|
# package.json specific
|
||||||
|
system = DataField(
|
||||||
|
type=ListOfType(DataField(max_length=50, regex=r"^[a-z\d\-_]+$"))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class StrictManifestModel(ManifestModel, StrictDataModel):
|
class StrictManifestModel(ManifestModel, StrictDataModel):
|
||||||
pass
|
pass
|
||||||
|
@ -401,3 +401,44 @@ class LibraryPropertiesManifestParser(BaseManifestParser):
|
|||||||
"include": include,
|
"include": include,
|
||||||
"exclude": ["extras", "docs", "tests", "test", "*.doxyfile", "*.pdf"],
|
"exclude": ["extras", "docs", "tests", "test", "*.doxyfile", "*.pdf"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class PlatformJsonManifestParser(BaseManifestParser):
|
||||||
|
def parse(self, contents):
|
||||||
|
data = json.loads(contents)
|
||||||
|
if "frameworks" in data:
|
||||||
|
data["frameworks"] = self._parse_frameworks(data["frameworks"])
|
||||||
|
return data
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_frameworks(raw):
|
||||||
|
if not isinstance(raw, dict):
|
||||||
|
return None
|
||||||
|
return [name.lower() for name in raw.keys()]
|
||||||
|
|
||||||
|
|
||||||
|
class PackageJsonManifestParser(BaseManifestParser):
|
||||||
|
def parse(self, contents):
|
||||||
|
data = json.loads(contents)
|
||||||
|
data = self._parse_system(data)
|
||||||
|
data = self._parse_homepage(data)
|
||||||
|
return data
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_system(data):
|
||||||
|
if "system" not in data:
|
||||||
|
return data
|
||||||
|
if data["system"] in ("*", ["*"]):
|
||||||
|
del data["system"]
|
||||||
|
return data
|
||||||
|
if not isinstance(data["system"], list):
|
||||||
|
data["system"] = [data["system"]]
|
||||||
|
data["system"] = [s.strip().lower() for s in data["system"]]
|
||||||
|
return data
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_homepage(data):
|
||||||
|
if "url" in data:
|
||||||
|
data["homepage"] = data["url"]
|
||||||
|
del data["url"]
|
||||||
|
return data
|
||||||
|
@ -206,13 +206,13 @@ def test_library_json_model():
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
data = parser.ManifestParserFactory.new(
|
mp = parser.ManifestParserFactory.new(
|
||||||
contents, parser.ManifestFileType.LIBRARY_JSON
|
contents, parser.ManifestFileType.LIBRARY_JSON
|
||||||
)
|
)
|
||||||
model = ManifestModel(**data.as_dict())
|
model = StrictManifestModel(**mp.as_dict())
|
||||||
assert model.repository.url == "https://github.com/bblanchon/ArduinoJson.git"
|
assert model.repository.url == "https://github.com/bblanchon/ArduinoJson.git"
|
||||||
assert model.examples["JsonHttpClient"].files == ["JsonHttpClient.ino"]
|
assert model.examples["JsonHttpClient"].files == ["JsonHttpClient.ino"]
|
||||||
assert model == ManifestModel(
|
assert model == StrictManifestModel(
|
||||||
**{
|
**{
|
||||||
"name": "ArduinoJson",
|
"name": "ArduinoJson",
|
||||||
"keywords": ["json", "rest", "http", "web"],
|
"keywords": ["json", "rest", "http", "web"],
|
||||||
@ -226,10 +226,10 @@ def test_library_json_model():
|
|||||||
"version": "6.12.0",
|
"version": "6.12.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
|
"name": "Benoit Blanchon",
|
||||||
"url": "https://blog.benoitblanchon.fr",
|
"url": "https://blog.benoitblanchon.fr",
|
||||||
"maintainer": False,
|
"maintainer": False,
|
||||||
"email": None,
|
"email": None,
|
||||||
"name": "Benoit Blanchon",
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"export": {
|
"export": {
|
||||||
@ -265,12 +265,12 @@ category=Display
|
|||||||
url=https://github.com/olikraus/u8glib
|
url=https://github.com/olikraus/u8glib
|
||||||
architectures=avr,sam
|
architectures=avr,sam
|
||||||
"""
|
"""
|
||||||
data = parser.ManifestParserFactory.new(
|
mp = parser.ManifestParserFactory.new(
|
||||||
contents, parser.ManifestFileType.LIBRARY_PROPERTIES
|
contents, parser.ManifestFileType.LIBRARY_PROPERTIES
|
||||||
)
|
)
|
||||||
model = ManifestModel(**data.as_dict())
|
model = StrictManifestModel(**mp.as_dict())
|
||||||
assert not model.get_exceptions()
|
assert not model.get_exceptions()
|
||||||
assert model == ManifestModel(
|
assert model == StrictManifestModel(
|
||||||
**{
|
**{
|
||||||
"license": None,
|
"license": None,
|
||||||
"description": (
|
"description": (
|
||||||
@ -304,6 +304,120 @@ architectures=avr,sam
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_platform_json_model():
|
||||||
|
contents = """
|
||||||
|
{
|
||||||
|
"name": "atmelavr",
|
||||||
|
"title": "Atmel AVR",
|
||||||
|
"description": "Atmel AVR 8- and 32-bit MCUs deliver a unique combination of performance, power efficiency and design flexibility. Optimized to speed time to market-and easily adapt to new ones-they are based on the industrys most code-efficient architecture for C and assembly programming.",
|
||||||
|
"url": "http://www.atmel.com/products/microcontrollers/avr/default.aspx",
|
||||||
|
"homepage": "http://platformio.org/platforms/atmelavr",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"platformio": "<5"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/platformio/platform-atmelavr.git"
|
||||||
|
},
|
||||||
|
"version": "1.15.0",
|
||||||
|
"frameworks": {
|
||||||
|
"arduino": {
|
||||||
|
"package": "framework-arduinoavr",
|
||||||
|
"script": "builder/frameworks/arduino.py"
|
||||||
|
},
|
||||||
|
"simba": {
|
||||||
|
"package": "framework-simba",
|
||||||
|
"script": "builder/frameworks/simba.py"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"packages": {
|
||||||
|
"toolchain-atmelavr": {
|
||||||
|
"type": "toolchain",
|
||||||
|
"version": "~1.50400.0"
|
||||||
|
},
|
||||||
|
"framework-arduinoavr": {
|
||||||
|
"type": "framework",
|
||||||
|
"optional": true,
|
||||||
|
"version": "~4.2.0"
|
||||||
|
},
|
||||||
|
"framework-simba": {
|
||||||
|
"type": "framework",
|
||||||
|
"optional": true,
|
||||||
|
"version": ">=7.0.0"
|
||||||
|
},
|
||||||
|
"tool-avrdude": {
|
||||||
|
"type": "uploader",
|
||||||
|
"optional": true,
|
||||||
|
"version": "~1.60300.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
mp = parser.ManifestParserFactory.new(
|
||||||
|
contents, parser.ManifestFileType.PLATFORM_JSON
|
||||||
|
)
|
||||||
|
model = ManifestModel(**mp.as_dict())
|
||||||
|
assert sorted(model.frameworks) == sorted(["arduino", "simba"])
|
||||||
|
assert model == ManifestModel(
|
||||||
|
**{
|
||||||
|
"name": "atmelavr",
|
||||||
|
"title": "Atmel AVR",
|
||||||
|
"description": (
|
||||||
|
"Atmel AVR 8- and 32-bit MCUs deliver a unique combination of "
|
||||||
|
"performance, power efficiency and design flexibility. Optimized to "
|
||||||
|
"speed time to market-and easily adapt to new ones-they are based "
|
||||||
|
"on the industrys most code-efficient architecture for C and "
|
||||||
|
"assembly programming."
|
||||||
|
),
|
||||||
|
"homepage": "http://platformio.org/platforms/atmelavr",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"repository": {
|
||||||
|
"url": "https://github.com/platformio/platform-atmelavr.git",
|
||||||
|
"type": "git",
|
||||||
|
"branch": None,
|
||||||
|
},
|
||||||
|
"frameworks": ["simba", "arduino"],
|
||||||
|
"version": "1.15.0",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_package_json_model():
|
||||||
|
contents = """
|
||||||
|
{
|
||||||
|
"name": "tool-scons",
|
||||||
|
"description": "SCons software construction tool",
|
||||||
|
"url": "http://www.scons.org",
|
||||||
|
"version": "3.30101.0"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
mp = parser.ManifestParserFactory.new(
|
||||||
|
contents, parser.ManifestFileType.PACKAGE_JSON
|
||||||
|
)
|
||||||
|
model = ManifestModel(**mp.as_dict())
|
||||||
|
assert model.system is None
|
||||||
|
assert model.homepage == "http://www.scons.org"
|
||||||
|
assert model == ManifestModel(
|
||||||
|
**{
|
||||||
|
"name": "tool-scons",
|
||||||
|
"description": "SCons software construction tool",
|
||||||
|
"homepage": "http://www.scons.org",
|
||||||
|
"version": "3.30101.0",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
mp = parser.ManifestParserFactory.new(
|
||||||
|
'{"system": "*"}', parser.ManifestFileType.PACKAGE_JSON
|
||||||
|
)
|
||||||
|
assert "system" not in mp.as_dict()
|
||||||
|
|
||||||
|
mp = parser.ManifestParserFactory.new(
|
||||||
|
'{"system": "darwin_x86_64"}', parser.ManifestFileType.PACKAGE_JSON
|
||||||
|
)
|
||||||
|
assert mp.as_dict()["system"] == ["darwin_x86_64"]
|
||||||
|
|
||||||
|
|
||||||
def test_broken_models():
|
def test_broken_models():
|
||||||
# non-strict mode
|
# non-strict mode
|
||||||
assert len(ManifestModel(name="MyPackage").get_exceptions()) == 4
|
assert len(ManifestModel(name="MyPackage").get_exceptions()) == 4
|
||||||
|
Reference in New Issue
Block a user