oh-my-posh/src/engine/migrate.go
Jan De Dobbeleer 7dce0fe3e7 fix(config): log errors
relates to #3441
2023-02-03 08:28:49 +01:00

278 lines
11 KiB
Go

package engine
import (
"fmt"
"strings"
"github.com/jandedobbeleer/oh-my-posh/src/platform"
"github.com/jandedobbeleer/oh-my-posh/src/properties"
"github.com/jandedobbeleer/oh-my-posh/src/segments"
)
const (
colorBackground = properties.Property("color_background")
prefix = properties.Property("prefix")
postfix = properties.Property("postfix")
segmentTemplate = properties.Property("template")
)
func (cfg *Config) Migrate() {
for _, block := range cfg.Blocks {
for _, segment := range block.Segments {
segment.migrate(cfg.env, cfg.Version)
}
}
for _, segment := range cfg.Tooltips {
segment.migrate(cfg.env, cfg.Version)
}
if strings.Contains(cfg.ConsoleTitleTemplate, ".Path") {
cfg.ConsoleTitleTemplate = strings.ReplaceAll(cfg.ConsoleTitleTemplate, ".Path", ".PWD")
}
cfg.updated = true
cfg.Version = configVersion
}
func (segment *Segment) migrate(env platform.Environment, version int) {
if version < 1 {
segment.migrationOne(env)
}
if version < 2 {
segment.migrationTwo(env)
}
}
func (segment *Segment) migrationOne(env platform.Environment) {
if err := segment.mapSegmentWithWriter(env); err != nil {
return
}
// General properties that need replacement
segment.migratePropertyKey("display_version", properties.FetchVersion)
delete(segment.Properties, "enable_hyperlink")
switch segment.Type { //nolint:exhaustive
case TEXT:
segment.migratePropertyKey("text", segmentTemplate)
segment.migrateTemplate()
case GIT:
hasTemplate := segment.hasProperty(segmentTemplate)
segment.migratePropertyKey("display_status", segments.FetchStatus)
segment.migratePropertyKey("display_stash_count", segments.FetchStashCount)
segment.migratePropertyKey("display_worktree_count", segments.FetchWorktreeCount)
segment.migratePropertyKey("display_upstream_icon", segments.FetchUpstreamIcon)
segment.migrateTemplate()
segment.migrateIconOverride("local_working_icon", " \uF044 ")
segment.migrateIconOverride("local_staged_icon", " \uF046 ")
segment.migrateIconOverride("stash_count_icon", " \uF692 ")
segment.migrateIconOverride("worktree_count_icon", " \uf1bb ")
segment.migrateIconOverride("status_separator_icon", " |")
if segment.Properties.GetBool(properties.Property("status_colors_enabled"), false) {
background := segment.Properties.GetBool(colorBackground, true)
segment.migrateColorOverride("local_changes_color", "{{ if or (.Working.Changed) (.Staging.Changed) }}%s{{ end }}", background)
segment.migrateColorOverride("ahead_and_behind_color", "{{ if and (gt .Ahead 0) (gt .Behind 0) }}%s{{ end }}", background)
segment.migrateColorOverride("behind_color", "{{ if gt .Ahead 0 }}%s{{ end }}", background)
segment.migrateColorOverride("ahead_color", "{{ if gt .Behind 0 }}%s{{ end }}", background)
}
if !hasTemplate {
segment.migrateInlineColorOverride("working_color", "{{ .Working.String }}")
segment.migrateInlineColorOverride("staging_color", "{{ .Staging.String }}")
}
// legacy properties
delete(segment.Properties, "display_branch_status")
delete(segment.Properties, "display_status_detail")
delete(segment.Properties, "status_colors_enabled")
case BATTERY:
segment.migrateTemplate()
background := segment.Properties.GetBool(colorBackground, false)
segment.migrateColorOverride("charged_color", `{{ if eq "Full" .State.String }}%s{{ end }}`, background)
segment.migrateColorOverride("charging_color", `{{ if eq "Charging" .State.String }}%s{{ end }}`, background)
segment.migrateColorOverride("discharging_color", `{{ if eq "Discharging" .State.String }}%s{{ end }}`, background)
stateList := []string{`"Discharging"`}
if segment.Properties.GetBool(properties.Property("display_charging"), true) {
stateList = append(stateList, `"Charging"`)
}
if segment.Properties.GetBool(properties.Property("display_charged"), true) {
stateList = append(stateList, `"Full"`)
}
if len(stateList) < 3 {
enabledTemplate := "{{ $stateList := list %s }}{{ if has .State.String $stateList }}{{ .Icon }}{{ .Percentage }}{{ end }}"
template := segment.Properties.GetString(segmentTemplate, segment.writer.Template())
template = strings.ReplaceAll(template, "{{ .Icon }}{{ .Percentage }}", fmt.Sprintf(enabledTemplate, strings.Join(stateList, " ")))
segment.Properties[segmentTemplate] = template
}
// legacy properties
delete(segment.Properties, "display_charging")
delete(segment.Properties, "display_charged")
delete(segment.Properties, "battery_icon")
case PYTHON:
segment.migrateTemplate()
segment.migratePropertyKey("display_virtual_env", segments.FetchVirtualEnv)
case SESSION:
hasTemplate := segment.hasProperty(segmentTemplate)
segment.migrateTemplate()
segment.migrateIconOverride("ssh_icon", "\uf817 ")
template := segment.Properties.GetString(segmentTemplate, segment.writer.Template())
template = strings.ReplaceAll(template, ".ComputerName", ".HostName")
if !segment.Properties.GetBool(properties.Property("display_host"), true) {
template = strings.ReplaceAll(template, "@{{ .HostName }}", "")
}
if !segment.Properties.GetBool(properties.Property("display_user"), true) {
template = strings.ReplaceAll(template, "@", "")
template = strings.ReplaceAll(template, "{{ .UserName }}", "")
}
segment.Properties[segmentTemplate] = template
segment.migrateIconOverride("user_info_separator", "@")
if !hasTemplate {
segment.migrateInlineColorOverride("user_color", "{{ .UserName }}")
segment.migrateInlineColorOverride("host_color", "{{ .HostName }}")
}
case NODE:
segment.migrateTemplate()
segment.migratePropertyKey("display_package_manager", segments.FetchPackageManager)
enableVersionMismatch := "enable_version_mismatch"
if segment.Properties.GetBool(properties.Property(enableVersionMismatch), false) {
delete(segment.Properties, properties.Property(enableVersionMismatch))
background := segment.Properties.GetBool(colorBackground, false)
segment.migrateColorOverride("version_mismatch_color", "{{ if .Mismatch }}%s{{ end }}", background)
}
case EXIT:
template := segment.Properties.GetString(segmentTemplate, segment.writer.Template())
if strings.Contains(template, ".Text") {
template = strings.ReplaceAll(template, ".Text", ".Meaning")
segment.Properties[segmentTemplate] = template
}
displayExitCode := properties.Property("display_exit_code")
if !segment.Properties.GetBool(displayExitCode, true) {
delete(segment.Properties, displayExitCode)
template = strings.ReplaceAll(template, " {{ .Meaning }}", "")
}
alwaysNumeric := properties.Property("always_numeric")
if segment.Properties.GetBool(alwaysNumeric, false) {
delete(segment.Properties, alwaysNumeric)
template = strings.ReplaceAll(template, ".Meaning", ".Code")
}
segment.Properties[segmentTemplate] = template
segment.migrateTemplate()
segment.migrateIconOverride("success_icon", "\uf42e")
segment.migrateIconOverride("error_icon", "\uf00d")
background := segment.Properties.GetBool(colorBackground, false)
segment.migrateColorOverride("error_color", "{{ if gt .Code 0 }}%s{{ end }}", background)
default:
segment.migrateTemplate()
}
delete(segment.Properties, colorBackground)
}
func (segment *Segment) migrationTwo(env platform.Environment) {
if err := segment.mapSegmentWithWriter(env); err != nil {
return
}
if !segment.hasProperty(segmentTemplate) {
return
}
template := segment.Properties.GetString(segmentTemplate, segment.writer.Template())
segment.Template = template
delete(segment.Properties, segmentTemplate)
}
func (segment *Segment) hasProperty(property properties.Property) bool {
for key := range segment.Properties {
if key == property {
return true
}
}
return false
}
func (segment *Segment) migratePropertyValue(property properties.Property, value interface{}) {
if !segment.hasProperty(property) {
return
}
segment.Properties[property] = value
}
func (segment *Segment) migratePropertyKey(oldProperty, newProperty properties.Property) {
if !segment.hasProperty(oldProperty) {
return
}
value := segment.Properties[oldProperty]
delete(segment.Properties, oldProperty)
segment.Properties[newProperty] = value
}
func (segment *Segment) migrateTemplate() {
defer segment.migratePreAndPostFix()
if segment.hasProperty(segmentTemplate) {
// existing template, ensure to add default pre/postfix values
if !segment.hasProperty(prefix) {
segment.Properties[prefix] = " "
}
if !segment.hasProperty(postfix) {
segment.Properties[postfix] = " "
}
return
}
segment.Properties[segmentTemplate] = segment.writer.Template()
}
func (segment *Segment) migrateIconOverride(property properties.Property, overrideValue string) {
if !segment.hasProperty(property) {
return
}
template := segment.Properties.GetString(segmentTemplate, segment.writer.Template())
if strings.Contains(template, overrideValue) {
template = strings.ReplaceAll(template, overrideValue, segment.Properties.GetString(property, ""))
}
segment.Properties[segmentTemplate] = template
delete(segment.Properties, property)
}
func (segment *Segment) migrateColorOverride(property properties.Property, template string, background bool) {
if !segment.hasProperty(property) {
return
}
color := segment.Properties.GetColor(property, "")
delete(segment.Properties, property)
if len(color) == 0 {
return
}
colorTemplate := fmt.Sprintf(template, color)
if background {
segment.BackgroundTemplates = append(segment.BackgroundTemplates, colorTemplate)
return
}
segment.ForegroundTemplates = append(segment.ForegroundTemplates, colorTemplate)
}
func (segment *Segment) migrateInlineColorOverride(property properties.Property, old string) {
if !segment.hasProperty(property) {
return
}
color := segment.Properties.GetColor(property, "")
delete(segment.Properties, property)
if len(color) == 0 {
return
}
colorTemplate := fmt.Sprintf("<%s>%s</>", color, old)
template := segment.Properties.GetString(segmentTemplate, segment.writer.Template())
template = strings.ReplaceAll(template, old, colorTemplate)
segment.Properties[segmentTemplate] = template
}
func (segment *Segment) migratePreAndPostFix() {
template := segment.Properties.GetString(segmentTemplate, segment.writer.Template())
defaultValue := " "
if segment.hasProperty(prefix) {
prefix := segment.Properties.GetString(prefix, defaultValue)
template = strings.TrimPrefix(template, defaultValue)
template = prefix + template
delete(segment.Properties, "prefix")
}
if segment.hasProperty(postfix) {
postfix := segment.Properties.GetString(postfix, defaultValue)
template = strings.TrimSuffix(template, defaultValue)
template += postfix
delete(segment.Properties, "postfix")
}
segment.Properties[segmentTemplate] = template
}