feat: add gitversion segment

This commit is contained in:
Lemorz56 2022-08-26 20:58:48 +02:00 committed by Jan De Dobbeleer
parent c7616c1f7d
commit acd4d01d4d
6 changed files with 284 additions and 0 deletions

View file

@ -121,6 +121,8 @@ const (
GCP SegmentType = "gcp"
// GIT represents the git status and information
GIT SegmentType = "git"
// GITVERSION represents the gitversion information
GITVERSION SegmentType = "gitversion"
// GOLANG writes which go version is currently active
GOLANG SegmentType = "go"
// HASKELL segment
@ -294,6 +296,7 @@ func (segment *Segment) mapSegmentWithWriter(env platform.Environment) error {
FOSSIL: &segments.Fossil{},
GCP: &segments.Gcp{},
GIT: &segments.Git{},
GITVERSION: &segments.GitVersion{},
GOLANG: &segments.Golang{},
HASKELL: &segments.Haskell{},
IPIFY: &segments.IPify{},

112
src/segments/gitversion.go Normal file
View 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
}

View 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)
}
}
}

View file

@ -239,6 +239,7 @@
"fossil",
"gcp",
"git",
"gitversion",
"go",
"haskell",
"ipify",
@ -2855,6 +2856,17 @@
"title": "GCP Segment",
"description": "https://ohmyposh.dev/docs/segments/gcp"
}
},
{
"if": {
"properties": {
"type": { "const": "gitversion" }
}
},
"then": {
"title": "Display GitVersion segment",
"description": "https://ohmyposh.dev/docs/segments/gitversion"
}
}
]
}

View 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

View file

@ -73,6 +73,7 @@ module.exports = {
"segments/fossil",
"segments/gcp",
"segments/git",
"segments/gitversion",
"segments/golang",
"segments/haskell",
"segments/ipify",