feat: cloud foundry target segment

This commit is contained in:
Jacek W 2022-02-19 13:45:21 +00:00 committed by Jan De Dobbeleer
parent 0b1aa9d5ee
commit 882e541b96
6 changed files with 208 additions and 0 deletions

View file

@ -0,0 +1,44 @@
---
id: cftarget
title: Cloud Foundry Target
sidebar_label: Cloud Foundry Target
---
## What
Display the details of the logged [Cloud Foundry endpoint][cf-target] (`cf target` details).
## Sample Configuration
```json
{
"background": "#a7cae1",
"foreground": "#100e23",
"powerline_symbol": "\ue0b0",
"properties": {
"template": " \uf40a {{ .Org }}/{{ .Space }} "
},
"style": "powerline",
"type": "cftarget"
}
```
## Template ([info][templates])
:::note default template
```template
{{if .Org }}{{ .Org }}{{ end }}{{ if .Space }}/{{ .Space }}{{ end }}
```
:::
## Template Properties
- `.Org`: `string` - Cloud Foundry organization
- `.Space`: `string` - Cloud Foundry space
- `.URL`: `string` - Cloud Foundry API URL
- `.User`: `string` - logged in user
[templates]: /docs/config-templates
[cf-target]: https://cli.cloudfoundry.org/en-US/v8/target.html

View file

@ -47,6 +47,7 @@ module.exports = {
"command",
"crystal",
"cf",
"cftarget",
"dart",
"dotnet",
"executiontime",

View file

@ -156,6 +156,8 @@ const (
UI5TOOLING SegmentType = "ui5tooling"
// Cloud Foundry segment
CF SegmentType = "cf"
// Cloud Foundry logged in target
CFTARGET SegmentType = "cftarget"
)
func (segment *Segment) shouldIncludeFolder() bool {
@ -281,6 +283,7 @@ func (segment *Segment) mapSegmentWithWriter(env environment.Environment) error
HASKELL: &segments.Haskell{},
UI5TOOLING: &segments.UI5Tooling{},
CF: &segments.Cf{},
CFTARGET: &segments.CfTarget{},
}
if segment.Properties == nil {
segment.Properties = make(properties.Map)

83
src/segments/cf_target.go Normal file
View file

@ -0,0 +1,83 @@
package segments
import (
"oh-my-posh/environment"
"oh-my-posh/properties"
"regexp"
)
type CfTarget struct {
props properties.Properties
env environment.Environment
CfTargetDetails
}
type CfTargetDetails struct {
URL string
User string
Org string
Space string
}
func (c *CfTarget) Template() string {
return "{{if .Org }}{{ .Org }}{{ end }}{{if .Space }}/{{ .Space }}{{ end }}"
}
func (c *CfTarget) Init(props properties.Properties, env environment.Environment) {
c.props = props
c.env = env
}
func (c *CfTarget) Enabled() bool {
return c.setCFTargetStatus()
}
func (c *CfTarget) getCFTargetCommandOutput() string {
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
}
regex := regexp.MustCompile(`API endpoint:\s*(?P<api_url>http[s].*)|user:\s*(?P<user>.*)|org:\s*(?P<org>.*)|space:\s*(?P<space>(.*))`)
match := regex.FindAllStringSubmatch(output, -1)
result := make(map[string]string)
for i, name := range regex.SubexpNames() {
if i == 0 || len(name) == 0 {
continue
}
for j, val := range match[i-1] {
if j == 0 {
continue
}
if val != "" {
result[name] = val
}
}
}
c.URL = result["api_url"]
c.Org = result["org"]
c.Space = result["space"]
c.User = result["user"]
return true
}

View file

@ -0,0 +1,66 @@
package segments
import (
"fmt"
"oh-my-posh/mock"
"oh-my-posh/properties"
"os/exec"
"testing"
"github.com/stretchr/testify/assert"
)
func TestCFTargetSegment(t *testing.T) {
cases := []struct {
Case string
Template string
ExpectedString string
ExpectedEnabled bool
TargetOutput string
CommandError error
}{
{
Case: "1) not logged in to CF account",
ExpectedString: "",
ExpectedEnabled: false,
TargetOutput: `Not logged in`,
CommandError: &exec.ExitError{},
},
{
Case: "2) logged in, default template",
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",
CommandError: nil,
},
{
Case: "3) logged in, full template",
Template: "{{.URL}} {{.User}} {{.Org}} {{.Space}}",
ExpectedString: "https://api.cf.eu10.hana.ondemand.com user@some.com 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",
CommandError: nil,
},
}
for _, tc := range cases {
var env = new(mock.MockedEnvironment)
env.On("HasCommand", "cf").Return(true)
env.On("RunCommand", "cf", []string{"target"}).Return(tc.TargetOutput, tc.CommandError)
env.On("Pwd", nil).Return("/usr/home/dev/my-app")
env.On("Home", nil).Return("/usr/home")
cfTarget := &CfTarget{}
props := properties.Map{}
if tc.Template == "" {
tc.Template = cfTarget.Template()
}
cfTarget.Init(props, env)
failMsg := fmt.Sprintf("Failed in case: %s", tc.Case)
assert.Equal(t, tc.ExpectedEnabled, cfTarget.Enabled(), failMsg)
assert.Equal(t, tc.ExpectedString, renderTemplate(env, tc.Template, cfTarget), failMsg)
}
}

View file

@ -1972,6 +1972,17 @@
}
}
}
},
{
"if": {
"properties": {
"type": { "const": "cftarget" }
}
},
"then": {
"title": "Clound Foundry Target segment",
"description": "https://ohmyposh.dev/docs/cftarget"
}
}
]
}