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
delete(segment.Properties, "cache_version")
segment.Cache = segment.migrateCache()
segment.IncludeFolders = segment.migrateFolders(includeFolders)
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 {
@ -45,24 +51,35 @@ func (segment *Segment) hasProperty(property properties.Property) bool {
return false
}
func (segment *Segment) migrateCache() *cache.Config {
func (segment *Segment) timeoutToCache() {
if !segment.hasProperty(cacheTimeout) {
return nil
return
}
timeout := segment.Properties.GetInt(cacheTimeout, 0)
delete(segment.Properties, cacheTimeout)
if timeout == 0 {
return nil
return
}
return &cache.Config{
segment.Cache = &cache.Config{
Duration: cache.ToDuration(timeout * 60),
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 {
if !segment.hasProperty(property) {
return []string{}

View file

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

View file

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

View file

@ -1,11 +1,16 @@
package segments
import (
"encoding/json"
"errors"
"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"
)
type upgradeData struct {
type UpgradeCache struct {
Latest string `json:"latest"`
Current string `json:"current"`
}
@ -16,36 +21,71 @@ type Upgrade struct {
// deprecated
Version string
upgradeData
UpgradeCache
}
const (
UPGRADECACHEKEY = "upgrade_segment"
)
func (u *Upgrade) Template() string {
return " \uf019 "
}
func (u *Upgrade) Enabled() bool {
u.Current = build.Version
latest, err := u.checkUpdate(u.Current)
latest, err := u.cachedLatest(u.Current)
if err != nil {
latest, err = u.checkUpdate(u.Current)
}
if err != nil || u.Current == latest.Latest {
return false
}
u.upgradeData = *latest
u.UpgradeCache = *latest
u.Version = u.Latest
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)
if err != nil {
return nil, err
}
return &upgradeData{
// strip leading v
Latest: tag[1:],
latest := tag[1:]
cacheData := &UpgradeCache{
Latest: latest,
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"
"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/runtime/mock"
"github.com/jandedobbeleer/oh-my-posh/src/upgrade"
"github.com/alecthomas/assert"
testify_ "github.com/stretchr/testify/mock"
)
func TestUpgrade(t *testing.T) {
@ -38,21 +40,42 @@ func TestUpgrade(t *testing.T) {
Case: "Error on update check",
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",
HasCache: true,
CurrentVersion: "1.0.2",
LatestVersion: "1.0.2",
CachedVersion: "1.0.1",
},
{
Case: "On previous, version changed",
HasCache: true,
CurrentVersion: "1.0.2",
LatestVersion: "1.0.3",
CachedVersion: "1.0.1",
ExpectedEnabled: true,
},
}
for _, tc := range cases {
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

View file

@ -18,9 +18,18 @@ import Config from "@site/src/components/Config.js";
style: "plain",
foreground: "#111111",
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])
:::note default template
@ -39,3 +48,4 @@ import Config from "@site/src/components/Config.js";
| `.Latest` | `string` | the latest available version number |
[templates]: /docs/configuration/templates
[time.ParseDuration]: https://golang.org/pkg/time/#ParseDuration