Skip to content

Commit

Permalink
Add --all flag to core list command and gRPC interface (#1166)
Browse files Browse the repository at this point in the history
Setting that flags return all installed and installable platforms,
including installed manually by the user in their Sketchbook hardware
folder.
  • Loading branch information
silvanocerza committed Feb 12, 2021
1 parent 560025a commit 13f5203
Show file tree
Hide file tree
Showing 12 changed files with 371 additions and 81 deletions.
11 changes: 6 additions & 5 deletions arduino/cores/cores.go
Expand Up @@ -28,11 +28,12 @@ import (

// Platform represents a platform package.
type Platform struct {
Architecture string // The name of the architecture of this package.
Name string
Category string
Releases map[string]*PlatformRelease // The Releases of this platform, labeled by version.
Package *Package `json:"-"`
Architecture string // The name of the architecture of this package.
Name string
Category string
Releases map[string]*PlatformRelease // The Releases of this platform, labeled by version.
Package *Package `json:"-"`
ManuallyInstalled bool // true if the Platform has been installed without the CLI
}

// PlatformReleaseHelp represents the help URL for this Platform release
Expand Down
23 changes: 13 additions & 10 deletions arduino/cores/packagemanager/loader.go
Expand Up @@ -166,18 +166,15 @@ func (pm *PackageManager) loadPlatforms(targetPackage *cores.Package, packageDir
return fmt.Errorf("looking for boards.txt in %s: %s", possibleBoardTxtPath, err)

} else if exist {

// case: ARCHITECTURE/boards.txt
// this is the general case for unversioned Platform
version := semver.MustParse("")

// FIXME: this check is duplicated, find a better way to handle this
if exist, err := platformPath.Join("boards.txt").ExistCheck(); err != nil {
return fmt.Errorf("opening boards.txt: %s", err)
} else if !exist {
continue
platformTxtPath := platformPath.Join("platform.txt")
platformProperties, err := properties.SafeLoad(platformTxtPath.String())
if err != nil {
return fmt.Errorf("loading platform.txt: %w", err)
}

platformName := platformProperties.Get("name")
version := semver.MustParse(platformProperties.Get("version"))

// check if package_bundled_index.json exists
isIDEBundled := false
packageBundledIndexPath := packageDir.Parent().Join("package_index_bundled.json")
Expand Down Expand Up @@ -210,6 +207,12 @@ func (pm *PackageManager) loadPlatforms(targetPackage *cores.Package, packageDir
}

platform := targetPackage.GetOrCreatePlatform(architecture)
if platform.Name == "" {
platform.Name = platformName
}
if !isIDEBundled {
platform.ManuallyInstalled = true
}
release := platform.GetOrCreateRelease(version)
release.IsIDEBundled = isIDEBundled
if isIDEBundled {
Expand Down
3 changes: 3 additions & 0 deletions cli/core/list.go
Expand Up @@ -39,11 +39,13 @@ func initListCommand() *cobra.Command {
Run: runListCommand,
}
listCommand.Flags().BoolVar(&listFlags.updatableOnly, "updatable", false, "List updatable platforms.")
listCommand.Flags().BoolVar(&listFlags.all, "all", false, "If set return all installable and installed cores, including manually installed.")
return listCommand
}

var listFlags struct {
updatableOnly bool
all bool
}

func runListCommand(cmd *cobra.Command, args []string) {
Expand All @@ -58,6 +60,7 @@ func runListCommand(cmd *cobra.Command, args []string) {
platforms, err := core.GetPlatforms(&rpc.PlatformListReq{
Instance: inst,
UpdatableOnly: listFlags.updatableOnly,
All: listFlags.all,
})
if err != nil {
feedback.Errorf("Error listing platforms: %v", err)
Expand Down
15 changes: 8 additions & 7 deletions commands/core.go
Expand Up @@ -51,13 +51,14 @@ func PlatformReleaseToRPC(platformRelease *cores.PlatformRelease) *rpc.Platform
}

result := &rpc.Platform{
ID: platformRelease.Platform.String(),
Name: platformRelease.Platform.Name,
Maintainer: platformRelease.Platform.Package.Maintainer,
Website: platformRelease.Platform.Package.WebsiteURL,
Email: platformRelease.Platform.Package.Email,
Boards: boards,
Latest: platformRelease.Version.String(),
ID: platformRelease.Platform.String(),
Name: platformRelease.Platform.Name,
Maintainer: platformRelease.Platform.Package.Maintainer,
Website: platformRelease.Platform.Package.WebsiteURL,
Email: platformRelease.Platform.Package.Email,
Boards: boards,
Latest: platformRelease.Version.String(),
ManuallyInstalled: platformRelease.Platform.ManuallyInstalled,
}

return result
Expand Down
15 changes: 15 additions & 0 deletions commands/core/list.go
Expand Up @@ -39,6 +39,21 @@ func GetPlatforms(req *rpc.PlatformListReq) ([]*rpc.Platform, error) {
for _, targetPackage := range packageManager.Packages {
for _, platform := range targetPackage.Platforms {
platformRelease := packageManager.GetInstalledPlatformRelease(platform)

// If both All and UpdatableOnly are set All takes precedence
if req.All {
installedVersion := ""
if platformRelease == nil {
platformRelease = platform.GetLatestRelease()
} else {
installedVersion = platformRelease.Version.String()
}
rpcPlatform := commands.PlatformReleaseToRPC(platform.GetLatestRelease())
rpcPlatform.Installed = installedVersion
res = append(res, rpcPlatform)
continue
}

if platformRelease != nil {
if req.UpdatableOnly {
if latest := platform.GetLatestRelease(); latest == nil || latest == platformRelease {
Expand Down
5 changes: 4 additions & 1 deletion commands/core/search.go
Expand Up @@ -50,7 +50,10 @@ func PlatformSearch(req *rpc.PlatformSearchReq) (*rpc.PlatformSearchResp, error)
for _, targetPackage := range pm.Packages {
for _, platform := range targetPackage.Platforms {
// discard invalid platforms
if platform == nil || platform.Name == "" {
// Users can install platforms manually in the Sketchbook hardware folder,
// the core search command must operate only on platforms installed through
// the PlatformManager, thus we skip the manually installed ones.
if platform == nil || platform.Name == "" || platform.ManuallyInstalled {
continue
}

Expand Down
46 changes: 23 additions & 23 deletions legacy/builder/test/hardware_loader_test.go
Expand Up @@ -49,24 +49,24 @@ func TestLoadHardware(t *testing.T) {
require.NotNil(t, packages["arduino"])
require.Equal(t, 2, len(packages["arduino"].Platforms))

require.Equal(t, "uno", packages["arduino"].Platforms["avr"].Releases[""].Boards["uno"].BoardID)
require.Equal(t, "uno", packages["arduino"].Platforms["avr"].Releases[""].Boards["uno"].Properties.Get("_id"))
require.Equal(t, "uno", packages["arduino"].Platforms["avr"].Releases["1.6.10"].Boards["uno"].BoardID)
require.Equal(t, "uno", packages["arduino"].Platforms["avr"].Releases["1.6.10"].Boards["uno"].Properties.Get("_id"))

require.Equal(t, "yun", packages["arduino"].Platforms["avr"].Releases[""].Boards["yun"].BoardID)
require.Equal(t, "true", packages["arduino"].Platforms["avr"].Releases[""].Boards["yun"].Properties.Get("upload.wait_for_upload_port"))
require.Equal(t, "yun", packages["arduino"].Platforms["avr"].Releases["1.6.10"].Boards["yun"].BoardID)
require.Equal(t, "true", packages["arduino"].Platforms["avr"].Releases["1.6.10"].Boards["yun"].Properties.Get("upload.wait_for_upload_port"))

require.Equal(t, "{build.usb_flags}", packages["arduino"].Platforms["avr"].Releases[""].Boards["robotMotor"].Properties.Get("build.extra_flags"))
require.Equal(t, "{build.usb_flags}", packages["arduino"].Platforms["avr"].Releases["1.6.10"].Boards["robotMotor"].Properties.Get("build.extra_flags"))

require.Equal(t, "arduino_due_x", packages["arduino"].Platforms["sam"].Releases[""].Boards["arduino_due_x"].BoardID)
require.Equal(t, "arduino_due_x", packages["arduino"].Platforms["sam"].Releases["1.6.7"].Boards["arduino_due_x"].BoardID)

require.Equal(t, "ATmega123", packages["arduino"].Platforms["avr"].Releases[""].Boards["diecimila"].Properties.Get("menu.cpu.atmega123"))
require.Equal(t, "ATmega123", packages["arduino"].Platforms["avr"].Releases["1.6.10"].Boards["diecimila"].Properties.Get("menu.cpu.atmega123"))

avrPlatform := packages["arduino"].Platforms["avr"]
require.Equal(t, "Arduino AVR Boards", avrPlatform.Releases[""].Properties.Get("name"))
require.Equal(t, "-v", avrPlatform.Releases[""].Properties.Get("tools.avrdude.bootloader.params.verbose"))
require.Equal(t, "/my/personal/avrdude", avrPlatform.Releases[""].Properties.Get("tools.avrdude.cmd.path"))
require.Equal(t, "Arduino AVR Boards", avrPlatform.Releases["1.6.10"].Properties.Get("name"))
require.Equal(t, "-v", avrPlatform.Releases["1.6.10"].Properties.Get("tools.avrdude.bootloader.params.verbose"))
require.Equal(t, "/my/personal/avrdude", avrPlatform.Releases["1.6.10"].Properties.Get("tools.avrdude.cmd.path"))

require.Equal(t, "AVRISP mkII", avrPlatform.Releases[""].Programmers["avrispmkii"].Name)
require.Equal(t, "AVRISP mkII", avrPlatform.Releases["1.6.10"].Programmers["avrispmkii"].Name)

//require.Equal(t, "{runtime.tools.ctags.path}", packages.Properties.Get("tools.ctags.path"])
//require.Equal(t, "\"{cmd.path}\" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives \"{source_file}\"", packages.Properties.Get("tools.ctags.pattern"])
Expand Down Expand Up @@ -103,17 +103,17 @@ func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) {
require.NotNil(t, packages["arduino"])
require.Equal(t, 2, len(packages["arduino"].Platforms))

require.Equal(t, "uno", packages["arduino"].Platforms["avr"].Releases[""].Boards["uno"].BoardID)
require.Equal(t, "uno", packages["arduino"].Platforms["avr"].Releases[""].Boards["uno"].Properties.Get("_id"))
require.Equal(t, "uno", packages["arduino"].Platforms["avr"].Releases["1.6.10"].Boards["uno"].BoardID)
require.Equal(t, "uno", packages["arduino"].Platforms["avr"].Releases["1.6.10"].Boards["uno"].Properties.Get("_id"))

require.Equal(t, "yun", packages["arduino"].Platforms["avr"].Releases[""].Boards["yun"].BoardID)
require.Equal(t, "true", packages["arduino"].Platforms["avr"].Releases[""].Boards["yun"].Properties.Get("upload.wait_for_upload_port"))
require.Equal(t, "yun", packages["arduino"].Platforms["avr"].Releases["1.6.10"].Boards["yun"].BoardID)
require.Equal(t, "true", packages["arduino"].Platforms["avr"].Releases["1.6.10"].Boards["yun"].Properties.Get("upload.wait_for_upload_port"))

require.Equal(t, "{build.usb_flags}", packages["arduino"].Platforms["avr"].Releases[""].Boards["robotMotor"].Properties.Get("build.extra_flags"))
require.Equal(t, "{build.usb_flags}", packages["arduino"].Platforms["avr"].Releases["1.6.10"].Boards["robotMotor"].Properties.Get("build.extra_flags"))

require.Equal(t, "arduino_due_x", packages["arduino"].Platforms["sam"].Releases[""].Boards["arduino_due_x"].BoardID)
require.Equal(t, "arduino_due_x", packages["arduino"].Platforms["sam"].Releases["1.6.7"].Boards["arduino_due_x"].BoardID)

avrPlatform := packages["arduino"].Platforms["avr"].Releases[""]
avrPlatform := packages["arduino"].Platforms["avr"].Releases["1.6.10"]
require.Equal(t, "Arduino AVR Boards", avrPlatform.Properties.Get("name"))
require.Equal(t, "-v", avrPlatform.Properties.Get("tools.avrdude.bootloader.params.verbose"))
require.Equal(t, "/my/personal/avrdude", avrPlatform.Properties.Get("tools.avrdude.cmd.path"))
Expand All @@ -128,7 +128,7 @@ func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) {
require.NotNil(t, packages["my_avr_platform"])
myAVRPlatform := packages["my_avr_platform"]
//require.Equal(t, "hello world", myAVRPlatform.Properties.Get("example"))
myAVRPlatformAvrArch := myAVRPlatform.Platforms["avr"].Releases[""]
myAVRPlatformAvrArch := myAVRPlatform.Platforms["avr"].Releases["9.9.9"]
require.Equal(t, "custom_yun", myAVRPlatformAvrArch.Boards["custom_yun"].BoardID)

require.False(t, myAVRPlatformAvrArch.Properties.ContainsKey("preproc.includes.flags"))
Expand Down Expand Up @@ -219,15 +219,15 @@ func TestLoadLotsOfHardware(t *testing.T) {
require.NotNil(t, packages["my_avr_platform"])

require.Equal(t, 3, len(packages["arduino"].Platforms))
require.Equal(t, 20, len(packages["arduino"].Platforms["avr"].Releases[""].Boards))
require.Equal(t, 2, len(packages["arduino"].Platforms["sam"].Releases[""].Boards))
require.Equal(t, 20, len(packages["arduino"].Platforms["avr"].Releases["1.6.10"].Boards))
require.Equal(t, 2, len(packages["arduino"].Platforms["sam"].Releases["1.6.7"].Boards))
require.Equal(t, 3, len(packages["arduino"].Platforms["samd"].Releases["1.6.5"].Boards))

require.Equal(t, 1, len(packages["my_avr_platform"].Platforms))
require.Equal(t, 2, len(packages["my_avr_platform"].Platforms["avr"].Releases[""].Boards))
require.Equal(t, 2, len(packages["my_avr_platform"].Platforms["avr"].Releases["9.9.9"].Boards))

if runtime.GOOS != "windows" {
require.Equal(t, 1, len(packages["my_symlinked_avr_platform"].Platforms))
require.Equal(t, 2, len(packages["my_symlinked_avr_platform"].Platforms["avr"].Releases[""].Boards))
require.Equal(t, 2, len(packages["my_symlinked_avr_platform"].Platforms["avr"].Releases["9.9.9"].Boards))
}
}

0 comments on commit 13f5203

Please sign in to comment.