Skip to content

Commit b563cf1

Browse files
authored
Changed core search to update indexes only after 24h (#1237)
1 parent 5f4f6e9 commit b563cf1

File tree

2 files changed

+92
-12
lines changed

2 files changed

+92
-12
lines changed

Diff for: cli/core/search.go

+63-6
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,23 @@ package core
1818
import (
1919
"context"
2020
"os"
21+
"path"
2122
"sort"
2223
"strings"
24+
"time"
2325

26+
"github.com/arduino/arduino-cli/arduino/utils"
2427
"github.com/arduino/arduino-cli/cli/errorcodes"
2528
"github.com/arduino/arduino-cli/cli/feedback"
29+
"github.com/arduino/arduino-cli/cli/globals"
2630
"github.com/arduino/arduino-cli/cli/instance"
2731
"github.com/arduino/arduino-cli/cli/output"
2832
"github.com/arduino/arduino-cli/commands"
2933
"github.com/arduino/arduino-cli/commands/core"
34+
"github.com/arduino/arduino-cli/configuration"
3035
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
3136
"github.com/arduino/arduino-cli/table"
37+
"github.com/arduino/go-paths-helper"
3238
"github.com/sirupsen/logrus"
3339
"github.com/spf13/cobra"
3440
)
@@ -51,19 +57,24 @@ func initSearchCommand() *cobra.Command {
5157
return searchCommand
5258
}
5359

60+
// indexUpdateInterval specifies the time threshold over which indexes are updated
61+
const indexUpdateInterval = "24h"
62+
5463
func runSearchCommand(cmd *cobra.Command, args []string) {
5564
inst, err := instance.CreateInstance()
5665
if err != nil {
5766
feedback.Errorf("Error searching for platforms: %v", err)
5867
os.Exit(errorcodes.ErrGeneric)
5968
}
6069

61-
_, err = commands.UpdateIndex(context.Background(), &rpc.UpdateIndexRequest{
62-
Instance: inst,
63-
}, output.ProgressBar())
64-
if err != nil {
65-
feedback.Errorf("Error updating index: %v", err)
66-
os.Exit(errorcodes.ErrGeneric)
70+
if indexesNeedUpdating(indexUpdateInterval) {
71+
_, err = commands.UpdateIndex(context.Background(), &rpc.UpdateIndexRequest{
72+
Instance: inst,
73+
}, output.ProgressBar())
74+
if err != nil {
75+
feedback.Errorf("Error updating index: %v", err)
76+
os.Exit(errorcodes.ErrGeneric)
77+
}
6778
}
6879

6980
arguments := strings.ToLower(strings.Join(args, " "))
@@ -107,3 +118,49 @@ func (sr searchResults) String() string {
107118
}
108119
return "No platforms matching your search."
109120
}
121+
122+
// indexesNeedUpdating returns whether one or more index files need updating.
123+
// A duration string must be provided to calculate the time threshold
124+
// used to update the indexes, if the duration is not valid a default
125+
// of 24 hours is used.
126+
// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
127+
func indexesNeedUpdating(duration string) bool {
128+
indexpath := paths.New(configuration.Settings.GetString("directories.Data"))
129+
130+
now := time.Now()
131+
modTimeThreshold, err := time.ParseDuration(duration)
132+
// Not the most elegant way of handling this error
133+
// but it does its job
134+
if err != nil {
135+
modTimeThreshold, _ = time.ParseDuration("24h")
136+
}
137+
138+
urls := []string{globals.DefaultIndexURL}
139+
urls = append(urls, configuration.Settings.GetStringSlice("board_manager.additional_urls")...)
140+
for _, u := range urls {
141+
URL, err := utils.URLParse(u)
142+
if err != nil {
143+
continue
144+
}
145+
146+
if URL.Scheme == "file" {
147+
// No need to update local files
148+
continue
149+
}
150+
151+
coreIndexPath := indexpath.Join(path.Base(URL.Path))
152+
if coreIndexPath.NotExist() {
153+
return true
154+
}
155+
156+
info, err := coreIndexPath.Stat()
157+
if err != nil {
158+
return true
159+
}
160+
161+
if now.After(info.ModTime().Add(modTimeThreshold)) {
162+
return true
163+
}
164+
}
165+
return false
166+
}

Diff for: test/test_core.py

+29-6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
# software without disclosing the source code of your own applications. To purchase
1414
# a commercial license, send an email to [email protected].
1515
import os
16+
import datetime
17+
import time
1618
import platform
1719
import pytest
1820
import simplejson as json
@@ -123,9 +125,7 @@ def test_core_search_no_args(run_command, httpserver):
123125
assert result.ok
124126
num_platforms = 0
125127
lines = [l.strip().split() for l in result.stdout.strip().splitlines()]
126-
# Index update output and the header are printed on the first lines
127-
assert ["Updating", "index:", "package_index.json", "downloaded"] in lines
128-
assert ["Updating", "index:", "package_index.json.sig", "downloaded"] in lines
128+
# The header is printed on the first lines
129129
assert ["test:x86", "2.0.0", "test_core"] in lines
130130
header_index = lines.index(["ID", "Version", "Name"])
131131
# 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):
147147
assert result.ok
148148
num_platforms = 0
149149
lines = [l.strip().split() for l in result.stdout.strip().splitlines()]
150-
# Index update output and the header are printed on the first lines
151-
assert ["Updating", "index:", "package_index.json", "downloaded"] in lines
152-
assert ["Updating", "index:", "package_index.json.sig", "downloaded"] in lines
150+
# The header is printed on the first lines
153151
assert ["test:x86", "2.0.0", "test_core"] in lines
154152
header_index = lines.index(["ID", "Version", "Name"])
155153
# 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):
507505
# platform.txt, turns out that this core has different names used in different files
508506
# thus the change.
509507
assert mapped["adafruit:avr"]["name"] == "Adafruit Boards"
508+
509+
510+
def test_core_search_update_index_delay(run_command, data_dir):
511+
assert run_command("update")
512+
513+
# Verifies index update is not run
514+
res = run_command("core search")
515+
assert res.ok
516+
assert "Updating index" not in res.stdout
517+
518+
# Change edit time of package index file
519+
index_file = Path(data_dir, "package_index.json")
520+
date = datetime.datetime.now() - datetime.timedelta(hours=25)
521+
mod_time = time.mktime(date.timetuple())
522+
os.utime(index_file, (mod_time, mod_time))
523+
524+
# Verifies index update is run
525+
res = run_command("core search")
526+
assert res.ok
527+
assert "Updating index" in res.stdout
528+
529+
# Verifies index update is not run again
530+
res = run_command("core search")
531+
assert res.ok
532+
assert "Updating index" not in res.stdout

0 commit comments

Comments
 (0)