diff --git a/platformio/package/manifest/parser.py b/platformio/package/manifest/parser.py index 4be71944..9ea5f4f3 100644 --- a/platformio/package/manifest/parser.py +++ b/platformio/package/manifest/parser.py @@ -334,7 +334,7 @@ class LibraryJsonManifestParser(BaseManifestParser): if "authors" in data: data["authors"] = self._parse_authors(data["authors"]) if "platforms" in data: - data["platforms"] = self._parse_platforms(data["platforms"]) or None + data["platforms"] = self._fix_platforms(data["platforms"]) or None if "export" in data: data["export"] = self._parse_export(data["export"]) if "dependencies" in data: @@ -367,16 +367,11 @@ class LibraryJsonManifestParser(BaseManifestParser): return [self.cleanup_author(author) for author in raw] @staticmethod - def _parse_platforms(raw): - assert isinstance(raw, list) - result = [] - # renamed platforms - for item in raw: - if item == "espressif": - item = "espressif8266" - if item not in result: - result.append(item) - return result + def _fix_platforms(items): + assert isinstance(items, list) + if "espressif" in items: + items[items.index("espressif")] = "espressif8266" + return items @staticmethod def _parse_export(raw): @@ -485,7 +480,7 @@ class LibraryPropertiesManifestParser(BaseManifestParser): repository=repository or None, description=self._parse_description(data), platforms=self._parse_platforms(data) or ["*"], - keywords=self._parse_keywords(data), + keywords=self._parse_keywords(data) or None, export=self._parse_export(), ) ) @@ -527,18 +522,17 @@ class LibraryPropertiesManifestParser(BaseManifestParser): lines[0] += "." return " ".join(lines) - @staticmethod - def _parse_keywords(properties): - result = [] - for item in re.split(r"[\s/]+", properties.get("category", "uncategorized")): - item = item.strip() - if not item: - continue - result.append(item.lower()) - return result + def _parse_keywords(self, properties): + return self.str_to_list( + re.split( + r"[\s/]+", + properties.get("category", ""), + ), + lowercase=True, + unique=True, + ) - @staticmethod - def _parse_platforms(properties): + def _parse_platforms(self, properties): result = [] platforms_map = { "avr": "atmelavr", @@ -557,9 +551,9 @@ class LibraryPropertiesManifestParser(BaseManifestParser): continue if arch == "*": return ["*"] - if arch in platforms_map and platforms_map[arch] not in result: + if arch in platforms_map: result.append(platforms_map[arch]) - return result + return self.str_to_list(result, lowercase=True, unique=True) def _parse_authors(self, properties): if "author" not in properties: @@ -655,19 +649,17 @@ class PlatformJsonManifestParser(BaseManifestParser): def parse(self, contents): data = json.loads(contents) if "keywords" in data: - data["keywords"] = self.str_to_list(data["keywords"], sep=",", unique=True) - if "frameworks" in data: - data["frameworks"] = self._parse_frameworks(data["frameworks"]) + data["keywords"] = self.str_to_list( + data["keywords"], sep=",", lowercase=True, unique=True + ) + if "frameworks" in data and not isinstance(data["frameworks"], dict): + data["frameworks"] = self.str_to_list( + data["frameworks"].keys(), lowercase=True, unique=True + ) if "packages" in data: data["dependencies"] = self._parse_dependencies(data["packages"]) return data - @staticmethod - def _parse_frameworks(raw): - if not isinstance(raw, dict): - return None - return [name.lower() for name in raw.keys()] - @staticmethod def _parse_dependencies(raw): result = [] @@ -694,16 +686,13 @@ class PackageJsonManifestParser(BaseManifestParser): data = self._parse_repository(data) return data - @staticmethod - def _parse_system(data): + def _parse_system(self, data): if "system" not in data: return data if data["system"] in ("*", ["*"], "all"): 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"]] + data["system"] = self.str_to_list(data["system"], lowercase=True, unique=True) return data @staticmethod diff --git a/tests/package/test_manager.py b/tests/package/test_manager.py index a42110e9..4dae6302 100644 --- a/tests/package/test_manager.py +++ b/tests/package/test_manager.py @@ -202,7 +202,7 @@ def test_install_from_registry(isolated_pio_core, tmpdir_factory): lm.install("AsyncMqttClient-esphome @ 0.8.4", silent=True) assert len(lm.get_installed()) == 3 pkg = lm.get_package("AsyncTCP-esphome") - assert pkg.metadata.spec.owner == "ottowinter" + assert pkg.metadata.spec.owner == "esphome" assert not lm.get_package("non-existing-package") # mbed library assert lm.install("wolfSSL", silent=True) diff --git a/tests/package/test_manifest.py b/tests/package/test_manifest.py index 94dd29f1..33bbfd95 100644 --- a/tests/package/test_manifest.py +++ b/tests/package/test_manifest.py @@ -206,6 +206,7 @@ version=1.2.3 author=SomeAuthor , Maintainer Author (nickname) maintainer=Maintainer Author (nickname) sentence=This is Arduino library +category=Signal Input/Output customField=Custom Value depends=First Library (=2.0.0), Second Library (>=1.2.0), Third ignore_empty_field= @@ -229,7 +230,8 @@ includes=Arduino.h, Arduino Space.hpp {"name": "SomeAuthor", "email": "info@author.com"}, {"name": "Maintainer Author", "maintainer": True}, ], - "keywords": ["uncategorized"], + "category": "Signal Input/Output", + "keywords": ["signal", "input", "output"], "headers": ["Arduino.h", "Arduino Space.hpp"], "customField": "Custom Value", "depends": "First Library (=2.0.0), Second Library (>=1.2.0), Third", @@ -297,6 +299,7 @@ maintainer=Rocket Scream Electronics assert data["authors"] == [ {"name": "Rocket Scream Electronics", "maintainer": True} ] + assert "keywords" not in data def test_library_json_schema(): @@ -559,7 +562,7 @@ def test_platform_json_schema(): "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.", - "keywords": "arduino, atmel, avr", + "keywords": "arduino, atmel, avr, MCU", "homepage": "http://www.atmel.com/products/microcontrollers/avr/default.aspx", "license": "Apache-2.0", "engines": { @@ -619,7 +622,7 @@ def test_platform_json_schema(): "on the industrys most code-efficient architecture for C and " "assembly programming." ), - "keywords": ["arduino", "atmel", "avr"], + "keywords": ["arduino", "atmel", "avr", "mcu"], "homepage": "http://www.atmel.com/products/microcontrollers/avr/default.aspx", "license": "Apache-2.0", "repository": { @@ -648,7 +651,7 @@ def test_package_json_schema(): "description": "SCons software construction tool", "keywords": "SCons, build", "homepage": "http://www.scons.org", - "system": ["linux_armv6l", "linux_armv7l", "linux_armv8l"], + "system": ["linux_armv6l", "linux_armv7l", "linux_armv8l", "LINUX_ARMV7L"], "version": "3.30101.0" } """