feat(cftarget): add display_mode

This commit is contained in:
Jan De Dobbeleer 2023-03-28 20:15:07 +02:00 committed by Jan De Dobbeleer
parent 7083cac3f1
commit 17bd13b0fc
4 changed files with 116 additions and 65 deletions

View file

@ -1,7 +1,8 @@
package segments package segments
import ( import (
"regexp" "errors"
"strings"
"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"
@ -31,54 +32,63 @@ func (c *CfTarget) Init(props properties.Properties, env platform.Environment) {
} }
func (c *CfTarget) Enabled() bool { func (c *CfTarget) Enabled() bool {
return c.setCFTargetStatus()
}
func (c *CfTarget) getCFTargetCommandOutput() string {
if !c.env.HasCommand("cf") { if !c.env.HasCommand("cf") {
return ""
}
output, err := c.env.RunCommand("cf", "target")
if err != nil {
return ""
}
return output
}
func (c *CfTarget) setCFTargetStatus() bool {
output := c.getCFTargetCommandOutput()
if output == "" {
return false return false
} }
regex := regexp.MustCompile(`API endpoint:\s*(?P<api_url>http[s].*)|user:\s*(?P<user>.*)|org:\s*(?P<org>.*)|space:\s*(?P<space>(.*))`) displayMode := c.props.GetString(DisplayMode, DisplayModeAlways)
match := regex.FindAllStringSubmatch(output, -1) if displayMode != DisplayModeFiles {
result := make(map[string]string) return c.setCFTargetStatus()
}
for i, name := range regex.SubexpNames() { manifest, err := c.env.HasParentFilePath("manifest.yml")
if i == 0 || len(name) == 0 { if err != nil || manifest.IsDir {
return false
}
return c.setCFTargetStatus()
}
func (c *CfTarget) setCFTargetStatus() bool {
output, err := c.getCFTargetCommandOutput()
if err != nil {
return false
}
lines := strings.Split(output, "\n")
for _, line := range lines {
splitted := strings.SplitN(line, ":", 2)
if len(splitted) < 2 {
continue continue
} }
key := splitted[0]
for j, val := range match[i-1] { value := strings.TrimSpace(splitted[1])
if j == 0 { switch key {
continue case "API endpoint":
} c.URL = value
case "user":
if val != "" { c.User = value
result[name] = val case "org":
} c.Org = value
case "space":
c.Space = value
} }
} }
c.URL = result["api_url"]
c.Org = result["org"]
c.Space = result["space"]
c.User = result["user"]
return true return true
} }
func (c *CfTarget) getCFTargetCommandOutput() (string, error) {
output, err := c.env.RunCommand("cf", "target")
if err != nil {
return "", err
}
if len(output) == 0 {
return "", errors.New("cf command output is empty")
}
return output, nil
}

View file

@ -1,11 +1,13 @@
package segments package segments
import ( import (
"errors"
"fmt" "fmt"
"os/exec" "os/exec"
"testing" "testing"
"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/properties" "github.com/jandedobbeleer/oh-my-posh/src/properties"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -13,34 +15,51 @@ import (
func TestCFTargetSegment(t *testing.T) { func TestCFTargetSegment(t *testing.T) {
cases := []struct { cases := []struct {
Case string Case string
Template string Template string
ExpectedString string ExpectedString string
ExpectedEnabled bool DisplayMode string
TargetOutput string FileInfo *platform.FileInfo
CommandError error TargetOutput string
CommandError error
}{ }{
{ {
Case: "1) not logged in to CF account", Case: "not logged in to CF account",
ExpectedString: "", TargetOutput: `Not logged in`,
ExpectedEnabled: false, CommandError: &exec.ExitError{},
TargetOutput: `Not logged in`,
CommandError: &exec.ExitError{},
}, },
{ {
Case: "2) logged in, default template", Case: "logged in, default template",
ExpectedString: "12345678trial/dev", ExpectedString: "12345678trial/dev",
ExpectedEnabled: true, TargetOutput: "API endpoint: https://api.cf.eu10.hana.ondemand.com\nAPI version: 3.109.0\nuser: user@some.com\norg: 12345678trial\nspace: dev",
TargetOutput: "API endpoint: https://api.cf.eu10.hana.ondemand.com\nAPI version: 3.109.0\nuser: user@some.com\norg: 12345678trial\nspace: dev",
CommandError: nil,
}, },
{ {
Case: "3) logged in, full template", Case: "no output from command",
Template: "{{.URL}} {{.User}} {{.Org}} {{.Space}}", },
ExpectedString: "https://api.cf.eu10.hana.ondemand.com user@some.com 12345678trial dev", {
ExpectedEnabled: true, Case: "logged in, full template",
TargetOutput: "API endpoint: https://api.cf.eu10.hana.ondemand.com\nAPI version: 3.109.0\nuser: user@some.com\norg: 12345678trial\nspace: dev", Template: "{{.URL}} {{.User}} {{.Org}} {{.Space}}",
CommandError: nil, ExpectedString: "https://api.cf.eu10.hana.ondemand.com user@some.com 12345678trial dev",
TargetOutput: "API endpoint: https://api.cf.eu10.hana.ondemand.com\nAPI version: 3.109.0\nuser: user@some.com\norg: 12345678trial\nspace: dev",
},
{
Case: "files and no manifest file",
DisplayMode: DisplayModeFiles,
TargetOutput: "API endpoint: https://api.cf.eu10.hana.ondemand.com\nAPI version: 3.109.0\nuser: user@some.com\norg: 12345678trial\nspace: dev",
},
{
Case: "files and a manifest file",
ExpectedString: "12345678trial/dev",
DisplayMode: DisplayModeFiles,
FileInfo: &platform.FileInfo{},
TargetOutput: "API endpoint: https://api.cf.eu10.hana.ondemand.com\nAPI version: 3.109.0\nuser: user@some.com\norg: 12345678trial\nspace: dev",
},
{
Case: "files and a manifest directory",
DisplayMode: DisplayModeFiles,
FileInfo: &platform.FileInfo{
IsDir: true,
},
}, },
} }
@ -50,9 +69,16 @@ func TestCFTargetSegment(t *testing.T) {
env.On("RunCommand", "cf", []string{"target"}).Return(tc.TargetOutput, tc.CommandError) env.On("RunCommand", "cf", []string{"target"}).Return(tc.TargetOutput, tc.CommandError)
env.On("Pwd", nil).Return("/usr/home/dev/my-app") env.On("Pwd", nil).Return("/usr/home/dev/my-app")
env.On("Home", nil).Return("/usr/home") env.On("Home", nil).Return("/usr/home")
var err error
if tc.FileInfo == nil {
err = errors.New("no such file or directory")
}
env.On("HasParentFilePath", "manifest.yml").Return(tc.FileInfo, err)
cfTarget := &CfTarget{} cfTarget := &CfTarget{}
props := properties.Map{} props := properties.Map{
DisplayMode: tc.DisplayMode,
}
if tc.Template == "" { if tc.Template == "" {
tc.Template = cfTarget.Template() tc.Template = cfTarget.Template()
@ -61,7 +87,7 @@ func TestCFTargetSegment(t *testing.T) {
cfTarget.Init(props, env) cfTarget.Init(props, env)
failMsg := fmt.Sprintf("Failed in case: %s", tc.Case) failMsg := fmt.Sprintf("Failed in case: %s", tc.Case)
assert.Equal(t, tc.ExpectedEnabled, cfTarget.Enabled(), failMsg) assert.Equal(t, len(tc.ExpectedString) > 0, cfTarget.Enabled(), failMsg)
assert.Equal(t, tc.ExpectedString, renderTemplate(env, tc.Template, cfTarget), failMsg) assert.Equal(t, tc.ExpectedString, renderTemplate(env, tc.Template, cfTarget), failMsg)
} }
} }

View file

@ -2863,7 +2863,16 @@
}, },
"then": { "then": {
"title": "Clound Foundry Target segment", "title": "Clound Foundry Target segment",
"description": "https://ohmyposh.dev/docs/segments/cftarget" "description": "https://ohmyposh.dev/docs/segments/cftarget",
"properties": {
"properties": {
"properties": {
"display_mode": {
"$ref": "#/definitions/display_mode"
}
}
}
}
} }
}, },
{ {

View file

@ -21,6 +21,12 @@ Display the details of the logged [Cloud Foundry endpoint][cf-target] (`cf targe
} }
``` ```
## Properties
| Name | Type | Description |
| -------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `display_mode` | `string` | <ul><li>`always`: the segment is always displayed (**default**)</li><li>`files`: the segment is only displayed when a `manifest.yml` file is present </li></ul> |
## Template ([info][templates]) ## Template ([info][templates])
:::note default template :::note default template