feat(language): expose version info

This commit is contained in:
Jan De Dobbeleer 2021-12-03 20:19:57 +01:00 committed by Jan De Dobbeleer
parent d477923f16
commit a24786b97d
15 changed files with 75 additions and 75 deletions

View file

@ -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"},

View file

@ -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"},

View file

@ -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"},

View file

@ -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"},

View file

@ -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"},

View file

@ -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"},

View file

@ -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{

View file

@ -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"},

View file

@ -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
}

View file

@ -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)

View file

@ -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",

View file

@ -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"},

View file

@ -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"},

View file

@ -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"},

View file

@ -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"},