From 38496cb8e7ab4018961ec747275a7269c400d4b2 Mon Sep 17 00:00:00 2001 From: ardnew Date: Fri, 1 Jul 2022 13:46:15 -0500 Subject: [PATCH 1/3] cli: use cached index with lib search (#1624) --- internal/cli/lib/search.go | 56 ++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/internal/cli/lib/search.go b/internal/cli/lib/search.go index af56994d4cc..00a34abb5d9 100644 --- a/internal/cli/lib/search.go +++ b/internal/cli/lib/search.go @@ -21,12 +21,16 @@ import ( "os" "sort" "strings" + "time" + "github.com/arduino/arduino-cli/cli/errorcodes" "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/lib" + "github.com/arduino/arduino-cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/instance" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "github.com/arduino/go-paths-helper" "github.com/sirupsen/logrus" "github.com/spf13/cobra" semver "go.bug.st/relaxed-semver" @@ -48,6 +52,9 @@ func initSearchCommand() *cobra.Command { return searchCommand } +// indexUpdateInterval specifies the time threshold over which indexes are updated +const indexUpdateInterval = "60m" + func runSearchCommand(args []string, namesOnly bool) { inst, status := instance.Create() logrus.Info("Executing `arduino-cli lib search`") @@ -56,12 +63,14 @@ func runSearchCommand(args []string, namesOnly bool) { feedback.Fatal(tr("Error creating instance: %v", status), feedback.ErrGeneric) } - if err := commands.UpdateLibrariesIndex( - context.Background(), - &rpc.UpdateLibrariesIndexRequest{Instance: inst}, - feedback.ProgressBar(), - ); err != nil { - feedback.Fatal(tr("Error updating library index: %v", err), feedback.ErrGeneric) + if indexNeedsUpdating(indexUpdateInterval) { + if err := commands.UpdateLibrariesIndex( + context.Background(), + &rpc.UpdateLibrariesIndexRequest{Instance: inst}, + feedback.ProgressBar(), + ); err != nil { + feedback.Fatal(tr("Error updating library index: %v", err), feedback.ErrGeneric) + } } instance.Init(inst) @@ -180,3 +189,38 @@ func versionsFromSearchedLibrary(library *rpc.SearchedLibrary) []*semver.Version sort.Sort(semver.List(res)) return res } + +// indexNeedsUpdating returns whether library_index.json need updating. +// A positive duration string must be provided to calculate the time threshold +// used to update the index (default: +24 hours). +// Valid duration units are "ns", "us" (or "µs"), "ms", "s", "m", "h". +// Use a duration of 0 to always update the index. +func indexNeedsUpdating(duration string) bool { + // Library index path is constant (relative to the data directory). + // It does not depend on board manager URLs or any other configuration. + dataDir := configuration.Settings.GetString("directories.Data") + indexPath := paths.New(dataDir).Join("library_index.json") + // Verify the index file exists and we can read its fstat attrs. + if indexPath.NotExist() { + return true + } + info, err := indexPath.Stat() + if err != nil { + return true + } + // Sanity check the given threshold duration string. + now := time.Now() + modTimeThreshold, err := time.ParseDuration(duration) + if err != nil { + feedback.Error(tr("Invalid timeout: %s", err)) + os.Exit(errorcodes.ErrBadArgument) + } + // The behavior of now.After(T) is confusing if T < 0 and MTIME in the future, + // and is probably not what the user intended. Disallow negative T and inform + // the user that positive thresholds are expected. + if modTimeThreshold < 0 { + feedback.Error(tr("Timeout must be non-negative: %dns (%s)", modTimeThreshold, duration)) + os.Exit(errorcodes.ErrBadArgument) + } + return modTimeThreshold == 0 || now.After(info.ModTime().Add(modTimeThreshold)) +} From a7d7934b18c2aee9da4f26f80eb56c6e71bada27 Mon Sep 17 00:00:00 2001 From: ardnew Date: Fri, 1 Jul 2022 14:09:00 -0500 Subject: [PATCH 2/3] remove comment on default cache timeout (maintenance smell) --- internal/cli/lib/search.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cli/lib/search.go b/internal/cli/lib/search.go index 00a34abb5d9..55fccc9b0b9 100644 --- a/internal/cli/lib/search.go +++ b/internal/cli/lib/search.go @@ -192,7 +192,7 @@ func versionsFromSearchedLibrary(library *rpc.SearchedLibrary) []*semver.Version // indexNeedsUpdating returns whether library_index.json need updating. // A positive duration string must be provided to calculate the time threshold -// used to update the index (default: +24 hours). +// used to update the index. // Valid duration units are "ns", "us" (or "µs"), "ms", "s", "m", "h". // Use a duration of 0 to always update the index. func indexNeedsUpdating(duration string) bool { From 6c898948e8b7aa9dbb6c06adee6687a4d7784bb4 Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Mon, 13 Feb 2023 12:18:20 +0100 Subject: [PATCH 3/3] Simplify code applying minor changes --- internal/cli/lib/search.go | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/internal/cli/lib/search.go b/internal/cli/lib/search.go index 55fccc9b0b9..938a002ae6e 100644 --- a/internal/cli/lib/search.go +++ b/internal/cli/lib/search.go @@ -23,7 +23,6 @@ import ( "strings" "time" - "github.com/arduino/arduino-cli/cli/errorcodes" "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/lib" "github.com/arduino/arduino-cli/configuration" @@ -53,7 +52,7 @@ func initSearchCommand() *cobra.Command { } // indexUpdateInterval specifies the time threshold over which indexes are updated -const indexUpdateInterval = "60m" +const indexUpdateInterval = 60 * time.Minute func runSearchCommand(args []string, namesOnly bool) { inst, status := instance.Create() @@ -190,12 +189,8 @@ func versionsFromSearchedLibrary(library *rpc.SearchedLibrary) []*semver.Version return res } -// indexNeedsUpdating returns whether library_index.json need updating. -// A positive duration string must be provided to calculate the time threshold -// used to update the index. -// Valid duration units are "ns", "us" (or "µs"), "ms", "s", "m", "h". -// Use a duration of 0 to always update the index. -func indexNeedsUpdating(duration string) bool { +// indexNeedsUpdating returns whether library_index.json needs updating +func indexNeedsUpdating(timeout time.Duration) bool { // Library index path is constant (relative to the data directory). // It does not depend on board manager URLs or any other configuration. dataDir := configuration.Settings.GetString("directories.Data") @@ -208,19 +203,5 @@ func indexNeedsUpdating(duration string) bool { if err != nil { return true } - // Sanity check the given threshold duration string. - now := time.Now() - modTimeThreshold, err := time.ParseDuration(duration) - if err != nil { - feedback.Error(tr("Invalid timeout: %s", err)) - os.Exit(errorcodes.ErrBadArgument) - } - // The behavior of now.After(T) is confusing if T < 0 and MTIME in the future, - // and is probably not what the user intended. Disallow negative T and inform - // the user that positive thresholds are expected. - if modTimeThreshold < 0 { - feedback.Error(tr("Timeout must be non-negative: %dns (%s)", modTimeThreshold, duration)) - os.Exit(errorcodes.ErrBadArgument) - } - return modTimeThreshold == 0 || now.After(info.ModTime().Add(modTimeThreshold)) + return time.Since(info.ModTime()) > timeout }