feat(git): add link to GitKraken

This commit is contained in:
Jan De Dobbeleer 2022-09-01 19:49:17 +02:00 committed by Jan De Dobbeleer
parent 5df8d89902
commit 56a59a1b32
3 changed files with 49 additions and 37 deletions

View file

@ -2,6 +2,7 @@ package segments
import (
"fmt"
url2 "net/url"
"oh-my-posh/environment"
"oh-my-posh/properties"
"oh-my-posh/regex"
@ -34,27 +35,6 @@ func (s *GitStatus) add(code string) {
}
}
type Git struct {
scm
Working *GitStatus
Staging *GitStatus
Ahead int
Behind int
HEAD string
Ref string
Hash string
BranchStatus string
Upstream string
UpstreamIcon string
UpstreamURL string
UpstreamGone bool
StashCount int
WorktreeCount int
IsWorkTree bool
RepoName string
}
const (
// FetchStatus fetches the status of the repository
FetchStatus properties.Property = "fetch_status"
@ -109,6 +89,28 @@ const (
GITCOMMAND = "git"
)
type Git struct {
scm
Working *GitStatus
Staging *GitStatus
Ahead int
Behind int
HEAD string
Ref string
Hash string
ShortHash string
BranchStatus string
Upstream string
UpstreamIcon string
UpstreamURL string
UpstreamGone bool
StashCount int
WorktreeCount int
IsWorkTree bool
RepoName string
}
func (g *Git) Template() string {
return " {{ .HEAD }} {{ .BranchStatus }}{{ if .Working.Changed }} \uF044 {{ .Working.String }}{{ end }}{{ if and (.Staging.Changed) (.Working.Changed) }} |{{ end }}{{ if .Staging.Changed }} \uF046 {{ .Staging.String }}{{ end }}{{ if gt .StashCount 0}} \uF692 {{ .StashCount }}{{ end }}{{ if gt .WorktreeCount 0}} \uf1bb {{ .WorktreeCount }}{{ end }} " //nolint: lll
}
@ -140,6 +142,12 @@ func (g *Git) Enabled() bool {
return true
}
func (g *Git) Kraken() string {
root := g.getGitCommandOutput("rev-list", "--max-parents=0", "HEAD")
remote := g.getGitCommandOutput("remote", "get-url", "origin")
return fmt.Sprintf("gitkraken://repolink/%s/commit/%s?url=%s", root, g.Hash, url2.QueryEscape(remote))
}
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
@ -307,7 +315,8 @@ func (g *Git) setGitStatus() {
output := g.getGitCommandOutput(args...)
for _, line := range strings.Split(output, "\n") {
if strings.HasPrefix(line, HASH) && len(line) >= len(HASH)+7 {
g.Hash = line[len(HASH) : len(HASH)+7]
g.ShortHash = line[len(HASH) : len(HASH)+7]
g.Hash = line[len(HASH):]
continue
}
if strings.HasPrefix(line, REF) && len(line) > len(REF) {
@ -480,7 +489,7 @@ func (g *Git) getGitRefFileSymbolicName(refFile string) string {
func (g *Git) setPrettyHEADName() {
// we didn't fetch status, fallback to parsing the HEAD file
if len(g.Hash) == 0 {
if len(g.ShortHash) == 0 {
HEADRef := g.FileContents(g.workingDir, "HEAD")
if strings.HasPrefix(HEADRef, BRANCHPREFIX) {
branchName := strings.TrimPrefix(HEADRef, BRANCHPREFIX)
@ -489,7 +498,8 @@ func (g *Git) setPrettyHEADName() {
}
// no branch, points to commit
if len(HEADRef) >= 7 {
g.Hash = HEADRef[0:7]
g.ShortHash = HEADRef[0:7]
g.Hash = HEADRef[0:]
}
}
// check for tag
@ -499,11 +509,11 @@ func (g *Git) setPrettyHEADName() {
return
}
// fallback to commit
if len(g.Hash) == 0 {
if len(g.ShortHash) == 0 {
g.HEAD = g.props.GetString(NoCommitsIcon, "\uF594 ")
return
}
g.HEAD = fmt.Sprintf("%s%s", g.props.GetString(CommitIcon, "\uF417"), g.Hash)
g.HEAD = fmt.Sprintf("%s%s", g.props.GetString(CommitIcon, "\uF417"), g.ShortHash)
}
func (g *Git) getStashContext() int {

View file

@ -308,8 +308,8 @@ func TestSetGitHEADContextClean(t *testing.T) {
RevertIcon: "revert ",
},
},
Hash: "1234567",
Ref: tc.Ref,
ShortHash: "1234567",
Ref: tc.Ref,
}
g.setGitHEADContext()
assert.Equal(t, tc.Expected, g.HEAD, tc.Case)
@ -318,17 +318,17 @@ func TestSetGitHEADContextClean(t *testing.T) {
func TestSetPrettyHEADName(t *testing.T) {
cases := []struct {
Case string
Expected string
Hash string
Tag string
HEAD string
Case string
Expected string
ShortHash string
Tag string
HEAD string
}{
{Case: "main", Expected: "branch main", HEAD: BRANCHPREFIX + "main"},
{Case: "no hash", Expected: "commit 1234567", HEAD: "12345678910"},
{Case: "hash on tag", Hash: "132312322321", Expected: "tag tag-1", HEAD: "12345678910", Tag: "tag-1"},
{Case: "hash on tag", ShortHash: "132312322321", Expected: "tag tag-1", HEAD: "12345678910", Tag: "tag-1"},
{Case: "no hash on tag", Expected: "tag tag-1", Tag: "tag-1"},
{Case: "hash on commit", Hash: "1234567", Expected: "commit 1234567"},
{Case: "hash on commit", ShortHash: "1234567", Expected: "commit 1234567"},
{Case: "no hash on commit", Expected: "commit 1234567", HEAD: "12345678910"},
}
for _, tc := range cases {
@ -346,7 +346,7 @@ func TestSetPrettyHEADName(t *testing.T) {
TagIcon: "tag ",
},
},
Hash: tc.Hash,
ShortHash: tc.ShortHash,
}
g.setPrettyHEADName()
assert.Equal(t, tc.Expected, g.HEAD, tc.Case)
@ -485,7 +485,7 @@ func TestSetGitStatus(t *testing.T) {
g.setGitStatus()
assert.Equal(t, tc.ExpectedStaging, g.Staging, tc.Case)
assert.Equal(t, tc.ExpectedWorking, g.Working, tc.Case)
assert.Equal(t, tc.ExpectedHash, g.Hash, tc.Case)
assert.Equal(t, tc.ExpectedHash, g.ShortHash, tc.Case)
assert.Equal(t, tc.ExpectedRef, g.Ref, tc.Case)
assert.Equal(t, tc.ExpectedUpstream, g.Upstream, tc.Case)
assert.Equal(t, tc.ExpectedUpstreamGone, g.UpstreamGone, tc.Case)

View file

@ -131,6 +131,7 @@ instead of the repo path.
- `.WorktreeCount`: `int` - the worktree count
- `.IsWorkTree`: `boolean` - if in a worktree repo or not
- `.Dir`: `string` - the repository's root directory
- `.Kraken`: `string` - a link to the current HEAD in [GitKraken][kraken-ref] for use in [hyperlinks][hyperlinks] in templates `{{ url .HEAD .Kraken }}`
### GitStatus
@ -146,3 +147,4 @@ instead of the repo path.
[hyperlinks]: /docs/configuration/templates#helper-functions
[untracked]: https://git-scm.com/docs/git-status#Documentation/git-status.txt---untracked-filesltmodegt
[submodules]: https://git-scm.com/docs/git-status#Documentation/git-status.txt---ignore-submodulesltwhengt
[kraken-ref]: https://www.gitkraken.com/invite/nQmDPR9D