Skip to content

Commit 1bc7c20

Browse files
authored
Merge pull request #285 from per1234/cli-1-format
Handle Arduino CLI 1.x `core list` command output data format
2 parents b35a113 + 26705b3 commit 1bc7c20

File tree

2 files changed

+80
-75
lines changed

2 files changed

+80
-75
lines changed

compilesketches/compilesketches.py

+57-65
Original file line numberDiff line numberDiff line change
@@ -558,15 +558,15 @@ def __init__(self):
558558
self.run_arduino_cli_command(command=["core", "update-index"])
559559
# Use Arduino CLI to get the list of installed platforms
560560
command_data = self.run_arduino_cli_command(command=["core", "list", "--format", "json"])
561-
installed_platform_list = json.loads(command_data.stdout)
561+
installed_platform_list = self.cli_core_list_platform_list(json.loads(command_data.stdout))
562562
for installed_platform in installed_platform_list:
563-
if installed_platform[self.cli_json_key("core list", "ID")] == platform[self.dependency_name_key]:
563+
if installed_platform[self.cli_json_key("core list", "id")] == platform[self.dependency_name_key]:
564564
# The platform has been installed via Board Manager, so do an overwrite
565565
platform_installation_path.path = self.board_manager_platforms_path.joinpath(
566566
platform_vendor,
567567
"hardware",
568568
platform_architecture,
569-
installed_platform[self.cli_json_key("core list", "Installed")],
569+
installed_platform[self.cli_json_key("core list", "installed_version")],
570570
)
571571
platform_installation_path.is_overwrite = True
572572

@@ -1437,77 +1437,69 @@ def create_sketches_report_file(self, sketches_report):
14371437
) as report_file:
14381438
json.dump(obj=sketches_report, fp=report_file, indent=2)
14391439

1440-
def cli_json_key(self, command, original_key_name):
1440+
def cli_core_list_platform_list(self, data):
1441+
"""Extract the list of platform data from the `arduino-cli core list` command output according to the Arduino
1442+
CLI version in use.
1443+
1444+
Keyword arguments:
1445+
data -- Arduino CLI command output data
1446+
"""
1447+
# Interface was changed at this Arduino CLI release:
1448+
# https://arduino.github.io/arduino-cli/dev/UPGRADING/#cli-changed-json-output-for-some-lib-core-config-board-and-sketch-commands
1449+
first_new_interface_version = "1.0.0"
1450+
1451+
if (
1452+
not semver.VersionInfo.is_valid(version=self.cli_version)
1453+
or semver.Version.parse(version=self.cli_version).compare(other=first_new_interface_version) >= 0
1454+
):
1455+
# cli_version is either "latest" (which will now always be >=1.0.0) or an explicit version >=1.0.0
1456+
return data["platforms"]
1457+
1458+
return data
1459+
1460+
def cli_json_key(self, command, key_name):
14411461
"""Return the appropriate JSON output key name for the Arduino CLI version in use.
14421462
14431463
Keyword arguments:
14441464
command -- Arduino CLI command (e.g., "core list")
1445-
original_key_name -- key name used by the original Arduino CLI JSON interface
1465+
key_name -- key name used by the current Arduino CLI JSON interface
14461466
"""
1447-
final_original_interface_version = "0.17.0" # Interface was changed in the next Arduino CLI release
1448-
1449-
key_translation = {
1450-
"board details": {
1451-
"identification_pref": "identification_prefs",
1452-
"usbID": "usb_id",
1453-
"PID": "pid",
1454-
"VID": "vid",
1455-
"websiteURL": "website_url",
1456-
"archiveFileName": "archive_filename",
1457-
"propertiesId": "properties_id",
1458-
"toolsDependencies": "tools_dependencies",
1459-
},
1460-
"board list": {"FQBN": "fqbn", "VID": "vid", "PID": "pid"},
1461-
"board listall": {
1462-
"FQBN": "fqbn",
1463-
"Email": "email",
1464-
"ID": "id",
1465-
"Installed": "installed",
1466-
"Latest": "latest",
1467-
"Name": "name",
1468-
"Maintainer": "maintainer",
1469-
"Website": "website",
1470-
},
1471-
"board search": {
1472-
"FQBN": "fqbn",
1473-
"Email": "email",
1474-
"ID": "id",
1475-
"Installed": "installed",
1476-
"Latest": "latest",
1477-
"Name": "name",
1478-
"Maintainer": "maintainer",
1479-
"Website": "website",
1480-
},
1467+
key_translations = {
14811468
"core list": {
1482-
"Boards": "boards",
1483-
"Email": "email",
1484-
"ID": "id",
1485-
"Installed": "installed",
1486-
"Latest": "latest",
1487-
"Maintainer": "maintainer",
1488-
"Name": "name",
1489-
"Website": "website",
1490-
},
1491-
"core search": {
1492-
"Boards": "boards",
1493-
"Email": "email",
1494-
"ID": "id",
1495-
"Latest": "latest",
1496-
"Maintainer": "maintainer",
1497-
"Name": "name",
1498-
"Website": "website",
1499-
},
1500-
"lib deps": {"versionRequired": "version_required", "versionInstalled": "version_installed"},
1501-
"lib search": {"archivefilename": "archive_filename", "cachepath": "cache_path"},
1469+
"id": [
1470+
{"constraints": [">=0.0.0", "<=0.17.0"], "name": "ID"},
1471+
# https://arduino.github.io/arduino-cli/dev/UPGRADING/#arduino-cli-json-output-breaking-changes
1472+
{"constraints": [">0.17.0"], "name": "id"},
1473+
],
1474+
"installed_version": [
1475+
{"constraints": [">=0.0.0", "<=0.17.0"], "name": "Installed"},
1476+
# https://arduino.github.io/arduino-cli/dev/UPGRADING/#arduino-cli-json-output-breaking-changes
1477+
{"constraints": [">0.17.0", "<1.0.0"], "name": "installed"},
1478+
# https://arduino.github.io/arduino-cli/dev/UPGRADING/#cli-core-list-and-core-search-changed-json-output
1479+
{"constraints": [">=1.0.0"], "name": "installed_version"},
1480+
],
1481+
}
15021482
}
15031483

