Skip to content

Commit

Permalink
fix: don't check language version in Enabled()
Browse files Browse the repository at this point in the history
fix: align dotnet segment with other languages
feat: missing command text + json schema updated
chore: doc updated
perf: cache executable path
chore: not supported version icon updated(previus one was unreadable)
  • Loading branch information
lnu authored and JanDeDobbeleer committed Dec 31, 2020
1 parent 07ac2c3 commit abfbb27
Show file tree
Hide file tree
Showing 22 changed files with 213 additions and 101 deletions.
3 changes: 2 additions & 1 deletion docs/docs/segment-dotnet.md
Expand Up @@ -27,5 +27,6 @@ Display the currently active .NET SDK version.

- display_version: `boolean` - display the active version or not; useful if all you need is an icon indicating `dotnet`
is present - defaults to `true`
- missing_command_text: `string` - text to display when the command is missing - default to ``
- unsupported_version_icon: `string` - text/icon that is displayed when the active .NET SDK version (e.g., one specified
by `global.json`) is not installed/supported - defaults to `\u2327` (X in a rectangle box)
by `global.json`) is not installed/supported - defaults to `\uf071` (X in a rectangle box)
1 change: 1 addition & 0 deletions docs/docs/segment-golang.md
Expand Up @@ -26,6 +26,7 @@ Display the currently active golang version when a folder contains `.go` files.
## Properties

- display_version: `boolean` - display the golang version - defaults to `true`
- missing_command_text: `string` - text to display when the command is missing - default to ``
- display_mode: `string` - determines when the segment is displayed
- `always`: The segment is always displayed
- `context`: The segment is only displayed when *.go or go.mod files are present (default)
Expand Down
1 change: 1 addition & 0 deletions docs/docs/segment-julia.md
Expand Up @@ -26,6 +26,7 @@ Display the currently active julia version when a folder contains `.jl` files.
## Properties

- display_version: `boolean` - display the julia version - defaults to `true`
- missing_command_text: `string` - text to display when the command is missing - default to ``
- display_mode: `string` - determines when the segment is displayed
- `always`: The segment is always displayed
- `context`: The segment is only displayed when *.jl files are present (default)
Expand Down
1 change: 1 addition & 0 deletions docs/docs/segment-node.md
Expand Up @@ -26,6 +26,7 @@ Display the currently active node version when a folder contains `.js` or `.ts`
## Properties

- display_version: `boolean` - display the node version - defaults to `true`
- missing_command_text: `string` - text to display when the command is missing - default to ``
- display_mode: `string` - determines when the segment is displayed
- `always`: The segment is always displayed
- `context`: The segment is only displayed when *.js, *.ts or package.json files are present (default)
Expand Down
2 changes: 2 additions & 0 deletions docs/docs/segment-python.md
Expand Up @@ -27,6 +27,8 @@ Supports conda, virtualenv and pyenv.
## Properties

