Skip to content

Commit 569e194

Browse files
authored
Improved pluggable discovery conversion for platforms not supporting it (#1629)
* Factored property composition in convertUploadToolsToPluggableDiscovery * Auto-generated properties are cached and added after cycling on the original map * Autogenerated upload tool properties are searched in sub-configs too Fix #1444 * Added STMicroelectronics:stm32:Nucleo_32:pnum=NUCLEO_F031K6 to upload mock tests * Use composed board properties to detect user fields Some platforms may add information through the optional config part of the FQBN (platforms menu items).
1 parent 530e671 commit 569e194

File tree

4 files changed

+109
-5
lines changed

4 files changed

+109
-5
lines changed

Diff for: arduino/cores/packagemanager/loader.go

+20-3
Original file line numberDiff line numberDiff line change
@@ -574,18 +574,35 @@ func convertVidPidIdentificationPropertiesToPluggableDiscovery(boardProperties *
574574

575575
func convertUploadToolsToPluggableDiscovery(props *properties.Map) {
576576
actions := []string{"upload", "bootloader", "program"}
577+
propsToAdd := properties.NewMap()
577578
for _, action := range actions {
578-
if !props.ContainsKey(fmt.Sprintf("%s.tool.default", action)) {
579-
tool, found := props.GetOk(fmt.Sprintf("%s.tool", action))
579+
action += ".tool"
580+
defaultAction := action + ".default"
581+
if !props.ContainsKey(defaultAction) {
582+
// Search for "menu.MENU-ID.MENU-ITEM.ACTION.tool" (some platforms sets ACTION.tool on
583+
// submenu config entries). See https://github.com/arduino/arduino-cli/issues/1444
584+
for key, value := range props.AsMap() {
585+
if !strings.HasPrefix(key, "menu.") {
586+
continue
587+
}
588+
split := strings.Split(key, ".")
589+
if len(split) != 5 || split[3]+"."+split[4] != action {
590+
continue
591+
}
592+
prefix := split[0] + "." + split[1] + "." + split[2]
593+
propsToAdd.Set(prefix+"."+defaultAction, value)
594+
}
595+
tool, found := props.GetOk(action)
580596
if !found {
581597
// Just skip it, ideally this must never happen but if a platform
582598
// doesn't define an expected upload.tool, bootloader.tool or program.tool
583599
// there will be other issues further down the road after this conversion
584600
continue
585601
}
586-
props.Set(fmt.Sprintf("%s.tool.default", action), tool)
602+
propsToAdd.Set(defaultAction, tool)
587603
}
588604
}
605+
props.Merge(propsToAdd)
589606
}
590607

591608
func (pm *PackageManager) loadToolsFromPackage(targetPackage *cores.Package, toolsPath *paths.Path) []*status.Status {

Diff for: arduino/cores/packagemanager/loader_test.go

+68
Original file line numberDiff line numberDiff line change
@@ -254,3 +254,71 @@ program.extra_params=-P{serial.port}
254254

255255
require.Equal(t, expectedProps.AsMap(), props.AsMap())
256256
}
257+
258+
func TestConvertUploadToolsToPluggableDiscoveryWithMenus(t *testing.T) {
259+
props, err := properties.LoadFromBytes([]byte(`
260+
name=Nucleo-64
261+
262+
build.core=arduino
263+
build.board=Nucleo_64
264+
build.variant_h=variant_{build.board}.h
265+
build.extra_flags=-D{build.product_line} {build.enable_usb} {build.xSerial}
266+
267+
# Upload menu
268+
menu.upload_method.MassStorage=Mass Storage
269+
menu.upload_method.MassStorage.upload.protocol=
270+
menu.upload_method.MassStorage.upload.tool=massStorageCopy
271+
272+
menu.upload_method.swdMethod=STM32CubeProgrammer (SWD)
273+
menu.upload_method.swdMethod.upload.protocol=0
274+
menu.upload_method.swdMethod.upload.options=-g
275+
menu.upload_method.swdMethod.upload.tool=stm32CubeProg
276+
277+
menu.upload_method.serialMethod=STM32CubeProgrammer (Serial)
278+
menu.upload_method.serialMethod.upload.protocol=1
279+
menu.upload_method.serialMethod.upload.options={serial.port.file} -s
280+
menu.upload_method.serialMethod.upload.tool=stm32CubeProg
281+
282+
menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
283+
menu.upload_method.dfuMethod.upload.protocol=2
284+
menu.upload_method.dfuMethod.upload.options=-g
285+
menu.upload_method.dfuMethod.upload.tool=stm32CubeProg
286+
`))
287+
require.NoError(t, err)
288+
convertUploadToolsToPluggableDiscovery(props)
289+
290+
expectedProps, err := properties.LoadFromBytes([]byte(`
291+
name=Nucleo-64
292+
293+
build.core=arduino
294+
build.board=Nucleo_64
295+
build.variant_h=variant_{build.board}.h
296+
build.extra_flags=-D{build.product_line} {build.enable_usb} {build.xSerial}
297+
298+
# Upload menu
299+
menu.upload_method.MassStorage=Mass Storage
300+
menu.upload_method.MassStorage.upload.protocol=
301+
menu.upload_method.MassStorage.upload.tool=massStorageCopy
302+
menu.upload_method.MassStorage.upload.tool.default=massStorageCopy
303+
304+
menu.upload_method.swdMethod=STM32CubeProgrammer (SWD)
305+
menu.upload_method.swdMethod.upload.protocol=0
306+
menu.upload_method.swdMethod.upload.options=-g
307+
menu.upload_method.swdMethod.upload.tool=stm32CubeProg
308+
menu.upload_method.swdMethod.upload.tool.default=stm32CubeProg
309+
310+
menu.upload_method.serialMethod=STM32CubeProgrammer (Serial)
311+
menu.upload_method.serialMethod.upload.protocol=1
312+
menu.upload_method.serialMethod.upload.options={serial.port.file} -s
313+
menu.upload_method.serialMethod.upload.tool=stm32CubeProg
314+
menu.upload_method.serialMethod.upload.tool.default=stm32CubeProg
315+
316+
menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
317+
menu.upload_method.dfuMethod.upload.protocol=2
318+
menu.upload_method.dfuMethod.upload.options=-g
319+
menu.upload_method.dfuMethod.upload.tool=stm32CubeProg
320+
menu.upload_method.dfuMethod.upload.tool.default=stm32CubeProg
321+
`))
322+
require.NoError(t, err)
323+
require.Equal(t, expectedProps.AsMap(), props.AsMap())
324+
}

Diff for: commands/upload/upload.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ func SupportedUserFields(ctx context.Context, req *rpc.SupportedUserFieldsReques
6666
return nil, &arduino.InvalidFQBNError{Cause: err}
6767
}
6868

69-
_, platformRelease, board, _, _, err := pm.ResolveFQBN(fqbn)
69+
_, platformRelease, _, boardProperties, _, err := pm.ResolveFQBN(fqbn)
7070
if err != nil {
7171
return nil, &arduino.UnknownFQBNError{Cause: err}
7272
}
7373

74-
toolID, err := getToolID(board.Properties, "upload", req.Protocol)
74+
toolID, err := getToolID(boardProperties, "upload", req.Protocol)
7575
if err != nil {
7676
return nil, err
7777
}

Diff for: test/test_upload_mock.py

+19
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ def generate_build_dir(sketch_path):
2828

2929

3030
indexes = [
31+
"https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json",
3132
"https://adafruit.github.io/arduino-board-index/package_adafruit_index.json",
3233
"https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json",
3334
"http://arduino.esp8266.com/stable/package_esp8266com_index.json",
3435
"https://github.com/sonydevworld/spresense-arduino-compatible/releases/download/generic/package_spresense_index.json",
3536
]
3637

3738
cores_to_install = [
39+
"STMicroelectronics:[email protected]",
3840
"arduino:[email protected]",
3941
"adafruit:[email protected]",
4042
"arduino:[email protected]",
@@ -44,6 +46,23 @@ def generate_build_dir(sketch_path):
4446
]
4547

4648
testdata = [
49+
(
50+
"STMicroelectronics:stm32:Nucleo_32:pnum=NUCLEO_F031K6,upload_method=serialMethod",
51+
"/dev/ttyACM0",
52+
"",
53+
{
54+
"darwin": '"" sh '
55+
'"{data_dir}/packages/STMicroelectronics/tools/STM32Tools/2.1.1/stm32CubeProg.sh" '
56+
'1 "{build_dir}/{sketch_name}.ino.bin" ttyACM0 -s\n',
57+
"linux": '"" sh '
58+
'"{data_dir}/packages/STMicroelectronics/tools/STM32Tools/2.1.1/stm32CubeProg.sh" '
59+
'1 "{build_dir}/{sketch_name}.ino.bin" ttyACM0 -s\n',
60+
"win32": '"{data_dir}/packages/STMicroelectronics/tools/STM32Tools/2.1.1/win/busybox.exe" '
61+
"sh "
62+
'"{data_dir}/packages/STMicroelectronics/tools/STM32Tools/2.1.1/stm32CubeProg.sh" '
63+
'1 "{build_dir}/{sketch_name}.ino.bin" ttyACM0 -s\n',
64+
},
65+
),
4766
(
4867
"arduino:avr:uno",
4968
"/dev/ttyACM0",

0 commit comments

Comments
 (0)