diff --git a/src/segment_angular.go b/src/segment_angular.go index 1723a15b..52ffa21c 100644 --- a/src/segment_angular.go +++ b/src/segment_angular.go @@ -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"}, diff --git a/src/segment_az_functions.go b/src/segment_az_functions.go index c6143cc9..397fc2ae 100644 --- a/src/segment_az_functions.go +++ b/src/segment_az_functions.go @@ -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"}, diff --git a/src/segment_crystal.go b/src/segment_crystal.go index 99a5ba0b..caef827a 100644 --- a/src/segment_crystal.go +++ b/src/segment_crystal.go @@ -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"}, diff --git a/src/segment_dart.go b/src/segment_dart.go index 69683296..a653f930 100644 --- a/src/segment_dart.go +++ b/src/segment_dart.go @@ -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"}, diff --git a/src/segment_dotnet.go b/src/segment_dotnet.go index 3217bc1b..50fb4255 100644 --- a/src/segment_dotnet.go +++ b/src/segment_dotnet.go @@ -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"}, diff --git a/src/segment_golang.go b/src/segment_golang.go index 437354d6..c8a620a5 100644 --- a/src/segment_golang.go +++ b/src/segment_golang.go @@ -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"}, diff --git a/src/segment_java.go b/src/segment_java.go index b179a3c0..c3aa2ba9 100644 --- a/src/segment_java.go +++ b/src/segment_java.go @@ -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{ diff --git a/src/segment_julia.go b/src/segment_julia.go index c49ee2f1..b67f9599 100644 --- a/src/segment_julia.go +++ b/src/segment_julia.go @@ -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"}, diff --git a/src/segment_language.go b/src/segment_language.go index 6fa84a2c..d9ced7b2 100644 --- a/src/segment_language.go +++ b/src/segment_language.go @@ -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 +} diff --git a/src/segment_node.go b/src/segment_node.go index bfef9ac1..1a3fc1f1 100644 --- a/src/segment_node.go +++ b/src/segment_node.go @@ -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) diff --git a/src/segment_node_test.go b/src/segment_node_test.go index de14b3ba..ecc183f3 100644 --- a/src/segment_node_test.go +++ b/src/segment_node_test.go @@ -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", diff --git a/src/segment_php.go b/src/segment_php.go index d2a55198..04304f70 100644 --- a/src/segment_php.go +++ b/src/segment_php.go @@ -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"}, diff --git a/src/segment_python.go b/src/segment_python.go index fd8e7b3d..c36010ed 100644 --- a/src/segment_python.go +++ b/src/segment_python.go @@ -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"}, diff --git a/src/segment_ruby.go b/src/segment_ruby.go index 8178932f..d37cc6d3 100644 --- a/src/segment_ruby.go +++ b/src/segment_ruby.go @@ -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"}, diff --git a/src/segment_rust.go b/src/segment_rust.go index 730bf4ff..b2f094e0 100644 --- a/src/segment_rust.go +++ b/src/segment_rust.go @@ -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"},