feat(upgrade): select source

This commit is contained in:
Jan De Dobbeleer 2024-12-01 17:13:21 +01:00 committed by Jan De Dobbeleer
parent 6068b56e40
commit 06a372424f
17 changed files with 318 additions and 215 deletions

View file

@ -2,9 +2,10 @@ package cli
import (
"fmt"
"os"
"github.com/jandedobbeleer/oh-my-posh/src/config"
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
"github.com/jandedobbeleer/oh-my-posh/src/upgrade"
"github.com/spf13/cobra"
)
@ -23,7 +24,12 @@ var noticeCmd = &cobra.Command{
env.Init(flags)
defer env.Close()
if notice, hasNotice := upgrade.Notice(env, false); hasNotice {
sh := os.Getenv("POSH_SHELL")
configFile := config.Path(configFlag)
cfg := config.Load(configFile, sh, false)
cfg.Upgrade.Cache = env.Cache()
if notice, hasNotice := cfg.Upgrade.Notice(); hasNotice {
fmt.Println(notice)
}
},

View file

@ -7,6 +7,7 @@ import (
"slices"
"github.com/jandedobbeleer/oh-my-posh/src/build"
"github.com/jandedobbeleer/oh-my-posh/src/config"
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
"github.com/jandedobbeleer/oh-my-posh/src/terminal"
"github.com/jandedobbeleer/oh-my-posh/src/upgrade"
@ -32,36 +33,42 @@ var upgradeCmd = &cobra.Command{
return
}
sh := os.Getenv("POSH_SHELL")
env := &runtime.Terminal{}
env.Init(nil)
defer env.Close()
terminal.Init(env.Shell())
terminal.Init(sh)
fmt.Print(terminal.StartProgress())
latest, err := upgrade.Latest(env)
configFile := config.Path(configFlag)
cfg := config.Load(configFile, sh, false)
cfg.Upgrade.Cache = env.Cache()
latest, err := cfg.Upgrade.Latest()
if err != nil {
fmt.Printf("\n❌ %s\n\n%s", err, terminal.StopProgress())
os.Exit(1)
return
}
cfg.Upgrade.Version = fmt.Sprintf("v%s", latest)
if force {
executeUpgrade(latest)
executeUpgrade(cfg.Upgrade)
return
}
version := fmt.Sprintf("v%s", build.Version)
if upgrade.IsMajorUpgrade(version, latest) {
if upgrade.IsMajorUpgrade(build.Version, latest) {
message := terminal.StopProgress()
message += fmt.Sprintf("\n🚨 major upgrade available: %s -> %s, use oh-my-posh upgrade --force to upgrade\n\n", version, latest)
message += fmt.Sprintf("\n🚨 major upgrade available: v%s -> v%s, use oh-my-posh upgrade --force to upgrade\n\n", build.Version, latest)
fmt.Print(message)
return
}
if version != latest {
executeUpgrade(latest)
if build.Version != latest {
executeUpgrade(cfg.Upgrade)
return
}
@ -69,8 +76,8 @@ var upgradeCmd = &cobra.Command{
},
}
func executeUpgrade(latest string) {
err := upgrade.Run(latest)
func executeUpgrade(cfg *upgrade.Config) {
err := upgrade.Run(cfg)
fmt.Print(terminal.StopProgress())
if err == nil {
return

View file

@ -7,6 +7,7 @@ import (
"github.com/jandedobbeleer/oh-my-posh/src/shell"
"github.com/jandedobbeleer/oh-my-posh/src/template"
"github.com/jandedobbeleer/oh-my-posh/src/terminal"
"github.com/jandedobbeleer/oh-my-posh/src/upgrade"
)
const (
@ -30,26 +31,27 @@ type Config struct {
SecondaryPrompt *Segment `json:"secondary_prompt,omitempty" toml:"secondary_prompt,omitempty"`
TransientPrompt *Segment `json:"transient_prompt,omitempty" toml:"transient_prompt,omitempty"`
ErrorLine *Segment `json:"error_line,omitempty" toml:"error_line,omitempty"`
ConsoleTitleTemplate string `json:"console_title_template,omitempty" toml:"console_title_template,omitempty"`
Format string `json:"-" toml:"-"`
TerminalBackground color.Ansi `json:"terminal_background,omitempty" toml:"terminal_background,omitempty"`
origin string
PWD string `json:"pwd,omitempty" toml:"pwd,omitempty"`
AccentColor color.Ansi `json:"accent_color,omitempty" toml:"accent_color,omitempty"`
Output string `json:"-" toml:"-"`
TerminalBackground color.Ansi `json:"terminal_background,omitempty" toml:"terminal_background,omitempty"`
ConsoleTitleTemplate string `json:"console_title_template,omitempty" toml:"console_title_template,omitempty"`
Format string `json:"-" toml:"-"`
Upgrade *upgrade.Config `json:"upgrade,omitempty" toml:"upgrade,omitempty"`
Cycle color.Cycle `json:"cycle,omitempty" toml:"cycle,omitempty"`
ITermFeatures terminal.ITermFeatures `json:"iterm_features,omitempty" toml:"iterm_features,omitempty"`
Blocks []*Block `json:"blocks,omitempty" toml:"blocks,omitempty"`
Tooltips []*Segment `json:"tooltips,omitempty" toml:"tooltips,omitempty"`
Version int `json:"version" toml:"version"`
UpgradeNotice bool `json:"upgrade_notice,omitempty" toml:"upgrade_notice,omitempty"`
AutoUpgrade bool `json:"auto_upgrade,omitempty" toml:"auto_upgrade,omitempty"`
AutoUpgrade bool `json:"-" toml:"-"`
ShellIntegration bool `json:"shell_integration,omitempty" toml:"shell_integration,omitempty"`
MigrateGlyphs bool `json:"-" toml:"-"`
PatchPwshBleed bool `json:"patch_pwsh_bleed,omitempty" toml:"patch_pwsh_bleed,omitempty"`
EnableCursorPositioning bool `json:"enable_cursor_positioning,omitempty" toml:"enable_cursor_positioning,omitempty"`
updated bool
FinalSpace bool `json:"final_space,omitempty" toml:"final_space,omitempty"`
UpgradeNotice bool `json:"-" toml:"-"`
}
func (cfg *Config) MakeColors(env runtime.Environment) color.String {
@ -98,12 +100,12 @@ func (cfg *Config) Features(env runtime.Environment) shell.Features {
feats = append(feats, shell.FTCSMarks)
}
autoUpgrade := cfg.AutoUpgrade
autoUpgrade := cfg.Upgrade.Auto
if _, OK := env.Cache().Get(AUTOUPGRADE); OK {
autoUpgrade = true
}
upgradeNotice := cfg.UpgradeNotice
upgradeNotice := cfg.Upgrade.DisplayNotice
if _, OK := env.Cache().Get(UPGRADENOTICE); OK {
upgradeNotice = true
}

View file

@ -15,6 +15,7 @@ import (
"github.com/jandedobbeleer/oh-my-posh/src/log"
"github.com/jandedobbeleer/oh-my-posh/src/runtime/path"
"github.com/jandedobbeleer/oh-my-posh/src/shell"
"github.com/jandedobbeleer/oh-my-posh/src/upgrade"
json "github.com/goccy/go-json"
yaml "github.com/goccy/go-yaml"
@ -32,6 +33,19 @@ func Load(configFile, sh string, migrate bool) *Config {
cfg.BackupAndMigrate()
}
if cfg.Upgrade == nil {
cfg.Upgrade = &upgrade.Config{
Source: upgrade.CDN,
DisplayNotice: cfg.UpgradeNotice,
Auto: cfg.AutoUpgrade,
Interval: cache.ONEWEEK,
}
}
if cfg.Upgrade.Interval.IsEmpty() {
cfg.Upgrade.Interval = cache.ONEWEEK
}
if !cfg.ShellIntegration {
return cfg
}

View file

@ -68,23 +68,29 @@ func (u *Upgrade) cachedLatest(current string) (*UpgradeCache, error) {
}
func (u *Upgrade) checkUpdate(current string) (*UpgradeCache, error) {
tag, err := upgrade.Latest(u.env)
duration := u.props.GetString(properties.CacheDuration, string(cache.ONEWEEK))
source := u.props.GetString(Source, string(upgrade.CDN))
cfg := &upgrade.Config{
Source: upgrade.Source(source),
Interval: cache.Duration(duration),
}
latest, err := cfg.Latest()
if err != nil {
return nil, err
}
latest := tag[1:]
cacheData := &UpgradeCache{
Latest: latest,
Current: current,
}
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

@ -1,7 +1,6 @@
package segments
import (
"errors"
"fmt"
"testing"
@ -16,8 +15,10 @@ import (
)
func TestUpgrade(t *testing.T) {
ugc := &upgrade.Config{}
latest, _ := ugc.Latest()
cases := []struct {
Error error
Case string
CurrentVersion string
LatestVersion string
@ -33,33 +34,28 @@ func TestUpgrade(t *testing.T) {
},
{
Case: "On latest",
CurrentVersion: "1.0.1",
LatestVersion: "1.0.1",
},
{
Case: "Error on update check",
Error: errors.New("error"),
CurrentVersion: latest,
},
{
Case: "On previous, from cache",
HasCache: true,
CurrentVersion: "1.0.2",
LatestVersion: "1.0.3",
LatestVersion: latest,
CachedVersion: "1.0.2",
ExpectedEnabled: true,
},
{
Case: "On latest, version changed",
HasCache: true,
CurrentVersion: "1.0.2",
LatestVersion: "1.0.2",
CurrentVersion: latest,
LatestVersion: latest,
CachedVersion: "1.0.1",
},
{
Case: "On previous, version changed",
HasCache: true,
CurrentVersion: "1.0.2",
LatestVersion: "1.0.3",
LatestVersion: latest,
CachedVersion: "1.0.1",
ExpectedEnabled: true,
},
@ -73,15 +69,13 @@ func TestUpgrade(t *testing.T) {
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
json := fmt.Sprintf(`{"tag_name":"v%s"}`, tc.LatestVersion)
env.On("HTTPRequest", upgrade.RELEASEURL).Return([]byte(json), tc.Error)
ug := &Upgrade{}
ug.Init(properties.Map{}, env)

View file

@ -39,42 +39,42 @@ type stateMsg state
type model struct {
error error
config *Config
message string
tag string
spinner spinner.Model
state state
}
func initialModel(tag string) *model {
func initialModel(cfg *Config) *model {
s := spinner.New()
s.Spinner = spinner.Dot
s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("170"))
return &model{spinner: s, tag: tag}
return &model{spinner: s, config: cfg}
}
func (m *model) Init() tea.Cmd {
defer func() {
go func() {
if err := install(m.tag); err != nil {
m.error = err
program.Send(resultMsg(fmt.Sprintf("❌ upgrade failed: %v", err)))
return
}
message := "🚀 Upgrade successful"
current := fmt.Sprintf("v%s", build.Version)
if current != m.tag {
message += ", restart your shell to take full advantage of the new functionality"
}
program.Send(resultMsg(message))
}()
}()
go m.start()
return m.spinner.Tick
}
func (m *model) start() {
if err := install(m.config); err != nil {
m.error = err
program.Send(resultMsg(fmt.Sprintf("❌ upgrade failed: %v", err)))
return
}
message := "🚀 Upgrade successful"
current := fmt.Sprintf("v%s", build.Version)
if current != m.config.Version {
message += ", restart your shell to take full advantage of the new functionality"
}
program.Send(resultMsg(message))
}
func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
@ -113,7 +113,7 @@ func (m *model) View() string {
message = "Validating current installation"
case downloading:
m.spinner.Spinner = spinner.Globe
message = "Downloading latest version"
message = fmt.Sprintf("Downloading latest version from %s", m.config.Source.String())
case verifying:
m.spinner.Spinner = spinner.Moon
message = "Verifying download"
@ -125,19 +125,19 @@ func (m *model) View() string {
return title + textStyle.Render(fmt.Sprintf("%s %s", m.spinner.View(), message))
}
func Run(latest string) error {
func Run(cfg *Config) error {
titleStyle := lipgloss.NewStyle().Margin(1, 0, 1, 0)
title = "📦 Upgrading Oh My Posh"
current := build.Version
current := fmt.Sprintf("v%s", build.Version)
if len(current) == 0 {
current = "dev"
}
title = fmt.Sprintf("%s from %s to %s", title, current, latest)
title = fmt.Sprintf("%s from %s to %s", title, current, cfg.Version)
title = titleStyle.Render(title)
program = tea.NewProgram(initialModel(latest))
program = tea.NewProgram(initialModel(cfg))
resultModel, _ := program.Run()
programModel, OK := resultModel.(*model)

100
src/upgrade/config.go Normal file
View file

@ -0,0 +1,100 @@
package upgrade
import (
"context"
"fmt"
"io"
httplib "net/http"
"strings"
"github.com/jandedobbeleer/oh-my-posh/src/cache"
"github.com/jandedobbeleer/oh-my-posh/src/runtime/http"
)
type Config struct {
Cache cache.Cache `json:"-" toml:"-"`
Source Source `json:"source" toml:"source"`
Interval cache.Duration `json:"interval" toml:"interval"`
Version string `json:"-" toml:"-"`
Auto bool `json:"auto" toml:"auto"`
DisplayNotice bool `json:"notice" toml:"notice"`
Force bool `json:"-" toml:"-"`
}
type Source string
const (
GitHub Source = "github"
CDN Source = "cdn"
)
func (s Source) String() string {
switch s {
case GitHub:
return "github.com"
case CDN:
return "cdn.ohmyposh.dev"
default:
return "Unknown"
}
}
func (cfg *Config) Latest() (string, error) {
cfg.Version = "latest"
v, err := cfg.DownloadAsset("version.txt")
version := strings.TrimSpace(string(v))
return strings.TrimPrefix(version, "v"), err
}
func (cfg *Config) DownloadAsset(asset string) ([]byte, error) {
if len(cfg.Source) == 0 {
cfg.Source = GitHub
}
switch cfg.Source {
case GitHub:
var url string
switch cfg.Version {
case "latest":
url = fmt.Sprintf("https://github.com/JanDeDobbeleer/oh-my-posh/releases/latest/download/%s", asset)
default:
url = fmt.Sprintf("https://github.com/JanDeDobbeleer/oh-my-posh/releases/download/%s/%s", cfg.Version, asset)
}
return cfg.Download(url)
case CDN:
fallthrough
default:
url := fmt.Sprintf("https://cdn.ohmyposh.dev/releases/%s/%s", cfg.Version, asset)
return cfg.Download(url)
}
}
func (cfg *Config) Download(url string) ([]byte, error) {
req, err := httplib.NewRequestWithContext(context.Background(), "GET", url, nil)
if err != nil {
return nil, err
}
req.Header.Add("User-Agent", "oh-my-posh")
req.Header.Add("Cache-Control", "max-age=0")
resp, err := http.HTTPClient.Do(req)
if err != nil {
return nil, err
}
if resp.StatusCode != httplib.StatusOK {
return nil, fmt.Errorf("failed to download asset: %s", url)
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return data, nil
}

View file

@ -1,39 +0,0 @@
package upgrade
import (
"context"
"fmt"
"io"
httplib "net/http"
"github.com/jandedobbeleer/oh-my-posh/src/runtime/http"
)
func downloadReleaseAsset(tag, asset string) ([]byte, error) {
url := fmt.Sprintf("https://github.com/JanDeDobbeleer/oh-my-posh/releases/download/%s/%s", tag, asset)
req, err := httplib.NewRequestWithContext(context.Background(), "GET", url, nil)
if err != nil {
return nil, err
}
req.Header.Add("User-Agent", "oh-my-posh")
resp, err := http.HTTPClient.Do(req)
if err != nil {
return nil, err
}
if resp.StatusCode != httplib.StatusOK {
return nil, fmt.Errorf("failed to download asset: %s", url)
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return data, nil
}

View file

@ -9,7 +9,7 @@ import (
"path/filepath"
)
func install(tag string) error {
func install(cfg *Config) error {
setState(validating)
executable, err := os.Executable()
@ -28,7 +28,7 @@ func install(tag string) error {
setState(downloading)
data, err := downloadAndVerify(tag)
data, err := downloadAndVerify(cfg)
if err != nil {
return err
}
@ -71,7 +71,7 @@ func install(tag string) error {
_ = hideFile(oldPath)
}
updateRegistry(tag, executable)
updateRegistry(cfg.Version, executable)
return nil
}

View file

@ -5,5 +5,3 @@ package upgrade
func hideFile(_ string) error {
return nil
}
func updateRegistry(_, _ string) {}

View file

@ -1,72 +1,38 @@
package upgrade
import (
"encoding/json"
"fmt"
"time"
"os"
"github.com/jandedobbeleer/oh-my-posh/src/build"
"github.com/jandedobbeleer/oh-my-posh/src/cache"
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
"github.com/jandedobbeleer/oh-my-posh/src/log"
"github.com/jandedobbeleer/oh-my-posh/src/runtime/http"
)
type release struct {
CreatedAt time.Time `json:"created_at"`
PublishedAt time.Time `json:"published_at"`
NodeID string `json:"node_id"`
TagName string `json:"tag_name"`
TarballURL string `json:"tarball_url"`
ZipballURL string `json:"zipball_url"`
DiscussionURL string `json:"discussion_url"`
HTMLURL string `json:"html_url"`
URL string `json:"url"`
UploadURL string `json:"upload_url"`
TargetCommitish string `json:"target_commitish"`
Name string `json:"name"`
Body string `json:"body"`
AssetsURL string `json:"assets_url"`
ID int `json:"id"`
Prerelease bool `json:"prerelease"`
Draft bool `json:"draft"`
}
const (
RELEASEURL = "https://api.github.com/repos/jandedobbeleer/oh-my-posh/releases/latest"
CACHEKEY = "upgrade_check"
CACHEKEY = "upgrade_check"
upgradeNotice = `
A new release of Oh My Posh is available: %s %s
A new release of Oh My Posh is available: v%s v%s
To upgrade, run: 'oh-my-posh upgrade%s'
To enable automated upgrades, run: 'oh-my-posh enable upgrade'.
`
)
func Latest(env runtime.Environment) (string, error) {
body, err := env.HTTPRequest(RELEASEURL, nil, 5000)
if err != nil {
return "", err
}
var release release
// this can't fail
_ = json.Unmarshal(body, &release)
if len(release.TagName) == 0 {
return "", fmt.Errorf("failed to get latest release")
}
return release.TagName, nil
}
// Returns the upgrade notice if a new version is available
// that should be displayed to the user.
//
// The upgrade check is only performed every other week.
func Notice(env runtime.Environment, force bool) (string, bool) {
func (cfg *Config) Notice() (string, bool) {
// never validate when we install using the Windows Store
if os.Getenv("POSH_INSTALLER") == "ws" {
log.Debug("skipping upgrade check because we are using the Windows Store")
return "", false
}
// do not check when last validation was < 1 week ago
if _, OK := env.Cache().Get(CACHEKEY); OK && !force {
if _, OK := cfg.Cache.Get(CACHEKEY); OK && !cfg.Force {
return "", false
}
@ -74,27 +40,21 @@ func Notice(env runtime.Environment, force bool) (string, bool) {
return "", false
}
// never validate when we install using the Windows Store
if env.Getenv("POSH_INSTALLER") == "ws" {
return "", false
}
latest, err := Latest(env)
latest, err := cfg.Latest()
if err != nil {
return "", false
}
env.Cache().Set(CACHEKEY, latest, cache.ONEWEEK)
cfg.Cache.Set(CACHEKEY, latest, cfg.Interval)
version := fmt.Sprintf("v%s", build.Version)
if latest == version {
if latest == build.Version {
return "", false
}
var forceUpdate string
if IsMajorUpgrade(version, latest) {
if IsMajorUpgrade(build.Version, latest) {
forceUpdate = " --force"
}
return fmt.Sprintf(upgradeNotice, version, latest, forceUpdate), true
return fmt.Sprintf(upgradeNotice, build.Version, latest, forceUpdate), true
}

View file

@ -1,52 +1,47 @@
package upgrade
import (
"fmt"
"os"
"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/runtime"
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
cache_ "github.com/jandedobbeleer/oh-my-posh/src/cache/mock"
"github.com/stretchr/testify/assert"
testify "github.com/stretchr/testify/mock"
testify_ "github.com/stretchr/testify/mock"
)
func TestCanUpgrade(t *testing.T) {
ugc := &Config{}
latest, _ := ugc.Latest()
cases := []struct {
Error error
Case string
CurrentVersion string
LatestVersion string
GOOS string
Installer string
Expected bool
Cache bool
}{
{Case: "Up to date", CurrentVersion: "3.0.0", LatestVersion: "v3.0.0"},
{Case: "Outdated Windows", Expected: true, CurrentVersion: "3.0.0", LatestVersion: "v3.0.1", GOOS: runtime.WINDOWS},
{Case: "Outdated Linux", Expected: true, CurrentVersion: "3.0.0", LatestVersion: "v3.0.1", GOOS: runtime.LINUX},
{Case: "Outdated Darwin", Expected: true, CurrentVersion: "3.0.0", LatestVersion: "v3.0.1", GOOS: runtime.DARWIN},
{Case: "Up to date", CurrentVersion: latest},
{Case: "Outdated Linux", Expected: true, CurrentVersion: "3.0.0"},
{Case: "Outdated Darwin", Expected: true, CurrentVersion: "3.0.0"},
{Case: "Cached", Cache: true},
{Case: "Error", Error: fmt.Errorf("error")},
{Case: "Windows Store", Installer: "ws"},
}
for _, tc := range cases {
env := new(mock.Environment)
build.Version = tc.CurrentVersion
c := &cache.Cache{}
c := &cache_.Cache{}
c.On("Get", CACHEKEY).Return("", tc.Cache)
c.On("Set", testify.Anything, testify.Anything, testify.Anything)
env.On("Cache").Return(c)
env.On("GOOS").Return(tc.GOOS)
env.On("Getenv", "POSH_INSTALLER").Return(tc.Installer)
c.On("Set", testify_.Anything, testify_.Anything, testify_.Anything)
ugc.Cache = c
json := fmt.Sprintf(`{"tag_name":"%s"}`, tc.LatestVersion)
env.On("HTTPRequest", RELEASEURL).Return([]byte(json), tc.Error)
// ignore the notice
_, canUpgrade := Notice(env, false)
if len(tc.Installer) > 0 {
os.Setenv("POSH_INSTALLER", tc.Installer)
}
_, canUpgrade := ugc.Notice()
assert.Equal(t, tc.Expected, canUpgrade, tc.Case)
os.Setenv("POSH_INSTALLER", "")
}
}

View file

@ -32,7 +32,7 @@ import (
//go:embed public_key.pem
var publicKey []byte
func downloadAndVerify(tag string) ([]byte, error) {
func downloadAndVerify(cfg *Config) ([]byte, error) {
extension := ""
if stdruntime.GOOS == runtime.WINDOWS {
extension = ".exe"
@ -40,14 +40,14 @@ func downloadAndVerify(tag string) ([]byte, error) {
asset := fmt.Sprintf("posh-%s-%s%s", stdruntime.GOOS, stdruntime.GOARCH, extension)
data, err := downloadReleaseAsset(tag, asset)
data, err := cfg.DownloadAsset(asset)
if err != nil {
return nil, err
}
setState(verifying)
err = verify(tag, asset, data)
err = verify(cfg, asset, data)
if err != nil {
return nil, err
}
@ -55,13 +55,13 @@ func downloadAndVerify(tag string) ([]byte, error) {
return data, nil
}
func verify(tag, asset string, binary []byte) error {
checksums, err := downloadReleaseAsset(tag, "checksums.txt")
func verify(cfg *Config, asset string, binary []byte) error {
checksums, err := cfg.DownloadAsset("checksums.txt")
if err != nil {
return err
}
signature, err := downloadReleaseAsset(tag, "checksums.txt.sig")
signature, err := cfg.DownloadAsset("checksums.txt.sig")
if err != nil {
return err
}

View file

@ -1281,8 +1281,22 @@
"description": "The extensions to look for when determining if a folder is a Fortran workspace",
"default": [
"fpm.toml",
"*.f", "*.for", "*.fpp", "*.f77", "*.f90", "*.f95", "*.f03", "*.f08",
"*.F", "*.FOR", "*.FPP", "*.F77", "*.F90", "*.F95", "*.F03", "*.F08"
"*.f",
"*.for",
"*.fpp",
"*.f77",
"*.f90",
"*.f95",
"*.f03",
"*.f08",
"*.F",
"*.FOR",
"*.FPP",
"*.F77",
"*.F90",
"*.F95",
"*.F03",
"*.F08"
],
"items": {
"type": "string"
@ -5036,17 +5050,36 @@
"description": "https://ohmyposh.dev/docs/configuration/general#general-settings",
"default": ""
},
"upgrade_notice": {
"type": "boolean",
"upgrade": {
"type": "object",
"title": "Enable Upgrade Notice",
"description": "https://ohmyposh.dev/docs/configuration/general#general-settings",
"default": false
},
"auto_upgrade": {
"type": "boolean",
"title": "Enable automatic upgrades for Oh My Posh (supports Windows/macOS only)",
"description": "https://ohmyposh.dev/docs/configuration/general#general-settings",
"default": false
"default": {
"source": "cdn",
"auto": false,
"notice": false
},
"properties": {
"interval": {
"$ref": "#/definitions/cache_duration"
},
"source": {
"type": "string",
"enum": [
"cdn",
"github"
],
"default": "cdn"
},
"auto": {
"type": "boolean",
"default": false
},
"notice": {
"type": "boolean",
"default": false
}
}
},
"patch_pwsh_bleed": {
"type": "boolean",

View file

@ -136,8 +136,7 @@ For example, the following is a valid `--config` flag:
| `shell_integration` | `boolean` | `false` | enable shell integration using FinalTerm's OSC sequences. Works in bash, cmd (Clink v1.14.25+), fish, powershell and zsh |
| `enable_cursor_positioning` | `boolean` | `false` | enable fetching the cursor position in bash and zsh to allow automatic hiding of leading newlines when at the top of the shell |
| `patch_pwsh_bleed` | `boolean` | `false` | patch a PowerShell bug where the background colors bleed into the next line at the end of the buffer (can be removed when [this][pwsh-bleed] is merged) |
| `upgrade_notice` | `boolean` | `false` | enable the notice that a new upgrade is available when `auto_upgrade` is disabled |
| `auto_upgrade` | `boolean` | `false` | enable [automatic upgrades][upgrade] for Oh My Posh (supports Windows, macOS and Linux) |
| `upgrade` | `Upgrade` | | enable auto upgrade or the upgrade notice. See [Upgrade] |
| `iterm_features` | `[]string` | `false` | enable iTerm2 specific features:<ul><li>`prompt_mark`: add the `iterm2_prompt_mark` [function][iterm2-si] for supported shells</li><li>`current_dir`: expose the current directory for iTerm2</li><li>`remote_host`: expose the current remote and user for iTerm2</li></ul> |
### JSON Schema Validation
@ -194,4 +193,4 @@ Converters won't catch this change, so you will need to adjust manually.
[templates]: /docs/configuration/templates#config-variables
[pwsh-bleed]: https://github.com/PowerShell/PowerShell/pull/19019
[iterm2-si]: https://iterm2.com/documentation-shell-integration.html
[upgrade]: /docs/installation/upgrade#automatic
[Upgrade]: /docs/installation/upgrade

View file

@ -6,8 +6,34 @@ sidebar_label: ♻️ Upgrade
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import Config from "@site/src/components/Config.js";
## Manual
## Configuration
Oh My Posh can display the availability of an update, or auto update itself when
enabled by adding the following to your configuration.
<Config
data={{
upgrade: {
notice: true,
interval: "168h",
auto: false,
source: "cdn",
},
}}
/>
| Name | Type | Default | Description |
| ---------- | :-------: | :-----: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `notice` | `boolean` | `false` | enbale displaying the upgrade notice on shell start, only checks based on `interval` |
| `auto` | `boolean` | `false` | automatically update Oh My Posh when an update is found, only checks based on `interval` |
| `interval` | `string` | `24h` | the duration for which not to check for an update. The duration is a string in the format `1h2m3s` and is parsed using the [time.ParseDuration] function from the Go standard library |
| `source` | `string` | `cdn` | where to fetch the information from. Accepted values are `cdn` (`https://cdn.ohmyposh.dev/releases/latest/version.txt`) and `github` (`https://github.com/JanDeDobbeleer/oh-my-posh/releases/latest/download/version.txt`) |
## Upgrade
### Manual
While you can always follow the upgrade steps listed under the installation section,
you can also use the `upgrade` command to update Oh My Posh to the latest version.
@ -16,7 +42,7 @@ you can also use the `upgrade` command to update Oh My Posh to the latest versio
oh-my-posh upgrade
```
## Automated
### Automated
<Tabs
defaultValue="cli"
@ -35,11 +61,13 @@ oh-my-posh enable upgrade
</TabItem>
<TabItem value="config">
import Config from "@site/src/components/Config.js";
<Config
data={{
"auto_upgrade": true
upgrade: {
interval: "168h",
auto: true,
source: "cdn",
},
}}
/>