fix(upgrade): restore caching mechanism
Some checks failed
Code QL / code-ql (push) Waiting to run
Release / changelog (push) Waiting to run
Release / artifacts (push) Blocked by required conditions
Azure Static Web Apps CI/CD / Build and Deploy (push) Has been cancelled

This commit is contained in:
Jan De Dobbeleer 2024-11-06 17:02:19 +01:00 committed by Jan De Dobbeleer
parent 905dd2093d
commit 63d79fe294
6 changed files with 110 additions and 18 deletions

View file

@ -30,10 +30,16 @@ func (segment *Segment) migrate(version int) {
// Cache settings // Cache settings
delete(segment.Properties, "cache_version") delete(segment.Properties, "cache_version")
segment.Cache = segment.migrateCache()
segment.IncludeFolders = segment.migrateFolders(includeFolders) segment.IncludeFolders = segment.migrateFolders(includeFolders)
segment.ExcludeFolders = segment.migrateFolders(excludeFolders) segment.ExcludeFolders = segment.migrateFolders(excludeFolders)
switch segment.Type { //nolint:exhaustive
case UPGRADE:
segment.timeoutToDuration()
default:
segment.timeoutToCache()
}
} }
func (segment *Segment) hasProperty(property properties.Property) bool { func (segment *Segment) hasProperty(property properties.Property) bool {
@ -45,24 +51,35 @@ func (segment *Segment) hasProperty(property properties.Property) bool {
return false return false
} }
func (segment *Segment) migrateCache() *cache.Config { func (segment *Segment) timeoutToCache() {
if !segment.hasProperty(cacheTimeout) { if !segment.hasProperty(cacheTimeout) {
return nil return
} }
timeout := segment.Properties.GetInt(cacheTimeout, 0) timeout := segment.Properties.GetInt(cacheTimeout, 0)
delete(segment.Properties, cacheTimeout) delete(segment.Properties, cacheTimeout)
if timeout == 0 { if timeout == 0 {
return nil return
} }
return &cache.Config{ segment.Cache = &cache.Config{
Duration: cache.ToDuration(timeout * 60), Duration: cache.ToDuration(timeout * 60),
Strategy: cache.Folder, Strategy: cache.Folder,
} }
} }
func (segment *Segment) timeoutToDuration() {
timeout := segment.Properties.GetInt(cacheTimeout, 0)
delete(segment.Properties, cacheTimeout)
if timeout == 0 {
return
}
segment.Properties[properties.CacheDuration] = cache.ToDuration(timeout * 60)
}
func (segment *Segment) migrateFolders(property properties.Property) []string { func (segment *Segment) migrateFolders(property properties.Property) []string {
if !segment.hasProperty(property) { if !segment.hasProperty(property) {
return []string{} return []string{}

View file

@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestMigrateCache(t *testing.T) { func TestTimeoutToCache(t *testing.T) {
cases := []struct { cases := []struct {
Expected *cache.Config Expected *cache.Config
Case string Case string
@ -27,8 +27,8 @@ func TestMigrateCache(t *testing.T) {
}, },
} }
got := segment.migrateCache() segment.timeoutToCache()
assert.Equal(t, tc.Expected, got, tc.Case) assert.Equal(t, tc.Expected, segment.Cache, tc.Case)
} }
} }

View file

@ -45,6 +45,8 @@ const (
DefaultHTTPTimeout = 20 DefaultHTTPTimeout = 20
// Files to trigger the segment on // Files to trigger the segment on
Files Property = "files" Files Property = "files"
// Duration of the cache
CacheDuration Property = "cache_duration"
) )
type Map map[Property]any type Map map[Property]any

View file

@ -1,11 +1,16 @@
package segments package segments
import ( import (
"encoding/json"
"errors"
"github.com/jandedobbeleer/oh-my-posh/src/build" "github.com/jandedobbeleer/oh-my-posh/src/build"
"github.com/jandedobbeleer/oh-my-posh/src/cache"
"github.com/jandedobbeleer/oh-my-posh/src/properties"
"github.com/jandedobbeleer/oh-my-posh/src/upgrade" "github.com/jandedobbeleer/oh-my-posh/src/upgrade"
) )
type upgradeData struct { type UpgradeCache struct {
Latest string `json:"latest"` Latest string `json:"latest"`
Current string `json:"current"` Current string `json:"current"`
} }
@ -16,36 +21,71 @@ type Upgrade struct {
// deprecated // deprecated
Version string Version string
upgradeData UpgradeCache
} }
const (
UPGRADECACHEKEY = "upgrade_segment"
)
func (u *Upgrade) Template() string { func (u *Upgrade) Template() string {
return " \uf019 " return " \uf019 "
} }
func (u *Upgrade) Enabled() bool { func (u *Upgrade) Enabled() bool {
u.Current = build.Version u.Current = build.Version
latest, err := u.cachedLatest(u.Current)
latest, err := u.checkUpdate(u.Current) if err != nil {
latest, err = u.checkUpdate(u.Current)
}
if err != nil || u.Current == latest.Latest { if err != nil || u.Current == latest.Latest {
return false return false
} }
u.upgradeData = *latest u.UpgradeCache = *latest
u.Version = u.Latest u.Version = u.Latest
return true return true
} }
func (u *Upgrade) checkUpdate(current string) (*upgradeData, error) { func (u *Upgrade) cachedLatest(current string) (*UpgradeCache, error) {
data, ok := u.env.Cache().Get(UPGRADECACHEKEY)
if !ok {
return nil, errors.New("no cache data")
}
var cacheJSON UpgradeCache
err := json.Unmarshal([]byte(data), &cacheJSON)
if err != nil {
return nil, err // invalid cache data
}
if current != cacheJSON.Current {
return nil, errors.New("version changed, run the check again")
}
return &cacheJSON, nil
}
func (u *Upgrade) checkUpdate(current string) (*UpgradeCache, error) {
tag, err := upgrade.Latest(u.env) tag, err := upgrade.Latest(u.env)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &upgradeData{ latest := tag[1:]
// strip leading v cacheData := &UpgradeCache{
Latest: tag[1:], Latest: latest,
Current: current, Current: current,
}, nil }
cacheJSON, err := json.Marshal(cacheData)
if err != nil {
return nil, err
}
// update cache
duration := u.props.GetString(properties.CacheDuration, string(cache.ONEWEEK))
u.env.Cache().Set(UPGRADECACHEKEY, string(cacheJSON), cache.Duration(duration))
return cacheData, nil
} }

