Skip to content

Commit

Permalink
Support new Arduino CLI JSON output keys
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
per1234 committed Apr 1, 2021
1 parent 15d79dc commit 7c54778
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 6 deletions.
98 changes: 93 additions & 5 deletions compilesketches/compilesketches.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import git
import gitdb.exc
import github
import semver
import yaml
import yaml.parser

Expand Down Expand Up @@ -527,13 +528,15 @@ def __init__(self):
command_data = self.run_arduino_cli_command(command=["core", "list", "--format", "json"])
installed_platform_list = json.loads(command_data.stdout)
for installed_platform in installed_platform_list:
if installed_platform["ID"] == platform[self.dependency_name_key]:
if installed_platform[self.cli_json_key("core list", "ID")] == platform[self.dependency_name_key]:
# The platform has been installed via Board Manager, so do an overwrite
platform_installation_path.path = (
self.board_manager_platforms_path.joinpath(platform_vendor,
"hardware",
platform_architecture,
installed_platform["Installed"])
self.board_manager_platforms_path.joinpath(
platform_vendor,
"hardware",
platform_architecture,
installed_platform[self.cli_json_key("core list", "Installed")]
)
)
platform_installation_path.is_overwrite = True

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

def cli_json_key(self, command, original_key_name):
"""Return the appropriate JSON output key name for the Arduino CLI version in use.
Keyword arguments:
command -- Arduino CLI command (e.g., "core list")
original_key_name -- key name used by the original Arduino CLI JSON interface
"""
final_original_interface_version = "0.17.0" # Interface was changed in the next Arduino CLI release

key_translation = {
"board details": {
"identification_pref": "identification_prefs",
"usbID": "usb_id",
"PID": "pid",
"VID": "vid",
"websiteURL": "website_url",
"archiveFileName": "archive_filename",
"propertiesId": "properties_id",
"toolsDependencies": "tools_dependencies"
},
"board list": {
"FQBN": "fqbn",
"VID": "vid",
"PID": "pid"
},
"board listall": {
"FQBN": "fqbn",
"Email": "email",
"ID": "id",
"Installed": "installed",
"Latest": "latest",
"Name": "name",
"Maintainer": "maintainer",
"Website": "website"
},
"board search": {
"FQBN": "fqbn",
"Email": "email",
"ID": "id",
"Installed": "installed",
"Latest": "latest",
"Name": "name",
"Maintainer": "maintainer",
"Website": "website"
},
"core list": {
"Boards": "boards",
"Email": "email",
"ID": "id",
"Installed": "installed",
"Latest": "latest",
"Maintainer": "maintainer",
"Name": "name",
"Website": "website"
},
"core search": {
"Boards": "boards",
"Email": "email",
"ID": "id",
"Latest": "latest",
"Maintainer": "maintainer",
"Name": "name",
"Website": "website"
},
"lib deps": {
"versionRequired": "version_required",
"versionInstalled": "version_installed"
},
"lib search": {
"archivefilename": "archive_filename",
"cachepath": "cache_path"
}
}

if (
(
not semver.VersionInfo.isvalid(version=self.cli_version)
or semver.compare(ver1=self.cli_version, ver2=final_original_interface_version) > 0
)
and (command in key_translation and original_key_name in key_translation[command])
):
return key_translation[command][original_key_name]

return original_key_name


def parse_list_input(list_input):
"""Parse a space separated list and return the equivalent Python list
Expand Down
1 change: 1 addition & 0 deletions compilesketches/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
GitPython==3.1.2
PyGithub==1.51
PyYAML==5.3.1
semver==2.13.0
15 changes: 14 additions & 1 deletion compilesketches/tests/test_compilesketches.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


def get_compilesketches_object(
cli_version=unittest.mock.sentinel.cli_version,
cli_version="0.12.3",
fqbn_arg="foo fqbn_arg",
platforms="- name: FooVendor:BarArchitecture",
libraries="foo libraries",
Expand Down Expand Up @@ -2578,6 +2578,19 @@ def test_create_sketches_report_file(monkeypatch, tmp_path):
assert json.load(sketch_report_file) == sketches_report


@pytest.mark.parametrize("cli_version, command, original_key, expected_key",
[("latest", "core list", "ID", "id"), # Non-semver
("1.0.0", "core list", "ID", "id"), # >
("0.17.0", "core list", "ID", "ID"), # ==
("0.14.0-rc2", "core list", "ID", "ID"), # <
("1.0.0", "foo", "ID", "ID"), # Command has no translation
("1.0.0", "core list", "foo", "foo")]) # Key has no translation
def test_cli_json_key(cli_version, command, original_key, expected_key):
compile_sketches = get_compilesketches_object(cli_version=cli_version)

assert compile_sketches.cli_json_key(command, original_key) == expected_key


@pytest.mark.parametrize("verbose", ["true", "false"])
def test_verbose_print(capsys, verbose):
string_print_argument = "foo string argument"
Expand Down

0 comments on commit 7c54778

Please sign in to comment.