fix(git): populate .Dir and .RepoName correctly

This commit is contained in:
L. Yeung 2022-09-01 13:44:27 +08:00 committed by Jan De Dobbeleer
parent 2a1fdffb73
commit e5b3b00a43
6 changed files with 279 additions and 54 deletions

View file

@ -727,7 +727,7 @@ func (env *ShellEnvironment) TemplateCache() *TemplateCache {
tmplCache.Env[key] = strings.Join(val, separator)
}
pwd := env.Pwd()
tmplCache.PWD = strings.Replace(pwd, env.Home(), "~", 1)
tmplCache.PWD = ReplaceHomeDirPrefixWithTilde(env, pwd)
tmplCache.Folder = Base(env, pwd)
tmplCache.UserName = env.User()
if host, err := env.Host(); err == nil {
@ -780,6 +780,16 @@ func dirMatchesOneOf(dir, home, goos string, regexes []string) bool {
return false
}
func isPathSeparator(env Environment, c uint8) bool {
if c == '/' {
return true
}
if env.GOOS() == WINDOWS && c == '\\' {
return true
}
return false
}
// Base returns the last element of path.
// Trailing path separators are removed before extracting the last element.
// If the path consists entirely of separators, Base returns a single separator.
@ -789,7 +799,7 @@ func Base(env Environment, path string) string {
}
volumeName := filepath.VolumeName(path)
// Strip trailing slashes.
for len(path) > 0 && string(path[len(path)-1]) == env.PathSeparator() {
for len(path) > 0 && isPathSeparator(env, path[len(path)-1]) {
path = path[0 : len(path)-1]
}
if volumeName == path {
@ -799,7 +809,7 @@ func Base(env Environment, path string) string {
path = path[len(filepath.VolumeName(path)):]
// Find the last element
i := len(path) - 1
for i >= 0 && string(path[i]) != env.PathSeparator() {
for i >= 0 && !isPathSeparator(env, path[i]) {
i--
}
if i >= 0 {
@ -812,6 +822,13 @@ func Base(env Environment, path string) string {
return path
}
func ReplaceHomeDirPrefixWithTilde(env Environment, path string) string {
if strings.HasPrefix(path, env.Home()) {
return strings.Replace(path, env.Home(), "~", 1)
}
return path
}
func cleanHostName(hostName string) string {
garbage := []string{
".lan",

View file

@ -102,7 +102,7 @@ func (env *ShellEnvironment) InWSLSharedDrive() bool {
return false
}
windowsPath := env.ConvertToWindowsPath(env.Pwd())
return !strings.HasPrefix(windowsPath, `//wsl.localhost`) && !strings.HasPrefix(windowsPath, `//wsl$`)
return !strings.HasPrefix(windowsPath, `//wsl.localhost/`) && !strings.HasPrefix(windowsPath, `//wsl$/`)
}
func (env *ShellEnvironment) ConvertToWindowsPath(path string) string {

View file

@ -117,7 +117,7 @@ func (g *Git) Enabled() bool {
if !g.shouldDisplay() {
return false
}
g.RepoName = environment.Base(g.env, g.realDir)
g.RepoName = environment.Base(g.env, g.convertToLinuxPath(g.realDir))
displayStatus := g.props.GetBool(FetchStatus, false)
if displayStatus {
g.setGitStatus()
@ -141,8 +141,7 @@ func (g *Git) Enabled() bool {
}
func (g *Git) shouldDisplay() bool {
// when in wsl/wsl2 and in a windows shared folder
// we must use git.exe and convert paths accordingly
// 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()
@ -159,9 +158,12 @@ func (g *Git) shouldDisplay() bool {
return false
}
// convert the worktree file path to a windows one when in wsl 2 shared folder
dir := strings.Replace(gitdir.Path, g.env.Home(), "~", 1) // align with template PWD
g.Dir = strings.TrimSuffix(g.convertToWindowsPath(dir), "/.git")
dir := environment.ReplaceHomeDirPrefixWithTilde(g.env, gitdir.Path) // align with template PWD
if g.env.GOOS() == environment.WINDOWS {
g.Dir = strings.TrimSuffix(dir, `\.git`)
} else {
g.Dir = strings.TrimSuffix(dir, "/.git")
}
if !gitdir.IsDir {
return g.hasWorktree(gitdir)
@ -169,6 +171,7 @@ func (g *Git) shouldDisplay() bool {
g.workingDir = gitdir.Path
g.rootDir = gitdir.Path
// convert the worktree file path to a windows one when in a WSL shared folder
g.realDir = strings.TrimSuffix(g.convertToWindowsPath(gitdir.Path), "/.git")
return true
}
@ -180,7 +183,7 @@ func (g *Git) hasWorktree(gitdir *environment.FileInfo) bool {
if matches == nil || matches["dir"] == "" {
return false
}
// if we open a worktree file in a shared wsl2 folder, we have to convert it back
// if we open a worktree file in a WSL shared folder, we have to convert it back
// to the mounted path
g.workingDir = g.convertToLinuxPath(matches["dir"])

View file

@ -78,17 +78,18 @@ func TestRootLocationHome(t *testing.T) {
HomePath string
Pswd string
Pwd string
GOOS string
PathSeparator string
HomeIcon string
RegistryIcon string
}{
{Expected: "~", HomeIcon: "~", HomePath: "/home/bill/", Pwd: "/home/bill/", PathSeparator: "/"},
{Expected: "usr", HomePath: "/home/bill/", Pwd: "/usr/error/what", PathSeparator: "/"},
{Expected: "C:", HomePath: "C:\\Users\\Bill", Pwd: "C:\\Program Files\\Go", PathSeparator: "\\"},
{Expected: "REG", RegistryIcon: "REG", HomePath: "C:\\Users\\Bill", Pwd: "HKCU:\\Program Files\\Go", PathSeparator: "\\"},
{Expected: "~", HomeIcon: "~", HomePath: "C:\\Users\\Bill", Pwd: "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Bill", PathSeparator: "\\"},
{Expected: "C:", HomePath: "C:\\Users\\Jack", Pwd: "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Bill", PathSeparator: "\\"},
{Expected: "", HomePath: "C:\\Users\\Jack", Pwd: "", PathSeparator: "\\"},
{Expected: "C:", HomePath: "C:\\Users\\Bill", Pwd: "C:\\Program Files\\Go", GOOS: environment.WINDOWS, PathSeparator: "\\"},
{Expected: "REG", RegistryIcon: "REG", HomePath: "C:\\Users\\Bill", Pwd: "HKCU:\\Program Files\\Go", GOOS: environment.WINDOWS, PathSeparator: "\\"},
{Expected: "~", HomeIcon: "~", HomePath: "C:\\Users\\Bill", Pwd: "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Bill", GOOS: environment.WINDOWS, PathSeparator: "\\"},
{Expected: "C:", HomePath: "C:\\Users\\Jack", Pwd: "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Bill", GOOS: environment.WINDOWS, PathSeparator: "\\"},
{Expected: "", HomePath: "C:\\Users\\Jack", Pwd: "", GOOS: environment.WINDOWS, PathSeparator: "\\"},
{Expected: "DRIVE:", HomePath: "/home/bill/", Pwd: "/usr/error/what", Pswd: "DRIVE:", PathSeparator: "/"},
}
for _, tc := range cases {
@ -100,7 +101,7 @@ func TestRootLocationHome(t *testing.T) {
}
env.On("Flags").Return(args)
env.On("PathSeparator").Return(tc.PathSeparator)
env.On("GOOS").Return("")
env.On("GOOS").Return(tc.GOOS)
path := &Path{
env: env,
props: properties.Map{
@ -563,23 +564,125 @@ func TestAgnosterPath(t *testing.T) { //nolint:dupl
Expected string
Home string
PWD string
GOOS string
PathSeparator string
}{
{Case: "Windows outside home", Expected: "C: > f > f > location", Home: homeBillWindows, PWD: "C:\\Program Files\\Go\\location", PathSeparator: "\\"},
{Case: "Windows oustide home", Expected: "~ > f > f > location", Home: homeBillWindows, PWD: homeBillWindows + "\\Documents\\Bill\\location", PathSeparator: "\\"},
{Case: "Windows inside home zero levels", Expected: "C: > location", Home: homeBillWindows, PWD: "C:\\location", PathSeparator: "\\"},
{Case: "Windows inside home one level", Expected: "C: > f > location", Home: homeBillWindows, PWD: "C:\\Program Files\\location", PathSeparator: "\\"},
{Case: "Windows lower case drive letter", Expected: "C: > Windows", Home: homeBillWindows, PWD: "C:\\Windows\\", PathSeparator: "\\"},
{Case: "Windows lower case drive letter (other)", Expected: "P: > Other", Home: homeBillWindows, PWD: "P:\\Other\\", PathSeparator: "\\"},
{Case: "Windows lower word drive", Expected: "some: > some", Home: homeBillWindows, PWD: "some:\\some\\", PathSeparator: "\\"},
{Case: "Windows lower word drive (ending with c)", Expected: "src: > source", Home: homeBillWindows, PWD: "src:\\source\\", PathSeparator: "\\"},
{Case: "Windows lower word drive (arbitrary cases)", Expected: "sRc: > source", Home: homeBillWindows, PWD: "sRc:\\source\\", PathSeparator: "\\"},
{Case: "Windows registry drive", Expected: "\uf013 > f > magnetic:test", Home: homeBillWindows, PWD: "HKLM:\\SOFTWARE\\magnetic:test\\", PathSeparator: "\\"},
{Case: "Windows registry drive case sensitive", Expected: "\uf013 > f > magnetic:TOAST", Home: homeBillWindows, PWD: "HKLM:\\SOFTWARE\\magnetic:TOAST\\", PathSeparator: "\\"},
{Case: "Unix outside home", Expected: "mnt > f > f > location", Home: homeJan, PWD: "/mnt/go/test/location", PathSeparator: "/"},
{Case: "Unix inside home", Expected: "~ > f > f > location", Home: homeJan, PWD: homeJan + "/docs/jan/location", PathSeparator: "/"},
{Case: "Unix outside home zero levels", Expected: "mnt > location", Home: homeJan, PWD: "/mnt/location", PathSeparator: "/"},
{Case: "Unix outside home one level", Expected: "mnt > f > location", Home: homeJan, PWD: "/mnt/folder/location", PathSeparator: "/"},
{
Case: "Windows outside home",
Expected: "C: > f > f > location",
Home: homeBillWindows,
PWD: "C:\\Program Files\\Go\\location",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows oustide home",
Expected: "~ > f > f > location",
Home: homeBillWindows,
PWD: homeBillWindows + "\\Documents\\Bill\\location",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows inside home zero levels",
Expected: "C: > location",
Home: homeBillWindows,
PWD: "C:\\location",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows inside home one level",
Expected: "C: > f > location",
Home: homeBillWindows,
PWD: "C:\\Program Files\\location",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows lower case drive letter",
Expected: "C: > Windows",
Home: homeBillWindows,
PWD: "C:\\Windows\\",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows lower case drive letter (other)",
Expected: "P: > Other",
Home: homeBillWindows,
PWD: "P:\\Other\\",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows lower word drive",
Expected: "some: > some",
Home: homeBillWindows,
PWD: "some:\\some\\",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows lower word drive (ending with c)",
Expected: "src: > source",
Home: homeBillWindows,
PWD: "src:\\source\\",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows lower word drive (arbitrary cases)",
Expected: "sRc: > source",
Home: homeBillWindows,
PWD: "sRc:\\source\\",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows registry drive",
Expected: "\uf013 > f > magnetic:test",
Home: homeBillWindows,
PWD: "HKLM:\\SOFTWARE\\magnetic:test\\",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows registry drive case sensitive",
Expected: "\uf013 > f > magnetic:TOAST",
Home: homeBillWindows,
PWD: "HKLM:\\SOFTWARE\\magnetic:TOAST\\",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Unix outside home",
Expected: "mnt > f > f > location",
Home: homeJan,
PWD: "/mnt/go/test/location",
PathSeparator: "/",
},
{
Case: "Unix inside home",
Expected: "~ > f > f > location",
Home: homeJan,
PWD: homeJan + "/docs/jan/location",
PathSeparator: "/",
},
{
Case: "Unix outside home zero levels",
Expected: "mnt > location",
Home: homeJan,
PWD: "/mnt/location",
PathSeparator: "/",
},
{
Case: "Unix outside home one level",
Expected: "mnt > f > location",
Home: homeJan,
PWD: "/mnt/folder/location",
PathSeparator: "/",
},
}
for _, tc := range cases {
@ -587,7 +690,7 @@ func TestAgnosterPath(t *testing.T) { //nolint:dupl
env.On("Home").Return(tc.Home)
env.On("PathSeparator").Return(tc.PathSeparator)
env.On("Pwd").Return(tc.PWD)
env.On("GOOS").Return("")
env.On("GOOS").Return(tc.GOOS)
args := &environment.Flags{
PSWD: tc.PWD,
}
@ -611,23 +714,125 @@ func TestAgnosterLeftPath(t *testing.T) { //nolint:dupl
Expected string
Home string
PWD string
GOOS string
PathSeparator string
}{
{Case: "Windows outside home", Expected: "C: > Program Files > f > f", Home: homeBillWindows, PWD: "C:\\Program Files\\Go\\location", PathSeparator: "\\"},
{Case: "Windows inside home", Expected: "~ > Documents > f > f", Home: homeBillWindows, PWD: homeBillWindows + "\\Documents\\Bill\\location", PathSeparator: "\\"},
{Case: "Windows inside home zero levels", Expected: "C: > location", Home: homeBillWindows, PWD: "C:\\location", PathSeparator: "\\"},
{Case: "Windows inside home one level", Expected: "C: > Program Files > f", Home: homeBillWindows, PWD: "C:\\Program Files\\location", PathSeparator: "\\"},
{Case: "Windows lower case drive letter", Expected: "C: > Windows", Home: homeBillWindows, PWD: "C:\\Windows\\", PathSeparator: "\\"},
{Case: "Windows lower case drive letter (other)", Expected: "P: > Other", Home: homeBillWindows, PWD: "P:\\Other\\", PathSeparator: "\\"},
{Case: "Windows lower word drive", Expected: "some: > some", Home: homeBillWindows, PWD: "some:\\some\\", PathSeparator: "\\"},
{Case: "Windows lower word drive (ending with c)", Expected: "src: > source", Home: homeBillWindows, PWD: "src:\\source\\", PathSeparator: "\\"},
{Case: "Windows lower word drive (arbitrary cases)", Expected: "sRc: > source", Home: homeBillWindows, PWD: "sRc:\\source\\", PathSeparator: "\\"},
{Case: "Windows registry drive", Expected: "\uf013 > SOFTWARE > f", Home: homeBillWindows, PWD: "HKLM:\\SOFTWARE\\magnetic:test\\", PathSeparator: "\\"},
{Case: "Windows registry drive case sensitive", Expected: "\uf013 > SOFTWARE > f", Home: homeBillWindows, PWD: "HKLM:\\SOFTWARE\\magnetic:TOAST\\", PathSeparator: "\\"},
{Case: "Unix outside home", Expected: "mnt > go > f > f", Home: homeJan, PWD: "/mnt/go/test/location", PathSeparator: "/"},
{Case: "Unix inside home", Expected: "~ > docs > f > f", Home: homeJan, PWD: homeJan + "/docs/jan/location", PathSeparator: "/"},
{Case: "Unix outside home zero levels", Expected: "mnt > location", Home: homeJan, PWD: "/mnt/location", PathSeparator: "/"},
{Case: "Unix outside home one level", Expected: "mnt > folder > f", Home: homeJan, PWD: "/mnt/folder/location", PathSeparator: "/"},
{
Case: "Windows outside home",
Expected: "C: > Program Files > f > f",
Home: homeBillWindows,
PWD: "C:\\Program Files\\Go\\location",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows inside home",
Expected: "~ > Documents > f > f",
Home: homeBillWindows,
PWD: homeBillWindows + "\\Documents\\Bill\\location",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows inside home zero levels",
Expected: "C: > location",
Home: homeBillWindows,
PWD: "C:\\location",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows inside home one level",
Expected: "C: > Program Files > f",
Home: homeBillWindows,
PWD: "C:\\Program Files\\location",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows lower case drive letter",
Expected: "C: > Windows",
Home: homeBillWindows,
PWD: "C:\\Windows\\",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows lower case drive letter (other)",
Expected: "P: > Other",
Home: homeBillWindows,
PWD: "P:\\Other\\",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows lower word drive",
Expected: "some: > some",
Home: homeBillWindows,
PWD: "some:\\some\\",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows lower word drive (ending with c)",
Expected: "src: > source",
Home: homeBillWindows,
PWD: "src:\\source\\",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows lower word drive (arbitrary cases)",
Expected: "sRc: > source",
Home: homeBillWindows,
PWD: "sRc:\\source\\",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows registry drive",
Expected: "\uf013 > SOFTWARE > f",
Home: homeBillWindows,
PWD: "HKLM:\\SOFTWARE\\magnetic:test\\",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Windows registry drive case sensitive",
Expected: "\uf013 > SOFTWARE > f",
Home: homeBillWindows,
PWD: "HKLM:\\SOFTWARE\\magnetic:TOAST\\",
GOOS: environment.WINDOWS,
PathSeparator: "\\",
},
{
Case: "Unix outside home",
Expected: "mnt > go > f > f",
Home: homeJan,
PWD: "/mnt/go/test/location",
PathSeparator: "/",
},
{
Case: "Unix inside home",
Expected: "~ > docs > f > f",
Home: homeJan,
PWD: homeJan + "/docs/jan/location",
PathSeparator: "/",
},
{
Case: "Unix outside home zero levels",
Expected: "mnt > location",
Home: homeJan,
PWD: "/mnt/location",
PathSeparator: "/",
},
{
Case: "Unix outside home one level",
Expected: "mnt > folder > f",
Home: homeJan,
PWD: "/mnt/folder/location",
PathSeparator: "/",
},
}
for _, tc := range cases {
@ -635,7 +840,7 @@ func TestAgnosterLeftPath(t *testing.T) { //nolint:dupl
env.On("Home").Return(tc.Home)
env.On("PathSeparator").Return(tc.PathSeparator)
env.On("Pwd").Return(tc.PWD)
env.On("GOOS").Return("")
env.On("GOOS").Return(tc.GOOS)
args := &environment.Flags{
PSWD: tc.PWD,
}

View file

@ -79,6 +79,7 @@ func TestPythonTemplate(t *testing.T) {
for _, tc := range cases {
env := new(mock.MockedEnvironment)
env.On("GOOS").Return("")
env.On("HasCommand", "python").Return(true)
env.On("CommandPath", mock2.Anything).Return(tc.PythonPath)
env.On("RunCommand", "python", []string{"--version"}).Return("Python 3.8.4", nil)
@ -118,6 +119,7 @@ func TestPythonPythonInContext(t *testing.T) {
for _, tc := range cases {
env := new(mock.MockedEnvironment)
env.On("GOOS").Return("")
env.On("PathSeparator").Return("")
env.On("Getenv", "VIRTUAL_ENV").Return(tc.VirtualEnvName)
env.On("Getenv", "CONDA_ENV_PATH").Return("")

View file

@ -62,8 +62,7 @@ func (s *Svn) Enabled() bool {
}
func (s *Svn) shouldDisplay() bool {
// when in wsl/wsl2 and in a windows shared folder
// we must use Svn.exe and convert paths accordingly
// 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)) {
@ -80,7 +79,7 @@ func (s *Svn) shouldDisplay() bool {
if Svndir.IsDir {
s.workingDir = Svndir.Path
s.rootDir = Svndir.Path
// convert the worktree file path to a windows one when in wsl 2 shared folder
// convert the worktree file path to a windows one when in a WSL shared folder
s.realDir = strings.TrimSuffix(s.convertToWindowsPath(Svndir.Path), "/.svn")
return true
}
@ -89,10 +88,9 @@ func (s *Svn) shouldDisplay() bool {
dirPointer := strings.Trim(s.env.FileContent(Svndir.Path), " \r\n")
matches := regex.FindNamedRegexMatch(`^Svndir: (?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
// if we open a worktree file in a WSL shared folder, we have to convert it back
// to the mounted path
s.workingDir = s.convertToLinuxPath(matches["dir"])
return false
}
return false
}