From b3b41fc60d78727c3e8e3c9c0d7a83d74d8e25a3 Mon Sep 17 00:00:00 2001 From: Jan De Dobbeleer Date: Wed, 30 Oct 2024 17:10:14 +0100 Subject: [PATCH] feat(language): add version caching for 1 week --- src/segments/language.go | 77 +++++++++++++++++++++++++---------- src/segments/language_test.go | 12 ++++++ 2 files changed, 68 insertions(+), 21 deletions(-) diff --git a/src/segments/language.go b/src/segments/language.go index 2d54d545..11327a91 100644 --- a/src/segments/language.go +++ b/src/segments/language.go @@ -1,9 +1,13 @@ package segments import ( + "encoding/json" "errors" "fmt" + "path/filepath" + runtime_ "runtime" + "github.com/jandedobbeleer/oh-my-posh/src/cache" "github.com/jandedobbeleer/oh-my-posh/src/properties" "github.com/jandedobbeleer/oh-my-posh/src/regex" "github.com/jandedobbeleer/oh-my-posh/src/runtime" @@ -70,6 +74,7 @@ type language struct { displayMode string Error string versionURLTemplate string + name string commands []*cmd projectFiles []string folders []string @@ -100,7 +105,14 @@ const ( LanguageFolders properties.Property = "folders" ) +func (l *language) getName() string { + _, file, _, _ := runtime_.Caller(2) + base := filepath.Base(file) + return base[:len(base)-3] +} + func (l *language) Enabled() bool { + l.name = l.getName() // override default extensions if needed l.extensions = l.props.GetStringArray(LanguageExtensions, l.extensions) l.folders = l.props.GetStringArray(LanguageFolders, l.folders) @@ -194,28 +206,22 @@ func (l *language) hasLanguageFolders() bool { func (l *language) setVersion() error { var lastError error + cacheKey := fmt.Sprintf("version_%s", l.name) + + if versionCache, OK := l.env.Cache().Get(cacheKey); OK { + var version version + err := json.Unmarshal([]byte(versionCache), &version) + if err == nil { + l.version = version + return nil + } + } + for _, command := range l.commands { - var versionStr string - var err error - - if command.getVersion == nil { - if !l.env.HasCommand(command.executable) { - lastError = errors.New(noVersion) - continue - } - - versionStr, err = l.env.RunCommand(command.executable, command.args...) - if exitErr, ok := err.(*runtime.CommandError); ok { - l.exitCode = exitErr.ExitCode - lastError = fmt.Errorf("err executing %s with %s", command.executable, command.args) - continue - } - } else { - versionStr, err = command.getVersion() - if err != nil || versionStr == "" { - lastError = errors.New("cannot get version") - continue - } + versionStr, err := l.runCommand(command) + if err != nil { + lastError = err + continue } version, err := command.parse(versionStr) @@ -232,14 +238,43 @@ func (l *language) setVersion() error { l.buildVersionURL() l.version.Executable = command.executable + if marchalled, err := json.Marshal(l.version); err == nil { + l.env.Cache().Set(cacheKey, string(marchalled), cache.ONEWEEK) + } + return nil } + if lastError != nil { return lastError } + return errors.New(l.props.GetString(MissingCommandText, "")) } +func (l *language) runCommand(command *cmd) (string, error) { + if command.getVersion == nil { + if !l.env.HasCommand(command.executable) { + return "", errors.New(noVersion) + } + + versionStr, err := l.env.RunCommand(command.executable, command.args...) + if exitErr, ok := err.(*runtime.CommandError); ok { + l.exitCode = exitErr.ExitCode + return "", fmt.Errorf("err executing %s with %s", command.executable, command.args) + } + + return versionStr, nil + } + + versionStr, err := command.getVersion() + if err != nil || versionStr == "" { + return "", errors.New("cannot get version") + } + + return versionStr, nil +} + func (l *language) loadLanguageContext() { if l.loadContext == nil { return diff --git a/src/segments/language_test.go b/src/segments/language_test.go index e53bfef6..08e55f7d 100644 --- a/src/segments/language_test.go +++ b/src/segments/language_test.go @@ -3,11 +3,13 @@ package segments import ( "testing" + 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" "github.com/jandedobbeleer/oh-my-posh/src/runtime/mock" "github.com/stretchr/testify/assert" + mock_ "github.com/stretchr/testify/mock" ) const ( @@ -59,6 +61,11 @@ func bootStrapLanguageTest(args *languageArgs) *language { env.On("Pwd").Return(cwd) env.On("Home").Return(home) + cache := &cache_.Cache{} + cache.On("Get", mock_.Anything).Return("", false) + cache.On("Set", mock_.Anything, mock_.Anything, mock_.Anything).Return(nil) + env.On("Cache").Return(cache) + if args.properties == nil { args.properties = properties.Map{} } @@ -541,6 +548,11 @@ func getMockedLanguageEnv(params *mockedLanguageParams) (*mock.Environment, prop env.On("Pwd").Return("/usr/home/project") env.On("Home").Return("/usr/home") + cache := &cache_.Cache{} + cache.On("Get", mock_.Anything).Return("", false) + cache.On("Set", mock_.Anything, mock_.Anything, mock_.Anything).Return(nil) + env.On("Cache").Return(cache) + props := properties.Map{ properties.FetchVersion: true, }