Unverified Commit 36e36cfa authored by Massimiliano Pippi's avatar Massimiliano Pippi Committed by GitHub

Update single libraries (#315)

* no need to pass around the whole request object

* always show available versions on list

* refactor libraries API, let upgrade single libraries

* fixed examples

* forgot
parent d7643ae4
...@@ -45,7 +45,7 @@ func initInstance() *rpc.InitResp { ...@@ -45,7 +45,7 @@ func initInstance() *rpc.InitResp {
if resp.GetLibrariesIndexError() != "" { if resp.GetLibrariesIndexError() != "" {
commands.UpdateLibrariesIndex(context.Background(), commands.UpdateLibrariesIndex(context.Background(),
&rpc.UpdateLibrariesIndexReq{Instance: resp.GetInstance()}, output.ProgressBar()) &rpc.UpdateLibrariesIndexReq{Instance: resp.GetInstance()}, output.ProgressBar())
rescResp, err := commands.Rescan(context.Background(), &rpc.RescanReq{Instance: resp.GetInstance()}) rescResp, err := commands.Rescan(resp.GetInstance().GetId())
if rescResp.GetLibrariesIndexError() != "" { if rescResp.GetLibrariesIndexError() != "" {
formatter.PrintErrorMessage("Error loading library index: " + rescResp.GetLibrariesIndexError()) formatter.PrintErrorMessage("Error loading library index: " + rescResp.GetLibrariesIndexError())
os.Exit(errorcodes.ErrGeneric) os.Exit(errorcodes.ErrGeneric)
......
...@@ -26,21 +26,22 @@ import ( ...@@ -26,21 +26,22 @@ import (
"github.com/arduino/arduino-cli/cli/output" "github.com/arduino/arduino-cli/cli/output"
"github.com/arduino/arduino-cli/commands/lib" "github.com/arduino/arduino-cli/commands/lib"
"github.com/arduino/arduino-cli/common/formatter" "github.com/arduino/arduino-cli/common/formatter"
rpc "github.com/arduino/arduino-cli/rpc/commands"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"golang.org/x/net/context"
) )
func initUpgradeCommand() *cobra.Command { func initUpgradeCommand() *cobra.Command {
listCommand := &cobra.Command{ listCommand := &cobra.Command{
Use: "upgrade", Use: "upgrade",
Short: "Upgrades installed libraries.", Short: "Upgrades installed libraries.",
Long: "This command ungrades all installed libraries to the latest available version." + Long: "This command upgrades an installed library to the latest available version. " +
"To upgrade a single library use the 'install' command.", "Multiple libraries can be passed separated by a space. If no arguments are provided, " +
Example: " " + os.Args[0] + " lib upgrade", "the command will upgrade all the installed libraries where an update is available.",
Args: cobra.NoArgs, Example: " " + os.Args[0] + " lib upgrade \n" +
Run: runUpgradeCommand, " " + os.Args[0] + " lib upgrade Audio\n" +
" " + os.Args[0] + " lib upgrade Audio ArduinoJson",
Args: cobra.ArbitraryArgs,
Run: runUpgradeCommand,
} }
return listCommand return listCommand
} }
...@@ -48,12 +49,18 @@ func initUpgradeCommand() *cobra.Command { ...@@ -48,12 +49,18 @@ func initUpgradeCommand() *cobra.Command {
func runUpgradeCommand(cmd *cobra.Command, args []string) { func runUpgradeCommand(cmd *cobra.Command, args []string) {
instance := instance.CreateInstaceIgnorePlatformIndexErrors() instance := instance.CreateInstaceIgnorePlatformIndexErrors()
err := lib.LibraryUpgradeAll(context.Background(), &rpc.LibraryUpgradeAllReq{ if len(args) == 0 {
Instance: instance, err := lib.LibraryUpgradeAll(instance.Id, output.ProgressBar(), output.TaskProgress(), globals.HTTPClientHeader)
}, output.ProgressBar(), output.TaskProgress(), globals.HTTPClientHeader) if err != nil {
if err != nil { formatter.PrintError(err, "Error upgrading libraries")
formatter.PrintError(err, "Error upgrading libraries") os.Exit(errorcodes.ErrGeneric)
os.Exit(errorcodes.ErrGeneric) }
} else {
err := lib.LibraryUpgrade(instance.Id, args, output.ProgressBar(), output.TaskProgress(), globals.HTTPClientHeader)
if err != nil {
formatter.PrintError(err, "Error upgrading libraries")
os.Exit(errorcodes.ErrGeneric)
}
} }
logrus.Info("Done") logrus.Info("Done")
......
...@@ -57,7 +57,7 @@ func PlatformInstall(ctx context.Context, req *rpc.PlatformInstallReq, ...@@ -57,7 +57,7 @@ func PlatformInstall(ctx context.Context, req *rpc.PlatformInstallReq,
return nil, err return nil, err
} }
_, err = commands.Rescan(ctx, &rpc.RescanReq{Instance: req.Instance}) _, err = commands.Rescan(req.GetInstance().GetId())
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -69,7 +69,7 @@ func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallReq, taskC ...@@ -69,7 +69,7 @@ func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallReq, taskC
} }
} }
_, err = commands.Rescan(ctx, &rpc.RescanReq{Instance: req.Instance}) _, err = commands.Rescan(req.GetInstance().GetId())
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -52,7 +52,7 @@ func PlatformUpgrade(ctx context.Context, req *rpc.PlatformUpgradeReq, ...@@ -52,7 +52,7 @@ func PlatformUpgrade(ctx context.Context, req *rpc.PlatformUpgradeReq,
return nil, err return nil, err
} }
if _, err := commands.Rescan(ctx, &rpc.RescanReq{Instance: req.Instance}); err != nil { if _, err := commands.Rescan(req.GetInstance().GetId()); err != nil {
return nil, err return nil, err
} }
......
...@@ -76,7 +76,7 @@ func (s *ArduinoCoreServerImpl) Destroy(ctx context.Context, req *rpc.DestroyReq ...@@ -76,7 +76,7 @@ func (s *ArduinoCoreServerImpl) Destroy(ctx context.Context, req *rpc.DestroyReq
// Rescan FIXMEDOC // Rescan FIXMEDOC
func (s *ArduinoCoreServerImpl) Rescan(ctx context.Context, req *rpc.RescanReq) (*rpc.RescanResp, error) { func (s *ArduinoCoreServerImpl) Rescan(ctx context.Context, req *rpc.RescanReq) (*rpc.RescanResp, error) {
return commands.Rescan(ctx, req) return commands.Rescan(req.GetInstance().GetId())
} }
// UpdateIndex FIXMEDOC // UpdateIndex FIXMEDOC
...@@ -277,7 +277,7 @@ func (s *ArduinoCoreServerImpl) LibraryUninstall(req *rpc.LibraryUninstallReq, s ...@@ -277,7 +277,7 @@ func (s *ArduinoCoreServerImpl) LibraryUninstall(req *rpc.LibraryUninstallReq, s
// LibraryUpgradeAll FIXMEDOC // LibraryUpgradeAll FIXMEDOC
func (s *ArduinoCoreServerImpl) LibraryUpgradeAll(req *rpc.LibraryUpgradeAllReq, stream rpc.ArduinoCore_LibraryUpgradeAllServer) error { func (s *ArduinoCoreServerImpl) LibraryUpgradeAll(req *rpc.LibraryUpgradeAllReq, stream rpc.ArduinoCore_LibraryUpgradeAllServer) error {
err := lib.LibraryUpgradeAll(stream.Context(), req, err := lib.LibraryUpgradeAll(req.GetInstance().GetId(),
func(p *rpc.DownloadProgress) { stream.Send(&rpc.LibraryUpgradeAllResp{Progress: p}) }, func(p *rpc.DownloadProgress) { stream.Send(&rpc.LibraryUpgradeAllResp{Progress: p}) },
func(p *rpc.TaskProgress) { stream.Send(&rpc.LibraryUpgradeAllResp{TaskProgress: p}) }, func(p *rpc.TaskProgress) { stream.Send(&rpc.LibraryUpgradeAllResp{TaskProgress: p}) },
s.DownloaderHeaders, s.DownloaderHeaders,
......
...@@ -75,9 +75,9 @@ func GetPackageManager(req InstanceContainer) *packagemanager.PackageManager { ...@@ -75,9 +75,9 @@ func GetPackageManager(req InstanceContainer) *packagemanager.PackageManager {
return i.PackageManager return i.PackageManager
} }
// GetLibraryManager FIXMEDOC // GetLibraryManager returns the library manager for the given instance ID
func GetLibraryManager(req InstanceContainer) *librariesmanager.LibrariesManager { func GetLibraryManager(instanceID int32) *librariesmanager.LibrariesManager {
i, ok := instances[req.GetInstance().GetId()] i, ok := instances[instanceID]
if !ok { if !ok {
return nil return nil
} }
...@@ -231,7 +231,7 @@ func Destroy(ctx context.Context, req *rpc.DestroyReq) (*rpc.DestroyResp, error) ...@@ -231,7 +231,7 @@ func Destroy(ctx context.Context, req *rpc.DestroyReq) (*rpc.DestroyResp, error)
// UpdateLibrariesIndex updates the library_index.json // UpdateLibrariesIndex updates the library_index.json
func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexReq, downloadCB func(*rpc.DownloadProgress)) error { func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexReq, downloadCB func(*rpc.DownloadProgress)) error {
logrus.Info("Updating libraries index") logrus.Info("Updating libraries index")
lm := GetLibraryManager(req) lm := GetLibraryManager(req.GetInstance().GetId())
if lm == nil { if lm == nil {
return fmt.Errorf("invalid handle") return fmt.Errorf("invalid handle")
} }
...@@ -243,7 +243,7 @@ func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexReq, ...@@ -243,7 +243,7 @@ func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexReq,
if d.Error() != nil { if d.Error() != nil {
return d.Error() return d.Error()
} }
if _, err := Rescan(ctx, &rpc.RescanReq{Instance: req.Instance}); err != nil { if _, err := Rescan(req.GetInstance().GetId()); err != nil {
return fmt.Errorf("rescanning filesystem: %s", err) return fmt.Errorf("rescanning filesystem: %s", err)
} }
return nil return nil
...@@ -293,21 +293,20 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexReq, downloadCB Downlo ...@@ -293,21 +293,20 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexReq, downloadCB Downlo
return nil, fmt.Errorf("saving downloaded index %s: %s", URL, err) return nil, fmt.Errorf("saving downloaded index %s: %s", URL, err)
} }
} }
if _, err := Rescan(ctx, &rpc.RescanReq{Instance: req.Instance}); err != nil { if _, err := Rescan(id); err != nil {
return nil, fmt.Errorf("rescanning filesystem: %s", err) return nil, fmt.Errorf("rescanning filesystem: %s", err)
} }
return &rpc.UpdateIndexResp{}, nil return &rpc.UpdateIndexResp{}, nil
} }
// Rescan FIXMEDOC // Rescan restart discoveries for the given instance
func Rescan(ctx context.Context, req *rpc.RescanReq) (*rpc.RescanResp, error) { func Rescan(instanceID int32) (*rpc.RescanResp, error) {
id := req.GetInstance().GetId() coreInstance, ok := instances[instanceID]
coreInstance, ok := instances[id]
if !ok { if !ok {
return nil, fmt.Errorf("invalid handle") return nil, fmt.Errorf("invalid handle")
} }
pm, lm, reqPltIndex, reqLibIndex, err := createInstance(ctx, coreInstance.config, coreInstance.getLibOnly) pm, lm, reqPltIndex, reqLibIndex, err := createInstance(context.Background(), coreInstance.config, coreInstance.getLibOnly)
if err != nil { if err != nil {
return nil, fmt.Errorf("rescanning filesystem: %s", err) return nil, fmt.Errorf("rescanning filesystem: %s", err)
} }
......
...@@ -34,7 +34,7 @@ func LibraryDownload(ctx context.Context, req *rpc.LibraryDownloadReq, downloadC ...@@ -34,7 +34,7 @@ func LibraryDownload(ctx context.Context, req *rpc.LibraryDownloadReq, downloadC
downloaderHeaders http.Header) (*rpc.LibraryDownloadResp, error) { downloaderHeaders http.Header) (*rpc.LibraryDownloadResp, error) {
logrus.Info("Executing `arduino lib download`") logrus.Info("Executing `arduino lib download`")
lm := commands.GetLibraryManager(req) lm := commands.GetLibraryManager(req.GetInstance().GetId())
logrus.Info("Preparing download") logrus.Info("Preparing download")
......
...@@ -33,7 +33,7 @@ import ( ...@@ -33,7 +33,7 @@ import (
func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallReq, func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallReq,
downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB, downloaderHeaders http.Header) error { downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB, downloaderHeaders http.Header) error {
lm := commands.GetLibraryManager(req) lm := commands.GetLibraryManager(req.GetInstance().GetId())
libRelease, err := findLibraryIndexRelease(lm, req) libRelease, err := findLibraryIndexRelease(lm, req)
if err != nil { if err != nil {
...@@ -48,7 +48,7 @@ func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallReq, ...@@ -48,7 +48,7 @@ func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallReq,
return err return err
} }
if _, err := commands.Rescan(ctx, &rpc.RescanReq{Instance: req.Instance}); err != nil { if _, err := commands.Rescan(req.GetInstance().GetId()); err != nil {
return fmt.Errorf("rescanning libraries: %s", err) return fmt.Errorf("rescanning libraries: %s", err)
} }
return nil return nil
......
...@@ -34,7 +34,7 @@ type installedLib struct { ...@@ -34,7 +34,7 @@ type installedLib struct {
// LibraryList FIXMEDOC // LibraryList FIXMEDOC
func LibraryList(ctx context.Context, req *rpc.LibraryListReq) (*rpc.LibraryListResp, error) { func LibraryList(ctx context.Context, req *rpc.LibraryListReq) (*rpc.LibraryListResp, error) {
lm := commands.GetLibraryManager(req) lm := commands.GetLibraryManager(req.GetInstance().GetId())
instaledLib := []*rpc.InstalledLibrary{} instaledLib := []*rpc.InstalledLibrary{}
res := listLibraries(lm, req.GetUpdatable(), req.GetAll()) res := listLibraries(lm, req.GetUpdatable(), req.GetAll())
...@@ -64,12 +64,9 @@ func listLibraries(lm *librariesmanager.LibrariesManager, updatable bool, all bo ...@@ -64,12 +64,9 @@ func listLibraries(lm *librariesmanager.LibrariesManager, updatable bool, all bo
continue continue
} }
} }
var available *librariesindex.Release available := lm.Index.FindLibraryUpdate(lib)
if updatable { if updatable && available == nil {
available = lm.Index.FindLibraryUpdate(lib) continue
if available == nil {
continue
}
} }
res = append(res, &installedLib{ res = append(res, &installedLib{
Library: lib, Library: lib,
......
...@@ -29,7 +29,7 @@ import ( ...@@ -29,7 +29,7 @@ import (
// LibrarySearch FIXMEDOC // LibrarySearch FIXMEDOC
func LibrarySearch(ctx context.Context, req *rpc.LibrarySearchReq) (*rpc.LibrarySearchResp, error) { func LibrarySearch(ctx context.Context, req *rpc.LibrarySearchReq) (*rpc.LibrarySearchResp, error) {
lm := commands.GetLibraryManager(req) lm := commands.GetLibraryManager(req.GetInstance().GetId())
if lm == nil { if lm == nil {
return nil, errors.New("invalid instance") return nil, errors.New("invalid instance")
} }
......
...@@ -27,7 +27,7 @@ import ( ...@@ -27,7 +27,7 @@ import (
// LibraryUninstall FIXMEDOC // LibraryUninstall FIXMEDOC
func LibraryUninstall(ctx context.Context, req *rpc.LibraryUninstallReq, taskCB commands.TaskProgressCB) error { func LibraryUninstall(ctx context.Context, req *rpc.LibraryUninstallReq, taskCB commands.TaskProgressCB) error {
lm := commands.GetLibraryManager(req) lm := commands.GetLibraryManager(req.GetInstance().GetId())
ref, err := createLibIndexReference(lm, req) ref, err := createLibIndexReference(lm, req)
if err != nil { if err != nil {
return err return err
......
...@@ -18,33 +18,78 @@ ...@@ -18,33 +18,78 @@
package lib package lib
import ( import (
"context"
"fmt" "fmt"
"net/http" "net/http"
"github.com/arduino/arduino-cli/arduino/libraries/librariesmanager"
"github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands"
rpc "github.com/arduino/arduino-cli/rpc/commands"
) )
// LibraryUpgradeAll FIXMEDOC // LibraryUpgradeAll upgrades all the available libraries
func LibraryUpgradeAll(ctx context.Context, req *rpc.LibraryUpgradeAllReq, downloadCB commands.DownloadProgressCB, func LibraryUpgradeAll(instanceID int32, downloadCB commands.DownloadProgressCB,
taskCB commands.TaskProgressCB, headers http.Header) error {
// get the library manager
lm := commands.GetLibraryManager(instanceID)
if err := upgrade(lm, listLibraries(lm, true, true), downloadCB, taskCB, headers); err != nil {
return err
}
if _, err := commands.Rescan(instanceID); err != nil {
return fmt.Errorf("rescanning libraries: %s", err)
}
return nil
}
// LibraryUpgrade upgrades only the given libraries
func LibraryUpgrade(instanceID int32, libraryNames []string, downloadCB commands.DownloadProgressCB,
taskCB commands.TaskProgressCB, headers http.Header) error {
// get the library manager
lm := commands.GetLibraryManager(instanceID)
// get the libs to upgrade
libs := filterByName(listLibraries(lm, true, true), libraryNames)
// do it
return upgrade(lm, libs, downloadCB, taskCB, headers)
}
func upgrade(lm *librariesmanager.LibrariesManager, libs []*installedLib, downloadCB commands.DownloadProgressCB,
taskCB commands.TaskProgressCB, downloaderHeaders http.Header) error { taskCB commands.TaskProgressCB, downloaderHeaders http.Header) error {
lm := commands.GetLibraryManager(req)
// Obtain the list of upgradable libraries // Go through the list and download them
list := listLibraries(lm, true, true)
for _, upgradeDesc := range list { for _, lib := range libs {
if err := downloadLibrary(lm, upgradeDesc.Available, downloadCB, taskCB, downloaderHeaders); err != nil { if err := downloadLibrary(lm, lib.Available, downloadCB, taskCB, downloaderHeaders); err != nil {
return err return err
} }
} }
for _, upgradeDesc := range list {
installLibrary(lm, upgradeDesc.Available, taskCB)
}
if _, err := commands.Rescan(ctx, &rpc.RescanReq{Instance: req.Instance}); err != nil { // Go through the list and install them
return fmt.Errorf("rescanning libraries: %s", err) for _, lib := range libs {
if err := installLibrary(lm, lib.Available, taskCB); err != nil {
return err
}
} }
return nil return nil
} }
func filterByName(libs []*installedLib, names []string) []*installedLib {
// put the names in a map to ease lookup
queryMap := make(map[string]struct{})
for _, name := range names {
queryMap[name] = struct{}{}
}
ret := []*installedLib{}
for _, lib := range libs {
// skip if library name wasn't in the query
if _, found := queryMap[lib.Library.Name]; found {
ret = append(ret, lib)
}
}
return ret
}
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