Repository: JanDeDobbeleer/oh-my-posh
Pull request #2571 (2022-07-26 05:29:53)

fix(python): do not stop at pyenv fail
### 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

adds more logging for #2569


<!---

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/environment/shell.go b/src/environment/shell.go
index 93c05ab8..3033b97e 100644
--- a/src/environment/shell.go
+++ b/src/environment/shell.go
@@ -416,7 +416,14 @@ func (env *ShellEnvironment) HasFolder(folder string) bool {
 }
 
 func (env *ShellEnvironment) ResolveSymlink(path string) (string, error) {
-	return filepath.EvalSymlinks(path)
+	defer env.Trace(time.Now(), "ResolveSymlink", path)
+	link, err := filepath.EvalSymlinks(path)
+	if err != nil {
+		env.Log(Error, "ResolveSymlink", err.Error())
+		return "", err
+	}
+	env.Log(Debug, "ResolveSymlink", link)
+	return link, nil
 }
 
 func (env *ShellEnvironment) FileContent(file string) string {
@@ -505,18 +512,21 @@ func (env *ShellEnvironment) RunShellCommand(shell, command string) string {
 }
 
 func (env *ShellEnvironment) CommandPath(command string) string {
-	defer env.Trace(time.Now(), "HasCommand", command)
+	defer env.Trace(time.Now(), "CommandPath", command)
 	if path, ok := env.cmdCache.get(command); ok {
+		env.Log(Debug, "CommandPath", path)
 		return path
 	}
 	path, err := exec.LookPath(command)
 	if err == nil {
 		env.cmdCache.set(command, path)
+		env.Log(Debug, "CommandPath", path)
 		return path
 	}
 	path, err = env.LookWinAppPath(command)
 	if err == nil {
 		env.cmdCache.set(command, path)
+		env.Log(Debug, "CommandPath", path)
 		return path
 	}
 	env.Log(Error, "CommandPath", err.Error())
@@ -524,6 +534,7 @@ func (env *ShellEnvironment) CommandPath(command string) string {
 }
 
 func (env *ShellEnvironment) HasCommand(command string) bool {
+	defer env.Trace(time.Now(), "HasCommand", command)
 	if path := env.CommandPath(command); path != "" {
 		return true
 	}
diff --git a/src/segments/language.go b/src/segments/language.go
index 05e2e013..dceff639 100644
--- a/src/segments/language.go
+++ b/src/segments/language.go
@@ -171,7 +171,7 @@ func (l *language) setVersion() error {
 		} else {
 			versionStr, err = command.getVersion()
 			if err != nil {
-				return err
+				continue
 			}
 		}
 		if versionStr == "" {
diff --git a/src/segments/python.go b/src/segments/python.go
index c59b90a5..55873d19 100644
--- a/src/segments/python.go
+++ b/src/segments/python.go
@@ -1,6 +1,8 @@
 package segments
 
 import (
+	"errors"
+	"fmt"
 	"oh-my-posh/environment"
 	"oh-my-posh/properties"
 	"path/filepath"
@@ -102,36 +104,36 @@ func (p *Python) pyenvVersion() (string, error) {
 	// Is our Python executable at $PYENV_ROOT/bin/python ?
 	// Should p.env expose command paths?
 	path := p.env.CommandPath("python")
-	if path == "" {
+	if len(path) == 0 {
 		path = p.env.CommandPath("python3")
 	}
-	if path == "" {
-		return "", nil
+	if len(path) == 0 {
+		return "", errors.New("no python executable found")
 	}
+	pyEnvRoot := p.env.Getenv("PYENV_ROOT")
 	// TODO:  pyenv-win has this at $PYENV_ROOT/pyenv-win/shims
-	if path != filepath.Join(p.env.Getenv("PYENV_ROOT"), "shims", "python") {
-		return "", nil
+	if path != filepath.Join(pyEnvRoot, "shims", "python") {
+		return "", fmt.Errorf("executable at %s is not a pyenv shim", path)
 	}
 	// pyenv version-name will return current version or virtualenv
 	cmdOutput, err := p.env.RunCommand("pyenv", "version-name")
 	if err != nil {
-		// TODO: Improve reporting
-		return "", nil
+		return "", err
 	}
 	versionString := strings.Split(cmdOutput, ":")[0]
-	if versionString == "" {
-		return "", nil
+	if len(versionString) == 0 {
+		return "", errors.New("no pyenv version-name found")
 	}
 
 	// $PYENV_ROOT/versions + versionString (symlinks resolved) == $PYENV_ROOT/versions/(version)[/envs/(virtualenv)]
-	realPath, err := p.env.ResolveSymlink(filepath.Join(p.env.Getenv("PYENV_ROOT"), "versions", versionString))
+	realPath, err := p.env.ResolveSymlink(filepath.Join(pyEnvRoot, "versions", versionString))
 	if err != nil {
-		return "", nil
+		return "", err
 	}
 	// ../versions/(version)[/envs/(virtualenv)]
-	shortPath, err := filepath.Rel(filepath.Join(p.env.Getenv("PYENV_ROOT"), "versions"), realPath)
+	shortPath, err := filepath.Rel(filepath.Join(pyEnvRoot, "versions"), realPath)
 	if err != nil {
-		return "", nil
+		return "", err
 	}
 	// Unset whatever loadContext thinks Venv should be
 	p.Venv = ""


Test patch:
diff --git a/src/segments/golang_test.go b/src/segments/golang_test.go
index 7eb45642..ef4941d4 100644
--- a/src/segments/golang_test.go
+++ b/src/segments/golang_test.go
@@ -53,7 +53,7 @@ func TestGolang(t *testing.T) {
 			ParseModFile:          true,
 			HasModFileInParentDir: true,
 			InvalidModfile:        true,
-			ExpectedString:        "../go.mod:1: unknown directive: invalid",
+			ExpectedString:        "1.16",
 			Version:               "go version go1.16 darwin/amd64",
 		},
 	}
diff --git a/src/segments/python_test.go b/src/segments/python_test.go
index a8ba42f9..e9e935ec 100644
--- a/src/segments/python_test.go
+++ b/src/segments/python_test.go
@@ -8,6 +8,7 @@ import (
 	"testing"
 
 	"github.com/alecthomas/assert"
+	mock2 "github.com/stretchr/testify/mock"
 )
 
 func TestPythonTemplate(t *testing.T) {
@@ -70,7 +71,7 @@ func TestPythonTemplate(t *testing.T) {
 	for _, tc := range cases {
 		env := new(mock.MockedEnvironment)
 		env.On("HasCommand", "python").Return(true)
-		env.On("CommandPath", "mock.Anything").Return(tc.PythonPath)
+		env.On("CommandPath", mock2.Anything).Return(tc.PythonPath)
 		env.On("RunCommand", "python", []string{"--version"}).Return("Python 3.8.4", nil)
 		env.On("RunCommand", "pyenv", []string{"version-name"}).Return(tc.VirtualEnvName, nil)
 		env.On("HasFiles", "*.py").Return(true)
@@ -81,7 +82,7 @@ func TestPythonTemplate(t *testing.T) {
 		env.On("PathSeparator").Return("")
 		env.On("Pwd").Return("/usr/home/project")
 		env.On("Home").Return("/usr/home")
-		env.On("ResolveSymlink", "mock.Anything").Return(tc.ResolveSymlink.Path, tc.ResolveSymlink.Err)
+		env.On("ResolveSymlink", mock2.Anything).Return(tc.ResolveSymlink.Path, tc.ResolveSymlink.Err)
 		props := properties.Map{
 			properties.FetchVersion: tc.FetchVersion,
 			UsePythonVersionFile:    true,