mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-12-31 13:57:26 -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 {
|
func (f *Fossil) Enabled() bool {
|
||||||
command := f.getCommand(FOSSILCOMMAND)
|
if !f.hasCommand(FOSSILCOMMAND) {
|
||||||
if !f.env.HasCommand(command) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// run fossil command
|
// run fossil command
|
||||||
output, err := f.env.RunCommand(command, "status")
|
output, err := f.env.RunCommand(f.command, "status")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ func TestFossilStatus(t *testing.T) {
|
||||||
env := new(mock.MockedEnvironment)
|
env := new(mock.MockedEnvironment)
|
||||||
env.On("GOOS").Return("unix")
|
env.On("GOOS").Return("unix")
|
||||||
env.On("IsWsl").Return(false)
|
env.On("IsWsl").Return(false)
|
||||||
|
env.On("InWSLSharedDrive").Return(false)
|
||||||
env.On("HasCommand", FOSSILCOMMAND).Return(tc.HasCommand)
|
env.On("HasCommand", FOSSILCOMMAND).Return(tc.HasCommand)
|
||||||
env.On("RunCommand", FOSSILCOMMAND, []string{"status"}).Return(strings.ReplaceAll(tc.Output, "\t", ""), tc.OutputError)
|
env.On("RunCommand", FOSSILCOMMAND, []string{"status"}).Return(strings.ReplaceAll(tc.Output, "\t", ""), tc.OutputError)
|
||||||
f := &Fossil{
|
f := &Fossil{
|
||||||
|
|
|
@ -164,11 +164,7 @@ func (g *Git) Kraken() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Git) shouldDisplay() bool {
|
func (g *Git) shouldDisplay() bool {
|
||||||
// when in a WSL shared folder, we must use git.exe and convert paths accordingly
|
if !g.hasCommand(GITCOMMAND) {
|
||||||
// for worktrees, stashes, and path to work
|
|
||||||
g.IsWslSharedPath = g.env.InWSLSharedDrive()
|
|
||||||
|
|
||||||
if !g.env.HasCommand(g.getCommand(GITCOMMAND)) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,7 +372,7 @@ func (g *Git) setGitStatus() {
|
||||||
|
|
||||||
func (g *Git) getGitCommandOutput(args ...string) string {
|
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...)
|
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 {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,6 +156,7 @@ func TestGetGitOutputForCommand(t *testing.T) {
|
||||||
scm: scm{
|
scm: scm{
|
||||||
env: env,
|
env: env,
|
||||||
props: properties.Map{},
|
props: properties.Map{},
|
||||||
|
command: GITCOMMAND,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
got := g.getGitCommandOutput(commandArgs...)
|
got := g.getGitCommandOutput(commandArgs...)
|
||||||
|
@ -308,6 +309,7 @@ func TestSetGitHEADContextClean(t *testing.T) {
|
||||||
TagIcon: "tag ",
|
TagIcon: "tag ",
|
||||||
RevertIcon: "revert ",
|
RevertIcon: "revert ",
|
||||||
},
|
},
|
||||||
|
command: GITCOMMAND,
|
||||||
},
|
},
|
||||||
ShortHash: "1234567",
|
ShortHash: "1234567",
|
||||||
Ref: tc.Ref,
|
Ref: tc.Ref,
|
||||||
|
@ -346,6 +348,7 @@ func TestSetPrettyHEADName(t *testing.T) {
|
||||||
CommitIcon: "commit ",
|
CommitIcon: "commit ",
|
||||||
TagIcon: "tag ",
|
TagIcon: "tag ",
|
||||||
},
|
},
|
||||||
|
command: GITCOMMAND,
|
||||||
},
|
},
|
||||||
ShortHash: tc.ShortHash,
|
ShortHash: tc.ShortHash,
|
||||||
}
|
}
|
||||||
|
@ -475,6 +478,7 @@ func TestSetGitStatus(t *testing.T) {
|
||||||
scm: scm{
|
scm: scm{
|
||||||
env: env,
|
env: env,
|
||||||
props: properties.Map{},
|
props: properties.Map{},
|
||||||
|
command: GITCOMMAND,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if tc.ExpectedWorking == nil {
|
if tc.ExpectedWorking == nil {
|
||||||
|
@ -548,6 +552,7 @@ func TestGitUpstream(t *testing.T) {
|
||||||
scm: scm{
|
scm: scm{
|
||||||
env: env,
|
env: env,
|
||||||
props: props,
|
props: props,
|
||||||
|
command: GITCOMMAND,
|
||||||
},
|
},
|
||||||
Upstream: "origin/main",
|
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) {
|
func TestGitTemplateString(t *testing.T) {
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
Case string
|
Case string
|
||||||
|
|
|
@ -193,6 +193,7 @@ func TestPoshGitSegment(t *testing.T) {
|
||||||
props: &properties.Map{
|
props: &properties.Map{
|
||||||
FetchUpstreamIcon: tc.FetchUpstreamIcon,
|
FetchUpstreamIcon: tc.FetchUpstreamIcon,
|
||||||
},
|
},
|
||||||
|
command: GITCOMMAND,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if len(tc.Template) == 0 {
|
if len(tc.Template) == 0 {
|
||||||
|
|
|
@ -7,6 +7,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Fallback to native command
|
||||||
|
NativeFallback properties.Property = "native_fallback"
|
||||||
|
)
|
||||||
|
|
||||||
// ScmStatus represents part of the status of a repository
|
// ScmStatus represents part of the status of a repository
|
||||||
type ScmStatus struct {
|
type ScmStatus struct {
|
||||||
Unmerged int
|
Unmerged int
|
||||||
|
@ -45,6 +50,7 @@ type scm struct {
|
||||||
env environment.Environment
|
env environment.Environment
|
||||||
|
|
||||||
IsWslSharedPath bool
|
IsWslSharedPath bool
|
||||||
|
CommandMissing bool
|
||||||
Dir string // actual repo root directory
|
Dir string // actual repo root directory
|
||||||
|
|
||||||
workingDir string
|
workingDir string
|
||||||
|
@ -107,13 +113,28 @@ func (s *scm) convertToLinuxPath(path string) string {
|
||||||
return s.env.ConvertToLinuxPath(path)
|
return s.env.ConvertToLinuxPath(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scm) getCommand(command string) string {
|
func (s *scm) hasCommand(command string) bool {
|
||||||
if len(s.command) > 0 {
|
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 {
|
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
|
package segments
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"oh-my-posh/environment"
|
||||||
|
"oh-my-posh/mock"
|
||||||
"oh-my-posh/properties"
|
"oh-my-posh/properties"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -154,3 +156,39 @@ func TestTruncateBranchWithSymbol(t *testing.T) {
|
||||||
assert.Equal(t, tc.Expected, p.truncateBranch(tc.Branch), tc.Case)
|
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 {
|
func (s *Svn) shouldDisplay() bool {
|
||||||
// when in a WSL shared folder, we must use git.exe and convert paths accordingly
|
if !s.hasCommand(SVNCOMMAND) {
|
||||||
// for worktrees, stashes, and path to work
|
|
||||||
s.IsWslSharedPath = s.env.InWSLSharedDrive()
|
|
||||||
if !s.env.HasCommand(s.getCommand(SVNCOMMAND)) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
Svndir, err := s.env.HasParentFilePath(".svn")
|
Svndir, err := s.env.HasParentFilePath(".svn")
|
||||||
|
@ -120,7 +117,7 @@ func (s *Svn) setSvnStatus() {
|
||||||
|
|
||||||
func (s *Svn) getSvnCommandOutput(command string, args ...string) string {
|
func (s *Svn) getSvnCommandOutput(command string, args ...string) string {
|
||||||
args = append([]string{command, s.realDir}, args...)
|
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 {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,6 +236,7 @@ R Moved.File`,
|
||||||
scm: scm{
|
scm: scm{
|
||||||
env: env,
|
env: env,
|
||||||
props: properties.Map{},
|
props: properties.Map{},
|
||||||
|
command: SVNCOMMAND,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
s.setSvnStatus()
|
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])
|
## Template ([info][templates])
|
||||||
|
|
||||||
:::note default template
|
:::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`).
|
- 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
|
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.
|
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
|
### 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).
|
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`
|
- 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])
|
## Template ([info][templates])
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue