Unverified Commit 721ab252 authored by Luca Cipriani's avatar Luca Cipriani Committed by GitHub

Merge pull request #291 from arduino/massi/core-upgrade

Fix core upgrade
parents d876ac92 eed6d58f
......@@ -30,7 +30,7 @@ tasks:
test-legacy:
desc: Run tests for the `legacy` package
cmds:
- go test {{ default "-v" .GOFLAGS }} ./legacy/...
- go test {{ default "-v -failfast" .GOFLAGS }} ./legacy/...
test-unit-race:
desc: Run unit tests only with race condition detection
......
......@@ -18,6 +18,7 @@
package cores
import (
"encoding/json"
"strings"
paths "github.com/arduino/go-paths-helper"
......@@ -41,14 +42,13 @@ type PlatformRelease struct {
Resource *resources.DownloadResource
Version *semver.Version
BoardsManifest []*BoardManifest
Dependencies ToolDependencies // The Dependency entries to load tools.
Platform *Platform `json:"-"`
Properties *properties.Map `json:"-"`
Boards map[string]*Board `json:"-"`
Programmers map[string]*properties.Map `json:"-"`
Menus *properties.Map `json:"-"`
InstallDir *paths.Path `json:"-"`
Dependencies ToolDependencies // The Dependency entries to load tools.
Platform *Platform `json:"-"`
Properties *properties.Map `json:"-"`
Boards map[string]*Board `json:"-"`
Programmers map[string]*properties.Map `json:"-"`
Menus *properties.Map `json:"-"`
InstallDir *paths.Path `json:"-"`
}
// BoardManifest contains information about a board. These metadata are usually
......@@ -226,3 +226,25 @@ func (release *PlatformRelease) String() string {
}
return release.Platform.String() + "@" + version
}
// MarshalJSON provides a more user friendly serialization for
// PlatformRelease objects.
func (release *PlatformRelease) MarshalJSON() ([]byte, error) {
latestStr := ""
latest := release.Platform.GetLatestRelease()
if latest != nil {
latestStr = latest.Version.String()
}
return json.Marshal(&struct {
ID string `json:"ID,omitempty"`
Installed string `json:"Installed,omitempty"`
Latest string `json:"Latest,omitempty"`
Name string `json:"Name,omitempty"`
}{
ID: release.Platform.String(),
Installed: release.Version.String(),
Latest: latestStr,
Name: release.Platform.Name,
})
}
......@@ -24,7 +24,7 @@ import (
"github.com/arduino/arduino-cli/arduino/cores"
"github.com/arduino/arduino-cli/arduino/resources"
"github.com/arduino/go-paths-helper"
"go.bug.st/relaxed-semver"
semver "go.bug.st/relaxed-semver"
)
// Index represents Cores and Tools struct as seen from package_index.json file.
......@@ -97,13 +97,13 @@ type indexHelp struct {
// MergeIntoPackages converts the Index data into a cores.Packages and merge them
// with the existing conents of the cores.Packages passed as parameter.
func (index Index) MergeIntoPackages(outPackages *cores.Packages) {
func (index Index) MergeIntoPackages(outPackages cores.Packages) {
for _, inPackage := range index.Packages {
inPackage.extractPackageIn(outPackages)
}
}
func (inPackage indexPackage) extractPackageIn(outPackages *cores.Packages) {
func (inPackage indexPackage) extractPackageIn(outPackages cores.Packages) {
outPackage := outPackages.GetOrCreatePackage(inPackage.Name)
outPackage.Maintainer = inPackage.Maintainer
outPackage.WebsiteURL = inPackage.WebsiteURL
......
......@@ -23,7 +23,7 @@ import (
"github.com/arduino/arduino-cli/arduino/cores"
"go.bug.st/downloader"
"go.bug.st/relaxed-semver"
semver "go.bug.st/relaxed-semver"
)
// PlatformReference represents a tuple to identify a Platform
......@@ -44,7 +44,7 @@ func (platform *PlatformReference) String() string {
// FindPlatform returns the Platform matching the PlatformReference or nil if not found.
// The PlatformVersion field of the reference is ignored.
func (pm *PackageManager) FindPlatform(ref *PlatformReference) *cores.Platform {
targetPackage, ok := pm.GetPackages().Packages[ref.Package]
targetPackage, ok := pm.Packages[ref.Package]
if !ok {
return nil
}
......@@ -71,7 +71,7 @@ func (pm *PackageManager) FindPlatformRelease(ref *PlatformReference) *cores.Pla
// FindPlatformReleaseDependencies takes a PlatformReference and returns a set of items to download and
// a set of outputs for non existing platforms.
func (pm *PackageManager) FindPlatformReleaseDependencies(item *PlatformReference) (*cores.PlatformRelease, []*cores.ToolRelease, error) {
targetPackage, exists := pm.packages.Packages[item.Package]
targetPackage, exists := pm.Packages[item.Package]
if !exists {
return nil, nil, fmt.Errorf("package %s not found", item.Package)
}
......@@ -94,7 +94,7 @@ func (pm *PackageManager) FindPlatformReleaseDependencies(item *PlatformReferenc
}
// replaces "latest" with latest version too
toolDeps, err := pm.packages.GetDepsOfPlatformRelease(release)
toolDeps, err := pm.Packages.GetDepsOfPlatformRelease(release)
if err != nil {
return nil, nil, fmt.Errorf("getting tool dependencies for platform %s: %s", release.String(), err)
}
......
......@@ -127,7 +127,7 @@ func (pm *PackageManager) UninstallTool(toolRelease *cores.ToolRelease) error {
// passed as parameter
func (pm *PackageManager) IsToolRequired(toolRelease *cores.ToolRelease) bool {
// Search in all installed platforms
for _, targetPackage := range pm.packages.Packages {
for _, targetPackage := range pm.Packages {
for _, platform := range targetPackage.Platforms {
if platformRelease := pm.GetInstalledPlatformRelease(platform); platformRelease != nil {
if platformRelease.RequiresToolRelease(toolRelease) {
......
......@@ -112,7 +112,7 @@ func (pm *PackageManager) LoadHardwareFromDirectory(path *paths.Path) error {
continue
}
targetPackage := pm.packages.GetOrCreatePackage(packager)
targetPackage := pm.Packages.GetOrCreatePackage(packager)
if err := pm.loadPlatforms(targetPackage, architectureParentPath); err != nil {
return fmt.Errorf("loading package %s: %s", packager, err)
}
......@@ -419,7 +419,7 @@ func (pm *PackageManager) LoadToolsFromBundleDirectory(toolsPath *paths.Path) er
}
for packager, toolsData := range all.FirstLevelOf() {
targetPackage := pm.packages.GetOrCreatePackage(packager)
targetPackage := pm.Packages.GetOrCreatePackage(packager)
for toolName, toolVersion := range toolsData.AsMap() {
tool := targetPackage.GetOrCreateTool(toolName)
......@@ -431,7 +431,7 @@ func (pm *PackageManager) LoadToolsFromBundleDirectory(toolsPath *paths.Path) er
}
} else {
// otherwise load the tools inside the unnamed package
unnamedPackage := pm.packages.GetOrCreatePackage("")
unnamedPackage := pm.Packages.GetOrCreatePackage("")
pm.loadToolsFromPackage(unnamedPackage, toolsPath)
}
return nil
......
......@@ -38,9 +38,8 @@ import (
// The manager also keeps track of the status of the Packages (their Platform Releases, actually)
// installed in the system.
type PackageManager struct {
Log logrus.FieldLogger
packages *cores.Packages
Log logrus.FieldLogger
Packages cores.Packages
IndexDir *paths.Path
PackagesDir *paths.Path
DownloadDir *paths.Path
......@@ -51,7 +50,7 @@ type PackageManager struct {
func NewPackageManager(indexDir, packagesDir, downloadDir, tempDir *paths.Path) *PackageManager {
return &PackageManager{
Log: logrus.StandardLogger(),
packages: cores.NewPackages(),
Packages: cores.NewPackages(),
IndexDir: indexDir,
PackagesDir: packagesDir,
DownloadDir: downloadDir,
......@@ -59,20 +58,10 @@ func NewPackageManager(indexDir, packagesDir, downloadDir, tempDir *paths.Path)
}
}
// Clear FIXMEDOC
func (pm *PackageManager) Clear() {
pm.packages = cores.NewPackages()
}
// GetPackages FIXMEDOC
func (pm *PackageManager) GetPackages() *cores.Packages {
return pm.packages
}
// FindPlatformReleaseProvidingBoardsWithVidPid FIXMEDOC
func (pm *PackageManager) FindPlatformReleaseProvidingBoardsWithVidPid(vid, pid string) []*cores.PlatformRelease {
res := []*cores.PlatformRelease{}
for _, targetPackage := range pm.packages.Packages {
for _, targetPackage := range pm.Packages {
for _, targetPlatform := range targetPackage.Platforms {
platformRelease := targetPlatform.GetLatestRelease()
if platformRelease == nil {
......@@ -92,7 +81,7 @@ func (pm *PackageManager) FindPlatformReleaseProvidingBoardsWithVidPid(vid, pid
// FindBoardsWithVidPid FIXMEDOC
func (pm *PackageManager) FindBoardsWithVidPid(vid, pid string) []*cores.Board {
res := []*cores.Board{}
for _, targetPackage := range pm.packages.Packages {
for _, targetPackage := range pm.Packages {
for _, targetPlatform := range targetPackage.Platforms {
if platform := pm.GetInstalledPlatformRelease(targetPlatform); platform != nil {
for _, board := range platform.Boards {
......@@ -109,7 +98,7 @@ func (pm *PackageManager) FindBoardsWithVidPid(vid, pid string) []*cores.Board {
// FindBoardsWithID FIXMEDOC
func (pm *PackageManager) FindBoardsWithID(id string) []*cores.Board {
res := []*cores.Board{}
for _, targetPackage := range pm.packages.Packages {
for _, targetPackage := range pm.Packages {
for _, targetPlatform := range targetPackage.Platforms {
if platform := pm.GetInstalledPlatformRelease(targetPlatform); platform != nil {
for _, board := range platform.Boards {
......@@ -152,7 +141,7 @@ func (pm *PackageManager) ResolveFQBN(fqbn *cores.FQBN) (
*properties.Map, *cores.PlatformRelease, error) {
// Find package
targetPackage := pm.packages.Packages[fqbn.Package]
targetPackage := pm.Packages[fqbn.Package]
if targetPackage == nil {
return nil, nil, nil, nil, nil,
errors.New("unknown package " + fqbn.Package)
......@@ -189,7 +178,7 @@ func (pm *PackageManager) ResolveFQBN(fqbn *cores.FQBN) (
coreParts := strings.Split(buildProperties.Get("build.core"), ":")
if len(coreParts) > 1 {
referredPackage := coreParts[1]
buildPackage := pm.packages.Packages[referredPackage]
buildPackage := pm.Packages[referredPackage]
if buildPackage == nil {
return targetPackage, platformRelease, board, buildProperties, nil,
fmt.Errorf("missing package %s:%s required for build", referredPackage, platform)
......@@ -215,7 +204,7 @@ func (pm *PackageManager) LoadPackageIndexFromFile(indexPath *paths.Path) (*pack
return nil, fmt.Errorf("loading json index file %s: %s", indexPath, err)
}
index.MergeIntoPackages(pm.packages)
index.MergeIntoPackages(pm.Packages)
return index, nil
}
......@@ -224,7 +213,7 @@ func (pm *PackageManager) LoadPackageIndexFromFile(indexPath *paths.Path) (*pack
func (pm *PackageManager) Package(name string) *PackageActions {
//TODO: perhaps these 2 structure should be merged? cores.Packages vs pkgmgr??
var err error
thePackage := pm.packages.Packages[name]
thePackage := pm.Packages[name]
if thePackage == nil {
err = fmt.Errorf("package '%s' not found", name)
}
......@@ -350,7 +339,7 @@ func (pm *PackageManager) GetInstalledPlatformRelease(platform *cores.Platform)
// GetAllInstalledToolsReleases FIXMEDOC
func (pm *PackageManager) GetAllInstalledToolsReleases() []*cores.ToolRelease {
tools := []*cores.ToolRelease{}
for _, targetPackage := range pm.packages.Packages {
for _, targetPackage := range pm.Packages {
for _, tool := range targetPackage.Tools {
for _, release := range tool.Releases {
if release.IsInstalled() {
......@@ -366,7 +355,7 @@ func (pm *PackageManager) GetAllInstalledToolsReleases() []*cores.ToolRelease {
// useful to range all PlatformReleases in for loops.
func (pm *PackageManager) InstalledPlatformReleases() []*cores.PlatformRelease {
platforms := []*cores.PlatformRelease{}
for _, targetPackage := range pm.packages.Packages {
for _, targetPackage := range pm.Packages {
for _, platform := range targetPackage.Platforms {
for _, release := range platform.GetAllInstalled() {
platforms = append(platforms, release)
......@@ -380,7 +369,7 @@ func (pm *PackageManager) InstalledPlatformReleases() []*cores.PlatformRelease {
// all Boards in for loops.
func (pm *PackageManager) InstalledBoards() []*cores.Board {
boards := []*cores.Board{}
for _, targetPackage := range pm.packages.Packages {
for _, targetPackage := range pm.Packages {
for _, platform := range targetPackage.Platforms {
for _, release := range platform.GetAllInstalled() {
for _, board := range release.Boards {
......@@ -404,7 +393,7 @@ func (pm *PackageManager) FindToolsRequiredForBoard(board *cores.Board) ([]*core
// a Platform may not specify required tools (because it's a platform that comes from a
// sketchbook/hardware dir without a package_index.json) then add all available tools
for _, targetPackage := range pm.packages.Packages {
for _, targetPackage := range pm.Packages {
for _, tool := range targetPackage.Tools {
rel := tool.GetLatestInstalled()
if rel != nil {
......
......@@ -25,15 +25,11 @@ import (
)
// Packages represents a set of Packages
type Packages struct {
Packages map[string]*Package // Maps packager name to Package
}
type Packages map[string]*Package // Maps packager name to Package
// NewPackages creates a new Packages object
func NewPackages() *Packages {
return &Packages{
Packages: map[string]*Package{},
}
func NewPackages() Packages {
return map[string]*Package{}
}
// Package represents a package in the system.
......@@ -44,13 +40,13 @@ type Package struct {
Email string // Email of maintainer.
Platforms map[string]*Platform // The platforms in the system.
Tools map[string]*Tool // The tools in the system.
Packages *Packages `json:"-"`
Packages Packages `json:"-"`
}
// GetOrCreatePackage returns the specified Package or create an empty one
// filling all the cross-references
func (packages *Packages) GetOrCreatePackage(packager string) *Package {
if targetPackage, ok := packages.Packages[packager]; ok {
func (packages Packages) GetOrCreatePackage(packager string) *Package {
if targetPackage, ok := packages[packager]; ok {
return targetPackage
}
targetPackage := &Package{
......@@ -59,15 +55,15 @@ func (packages *Packages) GetOrCreatePackage(packager string) *Package {
Tools: map[string]*Tool{},
Packages: packages,
}
packages.Packages[packager] = targetPackage
packages[packager] = targetPackage
return targetPackage
}
// Names returns the array containing the name of the packages.
func (packages *Packages) Names() []string {
res := make([]string, len(packages.Packages))
func (packages Packages) Names() []string {
res := make([]string, len(packages))
i := 0
for n := range packages.Packages {
for n := range packages {
res[i] = n
i++
}
......@@ -75,6 +71,30 @@ func (packages *Packages) Names() []string {
return res
}
// GetDepsOfPlatformRelease returns the deps of a specified release of a core.
func (packages Packages) GetDepsOfPlatformRelease(release *PlatformRelease) ([]*ToolRelease, error) {
if release == nil {
return nil, errors.New("release cannot be nil")
}
ret := []*ToolRelease{}
for _, dep := range release.Dependencies {
pkg, exists := packages[dep.ToolPackager]
if !exists {
return nil, fmt.Errorf("package %s not found", dep.ToolPackager)
}
tool, exists := pkg.Tools[dep.ToolName]
if !exists {
return nil, fmt.Errorf("tool %s not found", dep.ToolName)
}
toolRelease, exists := tool.Releases[dep.ToolVersion.String()]
if !exists {
return nil, fmt.Errorf("tool version %s not found", dep.ToolVersion)
}
ret = append(ret, toolRelease)
}
return ret, nil
}
// GetOrCreatePlatform returns the Platform object with the specified architecture
// or creates a new one if not found
func (targetPackage *Package) GetOrCreatePlatform(architecure string) *Platform {
......@@ -110,7 +130,7 @@ func (targetPackage *Package) String() string {
}
func (tdep ToolDependency) extractTool(sc Packages) (*Tool, error) {
pkg, exists := sc.Packages[tdep.ToolPackager]
pkg, exists := sc[tdep.ToolPackager]
if !exists {
return nil, errors.New("package not found")
}
......@@ -132,27 +152,3 @@ func (tdep ToolDependency) extractRelease(sc Packages) (*ToolRelease, error) {
}
return release, nil
}
// GetDepsOfPlatformRelease returns the deps of a specified release of a core.
func (packages *Packages) GetDepsOfPlatformRelease(release *PlatformRelease) ([]*ToolRelease, error) {
if release == nil {
return nil, errors.New("release cannot be nil")
}
ret := []*ToolRelease{}
for _, dep := range release.Dependencies {
pkg, exists := packages.Packages[dep.ToolPackager]
if !exists {
return nil, fmt.Errorf("package %s not found", dep.ToolPackager)
}
tool, exists := pkg.Tools[dep.ToolName]
if !exists {
return nil, fmt.Errorf("tool %s not found", dep.ToolName)
}
toolRelease, exists := tool.Releases[dep.ToolVersion.String()]
if !exists {
return nil, fmt.Errorf("tool version %s not found", dep.ToolVersion)
}
ret = append(ret, toolRelease)
}
return ret, nil
}
......@@ -18,17 +18,16 @@
package core
import (
"context"
"fmt"
"os"
"sort"
"github.com/arduino/arduino-cli/arduino/cores"
"github.com/arduino/arduino-cli/cli/errorcodes"
"github.com/arduino/arduino-cli/cli/instance"
"github.com/arduino/arduino-cli/cli/output"
"github.com/arduino/arduino-cli/commands/core"
"github.com/arduino/arduino-cli/common/formatter"
rpc "github.com/arduino/arduino-cli/rpc/commands"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
......@@ -54,30 +53,29 @@ func runListCommand(cmd *cobra.Command, args []string) {
instance := instance.CreateInstance()
logrus.Info("Executing `arduino core list`")
resp, err := core.PlatformList(context.Background(), &rpc.PlatformListReq{
Instance: instance,
UpdatableOnly: listFlags.updatableOnly,
})
platforms, err := core.GetPlatforms(instance.Id, listFlags.updatableOnly)
if err != nil {
formatter.PrintError(err, "Error listing platforms")
os.Exit(errorcodes.ErrGeneric)
}
installed := resp.GetInstalledPlatform()
if installed != nil && len(installed) > 0 {
if output.JSONOrElse(installed) {
outputInstalledCores(installed)
}
if output.JSONOrElse(platforms) {
outputInstalledCores(platforms)
}
}
func outputInstalledCores(cores []*rpc.Platform) {
func outputInstalledCores(platforms []*cores.PlatformRelease) {
if platforms == nil || len(platforms) == 0 {
return
}
table := output.NewTable()
table.AddRow("ID", "Installed", "Latest", "Name")
sort.Slice(cores, func(i, j int) bool {
return cores[i].ID < cores[j].ID
sort.Slice(platforms, func(i, j int) bool {
return platforms[i].Platform.String() < platforms[j].Platform.String()
})
for _, item := range cores {
table.AddRow(item.GetID(), item.GetInstalled(), item.GetLatest(), item.GetName())
for _, p := range platforms {
table.AddRow(p.Platform.String(), p.Version.String(), p.Platform.GetLatestRelease().Version.String(), p.Platform.Name)
}
fmt.Print(table.Render())
}
......@@ -19,6 +19,7 @@ package core
import (
"context"
"fmt"
"os"
"github.com/arduino/arduino-cli/cli/errorcodes"
......@@ -51,23 +52,50 @@ func runUpgradeCommand(cmd *cobra.Command, args []string) {
instance := instance.CreateInstance()
logrus.Info("Executing `arduino core upgrade`")
// if no platform was passed, upgrade allthethings
if len(args) == 0 {
targets, err := core.GetPlatforms(instance.Id, true)
if err != nil {
formatter.PrintError(err, "Error retrieving core list")
os.Exit(errorcodes.ErrGeneric)
}
if len(targets) == 0 {
formatter.PrintResult("All the cores are already at the latest version")
return
}
for _, t := range targets {
args = append(args, t.Platform.String())
}
}
// proceed upgrading, if anything is upgradable
exitErr := false
platformsRefs := parsePlatformReferenceArgs(args)
for i, platformRef := range platformsRefs {
if platformRef.Version != "" {
formatter.PrintErrorMessage(("Invalid item " + args[i]))
os.Exit(errorcodes.ErrBadArgument)
exitErr = true
continue
}
}
for _, platformRef := range platformsRefs {
_, err := core.PlatformUpgrade(context.Background(), &rpc.PlatformUpgradeReq{
r := &rpc.PlatformUpgradeReq{
Instance: instance,
PlatformPackage: platformRef.Package,
Architecture: platformRef.Architecture,
}, output.ProgressBar(), output.TaskProgress(),
globals.HTTPClientHeader)
if err != nil {
}
_, err := core.PlatformUpgrade(context.Background(), r, output.ProgressBar(), output.TaskProgress(), globals.HTTPClientHeader)
if err == core.ErrAlreadyLatest {
formatter.PrintResult(fmt.Sprintf("Platform %s is already at the latest version", platformRef))
} else if err != nil {
formatter.PrintError(err, "Error during upgrade")
os.Exit(errorcodes.ErrGeneric)
}
}
if exitErr {
os.Exit(errorcodes.ErrBadArgument)
}
}
......@@ -48,7 +48,7 @@ func ListAll(ctx context.Context, req *rpc.BoardListAllReq) (*rpc.BoardListAllRe
}
list := &rpc.BoardListAllResp{Boards: []*rpc.BoardListItem{}}
for _, targetPackage := range pm.GetPackages().Packages {
for _, targetPackage := range pm.Packages {
for _, platform := range targetPackage.Platforms {
platformRelease := pm.GetInstalledPlatformRelease(platform)
if platformRelease == nil {
......
......@@ -25,7 +25,7 @@ import (
)
func loadBuiltinCtagsMetadata(pm *packagemanager.PackageManager) {
builtinPackage := pm.GetPackages().GetOrCreatePackage("builtin")
builtinPackage := pm.Packages.GetOrCreatePackage("builtin")
ctagsTool := builtinPackage.GetOrCreateTool("ctags")
ctagsRel := ctagsTool.GetOrCreateRelease(semver.ParseRelaxed("5.8-arduino11"))
ctagsRel.Flavors = []*cores.Flavor{
......
......@@ -30,7 +30,7 @@ import (
var serialDiscoveryVersion = semver.ParseRelaxed("0.5.0")
func loadBuiltinSerialDiscoveryMetadata(pm *packagemanager.PackageManager) {
builtinPackage := pm.GetPackages().GetOrCreatePackage("builtin")
builtinPackage := pm.Packages.GetOrCreatePackage("builtin")
ctagsTool := builtinPackage.GetOrCreateTool("serial-discovery")
ctagsRel := ctagsTool.GetOrCreateRelease(serialDiscoveryVersion)
ctagsRel.Flavors = []*cores.Flavor{
......
......@@ -22,10 +22,10 @@ import (
rpc "github.com/arduino/arduino-cli/rpc/commands"
)
// platformReleaseToRPC converts our internal structure to the RPC structure.
// PlatformReleaseToRPC converts our internal structure to the RPC structure.
// Note: this function does not touch the "Installed" field of rpc.Platform as it's not always clear that the
// platformRelease we're currently converting is actually installed.
func platformReleaseToRPC(platformRelease *cores.PlatformRelease) *rpc.Platform {
func PlatformReleaseToRPC(platformRelease *cores.PlatformRelease) *rpc.Platform {
boards := make([]*rpc.Board, len(platformRelease.Boards))
i := 0
for _, b := range platformRelease.Boards {
......
......@@ -18,36 +18,38 @@
package core
import (
"context"
"errors"
"github.com/arduino/arduino-cli/arduino/cores"
"github.com/arduino/arduino-cli/commands"
rpc "github.com/arduino/arduino-cli/rpc/commands"
"github.com/pkg/errors"
)
// PlatformList FIXMEDOC
func PlatformList(ctx context.Context, req *rpc.PlatformListReq) (*rpc.PlatformListResp, error) {
pm := commands.GetPackageManager(req)
if pm == nil {
// GetPlatforms returns a list of installed platforms, optionally filtered by
// those requiring an update.
func GetPlatforms(instanceID int32, updatableOnly bool) ([]*cores.PlatformRelease, error) {
i := commands.GetInstance(instanceID)
if i == nil {
return nil, errors.Errorf("unable to find an instance with ID: %d", instanceID)
}
packageManager := i.PackageManager
if packageManager == nil {
return nil, errors.New("invalid instance")
}
installed := []*rpc.Platform{}
for _, targetPackage := range pm.GetPackages().Packages {
res := []*cores.PlatformRelease{}
for _, targetPackage := range packageManager.Packages {
for _, platform := range targetPackage.Platforms {
if platformRelease := pm.GetInstalledPlatformRelease(platform); platformRelease != nil {
if req.GetUpdatableOnly() {
if platformRelease := packageManager.GetInstalledPlatformRelease(platform); platformRelease != nil {
if updatableOnly {
if latest := platform.GetLatestRelease(); latest == nil || latest == platformRelease {
continue
}
}
p := platformReleaseToRPC(platformRelease)
p.Installed = platformRelease.Version.String()
installed = append(installed, p)
res = append(res, platformRelease)
}
}
}
return &rpc.PlatformListResp{InstalledPlatform: installed}, nil
return res, nil
}
......@@ -45,7 +45,7 @@ func PlatformSearch(ctx context.Context, req *rpc.PlatformSearchReq) (*rpc.Platf
match := func(line string) bool {
return strings.Contains(strings.ToLower(line), search)
}
for _, targetPackage := range pm.GetPackages().Packages {
for _, targetPackage := range pm.Packages {
for _, platform := range targetPackage.Platforms {
platformRelease := platform.GetLatestRelease()
if platformRelease == nil {
......@@ -67,7 +67,7 @@ func PlatformSearch(ctx context.Context, req *rpc.PlatformSearchReq) (*rpc.Platf
out := make([]*rpc.Platform, len(res))
for i, platformRelease := range res {
out[i] = platformReleaseToRPC(platformRelease)
out[i] = PlatformReleaseToRPC(platformRelease)
}
return &rpc.PlatformSearchResp{SearchOutput: out}, nil
}
......@@ -28,6 +28,12 @@ import (
rpc "github.com/arduino/arduino-cli/rpc/commands"
)
var (
// ErrAlreadyLatest is returned when an upgrade is not possible because
// already at latest version.
ErrAlreadyLatest = errors.New("platform already at latest version")
)
// PlatformUpgrade FIXMEDOC
func PlatformUpgrade(ctx context.Context, req *rpc.PlatformUpgradeReq,
downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB, downloaderHeaders http.Header) (*rpc.PlatformUpgradeResp, error) {
......@@ -71,7 +77,7 @@ func upgradePlatform(pm *packagemanager.PackageManager, platformRef *packagemana
}
latest := platform.GetLatestRelease()
if !latest.Version.GreaterThan(installed.Version) {
return fmt.Errorf("platform %s is already at the latest version", platformRef)
return ErrAlreadyLatest
}
platformRef.PlatformVersion = latest.Version
toInstallRefs = append(toInstallRefs, platformRef)
......
......@@ -194,7 +194,19 @@ func (s *ArduinoCoreServerImpl) PlatformSearch(ctx context.Context, req *rpc.Pla
// PlatformList FIXMEDOC
func (s *ArduinoCoreServerImpl) PlatformList(ctx context.Context, req *rpc.PlatformListReq) (*rpc.PlatformListResp, error) {
return core.PlatformList(ctx, req)
platforms, err := core.GetPlatforms(req.Instance.Id, req.UpdatableOnly)
if err != nil {
return nil, err
}
installed := []*rpc.Platform{}
for _, p := range platforms {
rpcPlatform := core.PlatformReleaseToRPC(p)
rpcPlatform.Installed = p.Version.String()
installed = append(installed, rpcPlatform)
}
return &rpc.PlatformListResp{InstalledPlatform: installed}, nil
}
// Upload FIXMEDOC
......
......@@ -48,11 +48,11 @@ var instancesCount int32 = 1
// instantiate as many as needed by providing a different configuration
// for each one.
type CoreInstance struct {
config *configs.Configuration
pm *packagemanager.PackageManager
lm *librariesmanager.LibrariesManager
getLibOnly bool
discoveries []*discovery.Discovery
config *configs.Configuration
PackageManager *packagemanager.PackageManager
lm *librariesmanager.LibrariesManager
getLibOnly bool
discoveries []*discovery.Discovery
}
// InstanceContainer FIXMEDOC
......@@ -60,13 +60,19 @@ type InstanceContainer interface {
GetInstance() *rpc.Instance
}
// GetInstance returns a CoreInstance for the given ID, or nil if ID
// doesn't exist
func GetInstance(id int32) *CoreInstance {
return instances[id]
}
// GetPackageManager FIXMEDOC
func GetPackageManager(req InstanceContainer) *packagemanager.PackageManager {
i, ok := instances[req.GetInstance().GetId()]
if !ok {
return nil
}
return i.pm
return i.PackageManager
}
// GetLibraryManager FIXMEDOC
......@@ -93,11 +99,11 @@ func (instance *CoreInstance) installToolIfMissing(tool *cores.ToolRelease, down
return false, nil
}
taskCB(&rpc.TaskProgress{Name: "Downloading missing tool " + tool.String()})
if err := DownloadToolRelease(instance.pm, tool, downloadCB, downloaderHeaders); err != nil {
if err := DownloadToolRelease(instance.PackageManager, tool, downloadCB, downloaderHeaders); err != nil {
return false, fmt.Errorf("downloading %s tool: %s", tool, err)
}
taskCB(&rpc.TaskProgress{Completed: true})
if err := InstallToolRelease(instance.pm, tool, taskCB); err != nil {
if err := InstallToolRelease(instance.PackageManager, tool, taskCB); err != nil {
return false, fmt.Errorf("installing %s tool: %s", tool, err)
}
return true, nil
......@@ -106,21 +112,21 @@ func (instance *CoreInstance) installToolIfMissing(tool *cores.ToolRelease, down
func (instance *CoreInstance) checkForBuiltinTools(downloadCB DownloadProgressCB, taskCB TaskProgressCB,
downloaderHeaders http.Header) error {
// Check for ctags tool
ctags, _ := getBuiltinCtagsTool(instance.pm)
ctags, _ := getBuiltinCtagsTool(instance.PackageManager)
ctagsInstalled, err := instance.installToolIfMissing(ctags, downloadCB, taskCB, downloaderHeaders)
if err != nil {
return err
}
// Check for bultin serial-discovery tool
serialDiscoveryTool, _ := getBuiltinSerialDiscoveryTool(instance.pm)
serialDiscoveryTool, _ := getBuiltinSerialDiscoveryTool(instance.PackageManager)
serialDiscoveryInstalled, err := instance.installToolIfMissing(serialDiscoveryTool, downloadCB, taskCB, downloaderHeaders)
if err != nil {
return err
}
if ctagsInstalled || serialDiscoveryInstalled {
if err := instance.pm.LoadHardware(instance.config); err != nil {
if err := instance.PackageManager.LoadHardware(instance.config); err != nil {
return fmt.Errorf("could not load hardware packages: %s", err)
}
}
......@@ -128,14 +134,14 @@ func (instance *CoreInstance) checkForBuiltinTools(downloadCB DownloadProgressCB
}
func (instance *CoreInstance) startDiscoveries() error {
serialDiscovery, err := newBuiltinSerialDiscovery(instance.pm)
serialDiscovery, err := newBuiltinSerialDiscovery(instance.PackageManager)
if err != nil {
return fmt.Errorf("starting serial discovery: %s", err)
}
discoveriesToStop := instance.discoveries
discoveriesToStart := append(
discovery.ExtractDiscoveriesFromPlatforms(instance.pm),
discovery.ExtractDiscoveriesFromPlatforms(instance.PackageManager),
serialDiscovery,
)
......@@ -182,10 +188,10 @@ func Init(ctx context.Context, req *rpc.InitReq, downloadCB DownloadProgressCB,
return nil, fmt.Errorf("cannot initialize package manager: %s", err)
}
instance := &CoreInstance{
config: config,
pm: pm,
lm: lm,
getLibOnly: req.GetLibraryManagerOnly()}
config: config,
PackageManager: pm,
lm: lm,
getLibOnly: req.GetLibraryManagerOnly()}
handle := instancesCount
instancesCount++
instances[handle] = instance
......@@ -305,7 +311,7 @@ func Rescan(ctx context.Context, req *rpc.RescanReq) (*rpc.RescanResp, error) {
if err != nil {
return nil, fmt.Errorf("rescanning filesystem: %s", err)
}
coreInstance.pm = pm
coreInstance.PackageManager = pm
coreInstance.lm = lm
coreInstance.startDiscoveries()
......@@ -357,7 +363,7 @@ func createInstance(ctx context.Context, config *configs.Configuration, getLibOn
// Add libraries dirs from installed platforms
if pm != nil {
for _, targetPackage := range pm.GetPackages().Packages {
for _, targetPackage := range pm.Packages {
for _, platform := range targetPackage.Platforms {
if platformRelease := pm.GetInstalledPlatformRelease(platform); platformRelease != nil {
lm.AddPlatformReleaseLibrariesDir(platformRelease, libraries.PlatformBuiltIn)
......
......@@ -93,7 +93,7 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
uploadToolPattern = split[1]
architecture := board.PlatformRelease.Platform.Architecture
if referencedPackage := pm.GetPackages().Packages[referencedPackageName]; referencedPackage == nil {
if referencedPackage := pm.Packages[referencedPackageName]; referencedPackage == nil {
return nil, fmt.Errorf("required platform %s:%s not installed", referencedPackageName, architecture)
} else if referencedPlatform := referencedPackage.Platforms[architecture]; referencedPlatform == nil {
return nil, fmt.Errorf("required platform %s:%s not installed", referencedPackageName, architecture)
......
......@@ -43,7 +43,7 @@ func (*AddBuildBoardPropertyIfMissing) Run(ctx *types.Context) error {
packages := ctx.Hardware
logger := ctx.GetLogger()
for _, aPackage := range packages.Packages {
for _, aPackage := range packages {
for _, platform := range aPackage.Platforms {
for _, platformRelease := range platform.Releases {
for _, board := range platformRelease.Boards {
......
......@@ -45,6 +45,6 @@ func (s *HardwareLoader) Run(ctx *types.Context) error {
}
ctx.PackageManager = pm
}
ctx.Hardware = ctx.PackageManager.GetPackages()
ctx.Hardware = ctx.PackageManager.Packages
return nil
}
......@@ -46,7 +46,7 @@ func (s *RewriteHardwareKeys) Run(ctx *types.Context) error {
platformKeysRewrite := ctx.PlatformKeyRewrites
hardwareRewriteResults := ctx.HardwareRewriteResults
for _, aPackage := range packages.Packages {
for _, aPackage := range packages {
for _, platform := range aPackage.Platforms {
for _, platformRelease := range platform.Releases {
if platformRelease.Properties.Get(constants.REWRITING) != constants.REWRITING_DISABLED {
......
......@@ -90,7 +90,7 @@ func (s *SetupBuildProperties) Run(ctx *types.Context) error {
var variantPlatformRelease *cores.PlatformRelease
variantParts := strings.Split(variant, ":")
if len(variantParts) > 1 {
variantPlatform := packages.Packages[variantParts[0]].Platforms[targetPlatform.Platform.Architecture]
variantPlatform := packages[variantParts[0]].Platforms[targetPlatform.Platform.Architecture]
variantPlatformRelease = ctx.PackageManager.GetInstalledPlatformRelease(variantPlatform)
variant = variantParts[1]
} else {
......
This diff is collapsed.
......@@ -42,10 +42,9 @@ import (
func TestRewriteHardwareKeys(t *testing.T) {
ctx := &types.Context{}
packages := &cores.Packages{}
packages.Packages = map[string]*cores.Package{}
packages := cores.Packages{}
aPackage := &cores.Package{Name: "dummy"}
packages.Packages["dummy"] = aPackage
packages["dummy"] = aPackage
aPackage.Platforms = map[string]*cores.Platform{}
platform := &cores.PlatformRelease{
......@@ -83,10 +82,9 @@ func TestRewriteHardwareKeys(t *testing.T) {
func TestRewriteHardwareKeysWithRewritingDisabled(t *testing.T) {
ctx := &types.Context{}
packages := &cores.Packages{}
packages.Packages = make(map[string]*cores.Package)
packages := cores.Packages{}
aPackage := &cores.Package{Name: "dummy"}
packages.Packages["dummy"] = aPackage
packages["dummy"] = aPackage
aPackage.Platforms = make(map[string]*cores.Platform)
platform := &cores.PlatformRelease{
......
......@@ -39,7 +39,7 @@ type Context struct {
BuildOptionsJsonPrevious string
PackageManager *packagemanager.PackageManager
Hardware *cores.Packages
Hardware cores.Packages
AllTools []*cores.ToolRelease
RequiredTools []*cores.ToolRelease
TargetBoard *cores.Board
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment