diff --git a/generator/generator.py b/generator/generator.py index 3f581767..41966856 100644 --- a/generator/generator.py +++ b/generator/generator.py @@ -71,9 +71,9 @@ def create_firmware_data(binary, module, version): } -def get_uploader_id(tools, tool_executable): +def get_uploader_id(tools, tool_name): for t in tools: - if t["name"] == tool_executable: + if t["name"] == tool_name: packager = t["packager"] name = t["name"] version = t["version"] @@ -118,15 +118,27 @@ def create_upload_data(fqbn, installed_cores): # noqa: C901 installed_json_data = json.load(f) if f"{tool}.cmd" in platform_upload_data: - tool_executable = platform_upload_data[f"{tool}.cmd"] + tool_executable_generic = platform_upload_data[f"{tool}.cmd"] + tool_executable_linux = platform_upload_data.get(f"{tool}.cmd.linux", tool_executable_generic) + tool_executable_windows = platform_upload_data.get(f"{tool}.cmd.windows", "") + tool_executable_macosx = platform_upload_data.get(f"{tool}.cmd.macosx", "") + tool_name = tool_executable_generic elif f"{tool}.cmd.path" in platform_upload_data: - tool_executable = platform_upload_data[f"{tool}.cmd.path"].split("/")[-1] + tool_executable_generic = "/".join(platform_upload_data[f"{tool}.cmd.path"].split("/")[1:]) + tool_executable_linux = platform_upload_data.get(f"{tool}.cmd.path.linux", tool_executable_generic) + tool_executable_windows = platform_upload_data.get(f"{tool}.cmd.path.windows", "") + tool_executable_macosx = platform_upload_data.get(f"{tool}.cmd.path.macosx", "") + tool_name = tool_executable_generic.split("/")[-1] - if tool_executable == "rp2040load": - tool_executable = "rp2040tools" + tool_config_path = "" + if f"{tool}.config.path" in platform_upload_data: + tool_config_path = "/".join(platform_upload_data[f"{tool}.config.path"].split("/")[1:]) + + if tool_name == "rp2040load": + tool_name = "rp2040tools" tools = installed_json_data["packages"][0]["platforms"][0]["toolsDependencies"] - upload_data["uploader"] = get_uploader_id(tools, tool_executable) + upload_data["uploader"] = get_uploader_id(tools, tool_name) if "upload.use_1200bps_touch" in board_upload_data: upload_data["upload.use_1200bps_touch"] = bool(board_upload_data["upload.use_1200bps_touch"]) @@ -140,6 +152,7 @@ def create_upload_data(fqbn, installed_cores): # noqa: C901 .replace("{path}/{cmd}", "{uploader}") .replace("{cmd.path}", "{uploader}") .replace("{build.path}/{build.project_name}", "{loader.sketch}") + .replace("{config.path}", f"{{tool_dir}}/{tool_config_path}") .replace('\\"', "") ) @@ -163,7 +176,22 @@ def create_upload_data(fqbn, installed_cores): # noqa: C901 for k, v in {**board_upload_data, **params}.items(): command = command.replace(f"{{{k}}}", v) - upload_data["uploader.command"] = command + # This is ugly as hell and I don't care + upload_data["uploader.command"] = {} + if tool_executable_linux: + upload_data["uploader.command"]["linux"] = command.replace( + "{uploader}", f"{{tool_dir}}/{tool_executable_linux}" + ) + + if tool_executable_windows: + upload_data["uploader.command"]["windows"] = command.replace( + "{uploader}", f"{{tool_dir}}\\{tool_executable_windows}" + ) + + if tool_executable_macosx: + upload_data["uploader.command"]["macosx"] = command.replace( + "{uploader}", f"{{tool_dir}}/{tool_executable_macosx}" + ) return upload_data diff --git a/indexes/download/testdata/module_firmware_index.json b/indexes/download/testdata/module_firmware_index.json index 89ec7faf..0cced4e7 100644 --- a/indexes/download/testdata/module_firmware_index.json +++ b/indexes/download/testdata/module_firmware_index.json @@ -41,7 +41,10 @@ "uploader": "arduino:bossac@1.7.0-arduino3", "upload.use_1200bps_touch": true, "upload.wait_for_upload_port": true, - "uploader.command": "\"{uploader}\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + "uploader.command": { + "linux": "\"{tool_dir}/bossac\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R", + "windows": "\"{tool_dir}\\bossac.exe\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + } }, { "fqbn": "arduino:samd:mkrwifi1010", @@ -148,7 +151,10 @@ "uploader": "arduino:bossac@1.7.0-arduino3", "upload.use_1200bps_touch": true, "upload.wait_for_upload_port": true, - "uploader.command": "\"{uploader}\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + "uploader.command": { + "linux": "\"{tool_dir}/bossac\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R", + "windows": "\"{tool_dir}\\bossac.exe\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + } }, { "fqbn": "arduino:samd:nano_33_iot", @@ -255,7 +261,10 @@ "uploader": "arduino:bossac@1.7.0-arduino3", "upload.use_1200bps_touch": true, "upload.wait_for_upload_port": true, - "uploader.command": "\"{uploader}\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + "uploader.command": { + "linux": "\"{tool_dir}/bossac\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R", + "windows": "\"{tool_dir}\\bossac.exe\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + } }, { "fqbn": "arduino:samd:mkrvidor4000", @@ -357,7 +366,10 @@ "uploader": "arduino:bossac@1.7.0-arduino3", "upload.use_1200bps_touch": true, "upload.wait_for_upload_port": true, - "uploader.command": "\"{uploader}\" -i -d --port={serial.port.file} -I -U true -i -e -w \"{loader.sketch}.bin\" -R" + "uploader.command": { + "linux": "\"{tool_dir}/bossac\" -i -d --port={serial.port.file} -I -U true -i -e -w \"{loader.sketch}.bin\" -R", + "windows": "\"{tool_dir}\\bossac.exe\" -i -d --port={serial.port.file} -I -U true -i -e -w \"{loader.sketch}.bin\" -R" + } }, { "fqbn": "arduino:megaavr:uno2018", @@ -448,7 +460,9 @@ "module": "NINA", "name": "Arduino Uno WiFi Rev2", "uploader": "arduino:avrdude@6.3.0-arduino17", - "uploader.command": "\"{uploader}\" \"-C{config.path}\" -v -patmega4809 -cxplainedmini_updi -Pusb -b115200 -e -D \"-Uflash:w:{loader.sketch}.hex:i\" \"-Ufuse2:w:0x01:m\" \"-Ufuse5:w:0xC9:m\" \"-Ufuse8:w:0x02:m\" " + "uploader.command": { + "linux": "\"{tool_dir}/bin/avrdude\" \"-C{tool_dir}/etc/avrdude.conf\" -v -patmega4809 -cxplainedmini_updi -Pusb -b115200 -e -D \"-Uflash:w:{loader.sketch}.hex:i\" \"-Ufuse2:w:0x01:m\" \"-Ufuse5:w:0xC9:m\" \"-Ufuse8:w:0x02:m\" " + } }, { "fqbn": "arduino:samd:mkrnb1500", @@ -485,7 +499,10 @@ "uploader": "arduino:bossac@1.7.0-arduino3", "upload.use_1200bps_touch": true, "upload.wait_for_upload_port": true, - "uploader.command": "\"{uploader}\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + "uploader.command": { + "linux": "\"{tool_dir}/bossac\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R", + "windows": "\"{tool_dir}\\bossac.exe\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + } }, { "fqbn": "arduino:mbed_nano:nanorp2040connect", @@ -508,6 +525,8 @@ "uploader": "arduino:rp2040tools@1.0.2", "upload.use_1200bps_touch": true, "upload.wait_for_upload_port": true, - "uploader.command": "\"{uploader}\" -v -D \"{loader.sketch}.elf\"" + "uploader.command": { + "linux": "\"{tool_dir}/rp2040load\" -v -D \"{loader.sketch}.elf\"" + } } ] \ No newline at end of file diff --git a/indexes/download/testdata/module_firmware_index.json.sig b/indexes/download/testdata/module_firmware_index.json.sig index 7eff3591..7cd3f151 100644 Binary files a/indexes/download/testdata/module_firmware_index.json.sig and b/indexes/download/testdata/module_firmware_index.json.sig differ diff --git a/indexes/firmwareindex/firmwareindex.go b/indexes/firmwareindex/firmwareindex.go index 585b8665..f2c95892 100644 --- a/indexes/firmwareindex/firmwareindex.go +++ b/indexes/firmwareindex/firmwareindex.go @@ -22,6 +22,7 @@ package firmwareindex import ( "encoding/json" "fmt" + "runtime" "github.com/arduino/arduino-cli/arduino/security" "github.com/arduino/go-paths-helper" @@ -32,21 +33,27 @@ import ( // Index represents Boards struct as seen from module_firmware_index.json file. type Index struct { - Boards []*indexBoard + Boards []*IndexBoard IsTrusted bool } // indexPackage represents a single entry from module_firmware_index.json file. -type indexBoard struct { - Fqbn string `json:"fqbn,required"` - Firmwares []*IndexFirmware `json:"firmware,required"` - LoaderSketch *IndexLoaderSketch `json:"loader_sketch,required"` - Module string `json:"module,required"` - Name string `json:"name,required"` - Uploader string `json:"uploader,required"` - UploadTouch bool `json:"upload.use_1200bps_touch"` - UploadWait bool `json:"upload.wait_for_upload_port"` - UploaderCommand string `json:"uploader.command,required"` +type IndexBoard struct { + Fqbn string `json:"fqbn,required"` + Firmwares []*IndexFirmware `json:"firmware,required"` + LoaderSketch *IndexLoaderSketch `json:"loader_sketch,required"` + Module string `json:"module,required"` + Name string `json:"name,required"` + Uploader string `json:"uploader,required"` + UploadTouch bool `json:"upload.use_1200bps_touch"` + UploadWait bool `json:"upload.wait_for_upload_port"` + UploaderCommand *IndexUploaderCommand `json:"uploader.command,required"` +} + +type IndexUploaderCommand struct { + Linux string `json:"linux,required"` + Windows string `json:"windows"` + Macosx string `json:"macosx"` } // IndexFirmware represents a single Firmware version from module_firmware_index.json file. @@ -172,14 +179,14 @@ func (i *Index) GetLoaderSketchURL(fqbn string) (string, error) { return "", fmt.Errorf("invalid FQBN: %s", fqbn) } -// GetUploaderCommand will take the board's fqbn and return the command used for upload -func (i *Index) GetUploaderCommand(fqbn string) (string, error) { - for _, board := range i.Boards { - if board.Fqbn == fqbn { - return board.UploaderCommand, nil - } +func (b *IndexBoard) GetUploaderCommand() string { + if runtime.GOOS == "windows" && b.UploaderCommand.Windows != "" { + return b.UploaderCommand.Linux + } else if runtime.GOOS == "darwin" && b.UploaderCommand.Macosx != "" { + return b.UploaderCommand.Macosx } - return "", fmt.Errorf("invalid FQBN: %s", fqbn) + // The linux uploader command is considere to be the generic one + return b.UploaderCommand.Linux } // GetModule will take the board's fqbn and return the name of the module diff --git a/indexes/firmwareindex/firmwareindex_test.go b/indexes/firmwareindex/firmwareindex_test.go index 158a2239..41b49073 100644 --- a/indexes/firmwareindex/firmwareindex_test.go +++ b/indexes/firmwareindex/firmwareindex_test.go @@ -91,22 +91,6 @@ func TestGetLoaderSketchURL(t *testing.T) { require.Empty(t, result) } -func TestGetUploaderCommand(t *testing.T) { - indexFile := paths.New("testdata/module_firmware_index.json") - t.Logf("testing with index: %s", indexFile) - index, e := LoadIndexNoSign(indexFile) - require.NoError(t, e) - require.NotEmpty(t, index) - - result, err := index.GetUploaderCommand("arduino:samd:mkr1000") - require.NoError(t, err) - require.NotEmpty(t, result) - - result, err = index.GetUploaderCommand("arduino:samd:mkr1001") - require.Error(t, err) - require.Empty(t, result) -} - func TestGetModule(t *testing.T) { indexFile := paths.New("testdata/module_firmware_index.json") t.Logf("testing with index: %s", indexFile) diff --git a/indexes/firmwareindex/testdata/module_firmware_index.json b/indexes/firmwareindex/testdata/module_firmware_index.json index 89ec7faf..0cced4e7 100644 --- a/indexes/firmwareindex/testdata/module_firmware_index.json +++ b/indexes/firmwareindex/testdata/module_firmware_index.json @@ -41,7 +41,10 @@ "uploader": "arduino:bossac@1.7.0-arduino3", "upload.use_1200bps_touch": true, "upload.wait_for_upload_port": true, - "uploader.command": "\"{uploader}\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + "uploader.command": { + "linux": "\"{tool_dir}/bossac\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R", + "windows": "\"{tool_dir}\\bossac.exe\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + } }, { "fqbn": "arduino:samd:mkrwifi1010", @@ -148,7 +151,10 @@ "uploader": "arduino:bossac@1.7.0-arduino3", "upload.use_1200bps_touch": true, "upload.wait_for_upload_port": true, - "uploader.command": "\"{uploader}\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + "uploader.command": { + "linux": "\"{tool_dir}/bossac\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R", + "windows": "\"{tool_dir}\\bossac.exe\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + } }, { "fqbn": "arduino:samd:nano_33_iot", @@ -255,7 +261,10 @@ "uploader": "arduino:bossac@1.7.0-arduino3", "upload.use_1200bps_touch": true, "upload.wait_for_upload_port": true, - "uploader.command": "\"{uploader}\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + "uploader.command": { + "linux": "\"{tool_dir}/bossac\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R", + "windows": "\"{tool_dir}\\bossac.exe\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + } }, { "fqbn": "arduino:samd:mkrvidor4000", @@ -357,7 +366,10 @@ "uploader": "arduino:bossac@1.7.0-arduino3", "upload.use_1200bps_touch": true, "upload.wait_for_upload_port": true, - "uploader.command": "\"{uploader}\" -i -d --port={serial.port.file} -I -U true -i -e -w \"{loader.sketch}.bin\" -R" + "uploader.command": { + "linux": "\"{tool_dir}/bossac\" -i -d --port={serial.port.file} -I -U true -i -e -w \"{loader.sketch}.bin\" -R", + "windows": "\"{tool_dir}\\bossac.exe\" -i -d --port={serial.port.file} -I -U true -i -e -w \"{loader.sketch}.bin\" -R" + } }, { "fqbn": "arduino:megaavr:uno2018", @@ -448,7 +460,9 @@ "module": "NINA", "name": "Arduino Uno WiFi Rev2", "uploader": "arduino:avrdude@6.3.0-arduino17", - "uploader.command": "\"{uploader}\" \"-C{config.path}\" -v -patmega4809 -cxplainedmini_updi -Pusb -b115200 -e -D \"-Uflash:w:{loader.sketch}.hex:i\" \"-Ufuse2:w:0x01:m\" \"-Ufuse5:w:0xC9:m\" \"-Ufuse8:w:0x02:m\" " + "uploader.command": { + "linux": "\"{tool_dir}/bin/avrdude\" \"-C{tool_dir}/etc/avrdude.conf\" -v -patmega4809 -cxplainedmini_updi -Pusb -b115200 -e -D \"-Uflash:w:{loader.sketch}.hex:i\" \"-Ufuse2:w:0x01:m\" \"-Ufuse5:w:0xC9:m\" \"-Ufuse8:w:0x02:m\" " + } }, { "fqbn": "arduino:samd:mkrnb1500", @@ -485,7 +499,10 @@ "uploader": "arduino:bossac@1.7.0-arduino3", "upload.use_1200bps_touch": true, "upload.wait_for_upload_port": true, - "uploader.command": "\"{uploader}\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + "uploader.command": { + "linux": "\"{tool_dir}/bossac\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R", + "windows": "\"{tool_dir}\\bossac.exe\" -i -d --port={serial.port.file} -U true -i -e -w -v \"{loader.sketch}.bin\" -R" + } }, { "fqbn": "arduino:mbed_nano:nanorp2040connect", @@ -508,6 +525,8 @@ "uploader": "arduino:rp2040tools@1.0.2", "upload.use_1200bps_touch": true, "upload.wait_for_upload_port": true, - "uploader.command": "\"{uploader}\" -v -D \"{loader.sketch}.elf\"" + "uploader.command": { + "linux": "\"{tool_dir}/rp2040load\" -v -D \"{loader.sketch}.elf\"" + } } ] \ No newline at end of file diff --git a/indexes/firmwareindex/testdata/module_firmware_index.json.sig b/indexes/firmwareindex/testdata/module_firmware_index.json.sig index 7eff3591..7cd3f151 100644 Binary files a/indexes/firmwareindex/testdata/module_firmware_index.json.sig and b/indexes/firmwareindex/testdata/module_firmware_index.json.sig differ