diff --git a/src/segment.go b/src/segment.go index b3012a6b..607b4f98 100644 --- a/src/segment.go +++ b/src/segment.go @@ -88,6 +88,8 @@ const ( YTM SegmentType = "ytm" // ExecutionTime writes the execution time of the last run command ExecutionTime SegmentType = "executiontime" + // Ruby writes which ruby version is currently active + Ruby SegmentType = "ruby" ) func (segment *Segment) string() string { @@ -144,6 +146,7 @@ func (segment *Segment) mapSegmentWithWriter(env environmentInfo) error { Julia: &julia{}, YTM: &ytm{}, ExecutionTime: &executiontime{}, + Ruby: &ruby{}, } if writer, ok := functions[segment.Type]; ok { props := &properties{ diff --git a/src/segment_ruby.go b/src/segment_ruby.go new file mode 100644 index 00000000..bcfe3fa2 --- /dev/null +++ b/src/segment_ruby.go @@ -0,0 +1,56 @@ +package main + +type ruby struct { + props *properties + env environmentInfo + version string +} + +func (r *ruby) string() string { + if r.props.getBool(DisplayVersion, true) { + return r.version + } + return "" +} + +func (r *ruby) init(props *properties, env environmentInfo) { + r.props = props + r.env = env +} + +func (r *ruby) enabled() bool { + if !r.env.hasFiles("*.rb") && !r.env.hasFiles("Rakefile") && !r.env.hasFiles("Gemfile") { + return false + } + if !r.props.getBool(DisplayVersion, true) { + return true + } + r.version = r.getVersion() + return r.version != "" +} + +func (r *ruby) getVersion() string { + options := []struct { + Command string + Args []string + Regex string + }{ + {Command: "rbenv", Args: []string{"version-name"}, Regex: `(?P.+)`}, + {Command: "rvm-prompt", Args: []string{"i", "v", "g"}, Regex: `(?P.+)`}, + {Command: "chruby", Args: []string(nil), Regex: `\* (?P.+)\n`}, + {Command: "asdf", Args: []string{"current", "ruby"}, Regex: `ruby\s+(?P[^\s_]+)\s+`}, + {Command: "ruby", Args: []string{"--version"}, Regex: `ruby\s+(?P[^\s_]+)\s+`}, + } + for _, option := range options { + if !r.env.hasCommand(option.Command) { + continue + } + version, _ := r.env.runCommand(option.Command, option.Args...) + match := findNamedRegexMatch(option.Regex, version) + if match["version"] == "" { + continue + } + return match["version"] + } + return "" +} diff --git a/src/segment_ruby_test.go b/src/segment_ruby_test.go new file mode 100755 index 00000000..094eb8dd --- /dev/null +++ b/src/segment_ruby_test.go @@ -0,0 +1,97 @@ +package main + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestRuby(t *testing.T) { + cases := []struct { + ExpectedString string + ExpectedEnabled bool + HasRbenv bool + HasRvmprompt bool + HasChruby bool + HasAsdf bool + HasRuby bool + Version string + HasRubyFiles bool + HasRakeFile bool + HasGemFile bool + DisplayVersion bool + }{ + {ExpectedString: "", ExpectedEnabled: false}, + {ExpectedString: "", ExpectedEnabled: true, DisplayVersion: false, HasRubyFiles: true}, + {ExpectedString: "", ExpectedEnabled: true, DisplayVersion: false, HasRakeFile: true}, + {ExpectedString: "", ExpectedEnabled: true, DisplayVersion: false, HasGemFile: true}, + {ExpectedString: "", ExpectedEnabled: false, DisplayVersion: true, HasGemFile: true}, + {ExpectedString: "", ExpectedEnabled: false, DisplayVersion: true}, + { + ExpectedString: "ruby-2.6.3", + ExpectedEnabled: true, + DisplayVersion: true, + HasRubyFiles: true, + HasChruby: true, + Version: ` * ruby-2.6.3 + ruby-1.9.3-p392 + jruby-1.7.0 + rubinius-2.0.0-rc1`, + }, + { + ExpectedString: "ruby-1.9.3-p392", + ExpectedEnabled: true, + DisplayVersion: true, + HasRubyFiles: true, + HasChruby: true, + Version: ` ruby-2.6.3 + * ruby-1.9.3-p392 + jruby-1.7.0 + rubinius-2.0.0-rc1`, + }, + { + ExpectedString: "2.6.3", + ExpectedEnabled: true, + DisplayVersion: true, + HasRubyFiles: true, + HasAsdf: true, + Version: "ruby 2.6.3 /Users/jan/Projects/oh-my-posh3/.tool-versions", + }, + { + ExpectedString: "", + ExpectedEnabled: false, + DisplayVersion: true, + HasRubyFiles: true, + HasAsdf: true, + Version: "ruby ______ No version set. Run \"asdf ruby \"", + }, + } + for _, tc := range cases { + env := new(MockedEnvironment) + env.On("hasCommand", "rbenv").Return(tc.HasRbenv) + env.On("runCommand", "rbenv", []string{"version-name"}).Return(tc.Version, nil) + env.On("hasCommand", "rvm-prompt").Return(tc.HasRvmprompt) + env.On("runCommand", "rvm-prompt", []string{"i", "v", "g"}).Return(tc.Version, nil) + env.On("hasCommand", "chruby").Return(tc.HasChruby) + env.On("runCommand", "chruby", []string(nil)).Return(tc.Version, nil) + env.On("hasCommand", "asdf").Return(tc.HasAsdf) + env.On("runCommand", "asdf", []string{"current", "ruby"}).Return(tc.Version, nil) + env.On("hasCommand", "ruby").Return(tc.HasRuby) + env.On("runCommand", "ruby", []string{"--version"}).Return(tc.Version, nil) + env.On("hasFiles", "*.rb").Return(tc.HasRubyFiles) + env.On("hasFiles", "Rakefile").Return(tc.HasRakeFile) + env.On("hasFiles", "Gemfile").Return(tc.HasGemFile) + props := &properties{ + values: map[Property]interface{}{ + DisplayVersion: tc.DisplayVersion, + }, + } + ruby := &ruby{ + env: env, + props: props, + } + assert.Equal(t, tc.ExpectedEnabled, ruby.enabled(), fmt.Sprintf("Failed in case: %+v", tc)) + assert.Equal(t, tc.ExpectedString, ruby.string(), fmt.Sprintf("Failed in case: %+v", tc)) + } +} diff --git a/themes/schema.json b/themes/schema.json index 945cf0a4..0c6361cc 100644 --- a/themes/schema.json +++ b/themes/schema.json @@ -135,6 +135,7 @@ "terraform", "go", "julia", + "ruby", "ytm", "executiontime" ] @@ -670,6 +671,32 @@ } } }, + { + "if": { + "properties": { + "type": { "const": "ruby" } + } + }, + "then": { + "title": "Ruby Segment", + "description": "https://ohmyposh.dev/docs/ruby", + "properties": { + "properties": { + "properties": { + "display_version": { + "$ref": "#/definitions/display_version" + }, + "display_mode": { + "$ref": "#/definitions/display_mode" + }, + "missing_command_text": { + "$ref": "#/definitions/missing_command_text" + } + } + } + } + } + }, { "if": { "properties": {