1504-
if (
1505-
not semver.VersionInfo.is_valid(version=self.cli_version)
1506-
or semver.Version.parse(version=self.cli_version).compare(other=final_original_interface_version) > 0
1507-
) and (command in key_translation and original_key_name in key_translation[command]):
1508-
return key_translation[command][original_key_name]
1484+
if not semver.VersionInfo.is_valid(version=self.cli_version):
1485+
# cli_version is "latest", so use the current key name
1486+
return key_name
1487+
1488+
for translation in key_translations[command][key_name]:
1489+
match = True
1490+
for constraint in translation["constraints"]:
1491+
if not semver.Version.parse(version=self.cli_version).match(match_expr=constraint):
1492+
# The Arduino CLI version does not match the translation's version constraints
1493+
match = False
1494+
break
1495+
1496+
if match:
1497+
# The Arduino CLI version matches the translation's version constraints
1498+
return translation["name"]
15091499

1510-
return original_key_name
1500+
raise RuntimeError(
1501+
f"Translation not implemented for `{key_name}` key of `arduino-cli {command}` for version {self.cli_version}"
1502+
) # pragma: no cover
15111503

15121504

15131505
def parse_list_input(list_input):

compilesketches/tests/test_compilesketches.py

+23-10
Original file line numberDiff line numberDiff line change
@@ -2884,20 +2884,33 @@ def test_create_sketches_report_file(monkeypatch, tmp_path):
28842884

28852885

28862886
@pytest.mark.parametrize(
2887-
"cli_version, command, original_key, expected_key",
2887+
"cli_version, data, assertion",
28882888
[
2889-
("latest", "core list", "ID", "id"), # Non-semver
2890-
("1.0.0", "core list", "ID", "id"), # >
2891-
("0.17.0", "core list", "ID", "ID"), # ==
2892-
("0.14.0-rc2", "core list", "ID", "ID"), # <
2893-
("1.0.0", "foo", "ID", "ID"), # Command has no translation
2894-
("1.0.0", "core list", "foo", "foo"),
2889+
("latest", {"platforms": [unittest.mock.sentinel.list_item]}, [unittest.mock.sentinel.list_item]), # Non-semver
2890+
("2.0.0", {"platforms": [unittest.mock.sentinel.list_item]}, [unittest.mock.sentinel.list_item]), # >
2891+
("1.0.0", {"platforms": [unittest.mock.sentinel.list_item]}, [unittest.mock.sentinel.list_item]), # ==
2892+
("0.1.2", [unittest.mock.sentinel.list_item], [unittest.mock.sentinel.list_item]), # <
28952893
],
2896-
) # Key has no translation
2897-
def test_cli_json_key(cli_version, command, original_key, expected_key):
2894+
)
2895+
def test_cli_core_list_platform_list(cli_version, data, assertion):
2896+
compile_sketches = get_compilesketches_object(cli_version=cli_version)
2897+
2898+
assert compile_sketches.cli_core_list_platform_list(data) == assertion
2899+
2900+
2901+
@pytest.mark.parametrize(
2902+
"cli_version, command, key_name, expected_key",
2903+
[
2904+
("latest", "core list", "installed_version", "installed_version"), # Non-semver
2905+
("0.1.2", "core list", "installed_version", "Installed"),
2906+
("0.17.1", "core list", "installed_version", "installed"),
2907+
("1.2.3", "core list", "installed_version", "installed_version"),
2908+
],
2909+
)
2910+
def test_cli_json_key(cli_version, command, key_name, expected_key):
28982911
compile_sketches = get_compilesketches_object(cli_version=cli_version)
28992912

2900-
assert compile_sketches.cli_json_key(command, original_key) == expected_key
2913+
assert compile_sketches.cli_json_key(command, key_name) == expected_key
29012914

29022915

29032916
@pytest.mark.parametrize("verbose", ["true", "false"])

0 commit comments

Comments
 (0)