Skip to content

Commit a2f01e5

Browse files
committed
Add get_available_for flag
1 parent c4d5e6e commit a2f01e5

File tree

3 files changed

+99
-5
lines changed

3 files changed

+99
-5
lines changed

cli/main.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
package main
22

33
import (
4+
"encoding/json"
45
"flag"
5-
"github.com/arduino-libraries/FirmwareUpdater/utils/context"
6-
"github.com/arduino-libraries/FirmwareUpdater/modules/nina"
7-
"github.com/arduino-libraries/FirmwareUpdater/modules/winc"
8-
"github.com/arduino-libraries/FirmwareUpdater/modules/sara"
6+
"fmt"
97
"log"
8+
"os"
109
"strings"
10+
11+
"github.com/arduino-libraries/FirmwareUpdater/modules/nina"
12+
"github.com/arduino-libraries/FirmwareUpdater/modules/sara"
13+
"github.com/arduino-libraries/FirmwareUpdater/modules/winc"
14+
"github.com/arduino-libraries/FirmwareUpdater/utils"
15+
"github.com/arduino-libraries/FirmwareUpdater/utils/context"
1116
)
1217

1318
var ctx context.Context
@@ -22,18 +27,25 @@ func init() {
2227
flag.StringVar(&ctx.BinaryToRestore, "restore_binary", "", "firmware upload binary (precompiled for the right target)")
2328
flag.StringVar(&ctx.ProgrammerPath, "programmer", "", "path of programmer in use (avrdude/bossac)")
2429
flag.StringVar(&ctx.Model, "model", "", "module model (winc, nina or sara)")
30+
flag.StringVar(&ctx.Compatible, "get_available_for", "", "Ask for available firmwares matching a given board")
2531
}
2632

2733
func main() {
2834
flag.Parse()
2935

36+
if ctx.Compatible != "" {
37+
el, _ := json.Marshal(utils.GetCompatibleWith(ctx.Compatible))
38+
fmt.Println(string(el))
39+
os.Exit(0)
40+
}
41+
3042
if ctx.PortName == "" {
3143
log.Fatal("Please specify a serial port")
3244
}
3345

3446
if ctx.Model == "nina" || strings.Contains(ctx.FirmwareFile, "NINA") || strings.Contains(ctx.FWUploaderBinary, "NINA") {
3547
nina.Run(ctx)
36-
} else if ctx.Model == "winc" || strings.Contains(ctx.FirmwareFile, "WINC") || strings.Contains(ctx.FWUploaderBinary, "WINC"){
48+
} else if ctx.Model == "winc" || strings.Contains(ctx.FirmwareFile, "WINC") || strings.Contains(ctx.FWUploaderBinary, "WINC") {
3749
winc.Run(ctx)
3850
} else {
3951
sara.Run(ctx)

utils/context/context.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type Context struct {
2525
BinaryToRestore string
2626
ProgrammerPath string
2727
Model string
28+
Compatible string
2829
}
2930

3031
type Programmer interface {

utils/utils.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package utils
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"regexp"
7+
"strings"
8+
)
9+
10+
type firmware struct {
11+
Path string
12+
Name string
13+
IsLoader bool
14+
}
15+
16+
type combo struct {
17+
match string
18+
prefer string
19+
avoid string
20+
loader string
21+
}
22+
23+
func isPreferred(existing bool, path string, board combo) bool {
24+
if path == "" {
25+
return false
26+
}
27+
if board.avoid != "" && strings.Contains(path, board.avoid) {
28+
return false
29+
}
30+
if existing && !strings.Contains(path, board.prefer) {
31+
return false
32+
}
33+
return true
34+
}
35+
36+
func GetCompatibleWith(name string) map[string][]firmware {
37+
38+
files := make(map[string][]firmware)
39+
40+
knownBoards := make(map[string]combo)
41+
knownBoards["mkr1000"] = combo{match: "(WINC1500)*(3a0)", loader: "WINC1500/Firmware*"}
42+
knownBoards["mkrwifi1010"] = combo{match: "(NINA)", loader: "NINA/Firmware*(mkrwifi)*", avoid: "uno"}
43+
knownBoards["mkrvidor4000"] = combo{match: "(NINA)", loader: "NINA/Firmware*(mkrvidor)*", avoid: "uno"}
44+
knownBoards["uno2018"] = combo{match: "(NINA)", loader: "NINA/Firmware*(unowifi)*", prefer: "uno"}
45+
knownBoards["mkrnb1500"] = combo{match: "SARA", loader: "SARA/SerialSARAPassthrough*"}
46+
47+
listAll := false
48+
49+
if knownBoards[strings.ToLower(name)].match == "" {
50+
listAll = true
51+
}
52+
53+
exePath, _ := os.Executable()
54+
root := filepath.Dir(exePath)
55+
root = filepath.Join(root, "..", "firmwares")
56+
57+
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
58+
unixPath := filepath.ToSlash(path)
59+
parts := strings.Split(unixPath, "/")
60+
fancyName := parts[len(parts)-3] + " " + parts[len(parts)-2]
61+
loader := regexp.MustCompile(knownBoards[name].loader)
62+
fw := regexp.MustCompile(knownBoards[name].match)
63+
f := firmware{
64+
Path: path,
65+
Name: fancyName,
66+
IsLoader: loader.MatchString(path) && !listAll,
67+
}
68+
folder := filepath.Dir(path)
69+
lowerPath, _ := filepath.Rel(root, path)
70+
lowerPath = strings.ToLower(lowerPath)
71+
_, alreadyPopulated := files[folder]
72+
if listAll || ((fw.MatchString(path) || f.IsLoader) && isPreferred(alreadyPopulated, lowerPath, knownBoards[name])) {
73+
files[folder] = append(files[folder], f)
74+
}
75+
return nil
76+
})
77+
if err != nil {
78+
return files
79+
}
80+
return files
81+
}

0 commit comments

Comments
 (0)