mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2025-03-05 20:49:04 -08:00
feat(project): cargo and poetry support
This commit is contained in:
parent
af7db43889
commit
b61ec064dd
|
@ -11,6 +11,8 @@ Display the current version of your project defined in the package file.
|
||||||
Supports:
|
Supports:
|
||||||
|
|
||||||
- Node.js project (`package.json`)
|
- Node.js project (`package.json`)
|
||||||
|
- Cargo project (`Cargo.toml`)
|
||||||
|
- Poetry project (`pyproject.toml`)
|
||||||
|
|
||||||
## Sample Configuration
|
## Sample Configuration
|
||||||
|
|
||||||
|
@ -21,7 +23,7 @@ Supports:
|
||||||
"powerline_symbol": "\uE0B0",
|
"powerline_symbol": "\uE0B0",
|
||||||
"foreground": "#193549",
|
"foreground": "#193549",
|
||||||
"background": "#ffeb3b",
|
"background": "#ffeb3b",
|
||||||
"template": " {{ if .Error }}{{ .Error }}{{ else }}{{ if .Version }}\uf487 {{.Version}}{{ end }}{{ end }} "
|
"template": " {{ if .Error }}{{ .Error }}{{ else }}{{ if .Version }}\uf487 {{.Version}}{{ end }} {{ if .Name }}{{ .Name }}{{ end }}{{ end }} "
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -30,7 +32,7 @@ Supports:
|
||||||
:::note default template
|
:::note default template
|
||||||
|
|
||||||
``` template
|
``` template
|
||||||
{{ if .Error }}{{ .Error }}{{ else }}{{ if .Version }}\uf487 {{.Version}}{{ end }}{{ end }}
|
{{ if .Error }}{{ .Error }}{{ else }}{{ if .Version }}\uf487 {{.Version}}{{ end }} {{ if .Name }}{{ .Name }}{{ end }}{{ end }}
|
||||||
```
|
```
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
@ -38,5 +40,6 @@ Supports:
|
||||||
### Properties
|
### Properties
|
||||||
|
|
||||||
- `.Version`: `string` - The version of your project
|
- `.Version`: `string` - The version of your project
|
||||||
|
- `.Name`: `string` - The name of your project
|
||||||
|
|
||||||
[templates]: /docs/config-templates
|
[templates]: /docs/config-templates
|
||||||
|
|
|
@ -40,7 +40,7 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v1.0.0 // indirect
|
github.com/BurntSushi/toml v1.0.0
|
||||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
|
|
@ -4,18 +4,33 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"oh-my-posh/environment"
|
"oh-my-posh/environment"
|
||||||
"oh-my-posh/properties"
|
"oh-my-posh/properties"
|
||||||
|
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ProjectItem struct {
|
type ProjectItem struct {
|
||||||
Name string
|
Name string
|
||||||
File string
|
File string
|
||||||
Fetcher func(item ProjectItem) string
|
Fetcher func(item ProjectItem) (string, string)
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodePackageJSON struct {
|
type ProjectData struct {
|
||||||
Name string `json:"name"`
|
Version string
|
||||||
Description string `json:"description"`
|
Name string
|
||||||
Version string `json:"version"`
|
}
|
||||||
|
|
||||||
|
// Rust Cargo package
|
||||||
|
type CargoTOML struct {
|
||||||
|
Package ProjectData
|
||||||
|
}
|
||||||
|
|
||||||
|
// Python Poetry package
|
||||||
|
type PyProjectTOML struct {
|
||||||
|
Tool PyProjectToolTOML
|
||||||
|
}
|
||||||
|
|
||||||
|
type PyProjectToolTOML struct {
|
||||||
|
Poetry ProjectData
|
||||||
}
|
}
|
||||||
|
|
||||||
type Project struct {
|
type Project struct {
|
||||||
|
@ -23,8 +38,9 @@ type Project struct {
|
||||||
env environment.Environment
|
env environment.Environment
|
||||||
|
|
||||||
projects []*ProjectItem
|
projects []*ProjectItem
|
||||||
Version string
|
|
||||||
Error string
|
Error string
|
||||||
|
|
||||||
|
ProjectData
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Project) Enabled() bool {
|
func (n *Project) Enabled() bool {
|
||||||
|
@ -39,7 +55,7 @@ func (n *Project) Enabled() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Project) Template() string {
|
func (n *Project) Template() string {
|
||||||
return " {{ if .Error }}{{ .Error }}{{ else }}{{ if .Version }}\uf487 {{.Version}}{{ end }}{{ end }} "
|
return " {{ if .Error }}{{ .Error }}{{ else }}{{ if .Version }}\uf487 {{.Version}}{{ end }} {{ if .Name }}{{ .Name }}{{ end }}{{ end }} "
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Project) Init(props properties.Properties, env environment.Environment) {
|
func (n *Project) Init(props properties.Properties, env environment.Environment) {
|
||||||
|
@ -50,14 +66,25 @@ func (n *Project) Init(props properties.Properties, env environment.Environment)
|
||||||
{
|
{
|
||||||
Name: "node",
|
Name: "node",
|
||||||
File: "package.json",
|
File: "package.json",
|
||||||
Fetcher: n.getNodePackageVersion,
|
Fetcher: n.getNodePackage,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "cargo",
|
||||||
|
File: "Cargo.toml",
|
||||||
|
Fetcher: n.getCargoPackage,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "poetry",
|
||||||
|
File: "pyproject.toml",
|
||||||
|
Fetcher: n.getPoetryPackage,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Version = ""
|
n.Version = ""
|
||||||
|
n.Name = ""
|
||||||
for _, item := range n.projects {
|
for _, item := range n.projects {
|
||||||
if n.hasProjectFile(item) {
|
if n.hasProjectFile(item) {
|
||||||
n.Version = item.Fetcher(*item)
|
n.Version, n.Name = item.Fetcher(*item)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,15 +94,41 @@ func (n *Project) hasProjectFile(p *ProjectItem) bool {
|
||||||
return n.env.HasFiles(p.File)
|
return n.env.HasFiles(p.File)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Project) getNodePackageVersion(item ProjectItem) string {
|
func (n *Project) getNodePackage(item ProjectItem) (string, string) {
|
||||||
content := n.env.FileContent(item.File)
|
content := n.env.FileContent(item.File)
|
||||||
|
|
||||||
var data NodePackageJSON
|
var data ProjectData
|
||||||
err := json.Unmarshal([]byte(content), &data)
|
err := json.Unmarshal([]byte(content), &data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
n.Error = err.Error()
|
n.Error = err.Error()
|
||||||
return ""
|
return "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return data.Version
|
return data.Version, data.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Project) getCargoPackage(item ProjectItem) (string, string) {
|
||||||
|
content := n.env.FileContent(item.File)
|
||||||
|
|
||||||
|
var data CargoTOML
|
||||||
|
_, err := toml.Decode(content, &data)
|
||||||
|
if err != nil {
|
||||||
|
n.Error = err.Error()
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.Package.Version, data.Package.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Project) getPoetryPackage(item ProjectItem) (string, string) {
|
||||||
|
content := n.env.FileContent(item.File)
|
||||||
|
|
||||||
|
var data PyProjectTOML
|
||||||
|
_, err := toml.Decode(content, &data)
|
||||||
|
if err != nil {
|
||||||
|
n.Error = err.Error()
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.Tool.Poetry.Version, data.Tool.Poetry.Name
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/alecthomas/assert"
|
"github.com/alecthomas/assert"
|
||||||
|
|
||||||
|
testify_mock "github.com/stretchr/testify/mock"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MockData struct {
|
type MockData struct {
|
||||||
|
@ -20,17 +22,36 @@ type MockData struct {
|
||||||
func getMockedPackageEnv(tc *MockData) (*mock.MockedEnvironment, properties.Map) {
|
func getMockedPackageEnv(tc *MockData) (*mock.MockedEnvironment, properties.Map) {
|
||||||
env := new(mock.MockedEnvironment)
|
env := new(mock.MockedEnvironment)
|
||||||
props := properties.Map{}
|
props := properties.Map{}
|
||||||
env.On("HasFiles", tc.File).Return(true)
|
env.On("HasFiles", testify_mock.Anything).Run(func(args testify_mock.Arguments) {
|
||||||
|
for _, c := range env.ExpectedCalls {
|
||||||
|
if c.Method == "HasFiles" {
|
||||||
|
c.ReturnArguments = testify_mock.Arguments{args.Get(0).(string) == tc.File}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
env.On("FileContent", tc.File).Return(tc.PackageContents)
|
env.On("FileContent", tc.File).Return(tc.PackageContents)
|
||||||
return env, props
|
return env, props
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPackage(t *testing.T) {
|
func TestPackage(t *testing.T) {
|
||||||
cases := []*MockData{
|
cases := []*MockData{
|
||||||
{Case: "1.0.0", ExpectedString: "\uf487 1.0.0", Name: "node", File: "package.json", PackageContents: "{\"version\":\"1.0.0\"}"},
|
{Case: "1.0.0 node.js", ExpectedString: "\uf487 1.0.0 test", Name: "node", File: "package.json", PackageContents: "{\"version\":\"1.0.0\",\"name\":\"test\"}"},
|
||||||
{Case: "3.2.1", ExpectedString: "\uf487 3.2.1", Name: "node", File: "package.json", PackageContents: "{\"version\":\"3.2.1\"}"},
|
{Case: "3.2.1 node.js", ExpectedString: "\uf487 3.2.1 test", Name: "node", File: "package.json", PackageContents: "{\"version\":\"3.2.1\",\"name\":\"test\"}"},
|
||||||
{Case: "No version present", ExpectedString: "", Name: "node", File: "package.json", PackageContents: "{}"},
|
{Case: "1.0.0 cargo", ExpectedString: "\uf487 1.0.0 test", Name: "cargo", File: "Cargo.toml", PackageContents: "[package]\nname=\"test\"\nversion=\"1.0.0\"\n"},
|
||||||
|
{Case: "3.2.1 cargo", ExpectedString: "\uf487 3.2.1 test", Name: "cargo", File: "Cargo.toml", PackageContents: "[package]\nname=\"test\"\nversion=\"3.2.1\"\n"},
|
||||||
|
{Case: "1.0.0 poetry", ExpectedString: "\uf487 1.0.0 test", Name: "poetry", File: "pyproject.toml", PackageContents: "[tool.poetry]\nname=\"test\"\nversion=\"1.0.0\"\n"},
|
||||||
|
{Case: "3.2.1 poetry", ExpectedString: "\uf487 3.2.1 test", Name: "poetry", File: "pyproject.toml", PackageContents: "[tool.poetry]\nname=\"test\"\nversion=\"3.2.1\"\n"},
|
||||||
|
{Case: "No version present node.js", ExpectedString: "test", Name: "node", File: "package.json", PackageContents: "{\"name\":\"test\"}"},
|
||||||
|
{Case: "No version present cargo", ExpectedString: "test", Name: "cargo", File: "Cargo.toml", PackageContents: "[package]\nname=\"test\"\n"},
|
||||||
|
{Case: "No version present poetry", ExpectedString: "test", Name: "poetry", File: "pyproject.toml", PackageContents: "[tool.poetry]\nname=\"test\"\n"},
|
||||||
|
{Case: "No name present node.js", ExpectedString: "\uf487 1.0.0", Name: "node", File: "package.json", PackageContents: "{\"version\":\"1.0.0\"}"},
|
||||||
|
{Case: "No name present cargo", ExpectedString: "\uf487 1.0.0", Name: "cargo", File: "Cargo.toml", PackageContents: "[package]\nversion=\"1.0.0\"\n"},
|
||||||
|
{Case: "No name present poetry", ExpectedString: "\uf487 1.0.0", Name: "poetry", File: "pyproject.toml", PackageContents: "[tool.poetry]\nversion=\"1.0.0\"\n"},
|
||||||
|
{Case: "Empty project package node.js", ExpectedString: "", Name: "node", File: "package.json", PackageContents: "{}"},
|
||||||
|
{Case: "Empty project package cargo", ExpectedString: "", Name: "cargo", File: "Cargo.toml", PackageContents: ""},
|
||||||
|
{Case: "Empty project package poetry", ExpectedString: "", Name: "poetry", File: "pyproject.toml", PackageContents: ""},
|
||||||
{Case: "Invalid json", ExpectedString: "invalid character '}' looking for beginning of value", Name: "node", File: "package.json", PackageContents: "}"},
|
{Case: "Invalid json", ExpectedString: "invalid character '}' looking for beginning of value", Name: "node", File: "package.json", PackageContents: "}"},
|
||||||
|
{Case: "Invalid toml", ExpectedString: "toml: line 1: unexpected end of table name (table names cannot be empty)", Name: "cargo", File: "Cargo.toml", PackageContents: "["},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
|
|
Loading…
Reference in a new issue