Skip to content

Commit 6cf0122

Browse files
committed
Allow installation of arbitrary platform dependencies
Arbitrary platform dependencies may be specified via the platforms input. This input uses the same YAML-list format as the libraries input. Benefits: - Allows use of platforms that have a dependency on another platform for referenced tools, core, or variant - Allows testing against a specific platform version. - Allows specifying the additional Board Manager URL via the version key, rather than the previous awkward patch job of passing a space separated list with the FQBN and URL to the fqbn input. Backwards compatibility is provided by retaining the same behavior of automatically installing the board's platform dependency, as inferred from the fqbn input. The additional Board Manager URL may still be passed via the fqbn input, if desired.
1 parent 68df0b9 commit 6cf0122

File tree

4 files changed

+181
-58
lines changed

4 files changed

+181
-58
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,20 @@ For 3rd party boards, also specify the Boards Manager URL:
1616
fqbn: '"sandeepmistry:nRF5:Generic_nRF52832" "https://sandeepmistry.github.io/arduino-nRF5/package_nRF5_boards_index.json"'
1717
```
1818
19+
### `platforms`
20+
21+
YAML-format list of platform dependencies to install.
22+
23+
Default `""`. If no `platforms` input is provided, the board's dependency will be automatically determined from the `fqbn` input and the latest version of that platform will be installed via Board Manager.
24+
25+
#### Sources:
26+
27+
##### Board Manager
28+
29+
Keys:
30+
- `name` - platform name in the form of `VENDOR:ARCHITECTURE`.
31+
- `version` - version of the platform to install. Default is the latest version.
32+
1933
### `libraries`
2034

2135
YAML-format list of library dependencies to install.

action.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ inputs:
1010
libraries:
1111
description: 'YAML-format list of library dependencies to install'
1212
default: '- source-path: ./'
13+
platforms:
14+
description: 'YAML-format list of platform dependencies to install'
15+
default: ''
1316
sketch-paths:
1417
description: 'List of paths containing sketches to compile.'
1518
default: 'examples'

compilesketches/compilesketches.py

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def main():
2525
compile_sketches = CompileSketches(
2626
cli_version=os.environ["INPUT_CLI-VERSION"],
2727
fqbn_arg=os.environ["INPUT_FQBN"],
28+
platforms=os.environ["INPUT_PLATFORMS"],
2829
libraries=os.environ["INPUT_LIBRARIES"],
2930
sketch_paths=os.environ["INPUT_SKETCH-PATHS"],
3031
verbose=os.environ["INPUT_VERBOSE"],
@@ -48,6 +49,7 @@ class CompileSketches:
4849
cli_version -- version of the Arduino CLI to use
4950
fqbn_arg -- fully qualified board name of the board to compile for. Space separated list with Boards Manager URL if
5051
needed
52+
platforms -- YAML-format list of platforms to install
5153
libraries -- YAML-format or space-separated list of libraries to install
5254
sketch_paths -- space-separated list of paths containing sketches to compile. These paths will be searched
5355
recursively for sketches.
@@ -95,7 +97,7 @@ class RunCommandOutput(enum.Enum):
9597

9698
latest_release_indicator = "latest"
9799

98-
def __init__(self, cli_version, fqbn_arg, libraries, sketch_paths, verbose, github_token, report_sketch,
100+
def __init__(self, cli_version, fqbn_arg, platforms, libraries, sketch_paths, verbose, github_token, report_sketch,
99101
enable_size_deltas_report, sketches_report_path, enable_size_trends_report, google_key_file,
100102
size_trends_report_spreadsheet_id, size_trends_report_sheet_name):
101103
"""Process, store, and validate the action's inputs."""
@@ -104,6 +106,7 @@ def __init__(self, cli_version, fqbn_arg, libraries, sketch_paths, verbose, gith
104106
parsed_fqbn_arg = parse_fqbn_arg_input(fqbn_arg=fqbn_arg)
105107
self.fqbn = parsed_fqbn_arg["fqbn"]
106108
self.additional_url = parsed_fqbn_arg["additional_url"]
109+
self.platforms = platforms
107110
self.libraries = libraries
108111

109112
# Save the space-separated list of paths as a Python list
@@ -211,16 +214,26 @@ def verbose_print(self, *print_arguments):
211214

212215
def install_platforms(self):
213216
"""Install Arduino boards platforms."""
214-
# Extract the platform name from the FQBN (e.g., arduino:avr:uno => arduino:avr)
215-
fqbn_platform_name = self.fqbn.rsplit(sep=":", maxsplit=1)[0]
217+
platform_list = self.Dependencies()
218+
if self.platforms == "":
219+
# When no platforms input is provided, automatically determine the board's platform dependency from the FQBN
220+
platform_list.manager.append(self.get_fqbn_platform_dependency())
221+
else:
222+
platform_list = self.sort_dependency_list(yaml.load(stream=self.platforms, Loader=yaml.SafeLoader))
216223

217-
# TODO: this is in anticipation of permitting installation of arbitrary core dependencies from various sources
218-
additional_url_list = []
224+
if len(platform_list.manager) > 0:
225+
# This should always be called before the functions to install platforms from other sources so that the
226+
# override system will work
227+
self.install_platforms_from_board_manager(platform_list=platform_list.manager)
228+
229+
def get_fqbn_platform_dependency(self):
230+
"""Return the platform dependency definition automatically generated from the FQBN."""
231+
# Extract the platform name from the FQBN (e.g., arduino:avr:uno => arduino:avr)
232+
fqbn_platform_dependency = {self.dependency_name_key: self.fqbn.rsplit(sep=":", maxsplit=1)[0]}
219233
if self.additional_url is not None:
220-
additional_url_list.append(self.additional_url)
234+
fqbn_platform_dependency[self.dependency_source_url_key] = self.additional_url
221235

222-
self.install_platforms_from_board_manager(platform_list=[fqbn_platform_name],
223-
additional_url_list=additional_url_list)
236+
return fqbn_platform_dependency
224237

225238
def sort_dependency_list(self, dependency_list):
226239
"""Sort a list of sketch dependencies by source type
@@ -238,6 +251,12 @@ def sort_dependency_list(self, dependency_list):
238251
or dependency[self.dependency_source_url_key].startswith("git://")
239252
):
240253
sorted_dependencies.repository.append(dependency)
254+
elif re.match(
255+
pattern=".*/package_.*index.json", string=dependency[self.dependency_source_url_key]
256+
) is not None:
257+
# URLs that match the filename requirements of the package_index.json specification are assumed
258+
# to be additional Board Manager URLs (platform index)
259+
sorted_dependencies.manager.append(dependency)
241260
else:
242261
# All other URLs are assumed to be downloads
243262
sorted_dependencies.download.append(dependency)
@@ -259,30 +278,33 @@ def __init__(self):
259278
self.repository = []
260279
self.download = []
261280

262-
def install_platforms_from_board_manager(self, platform_list, additional_url_list):
281+
def install_platforms_from_board_manager(self, platform_list):
263282
"""Install platform dependencies from the Arduino Board Manager
264283
265284
Keyword arguments:
266-
platform_list -- a list of platform names
267-
additional_url_list -- a list of additional Board Manager URLs for 3rd party platforms
285+
platform_list -- list of dictionaries defining the Board Manager platform dependencies
268286
"""
269-
core_update_index_command = ["core", "update-index"]
270-
271-
core_install_command = ["core", "install"]
272-
core_install_command.extend(platform_list)
273-
274-
# Append additional Boards Manager URLs to the commands, if required
275-
if len(additional_url_list) > 0:
276-
additional_urls_option = ["--additional-urls", ",".join(additional_url_list)]
277-
core_update_index_command.extend(additional_urls_option)
278-
core_install_command.extend(additional_urls_option)
279-
280-
# Download the platform indexes for the platforms
281-
self.run_arduino_cli_command(command=core_update_index_command,
282-
enable_output=self.get_run_command_output_level())
283-
284-
# Install the platforms
285-
self.run_arduino_cli_command(command=core_install_command, enable_output=self.get_run_command_output_level())
287+
# Although Arduino CLI supports doing this all in one command, it may assist troubleshooting to install one
288+
# platform at a time, and most users will only do a single Board Manager platform installation anyway
289+
for platform in platform_list:
290+
core_update_index_command = ["core", "update-index"]
291+
core_install_command = ["core", "install"]
292+
293+
# Append additional Boards Manager URLs to the commands, if required
294+
if self.dependency_source_url_key in platform:
295+
additional_urls_option = ["--additional-urls", platform[self.dependency_source_url_key]]
296+
core_update_index_command.extend(additional_urls_option)
297+
core_install_command.extend(additional_urls_option)
298+
299+
core_install_command.append(self.get_manager_dependency_name(platform))
300+
301+
# Download the platform index for the platform
302+
self.run_arduino_cli_command(command=core_update_index_command,
303+
enable_output=self.get_run_command_output_level())
304+
305+
# Install the platform
306+
self.run_arduino_cli_command(command=core_install_command,
307+
enable_output=self.get_run_command_output_level())
286308

287309
def get_manager_dependency_name(self, dependency):
288310
"""Return the appropriate name value for a manager dependency. This allows the NAME@VERSION syntax to be used

0 commit comments

Comments
 (0)