mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2025-03-05 20:49:04 -08:00
feat: add gitversion segment
This commit is contained in:
parent
c7616c1f7d
commit
acd4d01d4d
|
@ -121,6 +121,8 @@ const (
|
||||||
GCP SegmentType = "gcp"
|
GCP SegmentType = "gcp"
|
||||||
// GIT represents the git status and information
|
// GIT represents the git status and information
|
||||||
GIT SegmentType = "git"
|
GIT SegmentType = "git"
|
||||||
|
// GITVERSION represents the gitversion information
|
||||||
|
GITVERSION SegmentType = "gitversion"
|
||||||
// GOLANG writes which go version is currently active
|
// GOLANG writes which go version is currently active
|
||||||
GOLANG SegmentType = "go"
|
GOLANG SegmentType = "go"
|
||||||
// HASKELL segment
|
// HASKELL segment
|
||||||
|
@ -294,6 +296,7 @@ func (segment *Segment) mapSegmentWithWriter(env platform.Environment) error {
|
||||||
FOSSIL: &segments.Fossil{},
|
FOSSIL: &segments.Fossil{},
|
||||||
GCP: &segments.Gcp{},
|
GCP: &segments.Gcp{},
|
||||||
GIT: &segments.Git{},
|
GIT: &segments.Git{},
|
||||||
|
GITVERSION: &segments.GitVersion{},
|
||||||
GOLANG: &segments.Golang{},
|
GOLANG: &segments.Golang{},
|
||||||
HASKELL: &segments.Haskell{},
|
HASKELL: &segments.Haskell{},
|
||||||
IPIFY: &segments.IPify{},
|
IPIFY: &segments.IPify{},
|
||||||
|
|
112
src/segments/gitversion.go
Normal file
112
src/segments/gitversion.go
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
package segments
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"oh-my-posh/platform"
|
||||||
|
"oh-my-posh/properties"
|
||||||
|
)
|
||||||
|
|
||||||
|
type gitVersion struct {
|
||||||
|
Major int `json:"Major"`
|
||||||
|
Minor int `json:"Minor"`
|
||||||
|
Patch int `json:"Patch"`
|
||||||
|
PreReleaseTag string `json:"PreReleaseTag"`
|
||||||
|
PreReleaseTagWithDash string `json:"PreReleaseTagWithDash"`
|
||||||
|
PreReleaseLabel string `json:"PreReleaseLabel"`
|
||||||
|
PreReleaseLabelWithDash string `json:"PreReleaseLabelWithDash"`
|
||||||
|
PreReleaseNumber int `json:"PreReleaseNumber"`
|
||||||
|
WeightedPreReleaseNumber int `json:"WeightedPreReleaseNumber"`
|
||||||
|
BuildMetaData int `json:"BuildMetaData"`
|
||||||
|
BuildMetaDataPadded string `json:"BuildMetaDataPadded"`
|
||||||
|
FullBuildMetaData string `json:"FullBuildMetaData"`
|
||||||
|
MajorMinorPatch string `json:"MajorMinorPatch"`
|
||||||
|
SemVer string `json:"SemVer"`
|
||||||
|
LegacySemVer string `json:"LegacySemVer"`
|
||||||
|
LegacySemVerPadded string `json:"LegacySemVerPadded"`
|
||||||
|
AssemblySemVer string `json:"AssemblySemVer"`
|
||||||
|
AssemblySemFileVer string `json:"AssemblySemFileVer"`
|
||||||
|
FullSemVer string `json:"FullSemVer"`
|
||||||
|
InformationalVersion string `json:"InformationalVersion"`
|
||||||
|
BranchName string `json:"BranchName"`
|
||||||
|
EscapedBranchName string `json:"EscapedBranchName"`
|
||||||
|
Sha string `json:"Sha"`
|
||||||
|
ShortSha string `json:"ShortSha"`
|
||||||
|
NuGetVersionV2 string `json:"NuGetVersionV2"`
|
||||||
|
NuGetVersion string `json:"NuGetVersion"`
|
||||||
|
NuGetPreReleaseTagV2 string `json:"NuGetPreReleaseTagV2"`
|
||||||
|
NuGetPreReleaseTag string `json:"NuGetPreReleaseTag"`
|
||||||
|
VersionSourceSha string `json:"VersionSourceSha"`
|
||||||
|
CommitsSinceVersionSource int `json:"CommitsSinceVersionSource"`
|
||||||
|
CommitsSinceVersionSourcePadded string `json:"CommitsSinceVersionSourcePadded"`
|
||||||
|
UncommittedChanges int `json:"UncommittedChanges"`
|
||||||
|
CommitDate string `json:"CommitDate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GitVersion struct {
|
||||||
|
props properties.Properties
|
||||||
|
env platform.Environment
|
||||||
|
|
||||||
|
gitVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *GitVersion) Template() string {
|
||||||
|
return " {{ .MajorMinorPatch }} "
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *GitVersion) Enabled() bool {
|
||||||
|
gitversion := "gitversion"
|
||||||
|
if !n.env.HasCommand(gitversion) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
dir := n.env.Pwd()
|
||||||
|
version, err := n.getCacheValue(dir)
|
||||||
|
// only return on valid cache value
|
||||||
|
if err == nil && len(version.FullSemVer) != 0 {
|
||||||
|
n.gitVersion = *version
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := n.env.RunCommand(gitversion, "-output", "json")
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
n.gitVersion = gitVersion{}
|
||||||
|
err = json.Unmarshal([]byte(response), &n.gitVersion)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheTimeout := n.props.GetInt(properties.CacheTimeout, 30)
|
||||||
|
if cacheTimeout > 0 {
|
||||||
|
n.env.Cache().Set(dir, response, cacheTimeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *GitVersion) getCacheValue(key string) (*gitVersion, error) {
|
||||||
|
var semVer = &gitVersion{}
|
||||||
|
cacheTimeout := n.props.GetInt(properties.CacheTimeout, 30)
|
||||||
|
|
||||||
|
if cacheTimeout <= 0 {
|
||||||
|
return semVer, errors.New("no cache needed")
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, found := n.env.Cache().Get(key); found {
|
||||||
|
err := json.Unmarshal([]byte(val), &semVer)
|
||||||
|
if err != nil {
|
||||||
|
return semVer, err
|
||||||
|
}
|
||||||
|
return semVer, nil
|
||||||
|
}
|
||||||
|
err := errors.New("no data in cache")
|
||||||
|
return semVer, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *GitVersion) Init(props properties.Properties, env platform.Environment) {
|
||||||
|
n.props = props
|
||||||
|
n.env = env
|
||||||
|
}
|
103
src/segments/gitversion_test.go
Normal file
103
src/segments/gitversion_test.go
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
package segments
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"oh-my-posh/mock"
|
||||||
|
"oh-my-posh/properties"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/alecthomas/assert"
|
||||||
|
mock2 "github.com/stretchr/testify/mock"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGitversion(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Case string
|
||||||
|
ExpectedEnabled bool
|
||||||
|
ExpectedString string
|
||||||
|
Response string
|
||||||
|
CacheResponse string
|
||||||
|
CacheError error
|
||||||
|
HasGitversion bool
|
||||||
|
Template string
|
||||||
|
CommandError error
|
||||||
|
CacheTimeout int
|
||||||
|
}{
|
||||||
|
{Case: "GitVersion not installed"},
|
||||||
|
{Case: "GitVersion installed, no GitVersion.yml file", HasGitversion: true, Response: "Cannot find the .git directory"},
|
||||||
|
{
|
||||||
|
Case: "Version",
|
||||||
|
ExpectedEnabled: true,
|
||||||
|
ExpectedString: "number",
|
||||||
|
HasGitversion: true,
|
||||||
|
Response: "{ \"FullSemVer\": \"0.1.0\", \"SemVer\": \"number\" }",
|
||||||
|
Template: "{{ .SemVer }}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Cache Version",
|
||||||
|
ExpectedEnabled: true,
|
||||||
|
ExpectedString: "number2",
|
||||||
|
HasGitversion: true,
|
||||||
|
CacheResponse: "{ \"FullSemVer\": \"0.1.2\", \"SemVer\": \"number2\" }",
|
||||||
|
Response: "{ \"FullSemVer\": \"0.1.0\", \"SemVer\": \"number\" }",
|
||||||
|
Template: "{{ .SemVer }}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "No Cache enabled",
|
||||||
|
ExpectedEnabled: true,
|
||||||
|
CacheTimeout: -1,
|
||||||
|
ExpectedString: "number",
|
||||||
|
HasGitversion: true,
|
||||||
|
CacheResponse: "{ \"FullSemVer\": \"0.1.2\", \"SemVer\": \"number2\" }",
|
||||||
|
Response: "{ \"FullSemVer\": \"0.1.0\", \"SemVer\": \"number\" }",
|
||||||
|
Template: "{{ .SemVer }}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Command Error",
|
||||||
|
HasGitversion: true,
|
||||||
|
CommandError: errors.New("error"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Bad cache",
|
||||||
|
ExpectedEnabled: true,
|
||||||
|
ExpectedString: "number",
|
||||||
|
HasGitversion: true,
|
||||||
|
CacheResponse: "{{",
|
||||||
|
Response: "{ \"FullSemVer\": \"0.1.0\", \"SemVer\": \"number\" }",
|
||||||
|
Template: "{{ .SemVer }}",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
env := new(mock.MockedEnvironment)
|
||||||
|
cache := &mock.MockedCache{}
|
||||||
|
|
||||||
|
env.On("HasCommand", "gitversion").Return(tc.HasGitversion)
|
||||||
|
env.On("Pwd").Return("test-dir")
|
||||||
|
env.On("Cache").Return(cache)
|
||||||
|
cache.On("Get", "test-dir").Return(tc.CacheResponse, len(tc.CacheResponse) != 0)
|
||||||
|
cache.On("Set", mock2.Anything, mock2.Anything, mock2.Anything).Return(tc.Response, true)
|
||||||
|
|
||||||
|
env.On("RunCommand", "gitversion", []string{"-output", "json"}).Return(tc.Response, tc.CommandError)
|
||||||
|
|
||||||
|
if tc.CacheTimeout == 0 {
|
||||||
|
tc.CacheTimeout = 30
|
||||||
|
}
|
||||||
|
gitversion := &GitVersion{
|
||||||
|
env: env,
|
||||||
|
props: properties.Map{
|
||||||
|
properties.CacheTimeout: tc.CacheTimeout,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if len(tc.Template) == 0 {
|
||||||
|
tc.Template = gitversion.Template()
|
||||||
|
}
|
||||||
|
|
||||||
|
enabled := gitversion.Enabled()
|
||||||
|
|
||||||
|
assert.Equal(t, tc.ExpectedEnabled, enabled, tc.Case)
|
||||||
|
if enabled {
|
||||||
|
assert.Equal(t, tc.ExpectedString, renderTemplate(env, tc.Template, gitversion), tc.Case)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -239,6 +239,7 @@
|
||||||
"fossil",
|
"fossil",
|
||||||
"gcp",
|
"gcp",
|
||||||
"git",
|
"git",
|
||||||
|
"gitversion",
|
||||||
"go",
|
"go",
|
||||||
"haskell",
|
"haskell",
|
||||||
"ipify",
|
"ipify",
|
||||||
|
@ -2855,6 +2856,17 @@
|
||||||
"title": "GCP Segment",
|
"title": "GCP Segment",
|
||||||
"description": "https://ohmyposh.dev/docs/segments/gcp"
|
"description": "https://ohmyposh.dev/docs/segments/gcp"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": {
|
||||||
|
"properties": {
|
||||||
|
"type": { "const": "gitversion" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"then": {
|
||||||
|
"title": "Display GitVersion segment",
|
||||||
|
"description": "https://ohmyposh.dev/docs/segments/gitversion"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
53
website/docs/segments/gitversion.mdx
Normal file
53
website/docs/segments/gitversion.mdx
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
id: gitversion
|
||||||
|
title: GitVersion
|
||||||
|
sidebar_label: GitVersion
|
||||||
|
---
|
||||||
|
|
||||||
|
## What
|
||||||
|
|
||||||
|
Display the [GitVersion][gitversion] version.
|
||||||
|
We _strongly_ recommend using [GitVersion Portable][gitversion-portable] for this.
|
||||||
|
|
||||||
|
:::caution
|
||||||
|
The GitVersion CLI can be a bit slow causing the prompt to feel slow. This why we cache
|
||||||
|
the value for 30 minutes by default.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Sample Configuration
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "gitversion",
|
||||||
|
"style": "powerline",
|
||||||
|
"powerline_symbol": "\uE0B0",
|
||||||
|
"foreground": "#ffffff",
|
||||||
|
"background": "#3a579b",
|
||||||
|
"template": " \uF1D2 {{ .MajorMinorPatch }} "
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Name | Type | Description |
|
||||||
|
| --------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| `cache_timeout` | `int` | in minutes - How long to wait before fetching new information using the gitversion CLI. Default is 30 minutes, a value of 0 disables the cache. |
|
||||||
|
|
||||||
|
## Template ([info][templates])
|
||||||
|
|
||||||
|
:::note default template
|
||||||
|
|
||||||
|
```template
|
||||||
|
{{ .MajorMinorPatch }}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Properties
|
||||||
|
|
||||||
|
You can leverage all variables from the [GitVersion][gitversion] CLI. Have a look at their [documentation][docs] for more information.
|
||||||
|
|
||||||
|
[gitversion]: https://github.com/GitTools/GitVersion
|
||||||
|
[gitversion-portable]: http://chocolatey.org/packages/GitVersion.Portable
|
||||||
|
[templates]: /docs/configuration/templates
|
||||||
|
[docs]: https://gitversion.net/docs/reference/variables
|
|
@ -73,6 +73,7 @@ module.exports = {
|
||||||
"segments/fossil",
|
"segments/fossil",
|
||||||
"segments/gcp",
|
"segments/gcp",
|
||||||
"segments/git",
|
"segments/git",
|
||||||
|
"segments/gitversion",
|
||||||
"segments/golang",
|
"segments/golang",
|
||||||
"segments/haskell",
|
"segments/haskell",
|
||||||
"segments/ipify",
|
"segments/ipify",
|
||||||
|
|
Loading…
Reference in a new issue