From 13c9b5d0de739b0eebecf9c248e2822129910e8e Mon Sep 17 00:00:00 2001
From: Umberto Baldi <u.baldi@arduino.cc>
Date: Mon, 26 Feb 2024 12:34:29 +0100
Subject: [PATCH 1/4] Put upload test under upload package

---
 upload/upload_test.go | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/upload/upload_test.go b/upload/upload_test.go
index 7f5f46418..1b3c1975c 100644
--- a/upload/upload_test.go
+++ b/upload/upload_test.go
@@ -13,14 +13,13 @@
 // You should have received a copy of the GNU Affero General Public License
 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
-package upload_test
+package upload
 
 import (
 	"log"
 	"strings"
 	"testing"
 
-	"github.com/arduino/arduino-create-agent/upload"
 	homedir "github.com/mitchellh/go-homedir"
 	"github.com/sirupsen/logrus"
 )
@@ -36,11 +35,11 @@ var TestSerialData = []struct {
 	Name        string
 	Port        string
 	Commandline string
-	Extra       upload.Extra
+	Extra       Extra
 }{
 	{
 		"leonardo", "/dev/ttyACM0",
-		`"$HOME/.arduino-create/avrdude/6.3.0-arduino6/bin/avrdude" "-C$HOME/.arduino-create/avrdude/6.3.0-arduino6/etc/avrdude.conf" -v -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:./upload_test.hex:i"`, upload.Extra{Use1200bpsTouch: true, WaitForUploadPort: true}},
+		`"$HOME/.arduino-create/avrdude/6.3.0-arduino6/bin/avrdude" "-C$HOME/.arduino-create/avrdude/6.3.0-arduino6/etc/avrdude.conf" -v -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:./upload_test.hex:i"`, Extra{Use1200bpsTouch: true, WaitForUploadPort: true}},
 }
 
 func TestSerial(t *testing.T) {
@@ -51,7 +50,7 @@ func TestSerial(t *testing.T) {
 
 	for _, test := range TestSerialData {
 		commandline := strings.Replace(test.Commandline, "$HOME", home, -1)
-		err := upload.Serial(test.Port, commandline, test.Extra, logger)
+		err := Serial(test.Port, commandline, test.Extra, logger)
 		log.Println(err)
 	}
 }
@@ -61,12 +60,16 @@ var TestResolveData = []struct {
 	File         string
 	PlatformPath string
 	Commandline  string
-	Extra        upload.Extra
+	Extra        Extra
 	Result       string
 }{
-	{"arduino:avr:leonardo", "./upload_test.hex", "",
-		`"{runtime.tools.avrdude.path}/bin/avrdude" "-C{runtime.tools.avrdude.path}/etc/avrdude.conf" -v {upload.verify} -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"`, upload.Extra{Use1200bpsTouch: true, WaitForUploadPort: true},
-		`"$loc$loc{runtime.tools.avrdude.path}/bin/avrdude" "-C{runtime.tools.avrdude.path}/etc/avrdude.conf" -v $loc{upload.verify} -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:./upload_test.hex:i"`},
+	{"arduino:avr:leonardo",
+		"./upload_test.hex",
+		"",
+		`{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v {upload.verify} -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"`,
+		Extra{Use1200bpsTouch: true, WaitForUploadPort: true},
+		`$loc$loc{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v $loc{upload.verify} -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:./upload_test.hex:i"`,
+	},
 }
 
 func TestResolve(t *testing.T) {

From a251b9cccb4c58b26f0e95de2620a3f459bea73d Mon Sep 17 00:00:00 2001
From: Umberto Baldi <u.baldi@arduino.cc>
Date: Mon, 26 Feb 2024 12:47:54 +0100
Subject: [PATCH 2/4] Allow user to specify fqbn in the commandline using the
 board parameter

---
 upload/upload.go      | 1 +
 upload/upload_test.go | 9 ++++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/upload/upload.go b/upload/upload.go
index 0a3b0bace..6e899c817 100644
--- a/upload/upload.go
+++ b/upload/upload.go
@@ -46,6 +46,7 @@ func PartiallyResolve(board, file, platformPath, commandline string, extra Extra
 	commandline = strings.Replace(commandline, "{build.path}", filepath.ToSlash(filepath.Dir(file)), -1)
 	commandline = strings.Replace(commandline, "{build.project_name}", strings.TrimSuffix(filepath.Base(file), filepath.Ext(filepath.Base(file))), -1)
 	commandline = strings.Replace(commandline, "{runtime.platform.path}", filepath.ToSlash(platformPath), -1)
+	commandline = strings.Replace(commandline, "{fqbn}", board, -1)
 
 	// search for runtime variables and replace with values from Locater
 	var runtimeRe = regexp.MustCompile("\\{(.*?)\\}")
diff --git a/upload/upload_test.go b/upload/upload_test.go
index 1b3c1975c..0b42efddc 100644
--- a/upload/upload_test.go
+++ b/upload/upload_test.go
@@ -68,7 +68,14 @@ var TestResolveData = []struct {
 		"",
 		`{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v {upload.verify} -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"`,
 		Extra{Use1200bpsTouch: true, WaitForUploadPort: true},
-		`$loc$loc{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v $loc{upload.verify} -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:./upload_test.hex:i"`,
+		`$loc$loc{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v $loc{upload.verify} -patmega32u4 -cavr109 -P$loc{serial.port} -b57600 -D "-Uflash:w:./upload_test.hex:i"`,
+	},
+	{"arduino:renesas_uno:unor4wifi",
+		"UpdateFirmware.bin",
+		"",
+		`{runtime.tools.arduino-fwuploader.path}/arduino-fwuploader firmware flash -a {serial.port} -b {fqbn} -v --retries 5"`,
+		Extra{Use1200bpsTouch: true, WaitForUploadPort: true},
+		`$loc{runtime.tools.arduino-fwuploader.path}/arduino-fwuploader firmware flash -a $loc{serial.port} -b arduino:renesas_uno:unor4wifi -v --retries 5"`,
 	},
 }
 

From 92499f8052b23cdc18acd15dbbb4854e38a40db4 Mon Sep 17 00:00:00 2001
From: Umberto Baldi <u.baldi@arduino.cc>
Date: Mon, 26 Feb 2024 12:48:54 +0100
Subject: [PATCH 3/4] Add test

---
 upload/upload_test.go | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/upload/upload_test.go b/upload/upload_test.go
index 0b42efddc..c5bb05f3b 100644
--- a/upload/upload_test.go
+++ b/upload/upload_test.go
@@ -66,7 +66,7 @@ var TestResolveData = []struct {
 	{"arduino:avr:leonardo",
 		"./upload_test.hex",
 		"",
-		`{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v {upload.verify} -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"`,
+		`{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v {upload.verify} -patmega32u4 -cavr109 -P{serial.port} -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"`,
 		Extra{Use1200bpsTouch: true, WaitForUploadPort: true},
 		`$loc$loc{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v $loc{upload.verify} -patmega32u4 -cavr109 -P$loc{serial.port} -b57600 -D "-Uflash:w:./upload_test.hex:i"`,
 	},
@@ -81,7 +81,32 @@ var TestResolveData = []struct {
 
 func TestResolve(t *testing.T) {
 	for _, test := range TestResolveData {
-		result, _ := upload.PartiallyResolve(test.Board, test.File, test.PlatformPath, test.Commandline, test.Extra, mockTools{})
+		result, _ := PartiallyResolve(test.Board, test.File, test.PlatformPath, test.Commandline, test.Extra, mockTools{})
+		if result != test.Result {
+			t.Error("expected " + test.Result + ", got " + result)
+			continue
+		}
+	}
+}
+
+var TestFixupData = []struct {
+	Port        string
+	Commandline string
+	Result      string
+}{
+	{"/dev/ttyACM0",
+		`{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v {upload.verify} -patmega32u4 -cavr109 -P{serial.port} -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"`,
+		`{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v {upload.verify} -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"`,
+	},
+	{"/dev/cu.usbmodemDC5475C5557C2",
+		`{runtime.tools.arduino-fwuploader.path}/arduino-fwuploader firmware flash -a {serial.port} -b arduino:renesas_uno:unor4wifi -v --retries 5"`,
+		`{runtime.tools.arduino-fwuploader.path}/arduino-fwuploader firmware flash -a /dev/cu.usbmodemDC5475C5557C2 -b arduino:renesas_uno:unor4wifi -v --retries 5"`,
+	},
+}
+
+func TestFixupPort(t *testing.T) {
+	for _, test := range TestFixupData {
+		result := fixupPort(test.Port, test.Commandline)
 		if result != test.Result {
 			t.Error("expected " + test.Result + ", got " + result)
 			continue

From 6f12fb53a9e49da76f5e66c1ad24e78e73700995 Mon Sep 17 00:00:00 2001
From: Umberto Baldi <u.baldi@arduino.cc>
Date: Mon, 26 Feb 2024 15:30:24 +0100
Subject: [PATCH 4/4] apply suggestion from code review

---
 upload/upload_test.go | 48 +++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 22 deletions(-)

diff --git a/upload/upload_test.go b/upload/upload_test.go
index c5bb05f3b..1e030b602 100644
--- a/upload/upload_test.go
+++ b/upload/upload_test.go
@@ -59,29 +59,31 @@ var TestResolveData = []struct {
 	Board        string
 	File         string
 	PlatformPath string
-	Commandline  string
+	CommandLine  string
 	Extra        Extra
 	Result       string
 }{
-	{"arduino:avr:leonardo",
-		"./upload_test.hex",
-		"",
-		`{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v {upload.verify} -patmega32u4 -cavr109 -P{serial.port} -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"`,
-		Extra{Use1200bpsTouch: true, WaitForUploadPort: true},
-		`$loc$loc{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v $loc{upload.verify} -patmega32u4 -cavr109 -P$loc{serial.port} -b57600 -D "-Uflash:w:./upload_test.hex:i"`,
+	{
+		Board:        "arduino:avr:leonardo",
+		File:         "./upload_test.hex",
+		PlatformPath: "",
+		CommandLine:  `{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v {upload.verify} -patmega32u4 -cavr109 -P{serial.port} -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"`,
+		Extra:        Extra{Use1200bpsTouch: true, WaitForUploadPort: true},
+		Result:       `$loc$loc{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v $loc{upload.verify} -patmega32u4 -cavr109 -P$loc{serial.port} -b57600 -D "-Uflash:w:./upload_test.hex:i"`,
 	},
-	{"arduino:renesas_uno:unor4wifi",
-		"UpdateFirmware.bin",
-		"",
-		`{runtime.tools.arduino-fwuploader.path}/arduino-fwuploader firmware flash -a {serial.port} -b {fqbn} -v --retries 5"`,
-		Extra{Use1200bpsTouch: true, WaitForUploadPort: true},
-		`$loc{runtime.tools.arduino-fwuploader.path}/arduino-fwuploader firmware flash -a $loc{serial.port} -b arduino:renesas_uno:unor4wifi -v --retries 5"`,
+	{
+		Board:        "arduino:renesas_uno:unor4wifi",
+		File:         "UpdateFirmware.bin",
+		PlatformPath: "",
+		CommandLine:  `{runtime.tools.arduino-fwuploader.path}/arduino-fwuploader firmware flash -a {serial.port} -b {fqbn} -v --retries 5"`,
+		Extra:        Extra{Use1200bpsTouch: true, WaitForUploadPort: true},
+		Result:       `$loc{runtime.tools.arduino-fwuploader.path}/arduino-fwuploader firmware flash -a $loc{serial.port} -b arduino:renesas_uno:unor4wifi -v --retries 5"`,
 	},
 }
 
 func TestResolve(t *testing.T) {
 	for _, test := range TestResolveData {
-		result, _ := PartiallyResolve(test.Board, test.File, test.PlatformPath, test.Commandline, test.Extra, mockTools{})
+		result, _ := PartiallyResolve(test.Board, test.File, test.PlatformPath, test.CommandLine, test.Extra, mockTools{})
 		if result != test.Result {
 			t.Error("expected " + test.Result + ", got " + result)
 			continue
@@ -91,22 +93,24 @@ func TestResolve(t *testing.T) {
 
 var TestFixupData = []struct {
 	Port        string
-	Commandline string
+	CommandLine string
 	Result      string
 }{
-	{"/dev/ttyACM0",
-		`{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v {upload.verify} -patmega32u4 -cavr109 -P{serial.port} -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"`,
-		`{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v {upload.verify} -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"`,
+	{
+		Port:        "/dev/ttyACM0",
+		CommandLine: `{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v {upload.verify} -patmega32u4 -cavr109 -P{serial.port} -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"`,
+		Result:      `{runtime.tools.avrdude.path}/bin/avrdude -C{runtime.tools.avrdude.path}/etc/avrdude.conf -v {upload.verify} -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"`,
 	},
-	{"/dev/cu.usbmodemDC5475C5557C2",
-		`{runtime.tools.arduino-fwuploader.path}/arduino-fwuploader firmware flash -a {serial.port} -b arduino:renesas_uno:unor4wifi -v --retries 5"`,
-		`{runtime.tools.arduino-fwuploader.path}/arduino-fwuploader firmware flash -a /dev/cu.usbmodemDC5475C5557C2 -b arduino:renesas_uno:unor4wifi -v --retries 5"`,
+	{
+		Port:        "/dev/cu.usbmodemDC5475C5557C2",
+		CommandLine: `{runtime.tools.arduino-fwuploader.path}/arduino-fwuploader firmware flash -a {serial.port} -b arduino:renesas_uno:unor4wifi -v --retries 5"`,
+		Result:      `{runtime.tools.arduino-fwuploader.path}/arduino-fwuploader firmware flash -a /dev/cu.usbmodemDC5475C5557C2 -b arduino:renesas_uno:unor4wifi -v --retries 5"`,
 	},
 }
 
 func TestFixupPort(t *testing.T) {
 	for _, test := range TestFixupData {
-		result := fixupPort(test.Port, test.Commandline)
+		result := fixupPort(test.Port, test.CommandLine)
 		if result != test.Result {
 			t.Error("expected " + test.Result + ", got " + result)
 			continue