mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-12-28 20:39:40 -08:00
refactor: fetch git enabled context via path
This commit is contained in:
parent
c2bc901a41
commit
5d6d64508d
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -30,6 +31,12 @@ func (e *commandError) Error() string {
|
||||||
return e.err
|
return e.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type fileInfo struct {
|
||||||
|
parentFolder string
|
||||||
|
path string
|
||||||
|
isDir bool
|
||||||
|
}
|
||||||
|
|
||||||
type environmentInfo interface {
|
type environmentInfo interface {
|
||||||
getenv(key string) string
|
getenv(key string) string
|
||||||
getcwd() string
|
getcwd() string
|
||||||
|
@ -54,6 +61,7 @@ type environmentInfo interface {
|
||||||
getShellName() string
|
getShellName() string
|
||||||
getWindowTitle(imageName, windowTitleRegex string) (string, error)
|
getWindowTitle(imageName, windowTitleRegex string) (string, error)
|
||||||
doGet(url string) ([]byte, error)
|
doGet(url string) ([]byte, error)
|
||||||
|
hasParentFilePath(path string) (fileInfo *fileInfo, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type environment struct {
|
type environment struct {
|
||||||
|
@ -239,6 +247,29 @@ func (env *environment) doGet(url string) ([]byte, error) {
|
||||||
return body, nil
|
return body, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (env *environment) hasParentFilePath(path string) (*fileInfo, error) {
|
||||||
|
currentFolder := env.getcwd()
|
||||||
|
for {
|
||||||
|
searchPath := filepath.Join(currentFolder, path)
|
||||||
|
info, err := os.Stat(searchPath)
|
||||||
|
if err == nil {
|
||||||
|
return &fileInfo{
|
||||||
|
parentFolder: currentFolder,
|
||||||
|
path: searchPath,
|
||||||
|
isDir: info.IsDir(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if dir := filepath.Dir(currentFolder); dir != currentFolder {
|
||||||
|
currentFolder = dir
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return nil, errors.New("no match at root level")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func cleanHostName(hostName string) string {
|
func cleanHostName(hostName string) string {
|
||||||
garbage := []string{
|
garbage := []string{
|
||||||
".lan",
|
".lan",
|
||||||
|
|
|
@ -15,7 +15,7 @@ type gitRepo struct {
|
||||||
HEAD string
|
HEAD string
|
||||||
upstream string
|
upstream string
|
||||||
stashCount string
|
stashCount string
|
||||||
root string
|
gitFolder string
|
||||||
}
|
}
|
||||||
|
|
||||||
type gitStatus struct {
|
type gitStatus struct {
|
||||||
|
@ -121,8 +121,24 @@ func (g *git) enabled() bool {
|
||||||
if !g.env.hasCommand("git") {
|
if !g.env.hasCommand("git") {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
output, _ := g.env.runCommand(gitCommand, "rev-parse", "--is-inside-work-tree")
|
gitdir, err := g.env.hasParentFilePath(".git")
|
||||||
return output == "true"
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
g.repo = &gitRepo{}
|
||||||
|
if gitdir.isDir {
|
||||||
|
g.repo.gitFolder = gitdir.path
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// handle worktree
|
||||||
|
dirPointer := g.env.getFileContent(gitdir.path)
|
||||||
|
dirPointer = strings.Trim(dirPointer, " \r\n")
|
||||||
|
matches := findNamedRegexMatch(`^gitdir: (?P<dir>.*)$`, dirPointer)
|
||||||
|
if matches != nil && matches["dir"] != "" {
|
||||||
|
g.repo.gitFolder = matches["dir"]
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *git) string() string {
|
func (g *git) string() string {
|
||||||
|
@ -198,8 +214,6 @@ func (g *git) getUpstreamSymbol() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *git) setGitStatus() {
|
func (g *git) setGitStatus() {
|
||||||
g.repo = &gitRepo{}
|
|
||||||
g.repo.root = g.getGitCommandOutput("rev-parse", "--show-toplevel")
|
|
||||||
output := g.getGitCommandOutput("status", "-unormal", "--short", "--branch")
|
output := g.getGitCommandOutput("status", "-unormal", "--short", "--branch")
|
||||||
splittedOutput := strings.Split(output, "\n")
|
splittedOutput := strings.Split(output, "\n")
|
||||||
g.repo.working = g.parseGitStats(splittedOutput, true)
|
g.repo.working = g.parseGitStats(splittedOutput, true)
|
||||||
|
@ -285,17 +299,17 @@ func (g *git) getGitHEADContext(ref string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *git) hasGitFile(file string) bool {
|
func (g *git) hasGitFile(file string) bool {
|
||||||
files := fmt.Sprintf(".git/%s", file)
|
return g.env.hasFilesInDir(g.repo.gitFolder, file)
|
||||||
return g.env.hasFilesInDir(g.repo.root, files)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *git) hasGitFolder(folder string) bool {
|
func (g *git) hasGitFolder(folder string) bool {
|
||||||
path := fmt.Sprintf("%s/.git/%s", g.repo.root, folder)
|
path := g.repo.gitFolder + "/" + folder
|
||||||
return g.env.hasFolder(path)
|
return g.env.hasFolder(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *git) getGitFileContents(file string) string {
|
func (g *git) getGitFileContents(file string) string {
|
||||||
content := g.env.getFileContent(fmt.Sprintf("%s/.git/%s", g.repo.root, file))
|
path := g.repo.gitFolder + "/" + file
|
||||||
|
content := g.env.getFileContent(path)
|
||||||
return strings.Trim(content, " \r\n")
|
return strings.Trim(content, " \r\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,11 +22,34 @@ func TestEnabledGitNotFound(t *testing.T) {
|
||||||
func TestEnabledInWorkingDirectory(t *testing.T) {
|
func TestEnabledInWorkingDirectory(t *testing.T) {
|
||||||
env := new(MockedEnvironment)
|
env := new(MockedEnvironment)
|
||||||
env.On("hasCommand", "git").Return(true)
|
env.On("hasCommand", "git").Return(true)
|
||||||
env.On("runCommand", "git", []string{"rev-parse", "--is-inside-work-tree"}).Return("true", nil)
|
fileInfo := &fileInfo{
|
||||||
|
path: "/dir/hello",
|
||||||
|
parentFolder: "/dir",
|
||||||
|
isDir: true,
|
||||||
|
}
|
||||||
|
env.On("hasParentFilePath", ".git").Return(fileInfo, nil)
|
||||||
g := &git{
|
g := &git{
|
||||||
env: env,
|
env: env,
|
||||||
}
|
}
|
||||||
assert.True(t, g.enabled())
|
assert.True(t, g.enabled())
|
||||||
|
assert.Equal(t, fileInfo.path, g.repo.gitFolder)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnabledInWorkingTree(t *testing.T) {
|
||||||
|
env := new(MockedEnvironment)
|
||||||
|
env.On("hasCommand", "git").Return(true)
|
||||||
|
fileInfo := &fileInfo{
|
||||||
|
path: "/dir/hello",
|
||||||
|
parentFolder: "/dir",
|
||||||
|
isDir: false,
|
||||||
|
}
|
||||||
|
env.On("hasParentFilePath", ".git").Return(fileInfo, nil)
|
||||||
|
env.On("getFileContent", "/dir/hello").Return("gitdir: /dir/hello/burp/burp")
|
||||||
|
g := &git{
|
||||||
|
env: env,
|
||||||
|
}
|
||||||
|
assert.True(t, g.enabled())
|
||||||
|
assert.Equal(t, "/dir/hello/burp/burp", g.repo.gitFolder)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetGitOutputForCommand(t *testing.T) {
|
func TestGetGitOutputForCommand(t *testing.T) {
|
||||||
|
@ -61,19 +84,19 @@ type detachedContext struct {
|
||||||
|
|
||||||
func setupHEADContextEnv(context *detachedContext) *git {
|
func setupHEADContextEnv(context *detachedContext) *git {
|
||||||
env := new(MockedEnvironment)
|
env := new(MockedEnvironment)
|
||||||
env.On("hasFolder", "/.git/rebase-merge").Return(context.rebaseMerge)
|
env.On("hasFolder", "/rebase-merge").Return(context.rebaseMerge)
|
||||||
env.On("hasFolder", "/.git/rebase-apply").Return(context.rebaseApply)
|
env.On("hasFolder", "/rebase-apply").Return(context.rebaseApply)
|
||||||
env.On("getFileContent", "/.git/rebase-merge/orig-head").Return(context.origin)
|
env.On("getFileContent", "/rebase-merge/orig-head").Return(context.origin)
|
||||||
env.On("getFileContent", "/.git/rebase-merge/onto").Return(context.onto)
|
env.On("getFileContent", "/rebase-merge/onto").Return(context.onto)
|
||||||
env.On("getFileContent", "/.git/rebase-merge/msgnum").Return(context.step)
|
env.On("getFileContent", "/rebase-merge/msgnum").Return(context.step)
|
||||||
env.On("getFileContent", "/.git/rebase-apply/next").Return(context.step)
|
env.On("getFileContent", "/rebase-apply/next").Return(context.step)
|
||||||
env.On("getFileContent", "/.git/rebase-merge/end").Return(context.total)
|
env.On("getFileContent", "/rebase-merge/end").Return(context.total)
|
||||||
env.On("getFileContent", "/.git/rebase-apply/last").Return(context.total)
|
env.On("getFileContent", "/rebase-apply/last").Return(context.total)
|
||||||
env.On("getFileContent", "/.git/rebase-apply/head-name").Return(context.origin)
|
env.On("getFileContent", "/rebase-apply/head-name").Return(context.origin)
|
||||||
env.On("getFileContent", "/.git/CHERRY_PICK_HEAD").Return(context.cherryPickSHA)
|
env.On("getFileContent", "/CHERRY_PICK_HEAD").Return(context.cherryPickSHA)
|
||||||
env.On("getFileContent", "/.git/MERGE_HEAD").Return(context.mergeHEAD)
|
env.On("getFileContent", "/MERGE_HEAD").Return(context.mergeHEAD)
|
||||||
env.On("hasFilesInDir", "", ".git/CHERRY_PICK_HEAD").Return(context.cherryPick)
|
env.On("hasFilesInDir", "", "CHERRY_PICK_HEAD").Return(context.cherryPick)
|
||||||
env.On("hasFilesInDir", "", ".git/MERGE_HEAD").Return(context.merge)
|
env.On("hasFilesInDir", "", "MERGE_HEAD").Return(context.merge)
|
||||||
env.mockGitCommand(context.currentCommit, "rev-parse", "--short", "HEAD")
|
env.mockGitCommand(context.currentCommit, "rev-parse", "--short", "HEAD")
|
||||||
env.mockGitCommand(context.tagName, "describe", "--tags", "--exact-match")
|
env.mockGitCommand(context.tagName, "describe", "--tags", "--exact-match")
|
||||||
env.mockGitCommand(context.origin, "name-rev", "--name-only", "--exclude=tags/*", context.origin)
|
env.mockGitCommand(context.origin, "name-rev", "--name-only", "--exclude=tags/*", context.origin)
|
||||||
|
@ -83,7 +106,7 @@ func setupHEADContextEnv(context *detachedContext) *git {
|
||||||
g := &git{
|
g := &git{
|
||||||
env: env,
|
env: env,
|
||||||
repo: &gitRepo{
|
repo: &gitRepo{
|
||||||
root: "",
|
gitFolder: "",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return g
|
return g
|
||||||
|
|
|
@ -127,6 +127,11 @@ func (env *MockedEnvironment) doGet(url string) ([]byte, error) {
|
||||||
return args.Get(0).([]byte), args.Error(1)
|
return args.Get(0).([]byte), args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (env *MockedEnvironment) hasParentFilePath(path string) (*fileInfo, error) {
|
||||||
|
args := env.Called(path)
|
||||||
|
return args.Get(0).(*fileInfo), args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
homeBill = "/home/bill"
|
homeBill = "/home/bill"
|
||||||
homeJan = "/usr/home/jan"
|
homeJan = "/usr/home/jan"
|
||||||
|
|
Loading…
Reference in a new issue