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