mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-12-31 13:57:26 -08:00
feat(language): expose version info
This commit is contained in:
parent
d477923f16
commit
a24786b97d
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
type angular struct {
|
type angular struct {
|
||||||
language *language
|
language
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *angular) string() string {
|
func (a *angular) string() string {
|
||||||
|
@ -9,7 +9,7 @@ func (a *angular) string() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *angular) init(props properties, env environmentInfo) {
|
func (a *angular) init(props properties, env environmentInfo) {
|
||||||
a.language = &language{
|
a.language = language{
|
||||||
env: env,
|
env: env,
|
||||||
props: props,
|
props: props,
|
||||||
extensions: []string{"angular.json"},
|
extensions: []string{"angular.json"},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
type azfunc struct {
|
type azfunc struct {
|
||||||
language *language
|
language
|
||||||
}
|
}
|
||||||
|
|
||||||
func (az *azfunc) string() string {
|
func (az *azfunc) string() string {
|
||||||
|
@ -9,7 +9,7 @@ func (az *azfunc) string() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (az *azfunc) init(props properties, env environmentInfo) {
|
func (az *azfunc) init(props properties, env environmentInfo) {
|
||||||
az.language = &language{
|
az.language = language{
|
||||||
env: env,
|
env: env,
|
||||||
props: props,
|
props: props,
|
||||||
extensions: []string{"host.json", "local.settings.json", "function.json"},
|
extensions: []string{"host.json", "local.settings.json", "function.json"},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
type crystal struct {
|
type crystal struct {
|
||||||
language *language
|
language
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *crystal) string() string {
|
func (c *crystal) string() string {
|
||||||
|
@ -9,7 +9,7 @@ func (c *crystal) string() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *crystal) init(props properties, env environmentInfo) {
|
func (c *crystal) init(props properties, env environmentInfo) {
|
||||||
c.language = &language{
|
c.language = language{
|
||||||
env: env,
|
env: env,
|
||||||
props: props,
|
props: props,
|
||||||
extensions: []string{"*.cr", "shard.yml"},
|
extensions: []string{"*.cr", "shard.yml"},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
type dart struct {
|
type dart struct {
|
||||||
language *language
|
language
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dart) string() string {
|
func (d *dart) string() string {
|
||||||
|
@ -9,7 +9,7 @@ func (d *dart) string() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dart) init(props properties, env environmentInfo) {
|
func (d *dart) init(props properties, env environmentInfo) {
|
||||||
d.language = &language{
|
d.language = language{
|
||||||
env: env,
|
env: env,
|
||||||
props: props,
|
props: props,
|
||||||
extensions: []string{"*.dart", "pubspec.yaml", "pubspec.yml", "pubspec.lock", ".dart_tool"},
|
extensions: []string{"*.dart", "pubspec.yaml", "pubspec.yml", "pubspec.lock", ".dart_tool"},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
type dotnet struct {
|
type dotnet struct {
|
||||||
language *language
|
language
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -22,7 +22,7 @@ func (d *dotnet) string() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dotnet) init(props properties, env environmentInfo) {
|
func (d *dotnet) init(props properties, env environmentInfo) {
|
||||||
d.language = &language{
|
d.language = language{
|
||||||
env: env,
|
env: env,
|
||||||
props: props,
|
props: props,
|
||||||
extensions: []string{"*.cs", "*.csx", "*.vb", "*.sln", "*.csproj", "*.vbproj", "*.fs", "*.fsx", "*.fsproj", "global.json"},
|
extensions: []string{"*.cs", "*.csx", "*.vb", "*.sln", "*.csproj", "*.vbproj", "*.fs", "*.fsx", "*.fsproj", "global.json"},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
type golang struct {
|
type golang struct {
|
||||||
language *language
|
language
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *golang) string() string {
|
func (g *golang) string() string {
|
||||||
|
@ -9,7 +9,7 @@ func (g *golang) string() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *golang) init(props properties, env environmentInfo) {
|
func (g *golang) init(props properties, env environmentInfo) {
|
||||||
g.language = &language{
|
g.language = language{
|
||||||
env: env,
|
env: env,
|
||||||
props: props,
|
props: props,
|
||||||
extensions: []string{"*.go", "go.mod"},
|
extensions: []string{"*.go", "go.mod"},
|
||||||
|
|
|
@ -3,7 +3,7 @@ package main
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
type java struct {
|
type java struct {
|
||||||
language *language
|
language
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *java) string() string {
|
func (j *java) string() string {
|
||||||
|
@ -17,7 +17,7 @@ func (j *java) init(props properties, env environmentInfo) {
|
||||||
args: []string{"-Xinternalversion"},
|
args: []string{"-Xinternalversion"},
|
||||||
regex: javaRegex,
|
regex: javaRegex,
|
||||||
}
|
}
|
||||||
j.language = &language{
|
j.language = language{
|
||||||
env: env,
|
env: env,
|
||||||
props: props,
|
props: props,
|
||||||
extensions: []string{
|
extensions: []string{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
type julia struct {
|
type julia struct {
|
||||||
language *language
|
language
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *julia) string() string {
|
func (j *julia) string() string {
|
||||||
|
@ -9,7 +9,7 @@ func (j *julia) string() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *julia) init(props properties, env environmentInfo) {
|
func (j *julia) init(props properties, env environmentInfo) {
|
||||||
j.language = &language{
|
j.language = language{
|
||||||
env: env,
|
env: env,
|
||||||
props: props,
|
props: props,
|
||||||
extensions: []string{"*.jl"},
|
extensions: []string{"*.jl"},
|
||||||
|
|
|
@ -25,44 +25,23 @@ type cmd struct {
|
||||||
executable string
|
executable string
|
||||||
args []string
|
args []string
|
||||||
regex string
|
regex string
|
||||||
|
|
||||||
version
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cmd) parse(versionInfo string) error {
|
func (c *cmd) parse(versionInfo string) (*version, error) {
|
||||||
values := findNamedRegexMatch(c.regex, versionInfo)
|
values := findNamedRegexMatch(c.regex, versionInfo)
|
||||||
if len(values) == 0 {
|
if len(values) == 0 {
|
||||||
return errors.New("cannot parse version string")
|
return nil, errors.New("cannot parse version string")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.version.Full = values["version"]
|
version := &version{
|
||||||
c.version.Major = values["major"]
|
Full: values["version"],
|
||||||
c.version.Minor = values["minor"]
|
Major: values["major"],
|
||||||
c.version.Patch = values["patch"]
|
Minor: values["minor"],
|
||||||
c.version.Prerelease = values["prerelease"]
|
Patch: values["patch"],
|
||||||
c.version.BuildMetadata = values["buildmetadata"]
|
Prerelease: values["prerelease"],
|
||||||
return nil
|
BuildMetadata: values["buildmetadata"],
|
||||||
}
|
|
||||||
|
|
||||||
func (c *cmd) buildVersionURL(text, template string) string {
|
|
||||||
if template == "" {
|
|
||||||
return text
|
|
||||||
}
|
}
|
||||||
truncatingSprintf := func(str string, args ...interface{}) (string, error) {
|
return version, nil
|
||||||
n := strings.Count(str, "%s")
|
|
||||||
if n > len(args) {
|
|
||||||
return "", errors.New("Too many parameters")
|
|
||||||
}
|
|
||||||
if n == 0 {
|
|
||||||
return fmt.Sprintf(str, args...), nil
|
|
||||||
}
|
|
||||||
return fmt.Sprintf(str, args[:n]...), nil
|
|
||||||
}
|
|
||||||
version, err := truncatingSprintf(template, text, c.version.Major, c.version.Minor, c.version.Patch)
|
|
||||||
if err != nil {
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
return version
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type language struct {
|
type language struct {
|
||||||
|
@ -71,13 +50,14 @@ type language struct {
|
||||||
extensions []string
|
extensions []string
|
||||||
commands []*cmd
|
commands []*cmd
|
||||||
versionURLTemplate string
|
versionURLTemplate string
|
||||||
activeCommand *cmd
|
|
||||||
exitCode int
|
exitCode int
|
||||||
loadContext loadContext
|
loadContext loadContext
|
||||||
inContext inContext
|
inContext inContext
|
||||||
matchesVersionFile matchesVersionFile
|
matchesVersionFile matchesVersionFile
|
||||||
homeEnabled bool
|
homeEnabled bool
|
||||||
displayMode string
|
displayMode string
|
||||||
|
|
||||||
|
version
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -120,7 +100,7 @@ func (l *language) string() string {
|
||||||
segmentTemplate := l.props.getString(SegmentTemplate, "{{.Full}}")
|
segmentTemplate := l.props.getString(SegmentTemplate, "{{.Full}}")
|
||||||
template := &textTemplate{
|
template := &textTemplate{
|
||||||
Template: segmentTemplate,
|
Template: segmentTemplate,
|
||||||
Context: l.activeCommand.version,
|
Context: l.version,
|
||||||
Env: l.env,
|
Env: l.env,
|
||||||
}
|
}
|
||||||
text, err := template.render()
|
text, err := template.render()
|
||||||
|
@ -132,11 +112,11 @@ func (l *language) string() string {
|
||||||
versionURLTemplate := l.props.getString(VersionURLTemplate, "")
|
versionURLTemplate := l.props.getString(VersionURLTemplate, "")
|
||||||
// backward compatibility
|
// backward compatibility
|
||||||
if versionURLTemplate == "" {
|
if versionURLTemplate == "" {
|
||||||
text = l.activeCommand.buildVersionURL(text, l.versionURLTemplate)
|
text = l.buildVersionURL(text)
|
||||||
} else {
|
} else {
|
||||||
template := &textTemplate{
|
template := &textTemplate{
|
||||||
Template: versionURLTemplate,
|
Template: versionURLTemplate,
|
||||||
Context: l.activeCommand.version,
|
Context: l.version,
|
||||||
Env: l.env,
|
Env: l.env,
|
||||||
}
|
}
|
||||||
url, err := template.render()
|
url, err := template.render()
|
||||||
|
@ -203,19 +183,19 @@ func (l *language) setVersion() error {
|
||||||
if !l.env.hasCommand(command.executable) {
|
if !l.env.hasCommand(command.executable) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
version, err := l.env.runCommand(command.executable, command.args...)
|
versionStr, err := l.env.runCommand(command.executable, command.args...)
|
||||||
if exitErr, ok := err.(*commandError); ok {
|
if exitErr, ok := err.(*commandError); ok {
|
||||||
l.exitCode = exitErr.exitCode
|
l.exitCode = exitErr.exitCode
|
||||||
return fmt.Errorf("err executing %s with %s", command.executable, command.args)
|
return fmt.Errorf("err executing %s with %s", command.executable, command.args)
|
||||||
}
|
}
|
||||||
if version == "" {
|
if versionStr == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err = command.parse(version)
|
version, err := command.parse(versionStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("err parsing info from %s with %s", command.executable, version)
|
return fmt.Errorf("err parsing info from %s with %s", command.executable, versionStr)
|
||||||
}
|
}
|
||||||
l.activeCommand = command
|
l.version = *version
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errors.New(l.props.getString(MissingCommandText, ""))
|
return errors.New(l.props.getString(MissingCommandText, ""))
|
||||||
|
@ -245,3 +225,24 @@ func (l *language) setVersionFileMismatch() {
|
||||||
}
|
}
|
||||||
l.props[ForegroundOverride] = l.props.getColor(VersionMismatchColor, l.props.getColor(ForegroundOverride, ""))
|
l.props[ForegroundOverride] = l.props.getColor(VersionMismatchColor, l.props.getColor(ForegroundOverride, ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *language) buildVersionURL(text string) string {
|
||||||
|
if l.versionURLTemplate == "" {
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
truncatingSprintf := func(str string, args ...interface{}) (string, error) {
|
||||||
|
n := strings.Count(str, "%s")
|
||||||
|
if n > len(args) {
|
||||||
|
return "", errors.New("Too many parameters")
|
||||||
|
}
|
||||||
|
if n == 0 {
|
||||||
|
return fmt.Sprintf(str, args...), nil
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(str, args[:n]...), nil
|
||||||
|
}
|
||||||
|
version, err := truncatingSprintf(l.versionURLTemplate, text, l.version.Major, l.version.Minor, l.version.Patch)
|
||||||
|
if err != nil {
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
return version
|
||||||
|
}
|
||||||
|
|
|
@ -3,8 +3,9 @@ package main
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
type node struct {
|
type node struct {
|
||||||
language *language
|
|
||||||
packageManagerIcon string
|
packageManagerIcon string
|
||||||
|
|
||||||
|
language
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -22,7 +23,7 @@ func (n *node) string() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) init(props properties, env environmentInfo) {
|
func (n *node) init(props properties, env environmentInfo) {
|
||||||
n.language = &language{
|
n.language = language{
|
||||||
env: env,
|
env: env,
|
||||||
props: props,
|
props: props,
|
||||||
extensions: []string{"*.js", "*.ts", "package.json", ".nvmrc", "pnpm-workspace.yaml", ".pnpmfile.cjs", ".npmrc"},
|
extensions: []string{"*.js", "*.ts", "package.json", ".nvmrc", "pnpm-workspace.yaml", ".pnpmfile.cjs", ".npmrc"},
|
||||||
|
@ -64,9 +65,9 @@ func (n *node) matchesVersionFile() bool {
|
||||||
|
|
||||||
regex := fmt.Sprintf(
|
regex := fmt.Sprintf(
|
||||||
`(?im)^v?%s(\.?%s)?(\.?%s)?$`,
|
`(?im)^v?%s(\.?%s)?(\.?%s)?$`,
|
||||||
n.language.activeCommand.version.Major,
|
n.language.version.Major,
|
||||||
n.language.activeCommand.version.Minor,
|
n.language.version.Minor,
|
||||||
n.language.activeCommand.version.Patch,
|
n.language.version.Patch,
|
||||||
)
|
)
|
||||||
|
|
||||||
return matchString(regex, fileVersion)
|
return matchString(regex, fileVersion)
|
||||||
|
|
|
@ -33,12 +33,10 @@ func TestNodeMatchesVersionFile(t *testing.T) {
|
||||||
env.On("getFileContent", ".nvmrc").Return(tc.RCVersion)
|
env.On("getFileContent", ".nvmrc").Return(tc.RCVersion)
|
||||||
|
|
||||||
node := &node{
|
node := &node{
|
||||||
language: &language{
|
language: language{
|
||||||
env: env,
|
env: env,
|
||||||
activeCommand: &cmd{
|
|
||||||
version: nodeVersion,
|
version: nodeVersion,
|
||||||
},
|
},
|
||||||
},
|
|
||||||
}
|
}
|
||||||
assert.Equal(t, tc.Expected, node.matchesVersionFile(), tc.Case)
|
assert.Equal(t, tc.Expected, node.matchesVersionFile(), tc.Case)
|
||||||
}
|
}
|
||||||
|
@ -67,7 +65,7 @@ func TestNodeInContext(t *testing.T) {
|
||||||
env.On("hasFiles", "package-lock.json").Return(tc.hasNPM)
|
env.On("hasFiles", "package-lock.json").Return(tc.hasNPM)
|
||||||
env.On("hasFiles", "package.json").Return(tc.hasDefault)
|
env.On("hasFiles", "package.json").Return(tc.hasDefault)
|
||||||
node := &node{
|
node := &node{
|
||||||
language: &language{
|
language: language{
|
||||||
env: env,
|
env: env,
|
||||||
props: map[Property]interface{}{
|
props: map[Property]interface{}{
|
||||||
YarnIcon: "yarn",
|
YarnIcon: "yarn",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
type php struct {
|
type php struct {
|
||||||
language *language
|
language
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *php) string() string {
|
func (n *php) string() string {
|
||||||
|
@ -9,7 +9,7 @@ func (n *php) string() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *php) init(props properties, env environmentInfo) {
|
func (n *php) init(props properties, env environmentInfo) {
|
||||||
n.language = &language{
|
n.language = language{
|
||||||
env: env,
|
env: env,
|
||||||
props: props,
|
props: props,
|
||||||
extensions: []string{"*.php", "composer.json", "composer.lock", ".php-version"},
|
extensions: []string{"*.php", "composer.json", "composer.lock", ".php-version"},
|
||||||
|
|
|
@ -3,7 +3,7 @@ package main
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
type python struct {
|
type python struct {
|
||||||
language *language
|
language
|
||||||
venvName string
|
venvName string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ func (p *python) string() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *python) init(props properties, env environmentInfo) {
|
func (p *python) init(props properties, env environmentInfo) {
|
||||||
p.language = &language{
|
p.language = language{
|
||||||
env: env,
|
env: env,
|
||||||
props: props,
|
props: props,
|
||||||
extensions: []string{"*.py", "*.ipynb", "pyproject.toml", "venv.bak", "venv", ".venv"},
|
extensions: []string{"*.py", "*.ipynb", "pyproject.toml", "venv.bak", "venv", ".venv"},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
type ruby struct {
|
type ruby struct {
|
||||||
language *language
|
language
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ruby) string() string {
|
func (r *ruby) string() string {
|
||||||
|
@ -14,7 +14,7 @@ func (r *ruby) string() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ruby) init(props properties, env environmentInfo) {
|
func (r *ruby) init(props properties, env environmentInfo) {
|
||||||
r.language = &language{
|
r.language = language{
|
||||||
env: env,
|
env: env,
|
||||||
props: props,
|
props: props,
|
||||||
extensions: []string{"*.rb", "Rakefile", "Gemfile"},
|
extensions: []string{"*.rb", "Rakefile", "Gemfile"},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
type rust struct {
|
type rust struct {
|
||||||
language *language
|
language
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rust) string() string {
|
func (r *rust) string() string {
|
||||||
|
@ -9,7 +9,7 @@ func (r *rust) string() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rust) init(props properties, env environmentInfo) {
|
func (r *rust) init(props properties, env environmentInfo) {
|
||||||
r.language = &language{
|
r.language = language{
|
||||||
env: env,
|
env: env,
|
||||||
props: props,
|
props: props,
|
||||||
extensions: []string{"*.rs", "Cargo.toml", "Cargo.lock"},
|
extensions: []string{"*.rs", "Cargo.toml", "Cargo.lock"},
|
||||||
|
|
Loading…
Reference in a new issue