mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-12-28 04:19:41 -08:00
feat(wsl): allow using native executable on shared drive
relates to #2097
This commit is contained in:
parent
620187aada
commit
4056729e8e
|
@ -38,12 +38,11 @@ func (f *Fossil) Template() string {
|
|||
}
|
||||
|
||||
func (f *Fossil) Enabled() bool {
|
||||
command := f.getCommand(FOSSILCOMMAND)
|
||||
if !f.env.HasCommand(command) {
|
||||
if !f.hasCommand(FOSSILCOMMAND) {
|
||||
return false
|
||||
}
|
||||
// run fossil command
|
||||
output, err := f.env.RunCommand(command, "status")
|
||||
output, err := f.env.RunCommand(f.command, "status")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ func TestFossilStatus(t *testing.T) {
|
|||
env := new(mock.MockedEnvironment)
|
||||
env.On("GOOS").Return("unix")
|
||||
env.On("IsWsl").Return(false)
|
||||
env.On("InWSLSharedDrive").Return(false)
|
||||
env.On("HasCommand", FOSSILCOMMAND).Return(tc.HasCommand)
|
||||
env.On("RunCommand", FOSSILCOMMAND, []string{"status"}).Return(strings.ReplaceAll(tc.Output, "\t", ""), tc.OutputError)
|
||||
f := &Fossil{
|
||||
|
|
|
@ -164,11 +164,7 @@ func (g *Git) Kraken() string {
|
|||
}
|
||||
|
||||
func (g *Git) shouldDisplay() bool {
|
||||
// when in a WSL shared folder, we must use git.exe and convert paths accordingly
|
||||
// for worktrees, stashes, and path to work
|
||||
g.IsWslSharedPath = g.env.InWSLSharedDrive()
|
||||
|
||||
if !g.env.HasCommand(g.getCommand(GITCOMMAND)) {
|
||||
if !g.hasCommand(GITCOMMAND) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -376,7 +372,7 @@ func (g *Git) setGitStatus() {
|
|||
|
||||
func (g *Git) getGitCommandOutput(args ...string) string {
|
||||
args = append([]string{"-C", g.realDir, "--no-optional-locks", "-c", "core.quotepath=false", "-c", "color.status=false"}, args...)
|
||||
val, err := g.env.RunCommand(g.getCommand(GITCOMMAND), args...)
|
||||
val, err := g.env.RunCommand(g.command, args...)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -154,8 +154,9 @@ func TestGetGitOutputForCommand(t *testing.T) {
|
|||
env.On("GOOS").Return("unix")
|
||||
g := &Git{
|
||||
scm: scm{
|
||||
env: env,
|
||||
props: properties.Map{},
|
||||
env: env,
|
||||
props: properties.Map{},
|
||||
command: GITCOMMAND,
|
||||
},
|
||||
}
|
||||
got := g.getGitCommandOutput(commandArgs...)
|
||||
|
@ -308,6 +309,7 @@ func TestSetGitHEADContextClean(t *testing.T) {
|
|||
TagIcon: "tag ",
|
||||
RevertIcon: "revert ",
|
||||
},
|
||||
command: GITCOMMAND,
|
||||
},
|
||||
ShortHash: "1234567",
|
||||
Ref: tc.Ref,
|
||||
|
@ -346,6 +348,7 @@ func TestSetPrettyHEADName(t *testing.T) {
|
|||
CommitIcon: "commit ",
|
||||
TagIcon: "tag ",
|
||||
},
|
||||
command: GITCOMMAND,
|
||||
},
|
||||
ShortHash: tc.ShortHash,
|
||||
}
|
||||
|
@ -473,8 +476,9 @@ func TestSetGitStatus(t *testing.T) {
|
|||
env.MockGitCommand("", strings.ReplaceAll(tc.Output, "\t", ""), "status", "-unormal", "--branch", "--porcelain=2")
|
||||
g := &Git{
|
||||
scm: scm{
|
||||
env: env,
|
||||
props: properties.Map{},
|
||||
env: env,
|
||||
props: properties.Map{},
|
||||
command: GITCOMMAND,
|
||||
},
|
||||
}
|
||||
if tc.ExpectedWorking == nil {
|
||||
|
@ -546,8 +550,9 @@ func TestGitUpstream(t *testing.T) {
|
|||
}
|
||||
g := &Git{
|
||||
scm: scm{
|
||||
env: env,
|
||||
props: props,
|
||||
env: env,
|
||||
props: props,
|
||||
command: GITCOMMAND,
|
||||
},
|
||||
Upstream: "origin/main",
|
||||
}
|
||||
|
@ -595,48 +600,6 @@ func TestGetBranchStatus(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGetGitCommand(t *testing.T) {
|
||||
cases := []struct {
|
||||
Case string
|
||||
Expected string
|
||||
IsWSL bool
|
||||
IsWSL1 bool
|
||||
GOOS string
|
||||
CWD string
|
||||
IsWslSharedPath bool
|
||||
}{
|
||||
{Case: "On Windows", Expected: "git.exe", GOOS: environment.WINDOWS},
|
||||
{Case: "Non Windows", Expected: "git"},
|
||||
{Case: "Iside WSL2, non shared", IsWSL: true, Expected: "git"},
|
||||
{Case: "Iside WSL2, shared", Expected: "git.exe", IsWSL: true, IsWslSharedPath: true, CWD: "/mnt/bill"},
|
||||
{Case: "Iside WSL1, shared", Expected: "git", IsWSL: true, IsWSL1: true, CWD: "/mnt/bill"},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
env := new(mock.MockedEnvironment)
|
||||
env.On("IsWsl").Return(tc.IsWSL)
|
||||
env.On("GOOS").Return(tc.GOOS)
|
||||
env.On("Pwd").Return(tc.CWD)
|
||||
wslUname := "5.10.60.1-microsoft-standard-WSL2"
|
||||
if tc.IsWSL1 {
|
||||
wslUname = "4.4.0-19041-Microsoft"
|
||||
}
|
||||
env.On("RunCommand", "uname", []string{"-r"}).Return(wslUname, nil)
|
||||
g := &Git{
|
||||
scm: scm{
|
||||
env: env,
|
||||
},
|
||||
}
|
||||
if tc.IsWslSharedPath {
|
||||
env.On("InWSLSharedDrive").Return(true)
|
||||
g.IsWslSharedPath = tc.IsWslSharedPath
|
||||
} else {
|
||||
env.On("InWSLSharedDrive").Return(false)
|
||||
}
|
||||
assert.Equal(t, tc.Expected, g.getCommand(GITCOMMAND), tc.Case)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGitTemplateString(t *testing.T) {
|
||||
cases := []struct {
|
||||
Case string
|
||||
|
|
|
@ -193,6 +193,7 @@ func TestPoshGitSegment(t *testing.T) {
|
|||
props: &properties.Map{
|
||||
FetchUpstreamIcon: tc.FetchUpstreamIcon,
|
||||
},
|
||||
command: GITCOMMAND,
|
||||
},
|
||||
}
|
||||
if len(tc.Template) == 0 {
|
||||
|
|
|
@ -7,6 +7,11 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// Fallback to native command
|
||||
NativeFallback properties.Property = "native_fallback"
|
||||
)
|
||||
|
||||
// ScmStatus represents part of the status of a repository
|
||||
type ScmStatus struct {
|
||||
Unmerged int
|
||||
|
@ -45,6 +50,7 @@ type scm struct {
|
|||
env environment.Environment
|
||||
|
||||
IsWslSharedPath bool
|
||||
CommandMissing bool
|
||||
Dir string // actual repo root directory
|
||||
|
||||
workingDir string
|
||||
|
@ -107,13 +113,28 @@ func (s *scm) convertToLinuxPath(path string) string {
|
|||
return s.env.ConvertToLinuxPath(path)
|
||||
}
|
||||
|
||||
func (s *scm) getCommand(command string) string {
|
||||
func (s *scm) hasCommand(command string) bool {
|
||||
if len(s.command) > 0 {
|
||||
return s.command
|
||||
return true
|
||||
}
|
||||
s.command = command
|
||||
// when in a WSL shared folder, we must use command.exe and convert paths accordingly
|
||||
// for worktrees, stashes, and path to work
|
||||
s.IsWslSharedPath = s.env.InWSLSharedDrive()
|
||||
if s.env.GOOS() == environment.WINDOWS || s.IsWslSharedPath {
|
||||
s.command += ".exe"
|
||||
command += ".exe"
|
||||
}
|
||||
return s.command
|
||||
if s.env.HasCommand(command) {
|
||||
s.command = command
|
||||
return true
|
||||
}
|
||||
s.CommandMissing = true
|
||||
// only use the native fallback when set by the user
|
||||
if s.IsWslSharedPath && s.props.GetBool(NativeFallback, false) {
|
||||
command = strings.TrimSuffix(command, ".exe")
|
||||
if s.env.HasCommand(command) {
|
||||
s.command = command
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package segments
|
||||
|
||||
import (
|
||||
"oh-my-posh/environment"
|
||||
"oh-my-posh/mock"
|
||||
"oh-my-posh/properties"
|
||||
"testing"
|
||||
|
||||
|
@ -154,3 +156,39 @@ func TestTruncateBranchWithSymbol(t *testing.T) {
|
|||
assert.Equal(t, tc.Expected, p.truncateBranch(tc.Branch), tc.Case)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasCommand(t *testing.T) {
|
||||
cases := []struct {
|
||||
Case string
|
||||
ExpectedCommand string
|
||||
Command string
|
||||
GOOS string
|
||||
IsWslSharedPath bool
|
||||
NativeFallback bool
|
||||
}{
|
||||
{Case: "On Windows", ExpectedCommand: "git.exe", GOOS: environment.WINDOWS},
|
||||
{Case: "Cache", ExpectedCommand: "git.exe", Command: "git.exe"},
|
||||
{Case: "Non Windows", ExpectedCommand: "git"},
|
||||
{Case: "Iside WSL2, non shared", ExpectedCommand: "git"},
|
||||
{Case: "Iside WSL2, shared", ExpectedCommand: "git.exe", IsWslSharedPath: true},
|
||||
{Case: "Iside WSL2, shared fallback", ExpectedCommand: "git", IsWslSharedPath: true, NativeFallback: true},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
env := new(mock.MockedEnvironment)
|
||||
env.On("GOOS").Return(tc.GOOS)
|
||||
env.On("InWSLSharedDrive").Return(tc.IsWslSharedPath)
|
||||
env.On("HasCommand", "git").Return(true)
|
||||
env.On("HasCommand", "git.exe").Return(!tc.NativeFallback)
|
||||
s := &scm{
|
||||
env: env,
|
||||
props: properties.Map{
|
||||
NativeFallback: tc.NativeFallback,
|
||||
},
|
||||
command: tc.Command,
|
||||
}
|
||||
|
||||
_ = s.hasCommand(GITCOMMAND)
|
||||
assert.Equal(t, tc.ExpectedCommand, s.command, tc.Case)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,10 +62,7 @@ func (s *Svn) Enabled() bool {
|
|||
}
|
||||
|
||||
func (s *Svn) shouldDisplay() bool {
|
||||
// when in a WSL shared folder, we must use git.exe and convert paths accordingly
|
||||
// for worktrees, stashes, and path to work
|
||||
s.IsWslSharedPath = s.env.InWSLSharedDrive()
|
||||
if !s.env.HasCommand(s.getCommand(SVNCOMMAND)) {
|
||||
if !s.hasCommand(SVNCOMMAND) {
|
||||
return false
|
||||
}
|
||||
Svndir, err := s.env.HasParentFilePath(".svn")
|
||||
|
@ -120,7 +117,7 @@ func (s *Svn) setSvnStatus() {
|
|||
|
||||
func (s *Svn) getSvnCommandOutput(command string, args ...string) string {
|
||||
args = append([]string{command, s.realDir}, args...)
|
||||
val, err := s.env.RunCommand(s.getCommand(SVNCOMMAND), args...)
|
||||
val, err := s.env.RunCommand(s.command, args...)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -234,8 +234,9 @@ R Moved.File`,
|
|||
|
||||
s := &Svn{
|
||||
scm: scm{
|
||||
env: env,
|
||||
props: properties.Map{},
|
||||
env: env,
|
||||
props: properties.Map{},
|
||||
command: SVNCOMMAND,
|
||||
},
|
||||
}
|
||||
s.setSvnStatus()
|
||||
|
|
|
@ -28,6 +28,11 @@ Local changes can also be displayed which uses the following syntax:
|
|||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
- native_fallback: `boolean` - when set to `true` and `fossil.exe` is not available when inside a WSL2 shared Windows drive, we will fallback to the native fossil
|
||||
executable to fetch data. Not all information can be displayed in this case. Defaults to `false`.
|
||||
|
||||
## Template ([info][templates])
|
||||
|
||||
:::note default template
|
||||
|
|
|
@ -66,6 +66,8 @@ You can set the following properties to `true` to enable fetching additional inf
|
|||
- ignore_submodules: `map[string]string` - map of repo's where to change the [--ignore-submodules][submodules] flag (`none`, `untracked`, `dirty` or `all`).
|
||||
For example `"ignore_submodules": { "/Users/me/repos/repo1": "all" }`. If you want to override for all repo's, use `*` to set the mode
|
||||
instead of the repo path.
|
||||
- native_fallback: `boolean` - when set to `true` and `git.exe` is not available when inside a WSL2 shared Windows drive, we will fallback to the native git
|
||||
executable to fetch data. Not all information can be displayed in this case. Defaults to `false`.
|
||||
|
||||
### Icons
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ As doing multiple [subversion][svn] calls can slow down the prompt experience, w
|
|||
You can set the following properties to `true` to enable fetching additional information (and populate the template).
|
||||
|
||||
- fetch_status: `boolean` - fetch the local changes - defaults to `false`
|
||||
- native_fallback: `boolean` - when set to `true` and `svn.exe` is not available when inside a WSL2 shared Windows drive, we will fallback to the native svn
|
||||
executable to fetch data. Not all information can be displayed in this case. Defaults to `false`.
|
||||
|
||||
## Template ([info][templates])
|
||||
|
||||
|
|
Loading…
Reference in a new issue