mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2025-03-05 20:49:04 -08:00
parent
a627be6b64
commit
b8c09f92ab
|
@ -6,6 +6,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/platform"
|
"github.com/jandedobbeleer/oh-my-posh/src/platform"
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/properties"
|
"github.com/jandedobbeleer/oh-my-posh/src/properties"
|
||||||
|
@ -14,6 +15,19 @@ import (
|
||||||
"gopkg.in/ini.v1"
|
"gopkg.in/ini.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Commit struct {
|
||||||
|
// git log -1 --pretty="format:%an%n%ae%n%cn%n%ce%n%at%n%s"
|
||||||
|
Author *User
|
||||||
|
Committer *User
|
||||||
|
Subject string
|
||||||
|
Timestamp time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Name string
|
||||||
|
Email string
|
||||||
|
}
|
||||||
|
|
||||||
// GitStatus represents part of the status of a git repository
|
// GitStatus represents part of the status of a git repository
|
||||||
type GitStatus struct {
|
type GitStatus struct {
|
||||||
ScmStatus
|
ScmStatus
|
||||||
|
@ -119,6 +133,8 @@ type Git struct {
|
||||||
poshgit bool
|
poshgit bool
|
||||||
stashCount int
|
stashCount int
|
||||||
worktreeCount int
|
worktreeCount int
|
||||||
|
|
||||||
|
commit *Commit
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Git) Template() string {
|
func (g *Git) Template() string {
|
||||||
|
@ -160,6 +176,43 @@ func (g *Git) Enabled() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *Git) Commit() *Commit {
|
||||||
|
if g.commit != nil {
|
||||||
|
return g.commit
|
||||||
|
}
|
||||||
|
g.commit = &Commit{
|
||||||
|
Author: &User{},
|
||||||
|
Committer: &User{},
|
||||||
|
}
|
||||||
|
commitBody := g.getGitCommandOutput("log", "-1", "--pretty=format:an:%an%nae:%ae%ncn:%cn%nce:%ce%nat:%at%nsu:%s")
|
||||||
|
splitted := strings.Split(strings.TrimSpace(commitBody), "\n")
|
||||||
|
for _, line := range splitted {
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if len(line) <= 3 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
anchor := line[:3]
|
||||||
|
line = line[3:]
|
||||||
|
switch anchor {
|
||||||
|
case "an:":
|
||||||
|
g.commit.Author.Name = line
|
||||||
|
case "ae:":
|
||||||
|
g.commit.Author.Email = line
|
||||||
|
case "cn:":
|
||||||
|
g.commit.Committer.Name = line
|
||||||
|
case "ce:":
|
||||||
|
g.commit.Committer.Email = line
|
||||||
|
case "at:":
|
||||||
|
if t, err := strconv.ParseInt(line, 10, 64); err == nil {
|
||||||
|
g.commit.Timestamp = time.Unix(t, 0)
|
||||||
|
}
|
||||||
|
case "su:":
|
||||||
|
g.commit.Subject = line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return g.commit
|
||||||
|
}
|
||||||
|
|
||||||
func (g *Git) StashCount() int {
|
func (g *Git) StashCount() int {
|
||||||
if g.poshgit || g.stashCount != 0 {
|
if g.poshgit || g.stashCount != 0 {
|
||||||
return g.stashCount
|
return g.stashCount
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/mock"
|
"github.com/jandedobbeleer/oh-my-posh/src/mock"
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/platform"
|
"github.com/jandedobbeleer/oh-my-posh/src/platform"
|
||||||
|
@ -892,3 +893,85 @@ func TestGitIgnoreSubmodules(t *testing.T) {
|
||||||
assert.Equal(t, tc.Expected, got, tc.Case)
|
assert.Equal(t, tc.Expected, got, tc.Case)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGitCommit(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Case string
|
||||||
|
Expected *Commit
|
||||||
|
Output string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Case: "Clean commit",
|
||||||
|
Output: `
|
||||||
|
an:Jan De Dobbeleer
|
||||||
|
ae:jan@ohmyposh.dev
|
||||||
|
cn:Jan De Dobbeleer
|
||||||
|
ce:jan@ohmyposh.dev
|
||||||
|
at:1673176335
|
||||||
|
su:docs(error): you can't use cross segment properties
|
||||||
|
`,
|
||||||
|
Expected: &Commit{
|
||||||
|
Author: &User{
|
||||||
|
Name: "Jan De Dobbeleer",
|
||||||
|
Email: "jan@ohmyposh.dev",
|
||||||
|
},
|
||||||
|
Committer: &User{
|
||||||
|
Name: "Jan De Dobbeleer",
|
||||||
|
Email: "jan@ohmyposh.dev",
|
||||||
|
},
|
||||||
|
Subject: "docs(error): you can't use cross segment properties",
|
||||||
|
Timestamp: time.Unix(1673176335, 0),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "No commit output",
|
||||||
|
Expected: &Commit{
|
||||||
|
Author: &User{},
|
||||||
|
Committer: &User{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "No author",
|
||||||
|
Output: `
|
||||||
|
an:
|
||||||
|
ae:
|
||||||
|
cn:Jan De Dobbeleer
|
||||||
|
ce:jan@ohmyposh.dev
|
||||||
|
at:1673176335
|
||||||
|
su:docs(error): you can't use cross segment properties
|
||||||
|
`,
|
||||||
|
Expected: &Commit{
|
||||||
|
Author: &User{},
|
||||||
|
Committer: &User{
|
||||||
|
Name: "Jan De Dobbeleer",
|
||||||
|
Email: "jan@ohmyposh.dev",
|
||||||
|
},
|
||||||
|
Subject: "docs(error): you can't use cross segment properties",
|
||||||
|
Timestamp: time.Unix(1673176335, 0),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Bad timestamp",
|
||||||
|
Output: `
|
||||||
|
at:err
|
||||||
|
`,
|
||||||
|
Expected: &Commit{
|
||||||
|
Author: &User{},
|
||||||
|
Committer: &User{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
env := new(mock.MockedEnvironment)
|
||||||
|
env.MockGitCommand("", tc.Output, "log", "-1", "--pretty=format:an:%an%nae:%ae%ncn:%cn%nce:%ce%nat:%at%nsu:%s")
|
||||||
|
g := &Git{
|
||||||
|
scm: scm{
|
||||||
|
env: env,
|
||||||
|
command: "git",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
got := g.Commit()
|
||||||
|
assert.Equal(t, tc.Expected, got, tc.Case)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -145,6 +145,7 @@ You can set the following properties to `true` to enable fetching additional inf
|
||||||
| `.IsBare` | `boolean` | if in a bare repo or not, only set when `fetch_bare_info` is set to `true` |
|
| `.IsBare` | `boolean` | if in a bare repo or not, only set when `fetch_bare_info` is set to `true` |
|
||||||
| `.Dir` | `string` | the repository's root directory |
|
| `.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 }}` |
|
| `.Kraken` | `string` | a link to the current HEAD in [GitKraken][kraken-ref] for use in [hyperlinks][hyperlinks] in templates `{{ url .HEAD .Kraken }}` |
|
||||||
|
| `.Commit` | `Commit` | HEAD commit information (see below) |
|
||||||
|
|
||||||
### GitStatus
|
### GitStatus
|
||||||
|
|
||||||
|
@ -158,6 +159,22 @@ You can set the following properties to `true` to enable fetching additional inf
|
||||||
| `.Changed` | `boolean` | if the status contains changes or not |
|
| `.Changed` | `boolean` | if the status contains changes or not |
|
||||||
| `.String` | `string` | a string representation of the changes above |
|
| `.String` | `string` | a string representation of the changes above |
|
||||||
|
|
||||||
|
### Commit
|
||||||
|
|
||||||
|
| Name | Type | Description |
|
||||||
|
| ------------ | ----------- | -------------------------------------- |
|
||||||
|
| `.Author` | `User` | the author or the commit (see below) |
|
||||||
|
| `.Committer` | `User` | the comitter or the commit (see below) |
|
||||||
|
| `.Subject` | `string` | the commit subject |
|
||||||
|
| `.Timestamp` | `time.Time` | the commit timestamp |
|
||||||
|
|
||||||
|
### User
|
||||||
|
|
||||||
|
| Name | Type | Description |
|
||||||
|
| -------- | -------- | ---------------- |
|
||||||
|
| `.Name` | `string` | the user's name |
|
||||||
|
| `.Email` | `string` | the user's email |
|
||||||
|
|
||||||
Local changes use the following syntax:
|
Local changes use the following syntax:
|
||||||
|
|
||||||
| Icon | Description |
|
| Icon | Description |
|
||||||
|
|
Loading…
Reference in a new issue