Skip to content

Commit 7c54778

Browse files
committed
Support new Arduino CLI JSON output keys
A breaking change was made to the key names of Arduino CLI's JSON output in its 0.18.0 release. This action was dependent on some of the keys that changed. Because the action has a `cli-version` input that allows it to be used with any Arduino CLI version, it is necessary to support both interface styles. Even though there is not currently extensive use of the interface, it seemed best to set up a translation system to support all usage of the interface rather than just doing a spot fix at the site of the current breakage.
1 parent 15d79dc commit 7c54778

File tree

3 files changed

+108
-6
lines changed

3 files changed

+108
-6
lines changed

compilesketches/compilesketches.py

+93-5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import git
1616
import gitdb.exc
1717
import github
18+
import semver
1819
import yaml
1920
import yaml.parser
2021

@@ -527,13 +528,15 @@ def __init__(self):
527528
command_data = self.run_arduino_cli_command(command=["core", "list", "--format", "json"])
528529
installed_platform_list = json.loads(command_data.stdout)
529530
for installed_platform in installed_platform_list:
530-
if installed_platform["ID"] == platform[self.dependency_name_key]:
531+
if installed_platform[self.cli_json_key("core list", "ID")] == platform[self.dependency_name_key]:
531532
# The platform has been installed via Board Manager, so do an overwrite
532533
platform_installation_path.path = (
533-
self.board_manager_platforms_path.joinpath(platform_vendor,
534-
"hardware",
535-
platform_architecture,
536-
installed_platform["Installed"])
534+
self.board_manager_platforms_path.joinpath(
535+
platform_vendor,
536+
"hardware",
537+
platform_architecture,
538+
installed_platform[self.cli_json_key("core list", "Installed")]
539+
)
537540
)
538541
platform_installation_path.is_overwrite = True
539542

@@ -1413,6 +1416,91 @@ def create_sketches_report_file(self, sketches_report):
14131416
encoding="utf-8") as report_file:
14141417
json.dump(obj=sketches_report, fp=report_file, indent=2)
14151418

1419+
def cli_json_key(self, command, original_key_name):
1420+
"""Return the appropriate JSON output key name for the Arduino CLI version in use.
1421+
1422+
Keyword arguments:
1423+
command -- Arduino CLI command (e.g., "core list")
1424+
original_key_name -- key name used by the original Arduino CLI JSON interface
1425+
"""
1426+
final_original_interface_version = "0.17.0" # Interface was changed in the next Arduino CLI release
1427+
1428+
key_translation = {
1429+
"board details": {
1430+
"identification_pref": "identification_prefs",
1431+
"usbID": "usb_id",
1432+
"PID": "pid",
1433+
"VID": "vid",
1434+
"websiteURL": "website_url",
1435+
"archiveFileName": "archive_filename",
1436+
"propertiesId": "properties_id",
1437+
"toolsDependencies": "tools_dependencies"
1438+
},
1439+
"board list": {
1440+
"FQBN": "fqbn",
1441+
"VID": "vid",
1442+
"PID": "pid"
1443+
},
1444+
"board listall": {
1445+
"FQBN": "fqbn",
1446+
"Email": "email",
1447+
"ID": "id",
1448+
"Installed": "installed",
1449+
"Latest": "latest",
1450+
"Name": "name",
1451+
"Maintainer": "maintainer",
1452+
"Website": "website"
1453+
},
1454+
"board search": {
1455+
"FQBN": "fqbn",
1456+
"Email": "email",
1457+
"ID": "id",
1458+
"Installed": "installed",
1459+
"Latest": "latest",
1460+
"Name": "name",
1461+
"Maintainer": "maintainer",
1462+
"Website": "website"
1463+
},
1464+
"core list": {
1465+
"Boards": "boards",
1466+
"Email": "email",
1467+
"ID": "id",
1468+
"Installed": "installed",
1469+
"Latest": "latest",
1470+
"Maintainer": "maintainer",
1471+
"Name": "name",
1472+
"Website": "website"
1473+
},
1474+
"core search": {
1475+
"Boards": "boards",
1476+
"Email": "email",
1477+
"ID": "id",
1478+
"Latest": "latest",
1479+
"Maintainer": "maintainer",
1480+
"Name": "name",
1481+
"Website": "website"
1482+
},
1483+
"lib deps": {
1484+
"versionRequired": "version_required",
1485+
"versionInstalled": "version_installed"
1486+
},
1487+
"lib search": {
1488+
"archivefilename": "archive_filename",
1489+
"cachepath": "cache_path"
1490+
}
1491+
}
1492+
1493+
if (
1494+
(
1495+
not semver.VersionInfo.isvalid(version=self.cli_version)
1496+
or semver.compare(ver1=self.cli_version, ver2=final_original_interface_version) > 0
1497+
)
1498+
and (command in key_translation and original_key_name in key_translation[command])
1499+
):
1500+
return key_translation[command][original_key_name]
1501+
1502+
return original_key_name
1503+
14161504

14171505
def parse_list_input(list_input):
14181506
"""Parse a space separated list and return the equivalent Python list

compilesketches/requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
GitPython==3.1.2
22
PyGithub==1.51
33
PyYAML==5.3.1
4+
semver==2.13.0

compilesketches/tests/test_compilesketches.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121

2222
def get_compilesketches_object(
23-
cli_version=unittest.mock.sentinel.cli_version,
23+
cli_version="0.12.3",
2424
fqbn_arg="foo fqbn_arg",
2525
platforms="- name: FooVendor:BarArchitecture",
2626
libraries="foo libraries",
@@ -2578,6 +2578,19 @@ def test_create_sketches_report_file(monkeypatch, tmp_path):
25782578
assert json.load(sketch_report_file) == sketches_report
25792579

25802580

2581+
@pytest.mark.parametrize("cli_version, command, original_key, expected_key",
2582+
[("latest", "core list", "ID", "id"), # Non-semver
2583+
("1.0.0", "core list", "ID", "id"), # >
2584+
("0.17.0", "core list", "ID", "ID"), # ==
2585+
("0.14.0-rc2", "core list", "ID", "ID"), # <
2586+
("1.0.0", "foo", "ID", "ID"), # Command has no translation
2587+
("1.0.0", "core list", "foo", "foo")]) # Key has no translation
2588+
def test_cli_json_key(cli_version, command, original_key, expected_key):
2589+
compile_sketches = get_compilesketches_object(cli_version=cli_version)
2590+
2591+
assert compile_sketches.cli_json_key(command, original_key) == expected_key
2592+
2593+
25812594
@pytest.mark.parametrize("verbose", ["true", "false"])
25822595
def test_verbose_print(capsys, verbose):
25832596
string_print_argument = "foo string argument"

0 commit comments

Comments
 (0)