View file

@ -6,11 +6,13 @@ import (
"testing" "testing"
"github.com/jandedobbeleer/oh-my-posh/src/build" "github.com/jandedobbeleer/oh-my-posh/src/build"
cache_ "github.com/jandedobbeleer/oh-my-posh/src/cache/mock"
"github.com/jandedobbeleer/oh-my-posh/src/properties" "github.com/jandedobbeleer/oh-my-posh/src/properties"
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock" "github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
"github.com/jandedobbeleer/oh-my-posh/src/upgrade" "github.com/jandedobbeleer/oh-my-posh/src/upgrade"
"github.com/alecthomas/assert" "github.com/alecthomas/assert"
testify_ "github.com/stretchr/testify/mock"
) )
func TestUpgrade(t *testing.T) { func TestUpgrade(t *testing.T) {
@ -38,21 +40,42 @@ func TestUpgrade(t *testing.T) {
Case: "Error on update check", Case: "Error on update check",
Error: errors.New("error"), Error: errors.New("error"),
}, },
{
Case: "On previous, from cache",
HasCache: true,
CurrentVersion: "1.0.2",
LatestVersion: "1.0.3",
CachedVersion: "1.0.2",
ExpectedEnabled: true,
},
{ {
Case: "On latest, version changed", Case: "On latest, version changed",
HasCache: true,
CurrentVersion: "1.0.2", CurrentVersion: "1.0.2",
LatestVersion: "1.0.2", LatestVersion: "1.0.2",
CachedVersion: "1.0.1",
}, },
{ {
Case: "On previous, version changed", Case: "On previous, version changed",
HasCache: true,
CurrentVersion: "1.0.2", CurrentVersion: "1.0.2",
LatestVersion: "1.0.3", LatestVersion: "1.0.3",
CachedVersion: "1.0.1",
ExpectedEnabled: true, ExpectedEnabled: true,
}, },
} }
for _, tc := range cases { for _, tc := range cases {
env := new(mock.Environment) env := new(mock.Environment)
cache := &cache_.Cache{}
env.On("Cache").Return(cache)
if len(tc.CachedVersion) == 0 {
tc.CachedVersion = tc.CurrentVersion
}
cacheData := fmt.Sprintf(`{"latest":"%s", "current": "%s"}`, tc.LatestVersion, tc.CachedVersion)
cache.On("Get", UPGRADECACHEKEY).Return(cacheData, tc.HasCache)
cache.On("Set", testify_.Anything, testify_.Anything, testify_.Anything)
build.Version = tc.CurrentVersion build.Version = tc.CurrentVersion

View file

@ -18,9 +18,18 @@ import Config from "@site/src/components/Config.js";
style: "plain", style: "plain",
foreground: "#111111", foreground: "#111111",
background: "#FFD664", background: "#FFD664",
properties: {
cache_duration: "168h",
},
}} }}
/> />
## Properties
| Name | Type | Default | Description |
| ---------------- | :------: | :-----: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cache_duration` | `string` | `` | the duration for which the segment will be cached. The duration is a string in the format `1h2m3s`. The duration is parsed using the [time.ParseDuration] function from the Go standard library |
## Template ([info][templates]) ## Template ([info][templates])
:::note default template :::note default template
@ -39,3 +48,4 @@ import Config from "@site/src/components/Config.js";
| `.Latest` | `string` | the latest available version number | | `.Latest` | `string` | the latest available version number |
[templates]: /docs/configuration/templates [templates]: /docs/configuration/templates
[time.ParseDuration]: https://golang.org/pkg/time/#ParseDuration