diff --git a/docs/docs/segment-julia.md b/docs/docs/segment-julia.md new file mode 100644 index 000000000000..7d0f8776a7b8 --- /dev/null +++ b/docs/docs/segment-julia.md @@ -0,0 +1,28 @@ +--- +id: julia +title: Julia +sidebar_label: Julia +--- + +## What + +Display the currently active julia version when a folder contains `.jl` files. + +## Sample Configuration + +```json +{ + "type": "julia", + "style": "powerline", + "powerline_symbol": "\uE0B0", + "foreground": "#ffffff", + "background": "#4063D8", + "properties": { + "prefix": " \uE624 " + } +} +``` + +## Properties + +- display_version: `boolean` - display the julia version - defaults to `true` diff --git a/docs/sidebars.js b/docs/sidebars.js index 81babf1d2ae7..35488c44cf77 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -22,6 +22,7 @@ module.exports = { "exit", "git", "golang", + "julia", "kubectl", "node", "os", diff --git a/go.mod b/go.mod index f4a273f273e9..0efb2f4eff93 100644 --- a/go.mod +++ b/go.mod @@ -4,9 +4,14 @@ go 1.15 require ( github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect + github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 + github.com/alecthomas/colour v0.1.0 // indirect + github.com/alecthomas/repr v0.0.0-20201103221029-55c485bd663f // indirect github.com/distatus/battery v0.10.1-0.20200722221337-7e1bf2bbb15c github.com/go-ole/go-ole v1.2.4 // indirect github.com/gookit/color v1.3.1 + github.com/mattn/go-isatty v0.0.12 // indirect + github.com/sergi/go-diff v1.1.0 // indirect github.com/shirou/gopsutil v2.20.9+incompatible github.com/stretchr/objx v0.3.0 // indirect github.com/stretchr/testify v1.6.1 diff --git a/go.sum b/go.sum index a6e002085f99..9f5093d818c1 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,12 @@ github.com/JanDeDobbeleer/color v1.3.1-0.20201014085303-5ffcdf66388a h1:0gU8YI1Z github.com/JanDeDobbeleer/color v1.3.1-0.20201014085303-5ffcdf66388a/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U= +github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI= +github.com/alecthomas/colour v0.1.0 h1:nOE9rJm6dsZ66RGWYSFrXw461ZIt9A6+nHgL7FRrDUk= +github.com/alecthomas/colour v0.1.0/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0= +github.com/alecthomas/repr v0.0.0-20201103221029-55c485bd663f h1:jXPaiovuWmnCXfJ8UYiiLtI/LAJPnaZnoV+LfIDEJRc= +github.com/alecthomas/repr v0.0.0-20201103221029-55c485bd663f/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -15,17 +21,23 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shirou/gopsutil v2.20.9+incompatible h1:msXs2frUV+O/JLva9EDLpuJ84PrFsdCTCQex8PUdtkQ= github.com/shirou/gopsutil v2.20.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20190912141932-bc967efca4b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 h1:9UQO31fZ+0aKQOFldThf7BKPMJTiBfWycGh/u3UoO88= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= @@ -34,7 +46,11 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/segment.go b/segment.go index e29d45fc2531..27dd4167abbc 100644 --- a/segment.go +++ b/segment.go @@ -73,6 +73,8 @@ const ( Terraform SegmentType = "terraform" // Golang writes which go version is currently active Golang SegmentType = "go" + // Julia writes which julia version is currently active + Julia SegmentType = "julia" // Powerline writes it Powerline style Powerline SegmentStyle = "powerline" // Plain writes it without ornaments @@ -132,6 +134,7 @@ func (segment *Segment) mapSegmentWithWriter(env environmentInfo) error { Dotnet: &dotnet{}, Terraform: &terraform{}, Golang: &golang{}, + Julia: &julia{}, } if writer, ok := functions[segment.Type]; ok { props := &properties{ diff --git a/segment_golang.go b/segment_golang.go index f7b659fce57c..b1fb0a5fb15c 100644 --- a/segment_golang.go +++ b/segment_golang.go @@ -1,35 +1,24 @@ package main -import "regexp" - type golang struct { - props *properties - env environmentInfo - golangVersion string + language *language } func (g *golang) string() string { - if g.props.getBool(DisplayVersion, true) { - return g.golangVersion - } - return "" + return g.language.string() } func (g *golang) init(props *properties, env environmentInfo) { - g.props = props - g.env = env + g.language = &language{ + env: env, + props: props, + commands: []string{"go"}, + versionParam: "version", + extensions: []string{"*.go"}, + versionRegex: `go(?P[0-9]+.[0-9]+.[0-9]+)`, + } } func (g *golang) enabled() bool { - if !g.env.hasFiles("*.go") { - return false - } - if !g.env.hasCommand("go") { - return false - } - versionInfo, _ := g.env.runCommand("go", "version") - r := regexp.MustCompile(`go(?P[0-9]+.[0-9]+.[0-9]+)`) - values := groupDict(r, versionInfo) - g.golangVersion = values["version"] - return true + return g.language.enabled() } diff --git a/segment_golang_test.go b/segment_golang_test.go deleted file mode 100644 index a3959df2eebd..000000000000 --- a/segment_golang_test.go +++ /dev/null @@ -1,90 +0,0 @@ -package main - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -type golangArgs struct { - enabled bool - goVersion string - hasFiles bool - displayVersion bool -} - -func bootStrapGolangTest(args *golangArgs) *golang { - env := new(MockedEnvironment) - env.On("hasCommand", "go").Return(args.enabled) - env.On("runCommand", "go", []string{"version"}).Return(args.goVersion, nil) - env.On("hasFiles", "*.go").Return(args.hasFiles) - props := &properties{ - values: map[Property]interface{}{ - DisplayVersion: args.displayVersion, - }, - } - g := &golang{ - env: env, - props: props, - } - return g -} - -func TestGolangNoGoInstalled(t *testing.T) { - args := &golangArgs{ - enabled: false, - } - golang := bootStrapGolangTest(args) - assert.False(t, golang.enabled()) -} - -func TestGolangGoInstalledNoFiles(t *testing.T) { - args := &golangArgs{ - enabled: true, - hasFiles: false, - } - golang := bootStrapGolangTest(args) - assert.False(t, golang.enabled()) -} - -func TestGolangFilesNoGo(t *testing.T) { - args := &golangArgs{ - enabled: false, - hasFiles: true, - } - golang := bootStrapGolangTest(args) - assert.False(t, golang.enabled()) -} - -func TestGolangGoEnabled(t *testing.T) { - args := &golangArgs{ - enabled: true, - hasFiles: true, - } - golang := bootStrapGolangTest(args) - assert.True(t, golang.enabled()) -} - -func TestGolangGoEnabledWithVersion(t *testing.T) { - args := &golangArgs{ - enabled: true, - hasFiles: true, - displayVersion: true, - goVersion: "go version go1.15.3 darwin/amd64", - } - golang := bootStrapGolangTest(args) - assert.True(t, golang.enabled()) - assert.Equal(t, "1.15.3", golang.string()) -} - -func TestGolangGoEnabledWithoutVersion(t *testing.T) { - args := &golangArgs{ - enabled: true, - hasFiles: true, - displayVersion: false, - goVersion: "go version go1.15.3 darwin/amd64", - } - golang := bootStrapGolangTest(args) - assert.True(t, golang.enabled()) - assert.Equal(t, "", golang.string()) -} diff --git a/segment_julia.go b/segment_julia.go new file mode 100644 index 000000000000..e2cabeb223a5 --- /dev/null +++ b/segment_julia.go @@ -0,0 +1,24 @@ +package main + +type julia struct { + language *language +} + +func (j *julia) string() string { + return j.language.string() +} + +func (j *julia) init(props *properties, env environmentInfo) { + j.language = &language{ + env: env, + props: props, + commands: []string{"julia"}, + versionParam: "--version", + extensions: []string{"*.jl"}, + versionRegex: `julia version (?P[0-9]+.[0-9]+.[0-9]+)`, + } +} + +func (j *julia) enabled() bool { + return j.language.enabled() +} diff --git a/segment_language.go b/segment_language.go new file mode 100644 index 000000000000..c3fb14c31c25 --- /dev/null +++ b/segment_language.go @@ -0,0 +1,46 @@ +package main + +import "regexp" + +type language struct { + props *properties + env environmentInfo + extensions []string + commands []string + versionParam string + versionRegex string + version string +} + +func (l *language) string() string { + if l.props.getBool(DisplayVersion, true) { + return l.version + } + return "" +} + +func (l *language) enabled() bool { + for i, extension := range l.extensions { + if l.env.hasFiles(extension) { + break + } + if i == len(l.extensions)-1 { + return false + } + } + var executable string + for i, command := range l.commands { + if l.env.hasCommand(command) { + executable = command + break + } + if i == len(l.commands)-1 { + return false + } + } + versionInfo, _ := l.env.runCommand(executable, l.versionParam) + r := regexp.MustCompile(l.versionRegex) + values := groupDict(r, versionInfo) + l.version = values["version"] + return true +} diff --git a/segment_language_test.go b/segment_language_test.go new file mode 100644 index 000000000000..33d145f5bd48 --- /dev/null +++ b/segment_language_test.go @@ -0,0 +1,160 @@ +package main + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +const ( + universion = "1.3.3.7" + uni = "*.uni" + corn = "*.corn" +) + +type languageArgs struct { + version string + displayVersion bool + extensions []string + enabledExtensions []string + commands []string + enabledCommands []string + versionParam string + versionRegex string +} + +func (l *languageArgs) hasvalue(value string, list []string) bool { + for _, element := range list { + if element == value { + return true + } + } + return false +} + +func bootStrapLanguageTest(args *languageArgs) *language { + env := new(MockedEnvironment) + for _, command := range args.commands { + env.On("hasCommand", command).Return(args.hasvalue(command, args.enabledCommands)) + env.On("runCommand", command, []string{args.versionParam}).Return(args.version, nil) + } + for _, extension := range args.extensions { + env.On("hasFiles", extension).Return(args.hasvalue(extension, args.enabledExtensions)) + } + props := &properties{ + values: map[Property]interface{}{ + DisplayVersion: args.displayVersion, + }, + } + l := &language{ + props: props, + env: env, + extensions: args.extensions, + commands: args.commands, + versionParam: args.versionParam, + versionRegex: args.versionRegex, + } + return l +} + +func TestLanguageFilesFoundButNoCommand(t *testing.T) { + args := &languageArgs{ + commands: []string{"unicorn"}, + versionParam: "--version", + extensions: []string{uni}, + enabledExtensions: []string{uni}, + } + lang := bootStrapLanguageTest(args) + assert.False(t, lang.enabled(), "unicorn is not available") +} + +func TestLanguageDisabledNoFiles(t *testing.T) { + args := &languageArgs{ + versionParam: "--version", + commands: []string{"unicorn"}, + enabledCommands: []string{"unicorn"}, + extensions: []string{uni}, + } + lang := bootStrapLanguageTest(args) + assert.False(t, lang.enabled(), "no files in the current directory") +} + +func TestLanguageEnabledOneExtensionFound(t *testing.T) { + args := &languageArgs{ + versionParam: "--version", + commands: []string{"unicorn"}, + enabledCommands: []string{"unicorn"}, + extensions: []string{uni, corn}, + enabledExtensions: []string{uni}, + versionRegex: "(?P.*)", + version: universion, + displayVersion: true, + } + lang := bootStrapLanguageTest(args) + assert.True(t, lang.enabled()) + assert.Equal(t, universion, lang.string(), "unicorn is available and uni files are found") +} + +func TestLanguageEnabledSecondExtensionFound(t *testing.T) { + args := &languageArgs{ + versionParam: "--version", + commands: []string{"unicorn"}, + enabledCommands: []string{"unicorn"}, + extensions: []string{uni, corn}, + versionRegex: "(?P.*)", + version: universion, + enabledExtensions: []string{corn}, + displayVersion: true, + } + lang := bootStrapLanguageTest(args) + assert.True(t, lang.enabled()) + assert.Equal(t, universion, lang.string(), "unicorn is available and corn files are found") +} + +func TestLanguageEnabledSecondCommand(t *testing.T) { + args := &languageArgs{ + versionParam: "--version", + commands: []string{"uni", "corn"}, + enabledCommands: []string{"corn"}, + extensions: []string{uni, corn}, + versionRegex: "(?P.*)", + version: universion, + enabledExtensions: []string{corn}, + displayVersion: true, + } + lang := bootStrapLanguageTest(args) + assert.True(t, lang.enabled()) + assert.Equal(t, universion, lang.string(), "unicorn is available and corn files are found") +} + +func TestLanguageEnabledAllExtensionsFound(t *testing.T) { + args := &languageArgs{ + versionParam: "--version", + commands: []string{"unicorn"}, + enabledCommands: []string{"unicorn"}, + extensions: []string{uni, corn}, + versionRegex: "(?P.*)", + version: universion, + enabledExtensions: []string{uni, corn}, + displayVersion: true, + } + lang := bootStrapLanguageTest(args) + assert.True(t, lang.enabled()) + assert.Equal(t, universion, lang.string(), "unicorn is available and uni and corn files are found") +} + +func TestLanguageEnabledNoVersion(t *testing.T) { + args := &languageArgs{ + versionParam: "--version", + commands: []string{"unicorn"}, + enabledCommands: []string{"unicorn"}, + extensions: []string{uni, corn}, + versionRegex: "(?P.*)", + version: universion, + enabledExtensions: []string{uni, corn}, + displayVersion: false, + } + lang := bootStrapLanguageTest(args) + assert.True(t, lang.enabled()) + assert.Equal(t, "", lang.string(), "unicorn is available and uni and corn files are found") +} diff --git a/segment_node.go b/segment_node.go index 251985b3ac0a..def042d486c5 100644 --- a/segment_node.go +++ b/segment_node.go @@ -1,30 +1,24 @@ package main type node struct { - props *properties - env environmentInfo - nodeVersion string + language *language } func (n *node) string() string { - if n.props.getBool(DisplayVersion, true) { - return n.nodeVersion - } - return "" + return n.language.string() } func (n *node) init(props *properties, env environmentInfo) { - n.props = props - n.env = env + n.language = &language{ + env: env, + props: props, + commands: []string{"node"}, + versionParam: "--version", + extensions: []string{"*.js", "*.ts"}, + versionRegex: `(?P[0-9]+.[0-9]+.[0-9]+)`, + } } func (n *node) enabled() bool { - if !n.env.hasFiles("*.js") && !n.env.hasFiles("*.ts") { - return false - } - if !n.env.hasCommand("node") { - return false - } - n.nodeVersion, _ = n.env.runCommand("node", "--version") - return true + return n.language.enabled() } diff --git a/segment_node_test.go b/segment_node_test.go deleted file mode 100644 index f9fc4fabb7cf..000000000000 --- a/segment_node_test.go +++ /dev/null @@ -1,119 +0,0 @@ -package main - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -const ( - node114 = "1.14" -) - -type nodeArgs struct { - enabled bool - nodeVersion string - hasJS bool - hasTS bool - displayVersion bool -} - -func bootStrapNodeTest(args *nodeArgs) *node { - env := new(MockedEnvironment) - env.On("hasCommand", "node").Return(args.enabled) - env.On("runCommand", "node", []string{"--version"}).Return(args.nodeVersion, nil) - env.On("hasFiles", "*.js").Return(args.hasJS) - env.On("hasFiles", "*.ts").Return(args.hasTS) - props := &properties{ - values: map[Property]interface{}{ - DisplayVersion: args.displayVersion, - }, - } - n := &node{ - env: env, - props: props, - } - return n -} - -func TestNodeWriterDisabled(t *testing.T) { - args := &nodeArgs{ - enabled: false, - } - node := bootStrapNodeTest(args) - assert.False(t, node.enabled(), "node is not available") -} - -func TestNodeWriterDisabledNoJSorTSFiles(t *testing.T) { - args := &nodeArgs{ - enabled: true, - } - node := bootStrapNodeTest(args) - assert.False(t, node.enabled(), "no JS or TS files in the current directory") -} - -func TestNodeEnabledJSFiles(t *testing.T) { - expected := node114 - args := &nodeArgs{ - enabled: true, - nodeVersion: expected, - hasJS: true, - displayVersion: true, - } - node := bootStrapNodeTest(args) - assert.True(t, node.enabled()) - assert.Equal(t, expected, node.string(), "node is available and JS files are found") -} - -func TestNodeEnabledTsFiles(t *testing.T) { - expected := node114 - args := &nodeArgs{ - enabled: true, - nodeVersion: expected, - hasTS: true, - displayVersion: true, - } - node := bootStrapNodeTest(args) - assert.True(t, node.enabled()) - assert.Equal(t, expected, node.string(), "node is available and TS files are found") -} - -func TestNodeEnabledJsAndTsFiles(t *testing.T) { - expected := node114 - args := &nodeArgs{ - enabled: true, - nodeVersion: expected, - hasJS: true, - hasTS: true, - displayVersion: true, - } - node := bootStrapNodeTest(args) - assert.True(t, node.enabled()) - assert.Equal(t, expected, node.string(), "node is available and JS and TS files are found") -} - -func TestNodeEnabledNoVersion(t *testing.T) { - expected := "" - args := &nodeArgs{ - enabled: true, - nodeVersion: node114, - hasJS: true, - displayVersion: false, - } - node := bootStrapNodeTest(args) - assert.True(t, node.enabled()) - assert.Equal(t, expected, node.string(), "we don't expect a version") -} - -func TestNodeEnabledNodeVersion(t *testing.T) { - expected := node114 - args := &nodeArgs{ - enabled: true, - nodeVersion: expected, - hasJS: true, - displayVersion: true, - } - node := bootStrapNodeTest(args) - assert.True(t, node.enabled()) - assert.Equal(t, expected, node.string(), "we expect a version") -} diff --git a/segment_python.go b/segment_python.go index 6deb41d3418d..66443705388e 100644 --- a/segment_python.go +++ b/segment_python.go @@ -1,16 +1,10 @@ package main -import ( - "fmt" - "regexp" - "strings" -) +import "fmt" type python struct { - props *properties - env environmentInfo - venvName string - pythonVersion string + language *language + venvName string } const ( @@ -19,38 +13,31 @@ const ( ) func (p *python) string() string { - if p.venvName == "" || !p.props.getBool(DisplayVirtualEnv, true) { - return p.pythonVersion + if p.venvName == "" || !p.language.props.getBool(DisplayVirtualEnv, true) { + return p.language.string() + } + version := p.language.string() + if version == "" { + return p.venvName } - return fmt.Sprintf("%s %s", p.venvName, p.pythonVersion) + return fmt.Sprintf("%s %s", p.venvName, version) } func (p *python) init(props *properties, env environmentInfo) { - p.props = props - p.env = env + p.language = &language{ + env: env, + props: props, + commands: []string{"python", "python3"}, + versionParam: "--version", + extensions: []string{"*.py", "*.ipynb"}, + versionRegex: `Python (?P[0-9]+.[0-9]+.[0-9]+)`, + } } func (p *python) enabled() bool { - if !p.env.hasFiles("*.py") && !p.env.hasFiles("*.ipynb") { + if !p.language.enabled() { return false } - pythonVersions := []string{ - "python3", - "python", - } - for index, python := range pythonVersions { - version, _ := p.env.runCommand(python, "--version") - if version != "" { - re := regexp.MustCompile(`Python (?P[0-9]+.[0-9]+.[0-9]+)`) - values := groupDict(re, version) - p.pythonVersion = strings.Trim(values["version"], " ") - break - } - // last element, Python isn't installed on this machine - if index == len(pythonVersions)-1 { - return false - } - } venvVars := []string{ "VIRTUAL_ENV", "CONDA_ENV_PATH", @@ -59,9 +46,9 @@ func (p *python) enabled() bool { } var venv string for _, venvVar := range venvVars { - venv = p.env.getenv(venvVar) + venv = p.language.env.getenv(venvVar) if venv != "" { - p.venvName = base(venv, p.env) + p.venvName = base(venv, p.language.env) break } } diff --git a/segment_python_test.go b/segment_python_test.go index 3c8179dcbc17..89273cac5610 100644 --- a/segment_python_test.go +++ b/segment_python_test.go @@ -1,10 +1,9 @@ package main import ( - "fmt" "testing" - "github.com/stretchr/testify/assert" + "github.com/alecthomas/assert" ) type pythonArgs struct { @@ -12,193 +11,78 @@ type pythonArgs struct { condaEnvName string condaDefaultName string pyEnvName string - pathSeparator string - pythonVersion string - python3Version string - hasPyFiles bool - hasNotebookFiles bool -} - -func newPythonArgs() *pythonArgs { - return &pythonArgs{ - virtualEnvName: "", - condaEnvName: "", - condaDefaultName: "", - pyEnvName: "", - pathSeparator: "/", - pythonVersion: "", - python3Version: "", - hasPyFiles: true, - hasNotebookFiles: true, - } + displayVersion bool } func bootStrapPythonTest(args *pythonArgs) *python { env := new(MockedEnvironment) - env.On("hasFiles", "*.py").Return(args.hasPyFiles) - env.On("hasFiles", "*.ipynb").Return(args.hasNotebookFiles) - env.On("runCommand", "python", []string{"--version"}).Return(args.pythonVersion, nil) - env.On("runCommand", "python3", []string{"--version"}).Return(args.python3Version, nil) + env.On("hasCommand", "python").Return(true) + env.On("runCommand", "python", []string{"--version"}).Return("Python 3.8.4", nil) + env.On("hasFiles", "*.py").Return(true) env.On("getenv", "VIRTUAL_ENV").Return(args.virtualEnvName) env.On("getenv", "CONDA_ENV_PATH").Return(args.condaEnvName) env.On("getenv", "CONDA_DEFAULT_ENV").Return(args.condaDefaultName) env.On("getenv", "PYENV_VERSION").Return(args.pyEnvName) - env.On("getPathSeperator", nil).Return(args.pathSeparator) - python := &python{ - env: env, - } - return python -} - -const ( - python345 = "Python 3.4.5" -) - -func TestPythonWriterDisabledNoPythonFiles(t *testing.T) { - args := newPythonArgs() - args.hasPyFiles = false - args.hasNotebookFiles = false - args.python3Version = python345 - python := bootStrapPythonTest(args) - assert.False(t, python.enabled(), "there are no Python files in the current folder") -} - -func TestPythonWriterDisabledHasPythonFiles(t *testing.T) { - args := newPythonArgs() - args.hasPyFiles = true - args.hasNotebookFiles = false - args.python3Version = python345 - python := bootStrapPythonTest(args) - assert.True(t, python.enabled(), "there should be a Python file in the current folder") -} - -func TestPythonWriterDisabledHasJupyterNotebookFiles(t *testing.T) { - args := newPythonArgs() - args.hasPyFiles = false - args.hasNotebookFiles = true - args.python3Version = python345 - python := bootStrapPythonTest(args) - assert.True(t, python.enabled(), "there should be a Jupyter Notebook file in the current folder") -} - -func TestPythonWriterDisabledHasPyAndJupyterNotebookFiles(t *testing.T) { - args := newPythonArgs() - args.hasPyFiles = true - args.hasNotebookFiles = true - args.python3Version = python345 - python := bootStrapPythonTest(args) - assert.True(t, python.enabled(), "there should be a Jupyter Notebook file in the current folder") -} - -func TestPythonWriterDisabledHasPyAndJupyterNotebookFilesButNoVersion(t *testing.T) { - args := newPythonArgs() - args.hasPyFiles = true - args.hasNotebookFiles = true - python := bootStrapPythonTest(args) - assert.False(t, python.enabled(), "there should be a Jupyter Notebook file in the current folder") -} - -func TestPythonWriterDisabledNoPythonInstalled(t *testing.T) { - args := newPythonArgs() - python := bootStrapPythonTest(args) - assert.False(t, python.enabled(), "Python isn't installed") -} - -func TestPythonWriterEnabledNoVirtualEnv(t *testing.T) { - args := newPythonArgs() - args.python3Version = python345 - python := bootStrapPythonTest(args) - assert.True(t, python.enabled()) - assert.Equal(t, "3.4.5", python.string()) -} - -func TestPythonWriterEnabledVirtualEnvOverrule(t *testing.T) { - args := newPythonArgs() - args.python3Version = python345 - args.condaEnvName = "myenv" - props := &properties{ - values: map[Property]interface{}{ - DisplayVirtualEnv: false, - }, - } - python := bootStrapPythonTest(args) - python.props = props - assert.True(t, python.enabled()) - assert.Equal(t, "3.4.5", python.string()) -} - -func TestPythonWriterEnabledVirtualEnv(t *testing.T) { - args := newPythonArgs() - args.python3Version = python345 - args.condaEnvName = "myenv" - expected := fmt.Sprintf("%s %s", args.condaEnvName, "3.4.5") + env.On("getPathSeperator", nil).Return("") props := &properties{ values: map[Property]interface{}{ + DisplayVersion: args.displayVersion, DisplayVirtualEnv: true, }, } - python := bootStrapPythonTest(args) - python.props = props - assert.True(t, python.enabled()) - assert.Equal(t, expected, python.string()) + python := &python{} + python.init(props, env) + return python } -func TestPythonWriterEnabledWithVirtualEnv(t *testing.T) { - args := newPythonArgs() - args.virtualEnvName = "venv" - args.python3Version = python345 - expected := fmt.Sprintf("%s %s", args.virtualEnvName, "3.4.5") +func TestPythonVertualEnv(t *testing.T) { + expected := "VENV" + args := &pythonArgs{ + virtualEnvName: expected, + } python := bootStrapPythonTest(args) assert.True(t, python.enabled()) assert.Equal(t, expected, python.string()) } -func TestPythonWriterEnabledWithCondaEnvPath(t *testing.T) { - args := newPythonArgs() - args.condaEnvName = "conda" - args.python3Version = "Python 3.4.5 something off about this one" - expected := fmt.Sprintf("%s %s", args.condaEnvName, "3.4.5") +func TestPythonCondaEnv(t *testing.T) { + expected := "CONDA" + args := &pythonArgs{ + condaEnvName: expected, + } python := bootStrapPythonTest(args) assert.True(t, python.enabled()) assert.Equal(t, expected, python.string()) } -func TestPythonWriterEnabledWithCondaDefaultEnv(t *testing.T) { - args := newPythonArgs() - args.condaDefaultName = "conda2" - args.python3Version = python345 - expected := fmt.Sprintf("%s %s", args.condaDefaultName, "3.4.5") +func TestPythonCondaDefaultName(t *testing.T) { + expected := "CONDADEF" + args := &pythonArgs{ + condaDefaultName: expected, + } python := bootStrapPythonTest(args) assert.True(t, python.enabled()) assert.Equal(t, expected, python.string()) } -func TestPythonWriterEnabledWithCondaDefaultEnvAnacondaInc(t *testing.T) { - args := newPythonArgs() - args.condaDefaultName = "flatland_rl" - args.pythonVersion = "Python 3.6.8 :: Anaconda, Inc." - expected := "flatland_rl 3.6.8" +func TestPythonPyEnv(t *testing.T) { + expected := "PYENV" + args := &pythonArgs{ + pyEnvName: expected, + } python := bootStrapPythonTest(args) assert.True(t, python.enabled()) assert.Equal(t, expected, python.string()) } -func TestPythonWriterEnabledWithTwoValidEnvs(t *testing.T) { - args := newPythonArgs() - args.condaEnvName = "conda" - args.condaDefaultName = "conda2" - args.python3Version = python345 - expected := fmt.Sprintf("%s %s", args.condaEnvName, "3.4.5") +func TestPythonPyEnvWithVersion(t *testing.T) { + expected := "PYENV 3.8.4" + args := &pythonArgs{ + pyEnvName: "PYENV", + displayVersion: true, + } python := bootStrapPythonTest(args) assert.True(t, python.enabled()) + assert.Equal(t, "3.8.4", python.language.version) assert.Equal(t, expected, python.string()) } - -func TestPythonWriterNameTrailingSlash(t *testing.T) { - args := newPythonArgs() - args.virtualEnvName = "python/" - args.pythonVersion = "Python 2.7.3" - python := bootStrapPythonTest(args) - assert.True(t, python.enabled()) - assert.Equal(t, "python", python.venvName) -}