Repository: JanDeDobbeleer/oh-my-posh
Pull request #2818 (2022-09-23 06:40:12)

Morning folks
### Prerequisites

- [x] I have read and understood the [contributing guide][CONTRIBUTING.md]
- [x] The commit message follows the [conventional commits][cc] guidelines
- [x] Tests for the changes have been added (for bug fixes/features)
- [x] Docs have been added/updated (for bug fixes/features)

### Description

<!--TemplateBody-->

<!---

Tips:

If you're not comfortable with working with Git, we're working a guide (https://ohmyposh.dev/docs/contributing_git) to help you out.
Oh My Posh advises GitKraken (https://www.gitkraken.com/invite/nQmDPR9D) as your preferred cross platform Git GUI power tool.

-->

[CONTRIBUTING.md]: https://github.com/JanDeDobbeleer/oh-my-posh/blob/main/CONTRIBUTING.md
[cc]: https://www.conventionalcommits.org/en/v1.0.0/#summary



Patch:
diff --git a/src/cli/get.go b/src/cli/get.go
index 473dcf33..a211b567 100644
--- a/src/cli/get.go
+++ b/src/cli/get.go
@@ -34,6 +34,9 @@ This command is used to get the value of the following variables:
 		}
 		env := &environment.ShellEnvironment{
 			Version: cliVersion,
+			CmdFlags: &environment.Flags{
+				Shell: shellName,
+			},
 		}
 		env.Init()
 		defer env.Close()
diff --git a/src/engine/segment.go b/src/engine/segment.go
index d6e2adab..f3f846b0 100644
--- a/src/engine/segment.go
+++ b/src/engine/segment.go
@@ -156,8 +156,6 @@ const (
 	PHP SegmentType = "php"
 	// PLASTIC represents the plastic scm status and information
 	PLASTIC SegmentType = "plastic"
-	// POSHGIT writes the posh git prompt
-	POSHGIT SegmentType = "poshgit"
 	// Project version
 	PROJECT SegmentType = "project"
 	// PYTHON writes the virtual env name
diff --git a/src/segments/gcp.go b/src/segments/gcp.go
index 163630d9..3b88d48b 100644
--- a/src/segments/gcp.go
+++ b/src/segments/gcp.go
@@ -5,11 +5,14 @@ import (
 	"oh-my-posh/environment"
 	"oh-my-posh/properties"
 	"path"
-	"path/filepath"
 
 	"gopkg.in/ini.v1"
 )
 
+const (
+	GCPNOACTIVECONFIG = "NO ACTIVE CONFIG FOUND"
+)
+
 type Gcp struct {
 	props properties.Properties
 	env   environment.Environment
@@ -17,11 +20,10 @@ type Gcp struct {
 	Account string
 	Project string
 	Region  string
-	Error   string
 }
 
 func (g *Gcp) Template() string {
-	return " {{ if not .Error }}{{ .Project }}{{ end }} "
+	return " {{ .Project }} "
 }
 
 func (g *Gcp) Init(props properties.Properties, env environment.Environment) {
@@ -33,44 +35,47 @@ func (g *Gcp) Enabled() bool {
 	cfgDir := g.getConfigDirectory()
 	configFile, err := g.getActiveConfig(cfgDir)
 	if err != nil {
-		g.Error = err.Error()
-		return true
+		g.env.Log(environment.Error, "Gcp.Enabled()", err.Error())
+		return false
 	}
 
 	cfgpath := path.Join(cfgDir, "configurations", "config_"+configFile)
+	cfg := g.env.FileContent(cfgpath)
 
-	cfg, err := ini.Load(cfgpath)
+	if len(cfg) == 0 {
+		g.env.Log(environment.Error, "Gcp.Enabled()", "config file is empty")
+		return false
+	}
+
+	data, err := ini.Load([]byte(cfg))
 	if err != nil {
-		g.Error = "GCLOUD CONFIG ERROR"
-		return true
+		g.env.Log(environment.Error, "Gcp.Enabled()", err.Error())
+		return false
 	}
 
-	g.Project = cfg.Section("core").Key("project").String()
-	g.Account = cfg.Section("core").Key("account").String()
-	g.Region = cfg.Section("compute").Key("region").String()
+	g.Project = data.Section("core").Key("project").String()
+	g.Account = data.Section("core").Key("account").String()
+	g.Region = data.Section("compute").Key("region").String()
 
 	return true
 }
 
 func (g *Gcp) getActiveConfig(cfgDir string) (string, error) {
 	ap := path.Join(cfgDir, "active_config")
-	absolutePath, err := filepath.Abs(ap)
-	if err != nil {
-		return "", err
-	}
-
-	fileContent := g.env.FileContent(absolutePath)
+	fileContent := g.env.FileContent(ap)
 	if len(fileContent) == 0 {
-		return "", errors.New("NO ACTIVE CONFIG FOUND")
+		return "", errors.New(GCPNOACTIVECONFIG)
 	}
 	return fileContent, nil
 }
 
 func (g *Gcp) getConfigDirectory() string {
 	cfgDir := g.env.Getenv("CLOUDSDK_CONFIG")
-	if len(cfgDir) == 0 {
-		cfgDir = path.Join(g.env.Home(), ".config", "gcloud")
+	if len(cfgDir) != 0 {
+		return cfgDir
 	}
-
-	return cfgDir
+	if g.env.GOOS() == environment.WINDOWS {
+		return path.Join(g.env.Getenv("APPDATA"), "gcloud")
+	}
+	return path.Join(g.env.Home(), ".config", "gcloud")
 }
diff --git a/src/shell/scripts/omp.bash b/src/shell/scripts/omp.bash
index 942deaee..f3fb7489 100644
--- a/src/shell/scripts/omp.bash
+++ b/src/shell/scripts/omp.bash
@@ -17,7 +17,7 @@ function _omp_hook() {
     local omp_stack_count=$((${#DIRSTACK[@]} - 1))
     local omp_elapsed=-1
     if [[ -n "$omp_start_time" ]]; then
-        local omp_now=$(::OMP:: get millis)
+        local omp_now=$(::OMP:: get millis --shell=bash)
         omp_elapsed=$((omp_now-omp_start_time))
         omp_start_time=""
     fi
diff --git a/src/shell/scripts/omp.lua b/src/shell/scripts/omp.lua
index 88afab1a..0ab06c9e 100644
--- a/src/shell/scripts/omp.lua
+++ b/src/shell/scripts/omp.lua
@@ -23,6 +23,7 @@ end
 local endedit_time = 0
 local last_duration = 0
 local tip
+local tooltips_enabled = ::TOOLTIPS::
 local tooltip_active = false
 local cached_prompt = {}
 
@@ -60,7 +61,7 @@ local function os_clock_millis()
     if (clink.version_encoded or 0) >= 10020030 then
         return math.floor(os.clock() * 1000)
     else
-        local prompt_exe = string.format('%s get millis', omp_exe())
+        local prompt_exe = string.format('%s get millis --shell=cmd', omp_exe())
         return run_posh_command(prompt_exe)
     end
 end
@@ -177,7 +178,7 @@ function p:rightfilter(prompt)
     return cached_prompt.right, false
 end
 function p:transientfilter(prompt)
-    local prompt_exe = string.format('%s print transient --config=%s %s', omp_exe(), omp_config(), error_level_option())
+    local prompt_exe = string.format('%s print transient --shell=cmd --config=%s %s', omp_exe(), omp_config(), error_level_option())
     prompt = run_posh_command(prompt_exe)
     if prompt == "" then
         prompt = nil
@@ -216,7 +217,7 @@ function ohmyposh_space(rl_buffer)
     end
 end
 
-if rl.setbinding then
+if tooltips_enabled and rl.setbinding then
     clink.onbeginedit(function () tip = nil cached_prompt = {} end)
     rl.setbinding(' ', [["luafunc:ohmyposh_space"]], 'emacs')
 end
diff --git a/src/shell/scripts/omp.zsh b/src/shell/scripts/omp.zsh
index c5e7fa22..566ad06b 100644
--- a/src/shell/scripts/omp.zsh
+++ b/src/shell/scripts/omp.zsh
@@ -14,7 +14,7 @@ function prompt_ohmyposh_precmd() {
   omp_stack_count=${#dirstack[@]}
   omp_elapsed=-1
   if [ $omp_start_time ]; then
-    omp_now=$(::OMP:: get millis)
+    omp_now=$(::OMP:: get millis --shell=zsh)
     omp_elapsed=$(($omp_now-$omp_start_time))
   fi
   eval "$(::OMP:: print primary --config="$POSH_THEME" --error="$omp_last_error" --execution-time="$omp_elapsed" --stack-count="$omp_stack_count" --eval --shell=zsh --shell-version="$ZSH_VERSION")"
diff --git a/themes/lambdageneration.omp.json b/themes/lambdageneration.omp.json
index 9ce0715f..ac6a6fd2 100644
--- a/themes/lambdageneration.omp.json
+++ b/themes/lambdageneration.omp.json
@@ -46,8 +46,7 @@
           "background": "#292929",
           "foreground": "#D4E157",
           "style": "plain",
-          "template": "<#fb7e14>\ue0b1 </>{{ .Status }} ",
-          "type": "poshgit"
+          "type": "git"
         },
         {
           "background": "#292929",
@@ -100,10 +99,10 @@
           "background": "#292929",
           "foreground": "#fb7e14",
           "properties": {
-            "time_format": "15:04:05"
+            "time_format": "15:04:05, _2"
           },
           "style": "diamond",
-          "template": "{{ .CurrentDate | date .Format }} \uf017 ",
+          "template": "{{ .CurrentDate | date .Format }} \uf5ef ",
           "trailing_diamond": "\ue0b4",
           "type": "time"
         }
@@ -132,4 +131,4 @@
   ],
   "final_space": true,
   "version": 2
-}
\ No newline at end of file
+}
diff --git a/themes/schema.json b/themes/schema.json
index 8ad81410..aad434bd 100644
--- a/themes/schema.json
+++ b/themes/schema.json
@@ -255,7 +255,6 @@
             "path",
             "perl",
             "python",
-            "poshgit",
             "php",
             "plastic",
             "project",
diff --git a/website/docs/segments/git.mdx b/website/docs/segments/git.mdx
index b156a81c..e1f47107 100644
--- a/website/docs/segments/git.mdx
+++ b/website/docs/segments/git.mdx
@@ -147,7 +147,7 @@ Local changes use the following syntax:
 | `-`  | deleted     |
 | `?`  | untracked   |
 
-[poshgit]: /docs/segments/poshgit
+[poshgit]: https://github.com/dahlbyk/posh-git
 [templates]: /docs/configuration/templates
 [hyperlinks]: /docs/configuration/templates#helper-functions
 [untracked]: https://git-scm.com/docs/git-status#Documentation/git-status.txt---untracked-filesltmodegt


Test patch:
diff --git a/src/segments/gcp_test.go b/src/segments/gcp_test.go
index 46d33b56..f3044def 100644
--- a/src/segments/gcp_test.go
+++ b/src/segments/gcp_test.go
@@ -2,61 +2,142 @@ package segments
 
 import (
 	"path"
-	"path/filepath"
 	"testing"
 
+	"oh-my-posh/environment"
 	"oh-my-posh/mock"
 
 	"github.com/stretchr/testify/assert"
+	mock2 "github.com/stretchr/testify/mock"
 )
 
 func TestGcpSegment(t *testing.T) {
-	standardTemplate := "{{ if .Error }}{{ .Error }}{{ else }}{{ .Project }}{{ end }}"
-	allTemplate := "{{.Project}} :: {{.Region}} :: {{.Account}}"
-
 	cases := []struct {
 		Case            string
-		Template        string
-		ConfigPath      string
+		CfgData         string
 		ActiveConfig    string
 		ExpectedEnabled bool
 		ExpectedString  string
 	}{
 		{
-			Case:            "all information",
-			Template:        allTemplate,
-			ConfigPath:      "../test/",
-			ActiveConfig:    "gcptest",
+			Case:            "happy path",
 			ExpectedEnabled: true,
-			ExpectedString:  "test-test-test :: europe-test1 :: test@example.com",
+			ActiveConfig:    "production",
+			CfgData: `
+			[core]
+			account = test@example.com
+			project = test-test-test
+
+			[compute]
+			region = europe-test1
+			`,
+			ExpectedString: "test-test-test :: europe-test1 :: test@example.com",
 		},
 		{
-			Case:            "non-existent config file",
-			Template:        standardTemplate,
-			ConfigPath:      "../invalid/",
-			ActiveConfig:    "nofile",
-			ExpectedEnabled: true,
-			ExpectedString:  "GCLOUD CONFIG ERROR",
+			Case:            "no active config",
+			ExpectedEnabled: false,
 		},
 		{
-			Case:            "invalid active config file",
-			Template:        standardTemplate,
-			ConfigPath:      "../invalid/",
-			ActiveConfig:    "",
-			ExpectedEnabled: true,
-			ExpectedString:  "NO ACTIVE CONFIG FOUND",
+			Case:            "empty config",
+			ActiveConfig:    "production",
+			ExpectedEnabled: false,
+		},
+		{
+			Case:            "bad config",
+			ActiveConfig:    "production",
+			CfgData:         "{bad}",
+			ExpectedEnabled: false,
 		},
 	}
 
 	for _, tc := range cases {
 		env := new(mock.MockedEnvironment)
-		env.On("Getenv", "CLOUDSDK_CONFIG").Return(tc.ConfigPath)
-		fcPath, _ := filepath.Abs(path.Join(tc.ConfigPath, "active_config"))
+		env.On("Getenv", "CLOUDSDK_CONFIG").Return("config")
+		fcPath := path.Join("config", "active_config")
 		env.On("FileContent", fcPath).Return(tc.ActiveConfig)
+		cfgpath := path.Join("config", "configurations", "config_production")
+		env.On("FileContent", cfgpath).Return(tc.CfgData)
+		env.On("Log", environment.Error, "Gcp.Enabled()", mock2.Anything).Return()
 		g := &Gcp{
 			env: env,
 		}
 		assert.Equal(t, tc.ExpectedEnabled, g.Enabled(), tc.Case)
-		assert.Equal(t, tc.ExpectedString, renderTemplate(env, tc.Template, g), tc.Case)
+		if tc.ExpectedEnabled {
+			assert.Equal(t, tc.ExpectedString, renderTemplate(env, "{{.Project}} :: {{.Region}} :: {{.Account}}", g), tc.Case)
+		}
+	}
+}
+
+func TestGetConfigDirectory(t *testing.T) {
+	cases := []struct {
+		Case           string
+		GOOS           string
+		Home           string
+		AppData        string
+		CloudSDKConfig string
+		Expected       string
+	}{
+		{
+			Case:           "CLOUDSDK_CONFIG",
+			CloudSDKConfig: "/Users/posh/.config/gcloud",
+			Expected:       "/Users/posh/.config/gcloud",
+		},
+		{
+			Case:     "Windows",
+			GOOS:     environment.WINDOWS,
+			AppData:  "/Users/posh/.config",
+			Expected: "/Users/posh/.config/gcloud",
+		},
+		{
+			Case:     "default",
+			Home:     "/Users/posh2/",
+			Expected: "/Users/posh2/.config/gcloud",
+		},
+	}
+
+	for _, tc := range cases {
+		env := new(mock.MockedEnvironment)
+		env.On("Getenv", "CLOUDSDK_CONFIG").Return(tc.CloudSDKConfig)
+		env.On("Getenv", "APPDATA").Return(tc.AppData)
+		env.On("Home").Return(tc.Home)
+		env.On("GOOS").Return(tc.GOOS)
+		g := &Gcp{
+			env: env,
+		}
+		assert.Equal(t, tc.Expected, g.getConfigDirectory(), tc.Case)
+	}
+}
+
+func TestGetActiveConfig(t *testing.T) {
+	cases := []struct {
+		Case           string
+		ActiveConfig   string
+		ExpectedString string
+		ExpectedError  string
+	}{
+		{
+			Case:          "No active config",
+			ExpectedError: GCPNOACTIVECONFIG,
+		},
+		{
+			Case:           "No active config",
+			ActiveConfig:   "production",
+			ExpectedString: "production",
+		},
+	}
+
+	for _, tc := range cases {
+		env := new(mock.MockedEnvironment)
+		env.On("FileContent", "active_config").Return(tc.ActiveConfig)
+		g := &Gcp{
+			env: env,
+		}
+		got, err := g.getActiveConfig("")
+		assert.Equal(t, tc.ExpectedString, got, tc.Case)
+		if len(tc.ExpectedError) > 0 {
+			assert.EqualError(t, err, tc.ExpectedError, tc.Case)
+		} else {
+			assert.NoError(t, err, tc.Case)
+		}
 	}
 }
diff --git a/src/test/configurations/config_gcptest b/src/test/configurations/config_gcptest
deleted file mode 100644
index e54e6df9..00000000
--- a/src/test/configurations/config_gcptest
+++ /dev/null
@@ -1,6 +0,0 @@
-[core]
-account = test@example.com
-project = test-test-test
-
-[compute]
-region = europe-test1