mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2025-02-21 02:55:37 -08:00
parent
859fd0bbef
commit
f2ccee6df6
|
@ -110,8 +110,7 @@ func (env *ShellEnvironment) ConvertToWindowsPath(path string) string {
|
|||
}
|
||||
|
||||
func (env *ShellEnvironment) ConvertToLinuxPath(path string) string {
|
||||
linuxPath, err := env.RunCommand("wslpath", "-u", path)
|
||||
if err == nil {
|
||||
if linuxPath, err := env.RunCommand("wslpath", "-u", path); err == nil {
|
||||
return linuxPath
|
||||
}
|
||||
return path
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"oh-my-posh/environment"
|
||||
"oh-my-posh/properties"
|
||||
"oh-my-posh/regex"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -144,63 +145,84 @@ func (g *Git) shouldDisplay() bool {
|
|||
// 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)) {
|
||||
return false
|
||||
}
|
||||
|
||||
gitdir, err := g.env.HasParentFilePath(".git")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if g.shouldIgnoreRootRepository(gitdir.ParentFolder) {
|
||||
return false
|
||||
}
|
||||
|
||||
if gitdir.IsDir {
|
||||
g.workingFolder = gitdir.Path
|
||||
g.rootFolder = gitdir.Path
|
||||
// convert the worktree file path to a windows one when in wsl 2 shared folder
|
||||
g.realFolder = strings.TrimSuffix(g.convertToWindowsPath(gitdir.Path), ".git")
|
||||
return true
|
||||
if !gitdir.IsDir {
|
||||
return g.hasWorktree(gitdir)
|
||||
}
|
||||
// handle worktree
|
||||
|
||||
g.workingFolder = gitdir.Path
|
||||
g.rootFolder = gitdir.Path
|
||||
// convert the worktree file path to a windows one when in wsl 2 shared folder
|
||||
g.realFolder = strings.TrimSuffix(g.convertToWindowsPath(gitdir.Path), ".git")
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *Git) hasWorktree(gitdir *environment.FileInfo) bool {
|
||||
g.rootFolder = gitdir.Path
|
||||
dirPointer := strings.Trim(g.env.FileContent(gitdir.Path), " \r\n")
|
||||
matches := regex.FindNamedRegexMatch(`^gitdir: (?P<dir>.*)$`, dirPointer)
|
||||
if matches != nil && matches["dir"] != "" {
|
||||
// if we open a worktree file in a shared wsl2 folder, we have to convert it back
|
||||
// to the mounted path
|
||||
g.workingFolder = g.convertToLinuxPath(matches["dir"])
|
||||
if matches == nil || matches["dir"] == "" {
|
||||
return false
|
||||
}
|
||||
// if we open a worktree file in a shared wsl2 folder, we have to convert it back
|
||||
// to the mounted path
|
||||
g.workingFolder = g.convertToLinuxPath(matches["dir"])
|
||||
|
||||
// in worktrees, the path looks like this: gitdir: path/.git/worktrees/branch
|
||||
// strips the last .git/worktrees part
|
||||
// :ind+5 = index + /.git
|
||||
ind := strings.LastIndex(g.workingFolder, "/.git/worktrees")
|
||||
if ind > -1 {
|
||||
g.rootFolder = g.workingFolder[:ind+5]
|
||||
g.realFolder = strings.TrimSuffix(g.env.FileContent(g.workingFolder+"/gitdir"), ".git\n")
|
||||
// in worktrees, the path looks like this: gitdir: path/.git/worktrees/branch
|
||||
// strips the last .git/worktrees part
|
||||
// :ind+5 = index + /.git
|
||||
ind := strings.LastIndex(g.workingFolder, "/.git/worktrees")
|
||||
if ind > -1 {
|
||||
gitDir := filepath.Join(g.workingFolder, "gitdir")
|
||||
g.rootFolder = g.workingFolder[:ind+5]
|
||||
g.realFolder = strings.TrimSuffix(g.env.FileContent(gitDir), ".git\n")
|
||||
g.IsWorkTree = true
|
||||
return true
|
||||
}
|
||||
// in submodules, the path looks like this: gitdir: ../.git/modules/test-submodule
|
||||
// we need the parent folder to detect where the real .git folder is
|
||||
ind = strings.LastIndex(g.workingFolder, "/.git/modules")
|
||||
if ind > -1 {
|
||||
g.rootFolder = filepath.Join(gitdir.ParentFolder, g.workingFolder)
|
||||
// this might be both a worktree and a submodule, where the path would look like
|
||||
// this: ../.git/modules/module/path/worktrees/location. We cannot distinguish
|
||||
// between worktree and a module path containing the word 'worktree,' however.
|
||||
ind = strings.LastIndex(g.rootFolder, g.env.PathSeparator()+"worktrees"+g.env.PathSeparator())
|
||||
if ind > -1 && g.env.HasFilesInDir(g.rootFolder, "gitdir") {
|
||||
gitDir := filepath.Join(g.rootFolder, "gitdir")
|
||||
realGitFolder := filepath.Clean(g.env.FileContent(gitDir))
|
||||
g.realFolder = strings.TrimSuffix(realGitFolder, ".git\n")
|
||||
g.rootFolder = g.rootFolder[:ind]
|
||||
g.workingFolder = g.rootFolder
|
||||
g.IsWorkTree = true
|
||||
return true
|
||||
}
|
||||
// in submodules, the path looks like this: gitdir: ../.git/modules/test-submodule
|
||||
// we need the parent folder to detect where the real .git folder is
|
||||
ind = strings.LastIndex(g.workingFolder, "/.git/modules")
|
||||
if ind > -1 {
|
||||
g.rootFolder = gitdir.ParentFolder + "/" + g.workingFolder
|
||||
g.realFolder = g.rootFolder
|
||||
g.workingFolder = g.rootFolder
|
||||
return true
|
||||
}
|
||||
g.realFolder = g.rootFolder
|
||||
g.workingFolder = g.rootFolder
|
||||
return true
|
||||
}
|
||||
|
||||
// check for separate git folder(--separate-git-dir)
|
||||
// check if the folder contains a HEAD file
|
||||
if g.env.HasFilesInDir(g.workingFolder, "HEAD") {
|
||||
gitFolder := strings.TrimSuffix(g.rootFolder, ".git")
|
||||
g.rootFolder = g.workingFolder
|
||||
g.workingFolder = gitFolder
|
||||
g.realFolder = gitFolder
|
||||
return true
|
||||
}
|
||||
return false
|
||||
// check for separate git folder(--separate-git-dir)
|
||||
// check if the folder contains a HEAD file
|
||||
if g.env.HasFilesInDir(g.workingFolder, "HEAD") {
|
||||
gitFolder := strings.TrimSuffix(g.rootFolder, ".git")
|
||||
g.rootFolder = g.workingFolder
|
||||
g.workingFolder = gitFolder
|
||||
g.realFolder = gitFolder
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"oh-my-posh/environment"
|
||||
"oh-my-posh/mock"
|
||||
"oh-my-posh/properties"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
@ -55,91 +57,97 @@ func TestEnabledInWorkingDirectory(t *testing.T) {
|
|||
assert.Equal(t, fileInfo.Path, g.workingFolder)
|
||||
}
|
||||
|
||||
func TestEnabledInWorkingTree(t *testing.T) {
|
||||
env := new(mock.MockedEnvironment)
|
||||
env.On("InWSLSharedDrive").Return(false)
|
||||
env.On("HasCommand", "git").Return(true)
|
||||
env.On("GOOS").Return("")
|
||||
env.On("IsWsl").Return(false)
|
||||
env.On("PathSeparator").Return("/")
|
||||
fileInfo := &environment.FileInfo{
|
||||
Path: "/dev/folder_worktree/.git",
|
||||
ParentFolder: "/dev/folder_worktree",
|
||||
IsDir: false,
|
||||
}
|
||||
env.On("FileContent", "/dev/real_folder/.git/worktrees/folder_worktree/HEAD").Return("")
|
||||
env.MockGitCommand(fileInfo.ParentFolder, "", "describe", "--tags", "--exact-match")
|
||||
env.On("HasParentFilePath", ".git").Return(fileInfo, nil)
|
||||
env.On("FileContent", "/dev/folder_worktree/.git").Return("gitdir: /dev/real_folder/.git/worktrees/folder_worktree")
|
||||
env.On("FileContent", "/dev/real_folder/.git/worktrees/folder_worktree/gitdir").Return("/dev/folder_worktree.git\n")
|
||||
g := &Git{
|
||||
scm: scm{
|
||||
env: env,
|
||||
props: properties.Map{},
|
||||
func TestEnabledInWorktree(t *testing.T) {
|
||||
cases := []struct {
|
||||
Case string
|
||||
ExpectedEnabled bool
|
||||
WorkingFolder string
|
||||
WorkingFolderAddon string
|
||||
WorkingFolderContent string
|
||||
GitDirContent string
|
||||
ExpectedRealFolder string
|
||||
ExpectedWorkingFolder string
|
||||
ExpectedRootFolder string
|
||||
WindowsPaths bool
|
||||
}{
|
||||
{
|
||||
Case: "worktree",
|
||||
ExpectedEnabled: true,
|
||||
WorkingFolder: "/dev/.git/worktrees/folder_worktree",
|
||||
WorkingFolderAddon: "gitdir",
|
||||
WorkingFolderContent: "/dev/worktree.git\n",
|
||||
ExpectedWorkingFolder: "/dev/.git/worktrees/folder_worktree",
|
||||
ExpectedRealFolder: "/dev/worktree",
|
||||
ExpectedRootFolder: "/dev/.git",
|
||||
},
|
||||
{
|
||||
Case: "submodule",
|
||||
ExpectedEnabled: true,
|
||||
WorkingFolder: "./.git/modules/submodule",
|
||||
ExpectedWorkingFolder: "/dev/.git/modules/submodule",
|
||||
ExpectedRealFolder: "/dev/.git/modules/submodule",
|
||||
ExpectedRootFolder: "/dev/.git/modules/submodule",
|
||||
WindowsPaths: true,
|
||||
},
|
||||
{
|
||||
Case: "submodule with root working folder",
|
||||
ExpectedEnabled: true,
|
||||
WorkingFolder: "/repo/.git/modules/submodule",
|
||||
ExpectedWorkingFolder: "/dev/repo/.git/modules/submodule",
|
||||
ExpectedRealFolder: "/dev/repo/.git/modules/submodule",
|
||||
ExpectedRootFolder: "/dev/repo/.git/modules/submodule",
|
||||
WindowsPaths: true,
|
||||
},
|
||||
{
|
||||
Case: "submodule with worktrees",
|
||||
ExpectedEnabled: true,
|
||||
WorkingFolder: "./.git/modules/module/path/worktrees/location",
|
||||
WorkingFolderAddon: "/dev/",
|
||||
GitDirContent: "/dev/worktree.git\n",
|
||||
ExpectedWorkingFolder: "/dev/.git/modules/module/path",
|
||||
ExpectedRealFolder: "/dev/worktree",
|
||||
ExpectedRootFolder: "/dev/.git/modules/module/path",
|
||||
WindowsPaths: true,
|
||||
},
|
||||
{
|
||||
Case: "separate git dir",
|
||||
ExpectedEnabled: true,
|
||||
WorkingFolder: "/dev/separate/.git/posh",
|
||||
ExpectedWorkingFolder: "/dev/",
|
||||
ExpectedRealFolder: "/dev/",
|
||||
ExpectedRootFolder: "/dev/separate/.git/posh",
|
||||
},
|
||||
}
|
||||
assert.True(t, g.Enabled())
|
||||
assert.Equal(t, "/dev/real_folder/.git/worktrees/folder_worktree", g.workingFolder)
|
||||
assert.Equal(t, "/dev/folder_worktree", g.realFolder)
|
||||
fileInfo := &environment.FileInfo{
|
||||
Path: "/dev/.git",
|
||||
ParentFolder: "/dev",
|
||||
}
|
||||
for _, tc := range cases {
|
||||
env := new(mock.MockedEnvironment)
|
||||
env.On("FileContent", "/dev/.git").Return(fmt.Sprintf("gitdir: %s", tc.WorkingFolder))
|
||||
env.On("FileContent", filepath.Join(tc.WorkingFolder, tc.WorkingFolderAddon)).Return(tc.WorkingFolderContent)
|
||||
env.On("HasFilesInDir", tc.WorkingFolder, "HEAD").Return(true)
|
||||
env.On("HasFilesInDir", filepath.Join(tc.WorkingFolderAddon, tc.WorkingFolder), "gitdir").Return(true)
|
||||
env.On("FileContent", filepath.Join(tc.WorkingFolderAddon, tc.WorkingFolder, "gitdir")).Return(tc.GitDirContent)
|
||||
env.On("PathSeparator").Return(string(os.PathSeparator))
|
||||
g := &Git{
|
||||
scm: scm{
|
||||
env: env,
|
||||
props: properties.Map{},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, tc.ExpectedEnabled, g.hasWorktree(fileInfo), tc.Case)
|
||||
if tc.WindowsPaths {
|
||||
tc.ExpectedRealFolder = filepath.Clean(tc.ExpectedRealFolder)
|
||||
tc.ExpectedRootFolder = filepath.Clean(tc.ExpectedRootFolder)
|
||||
tc.ExpectedWorkingFolder = filepath.Clean(tc.ExpectedWorkingFolder)
|
||||
}
|
||||
assert.Equal(t, tc.ExpectedWorkingFolder, g.workingFolder, tc.Case)
|
||||
assert.Equal(t, tc.ExpectedRealFolder, g.realFolder, tc.Case)
|
||||
assert.Equal(t, tc.ExpectedRootFolder, g.rootFolder, tc.Case)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnabledInSubmodule(t *testing.T) {
|
||||
env := new(mock.MockedEnvironment)
|
||||
env.On("InWSLSharedDrive").Return(false)
|
||||
env.On("HasCommand", "git").Return(true)
|
||||
env.On("GOOS").Return("")
|
||||
env.On("IsWsl").Return(false)
|
||||
env.On("PathSeparator").Return("/")
|
||||
fileInfo := &environment.FileInfo{
|
||||
Path: "/dev/parent/test-submodule/.git",
|
||||
ParentFolder: "/dev/parent/test-submodule",
|
||||
IsDir: false,
|
||||
}
|
||||
env.On("FileContent", "/dev/parent/test-submodule/../.git/modules/test-submodule/HEAD").Return("")
|
||||
env.MockGitCommand("/dev/parent/test-submodule/../.git/modules/test-submodule", "", "describe", "--tags", "--exact-match")
|
||||
env.On("HasParentFilePath", ".git").Return(fileInfo, nil)
|
||||
env.On("FileContent", "/dev/parent/test-submodule/.git").Return("gitdir: ../.git/modules/test-submodule")
|
||||
env.On("FileContent", "/dev/parent/.git/modules/test-submodule").Return("/dev/folder_worktree.git\n")
|
||||
g := &Git{
|
||||
scm: scm{
|
||||
env: env,
|
||||
props: properties.Map{},
|
||||
},
|
||||
}
|
||||
assert.True(t, g.Enabled())
|
||||
assert.Equal(t, "/dev/parent/test-submodule/../.git/modules/test-submodule", g.workingFolder)
|
||||
assert.Equal(t, "/dev/parent/test-submodule/../.git/modules/test-submodule", g.realFolder)
|
||||
assert.Equal(t, "/dev/parent/test-submodule/../.git/modules/test-submodule", g.rootFolder)
|
||||
}
|
||||
|
||||
func TestEnabledInSeparateGitDir(t *testing.T) {
|
||||
env := new(mock.MockedEnvironment)
|
||||
env.On("InWSLSharedDrive").Return(false)
|
||||
env.On("HasCommand", "git").Return(true)
|
||||
env.On("GOOS").Return("")
|
||||
env.On("IsWsl").Return(false)
|
||||
env.On("PathSeparator").Return("/")
|
||||
fileInfo := &environment.FileInfo{
|
||||
Path: "/dev/parent/test-separate-git-dir/.git",
|
||||
ParentFolder: "/dev/parent/test-separate-git-dir",
|
||||
IsDir: false,
|
||||
}
|
||||
env.On("HasFilesInDir", "/dev/separate-git-dir", "HEAD").Return(true)
|
||||
env.On("FileContent", "/dev/parent/test-separate-git-dir//HEAD").Return("")
|
||||
env.MockGitCommand("/dev/parent/test-separate-git-dir/", "", "describe", "--tags", "--exact-match")
|
||||
env.On("HasParentFilePath", ".git").Return(fileInfo, nil)
|
||||
env.On("FileContent", "/dev/parent/test-separate-git-dir/.git").Return("gitdir: /dev/separate-git-dir")
|
||||
g := &Git{
|
||||
scm: scm{
|
||||
env: env,
|
||||
props: properties.Map{},
|
||||
},
|
||||
}
|
||||
assert.True(t, g.Enabled())
|
||||
assert.Equal(t, "/dev/parent/test-separate-git-dir/", g.workingFolder)
|
||||
assert.Equal(t, "/dev/parent/test-separate-git-dir/", g.realFolder)
|
||||
assert.Equal(t, "/dev/separate-git-dir", g.rootFolder)
|
||||
}
|
||||
func TestGetGitOutputForCommand(t *testing.T) {
|
||||
args := []string{"-C", "", "--no-optional-locks", "-c", "core.quotepath=false", "-c", "color.status=false"}
|
||||
commandArgs := []string{"symbolic-ref", "--short", "HEAD"}
|
||||
|
|
Loading…
Reference in a new issue