Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Use public types defined in v2/pkgs package and move their methods …
…there
  • Loading branch information
MatteoPologruto committed Aug 29, 2023
commit 5fce69a98f23229e83544cd8257e74885410f7ee
114 changes: 6 additions & 108 deletions tools/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,53 +33,17 @@ import (
"os/exec"
"path"
"path/filepath"
"regexp"
"runtime"
"strings"
"time"

"golang.org/x/crypto/openpgp"

"github.com/arduino/arduino-create-agent/utilities"
"github.com/arduino/arduino-create-agent/v2/pkgs"
"github.com/blang/semver"
)

type system struct {
Host string `json:"host"`
URL string `json:"url"`
Name string `json:"archiveFileName"`
CheckSum string `json:"checksum"`
}

type tool struct {
Name string `json:"name"`
Version string `json:"version"`
Systems []system `json:"systems"`
}

type index struct {
Packages []struct {
Name string `json:"name"`
Tools []tool `json:"tools"`
} `json:"packages"`
}

// Source: https://github.com/arduino/arduino-cli/blob/master/arduino/cores/tools.go#L129-L142
var (
regexpLinuxArm = regexp.MustCompile("arm.*-linux-gnueabihf")
regexpLinuxArm64 = regexp.MustCompile("(aarch64|arm64)-linux-gnu")
regexpLinux64 = regexp.MustCompile("x86_64-.*linux-gnu")
regexpLinux32 = regexp.MustCompile("i[3456]86-.*linux-gnu")
regexpWindows32 = regexp.MustCompile("i[3456]86-.*(mingw32|cygwin)")
regexpWindows64 = regexp.MustCompile("(amd64|x86_64)-.*(mingw32|cygwin)")
regexpMac64 = regexp.MustCompile("x86_64-apple-darwin.*")
regexpMac32 = regexp.MustCompile("i[3456]86-apple-darwin.*")
regexpMacArm64 = regexp.MustCompile("arm64-apple-darwin.*")
regexpFreeBSDArm = regexp.MustCompile("arm.*-freebsd[0-9]*")
regexpFreeBSD32 = regexp.MustCompile("i?[3456]86-freebsd[0-9]*")
regexpFreeBSD64 = regexp.MustCompile("amd64-freebsd[0-9]*")
)

// public vars to allow override in the tests
var (
OS = runtime.GOOS
Expand Down Expand Up @@ -205,7 +169,7 @@ func (t *Tools) Download(pack, name, version, behaviour string) error {
return err
}

var data index
var data pkgs.Index
json.Unmarshal(body, &data)

// Find the tool by name
Expand Down Expand Up @@ -251,7 +215,7 @@ func (t *Tools) Download(pack, name, version, behaviour string) error {
checksum := sha256.Sum256(body)
checkSumString := "SHA-256:" + hex.EncodeToString(checksum[:sha256.Size])

if checkSumString != correctSystem.CheckSum {
if checkSumString != correctSystem.Checksum {
return errors.New("checksum doesn't match")
}

Expand Down Expand Up @@ -305,66 +269,8 @@ func (t *Tools) Download(pack, name, version, behaviour string) error {
return t.writeMap()
}

// Source: https://github.com/arduino/arduino-cli/blob/master/arduino/cores/tools.go#L144-L176
func (s *system) isExactMatchWith(osName, osArch string) bool {
if s.Host == "all" {
return true
}

switch osName + "," + osArch {
case "linux,arm", "linux,armbe":
return regexpLinuxArm.MatchString(s.Host)
case "linux,arm64":
return regexpLinuxArm64.MatchString(s.Host)
case "linux,amd64":
return regexpLinux64.MatchString(s.Host)
case "linux,386":
return regexpLinux32.MatchString(s.Host)
case "windows,386":
return regexpWindows32.MatchString(s.Host)
case "windows,amd64":
return regexpWindows64.MatchString(s.Host)
case "darwin,arm64":
return regexpMacArm64.MatchString(s.Host)
case "darwin,amd64":
return regexpMac64.MatchString(s.Host)
case "darwin,386":
return regexpMac32.MatchString(s.Host)
case "freebsd,arm":
return regexpFreeBSDArm.MatchString(s.Host)
case "freebsd,386":
return regexpFreeBSD32.MatchString(s.Host)
case "freebsd,amd64":
return regexpFreeBSD64.MatchString(s.Host)
}
return false
}

// Source: https://github.com/arduino/arduino-cli/blob/master/arduino/cores/tools.go#L178-L198
func (s *system) isCompatibleWith(osName, osArch string) (bool, int) {
if s.isExactMatchWith(osName, osArch) {
return true, 1000
}

switch osName + "," + osArch {
case "windows,amd64":
return regexpWindows32.MatchString(s.Host), 10
case "darwin,amd64":
return regexpMac32.MatchString(s.Host), 10
case "darwin,arm64":
// Compatibility guaranteed through Rosetta emulation
if regexpMac64.MatchString(s.Host) {
// Prefer amd64 version if available
return true, 20
}
return regexpMac32.MatchString(s.Host), 10
}

return false, 0
}

func findTool(pack, name, version string, data index) (tool, system) {
var correctTool tool
func findTool(pack, name, version string, data pkgs.Index) (pkgs.Tool, pkgs.System) {
var correctTool pkgs.Tool
correctTool.Version = "0.0"

for _, p := range data.Packages {
Expand All @@ -388,15 +294,7 @@ func findTool(pack, name, version string, data index) (tool, system) {
}

// Find the url based on system
var correctSystem system
maxSimilarity := -1

for _, s := range correctTool.Systems {
if comp, similarity := s.isCompatibleWith(OS, Arch); comp && similarity > maxSimilarity {
correctSystem = s
maxSimilarity = similarity
}
}
correctSystem := correctTool.GetFlavourCompatibleWith(OS, Arch)

return correctTool, correctSystem
}
Expand Down
5 changes: 3 additions & 2 deletions tools/download_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"path"
"testing"

"github.com/arduino/arduino-create-agent/v2/pkgs"
"github.com/arduino/go-paths-helper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand All @@ -47,7 +48,7 @@ func TestDownloadCorrectPlatform(t *testing.T) {
buf, err := testIndex.ReadFile()
require.NoError(t, err)

var data index
var data pkgs.Index
err = json.Unmarshal(buf, &data)
require.NoError(t, err)
for _, tc := range testCases {
Expand Down Expand Up @@ -79,7 +80,7 @@ func TestDownloadFallbackPlatform(t *testing.T) {
buf, err := testIndex.ReadFile()
require.NoError(t, err)

var data index
var data pkgs.Index
err = json.Unmarshal(buf, &data)
require.NoError(t, err)
for _, tc := range testCases {
Expand Down
111 changes: 104 additions & 7 deletions v2/pkgs/pkgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
// cores, and to download tools used for upload.
package pkgs

import "regexp"

// Index is the go representation of a typical
// package-index file, stripped from every non-used field.
type Index struct {
Expand All @@ -34,11 +36,106 @@ type Index struct {
// tool contained in a package-index file, stripped from
// every non-used field.
type Tool struct {
Name string `json:"name"`
Version string `json:"version"`
Systems []struct {
Host string `json:"host"`
URL string `json:"url"`
Checksum string `json:"checksum"`
} `json:"systems"`
Name string `json:"name"`
Version string `json:"version"`
Systems []System `json:"systems"`
}

// System is the go representation of the info needed to
// download a tool for a specific OS/Arch
type System struct {
Host string `json:"host"`
URL string `json:"url"`
Name string `json:"archiveFileName"`
Checksum string `json:"checksum"`
}

// Source: https://github.com/arduino/arduino-cli/blob/master/arduino/cores/tools.go#L129-L142
var (
regexpLinuxArm = regexp.MustCompile("arm.*-linux-gnueabihf")
regexpLinuxArm64 = regexp.MustCompile("(aarch64|arm64)-linux-gnu")
regexpLinux64 = regexp.MustCompile("x86_64-.*linux-gnu")
regexpLinux32 = regexp.MustCompile("i[3456]86-.*linux-gnu")
regexpWindows32 = regexp.MustCompile("i[3456]86-.*(mingw32|cygwin)")
regexpWindows64 = regexp.MustCompile("(amd64|x86_64)-.*(mingw32|cygwin)")
regexpMac64 = regexp.MustCompile("x86_64-apple-darwin.*")
regexpMac32 = regexp.MustCompile("i[3456]86-apple-darwin.*")
regexpMacArm64 = regexp.MustCompile("arm64-apple-darwin.*")
regexpFreeBSDArm = regexp.MustCompile("arm.*-freebsd[0-9]*")
regexpFreeBSD32 = regexp.MustCompile("i?[3456]86-freebsd[0-9]*")
regexpFreeBSD64 = regexp.MustCompile("amd64-freebsd[0-9]*")
)

// Source: https://github.com/arduino/arduino-cli/blob/master/arduino/cores/tools.go#L144-L176
func (s *System) isExactMatchWith(osName, osArch string) bool {
if s.Host == "all" {
return true
}

switch osName + "," + osArch {
case "linux,arm", "linux,armbe":
return regexpLinuxArm.MatchString(s.Host)
case "linux,arm64":
return regexpLinuxArm64.MatchString(s.Host)
case "linux,amd64":
return regexpLinux64.MatchString(s.Host)
case "linux,386":
return regexpLinux32.MatchString(s.Host)
case "windows,386":
return regexpWindows32.MatchString(s.Host)
case "windows,amd64":
return regexpWindows64.MatchString(s.Host)
case "darwin,arm64":
return regexpMacArm64.MatchString(s.Host)
case "darwin,amd64":
return regexpMac64.MatchString(s.Host)
case "darwin,386":
return regexpMac32.MatchString(s.Host)
case "freebsd,arm":
return regexpFreeBSDArm.MatchString(s.Host)
case "freebsd,386":
return regexpFreeBSD32.MatchString(s.Host)
case "freebsd,amd64":
return regexpFreeBSD64.MatchString(s.Host)
}
return false
}

// Source: https://github.com/arduino/arduino-cli/blob/master/arduino/cores/tools.go#L178-L198
func (s *System) isCompatibleWith(osName, osArch string) (bool, int) {
if s.isExactMatchWith(osName, osArch) {
return true, 1000
}

switch osName + "," + osArch {
case "windows,amd64":
return regexpWindows32.MatchString(s.Host), 10
case "darwin,amd64":
return regexpMac32.MatchString(s.Host), 10
case "darwin,arm64":
// Compatibility guaranteed through Rosetta emulation
if regexpMac64.MatchString(s.Host) {
// Prefer amd64 version if available
return true, 20
}
return regexpMac32.MatchString(s.Host), 10
}

return false, 0
}

// GetFlavourCompatibleWith returns the downloadable resource (System) compatible with the specified OS/Arch
// Source: https://github.com/arduino/arduino-cli/blob/master/arduino/cores/tools.go#L206-L216
func (t *Tool) GetFlavourCompatibleWith(osName, osArch string) System {
var correctSystem System
maxSimilarity := -1

for _, s := range t.Systems {
if comp, similarity := s.isCompatibleWith(osName, osArch); comp && similarity > maxSimilarity {
correctSystem = s
maxSimilarity = similarity
}
}

return correctSystem
}