Unverified Commit b563cf1c authored by Silvano Cerza's avatar Silvano Cerza Committed by GitHub

Changed core search to update indexes only after 24h (#1237)

parent 5f4f6e90
...@@ -18,17 +18,23 @@ package core ...@@ -18,17 +18,23 @@ package core
import ( import (
"context" "context"
"os" "os"
"path"
"sort" "sort"
"strings" "strings"
"time"
"github.com/arduino/arduino-cli/arduino/utils"
"github.com/arduino/arduino-cli/cli/errorcodes" "github.com/arduino/arduino-cli/cli/errorcodes"
"github.com/arduino/arduino-cli/cli/feedback" "github.com/arduino/arduino-cli/cli/feedback"
"github.com/arduino/arduino-cli/cli/globals"
"github.com/arduino/arduino-cli/cli/instance" "github.com/arduino/arduino-cli/cli/instance"
"github.com/arduino/arduino-cli/cli/output" "github.com/arduino/arduino-cli/cli/output"
"github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands"
"github.com/arduino/arduino-cli/commands/core" "github.com/arduino/arduino-cli/commands/core"
"github.com/arduino/arduino-cli/configuration"
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
"github.com/arduino/arduino-cli/table" "github.com/arduino/arduino-cli/table"
"github.com/arduino/go-paths-helper"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
...@@ -51,6 +57,9 @@ func initSearchCommand() *cobra.Command { ...@@ -51,6 +57,9 @@ func initSearchCommand() *cobra.Command {
return searchCommand return searchCommand
} }
// indexUpdateInterval specifies the time threshold over which indexes are updated
const indexUpdateInterval = "24h"
func runSearchCommand(cmd *cobra.Command, args []string) { func runSearchCommand(cmd *cobra.Command, args []string) {
inst, err := instance.CreateInstance() inst, err := instance.CreateInstance()
if err != nil { if err != nil {
...@@ -58,6 +67,7 @@ func runSearchCommand(cmd *cobra.Command, args []string) { ...@@ -58,6 +67,7 @@ func runSearchCommand(cmd *cobra.Command, args []string) {
os.Exit(errorcodes.ErrGeneric) os.Exit(errorcodes.ErrGeneric)
} }
if indexesNeedUpdating(indexUpdateInterval) {
_, err = commands.UpdateIndex(context.Background(), &rpc.UpdateIndexRequest{ _, err = commands.UpdateIndex(context.Background(), &rpc.UpdateIndexRequest{
Instance: inst, Instance: inst,
}, output.ProgressBar()) }, output.ProgressBar())
...@@ -65,6 +75,7 @@ func runSearchCommand(cmd *cobra.Command, args []string) { ...@@ -65,6 +75,7 @@ func runSearchCommand(cmd *cobra.Command, args []string) {
feedback.Errorf("Error updating index: %v", err) feedback.Errorf("Error updating index: %v", err)
os.Exit(errorcodes.ErrGeneric) os.Exit(errorcodes.ErrGeneric)
} }
}
arguments := strings.ToLower(strings.Join(args, " ")) arguments := strings.ToLower(strings.Join(args, " "))
logrus.Infof("Executing `arduino core search` with args: '%s'", arguments) logrus.Infof("Executing `arduino core search` with args: '%s'", arguments)
...@@ -107,3 +118,49 @@ func (sr searchResults) String() string { ...@@ -107,3 +118,49 @@ func (sr searchResults) String() string {
} }
return "No platforms matching your search." return "No platforms matching your search."
} }
// indexesNeedUpdating returns whether one or more index files need updating.
// A duration string must be provided to calculate the time threshold
// used to update the indexes, if the duration is not valid a default
// of 24 hours is used.
// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
func indexesNeedUpdating(duration string) bool {
indexpath := paths.New(configuration.Settings.GetString("directories.Data"))
now := time.Now()
modTimeThreshold, err := time.ParseDuration(duration)
// Not the most elegant way of handling this error
// but it does its job
if err != nil {
modTimeThreshold, _ = time.ParseDuration("24h")
}
urls := []string{globals.DefaultIndexURL}
urls = append(urls, configuration.Settings.GetStringSlice("board_manager.additional_urls")...)
for _, u := range urls {
URL, err := utils.URLParse(u)
if err != nil {
continue
}
if URL.Scheme == "file" {
// No need to update local files
continue
}
coreIndexPath := indexpath.Join(path.Base(URL.Path))
if coreIndexPath.NotExist() {
return true
}
info, err := coreIndexPath.Stat()
if err != nil {
return true
}
if now.After(info.ModTime().Add(modTimeThreshold)) {
return true
}
}
return false
}
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
# software without disclosing the source code of your own applications. To purchase # software without disclosing the source code of your own applications. To purchase
# a commercial license, send an email to license@arduino.cc. # a commercial license, send an email to license@arduino.cc.
import os import os
import datetime
import time
import platform import platform
import pytest import pytest
import simplejson as json import simplejson as json
...@@ -123,9 +125,7 @@ def test_core_search_no_args(run_command, httpserver): ...@@ -123,9 +125,7 @@ def test_core_search_no_args(run_command, httpserver):
assert result.ok assert result.ok
num_platforms = 0 num_platforms = 0
lines = [l.strip().split() for l in result.stdout.strip().splitlines()] lines = [l.strip().split() for l in result.stdout.strip().splitlines()]
# Index update output and the header are printed on the first lines # The header is printed on the first lines
assert ["Updating", "index:", "package_index.json", "downloaded"] in lines
assert ["Updating", "index:", "package_index.json.sig", "downloaded"] in lines
assert ["test:x86", "2.0.0", "test_core"] in lines assert ["test:x86", "2.0.0", "test_core"] in lines
header_index = lines.index(["ID", "Version", "Name"]) header_index = lines.index(["ID", "Version", "Name"])
# We use black to format and flake8 to lint .py files but they disagree on certain # We use black to format and flake8 to lint .py files but they disagree on certain
...@@ -147,9 +147,7 @@ def test_core_search_no_args(run_command, httpserver): ...@@ -147,9 +147,7 @@ def test_core_search_no_args(run_command, httpserver):
assert result.ok assert result.ok
num_platforms = 0 num_platforms = 0
lines = [l.strip().split() for l in result.stdout.strip().splitlines()] lines = [l.strip().split() for l in result.stdout.strip().splitlines()]
# Index update output and the header are printed on the first lines # The header is printed on the first lines
assert ["Updating", "index:", "package_index.json", "downloaded"] in lines
assert ["Updating", "index:", "package_index.json.sig", "downloaded"] in lines
assert ["test:x86", "2.0.0", "test_core"] in lines assert ["test:x86", "2.0.0", "test_core"] in lines
header_index = lines.index(["ID", "Version", "Name"]) header_index = lines.index(["ID", "Version", "Name"])
# We use black to format and flake8 to lint .py files but they disagree on certain # We use black to format and flake8 to lint .py files but they disagree on certain
...@@ -507,3 +505,28 @@ def test_core_list_with_installed_json(run_command, data_dir): ...@@ -507,3 +505,28 @@ def test_core_list_with_installed_json(run_command, data_dir):
# platform.txt, turns out that this core has different names used in different files # platform.txt, turns out that this core has different names used in different files
# thus the change. # thus the change.
assert mapped["adafruit:avr"]["name"] == "Adafruit Boards" assert mapped["adafruit:avr"]["name"] == "Adafruit Boards"
def test_core_search_update_index_delay(run_command, data_dir):
assert run_command("update")
# Verifies index update is not run
res = run_command("core search")
assert res.ok
assert "Updating index" not in res.stdout
# Change edit time of package index file
index_file = Path(data_dir, "package_index.json")
date = datetime.datetime.now() - datetime.timedelta(hours=25)
mod_time = time.mktime(date.timetuple())
os.utime(index_file, (mod_time, mod_time))
# Verifies index update is run
res = run_command("core search")
assert res.ok
assert "Updating index" in res.stdout
# Verifies index update is not run again
res = run_command("core search")
assert res.ok
assert "Updating index" not in res.stdout
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