- display_virtual_env: `boolean` - show the name of the virtualenv or not - defaults to `true`
- display_version: `boolean` - display the python version - defaults to `true`
- missing_command_text: `string` - text to display when the command is missing - default to ``
- display_mode: `string` - determines when the segment is displayed
- `always`: The segment is always displayed
- `context`: The segment is only displayed when *.py or *.ipynb files are present (default)
Expand Down
8 changes: 4 additions & 4 deletions src/environment.go
Expand Up @@ -39,7 +39,7 @@ type environmentInfo interface {
getHostName() (string, error)
getRuntimeGOOS() string
getPlatform() string
hasCommand(command string) bool
hasCommand(command string) (string, bool)
runCommand(command string, args ...string) (string, error)
runShellCommand(shell, command string) string
lastErrorCode() int
Expand Down Expand Up @@ -221,9 +221,9 @@ func (env *environment) runShellCommand(shell, command string) string {
return strings.TrimSpace(string(out))
}

func (env *environment) hasCommand(command string) bool {
_, err := exec.LookPath(command)
return err == nil
func (env *environment) hasCommand(command string) (string, bool) {
path, err := exec.LookPath(command)
return path, err == nil
}

func (env *environment) lastErrorCode() int {
Expand Down
5 changes: 3 additions & 2 deletions src/segment_az.go
Expand Up @@ -36,11 +36,12 @@ func (a *az) init(props *properties, env environmentInfo) {
}

func (a *az) enabled() bool {
if (!a.idEnabled() && !a.nameEnabled()) || !a.env.hasCommand("az") {
commandPath, commandExists := a.env.hasCommand("az")
if (!a.idEnabled() && !a.nameEnabled()) || !commandExists {
return false
}

output, _ := a.env.runCommand("az", "account", "show", "--query=[name,id]", "-o=tsv")
output, _ := a.env.runCommand(commandPath, "account", "show", "--query=[name,id]", "-o=tsv")
if output == "" {
return false
}
Expand Down
2 changes: 1 addition & 1 deletion src/segment_az_test.go
Expand Up @@ -18,7 +18,7 @@ type azArgs struct {

func bootStrapAzTest(args *azArgs) *az {
env := new(MockedEnvironment)
env.On("hasCommand", "az").Return(args.enabled)
env.On("hasCommand", "az").Return("az", args.enabled)
env.On("runCommand", "az", []string{"account", "show", "--query=[name,id]", "-o=tsv"}).Return(fmt.Sprintf("%s\n%s\n", args.subscriptionName, args.subscriptionID), nil)
props := &properties{
values: map[Property]interface{}{
Expand Down
3 changes: 2 additions & 1 deletion src/segment_command.go
Expand Up @@ -17,7 +17,8 @@ const (

func (c *command) enabled() bool {
shell := c.props.getString(ExecutableShell, "bash")
if !c.env.hasCommand(shell) {
shell, commandExists := c.env.hasCommand(shell)
if !commandExists {
return false
}
command := c.props.getString(Command, "echo no command specified")
Expand Down
53 changes: 17 additions & 36 deletions src/segment_dotnet.go
@@ -1,14 +1,7 @@
package main

import (
"errors"
)

type dotnet struct {
props *properties
env environmentInfo
activeVersion string
unsupportedVersion bool
language *language
}

const (
Expand All @@ -18,41 +11,29 @@ const (
)

func (d *dotnet) string() string {
if d.unsupportedVersion {
return d.props.getString(UnsupportedDotnetVersionIcon, "\u2327")
}
version := d.language.string()

if d.props.getBool(DisplayVersion, true) {
return d.activeVersion
// Exit code 145 is a special indicator that dotnet
// ran, but the current project config settings specify
// use of an SDK that isn't installed.
if d.language.exitCode == 145 {
return d.language.props.getString(UnsupportedDotnetVersionIcon, "\uf071 ")
}

return ""
return version
}

func (d *dotnet) init(props *properties, env environmentInfo) {
d.props = props
d.env = env
d.language = &language{
env: env,
props: props,
commands: []string{"dotnet"},
versionParam: "--version",
extensions: []string{"*.cs", "*.vb", "*.sln", "*.csproj", "*.vbproj"},
versionRegex: `(?P<version>[0-9]+.[0-9]+.[0-9]+)`,
}
}

func (d *dotnet) enabled() bool {
if !d.env.hasCommand("dotnet") {
return false
}

output, err := d.env.runCommand("dotnet", "--version")
if err == nil {
d.activeVersion = output
return true
}

// Exit code 145 is a special indicator that dotnet
// ran, but the current project config settings specify
// use of an SDK that isn't installed.
var exerr *commandError
if errors.As(err, &exerr) && exerr.exitCode == 145 {
d.unsupportedVersion = true
return true
}

return false
return d.language.enabled()
}
15 changes: 8 additions & 7 deletions src/segment_dotnet_test.go
Expand Up @@ -16,32 +16,33 @@ type dotnetArgs struct {

func bootStrapDotnetTest(args *dotnetArgs) *dotnet {
env := new(MockedEnvironment)
env.On("hasCommand", "dotnet").Return(args.enabled)
env.On("hasCommand", "dotnet").Return("dotnet", args.enabled)
if args.unsupported {
err := &commandError{exitCode: 145}
env.On("runCommand", "dotnet", []string{"--version"}).Return("", err)
} else {
env.On("runCommand", "dotnet", []string{"--version"}).Return(args.version, nil)
}

env.On("hasFiles", "*.cs").Return(true)
env.On("getPathSeperator", nil).Return("")
props := &properties{
values: map[Property]interface{}{
DisplayVersion: args.displayVersion,
UnsupportedDotnetVersionIcon: args.unsupportedIcon,
},
}
a := &dotnet{
env: env,
props: props,
}
return a
dotnet := &dotnet{}
dotnet.init(props, env)
return dotnet
}

func TestEnabledDotnetNotFound(t *testing.T) {
args := &dotnetArgs{
enabled: false,
}
dotnet := bootStrapDotnetTest(args)
assert.False(t, dotnet.enabled())
assert.True(t, dotnet.enabled())
}

func TestDotnetVersionNotDisplayed(t *testing.T) {
Expand Down
15 changes: 9 additions & 6 deletions src/segment_git.go
Expand Up @@ -47,9 +47,10 @@ func (s *gitStatus) string(prefix, color string) string {
}

type git struct {
props *properties
env environmentInfo
repo *gitRepo
props *properties
env environmentInfo
repo *gitRepo
commandPath string
}

const (
Expand Down Expand Up @@ -114,10 +115,12 @@ const (
)

func (g *git) enabled() bool {
if !g.env.hasCommand("git") {
commandPath, commandExists := g.env.hasCommand("git")
if !commandExists {
return false
}
output, _ := g.env.runCommand("git", "rev-parse", "--is-inside-work-tree")
g.commandPath = commandPath
output, _ := g.env.runCommand(g.commandPath, "rev-parse", "--is-inside-work-tree")
return output == "true"
}

Expand Down Expand Up @@ -235,7 +238,7 @@ func (g *git) getStatusColor(defaultValue string) string {

func (g *git) getGitCommandOutput(args ...string) string {
args = append([]string{"-c", "core.quotepath=false", "-c", "color.status=false"}, args...)
val, _ := g.env.runCommand("git", args...)
val, _ := g.env.runCommand(g.commandPath, args...)
return val
}

Expand Down
17 changes: 11 additions & 6 deletions src/segment_git_test.go
Expand Up @@ -12,7 +12,7 @@ const (

func TestEnabledGitNotFound(t *testing.T) {
env := new(MockedEnvironment)
env.On("hasCommand", "git").Return(false)
env.On("hasCommand", "git").Return("", false)
g := &git{
env: env,
}
Expand All @@ -21,7 +21,7 @@ func TestEnabledGitNotFound(t *testing.T) {

func TestEnabledInWorkingDirectory(t *testing.T) {
env := new(MockedEnvironment)
env.On("hasCommand", "git").Return(true)
env.On("hasCommand", "git").Return("git", true)
env.On("runCommand", "git", []string{"rev-parse", "--is-inside-work-tree"}).Return("true", nil)
g := &git{
env: env,
Expand All @@ -36,7 +36,8 @@ func TestGetGitOutputForCommand(t *testing.T) {
env := new(MockedEnvironment)
env.On("runCommand", "git", append(args, commandArgs...)).Return(want, nil)
g := &git{
env: env,
env: env,
commandPath: "git",
}
got := g.getGitCommandOutput(commandArgs...)
assert.Equal(t, want, got)
Expand Down Expand Up @@ -85,6 +86,7 @@ func setupHEADContextEnv(context *detachedContext) *git {
repo: &gitRepo{
root: "",
},
commandPath: "git",
}
return g
}
Expand Down Expand Up @@ -211,7 +213,8 @@ func TestGetStashContextZeroEntries(t *testing.T) {
env := new(MockedEnvironment)
env.On("runCommand", "git", []string{"-c", "core.quotepath=false", "-c", "color.status=false", "rev-list", "--walk-reflogs", "--count", "refs/stash"}).Return("", nil)
g := &git{
env: env,
env: env,
commandPath: "git",
}
got := g.getStashContext()
assert.Equal(t, want, got)
Expand All @@ -222,7 +225,8 @@ func TestGetStashContextMultipleEntries(t *testing.T) {
env := new(MockedEnvironment)
env.On("runCommand", "git", []string{"-c", "core.quotepath=false", "-c", "color.status=false", "rev-list", "--walk-reflogs", "--count", "refs/stash"}).Return("2", nil)
g := &git{
env: env,
env: env,
commandPath: "git",
}
got := g.getStashContext()
assert.Equal(t, want, got)
Expand Down Expand Up @@ -390,7 +394,8 @@ func bootstrapUpstreamTest(upstream string) *git {
repo: &gitRepo{
upstream: "origin/main",
},
props: props,
props: props,
commandPath: "git",
}
return g
}
Expand Down
5 changes: 3 additions & 2 deletions src/segment_kubectl.go
Expand Up @@ -16,9 +16,10 @@ func (k *kubectl) init(props *properties, env environmentInfo) {
}

func (k *kubectl) enabled() bool {
if !k.env.hasCommand("kubectl") {
commandPath, commandExists := k.env.hasCommand("kubectl")
if !commandExists {
return false
}
k.contextName, _ = k.env.runCommand("kubectl", "config", "current-context")
k.contextName, _ = k.env.runCommand(commandPath, "config", "current-context")
return k.contextName != ""
}
2 changes: 1 addition & 1 deletion src/segment_kubectl_test.go
Expand Up @@ -13,7 +13,7 @@ type kubectlArgs struct {

func bootStrapKubectlTest(args *kubectlArgs) *kubectl {
env := new(MockedEnvironment)
env.On("hasCommand", "kubectl").Return(args.enabled)
env.On("hasCommand", "kubectl").Return("kubectl", args.enabled)
env.On("runCommand", "kubectl", []string{"config", "current-context"}).Return(args.contextName, nil)
k := &kubectl{
env: env,
Expand Down

0 comments on commit abfbb27

Please sign in to comment.