Repository: JanDeDobbeleer/oh-my-posh
Pull request #4042 (2023-07-10 01:30:42)

feat: use asdf to determine elixir version
### Prerequisites

- [x] I have read and understood the [contributing guide][CONTRIBUTING.md].
- [x] The commit message follows the [conventional commits][cc] guidelines.
- [x] Tests for the changes have been added (for bug fixes / features).
- [x] Docs have been added/updated (for bug fixes / features).

### Description

In order to speed up version checking for the elixir segment, this change makes it so that we first ask `asdf` for the elixir version, which is much faster.

If asdf is not installed or configured, the previous behavior of running `elixir --version` will be used.

This also includes a minor fix to a mistake in the elixir docs, replacing 'flutter' with 'elixir'.

### How

I followed the established pattern used in other segments like Ruby to add the asdf check. I verified that it works on my machine with bash, elixir, and asdf.

<!---

Tips:

If you're not comfortable with working with Git,
we're working a guide (https://ohmyposh.dev/docs/contributing_git) to help you out.
Oh My Posh advises GitKraken (https://www.gitkraken.com/invite/nQmDPR9D) as your preferred cross platform Git GUI power tool.

-->

[CONTRIBUTING.md]: https://github.com/JanDeDobbeleer/oh-my-posh/blob/main/CONTRIBUTING.md
[cc]: https://www.conventionalcommits.org/en/v1.0.0/#summary



Patch:
diff --git a/src/segments/elixir.go b/src/segments/elixir.go
index 8589a9ab..50851b2b 100644
--- a/src/segments/elixir.go
+++ b/src/segments/elixir.go
@@ -19,6 +19,11 @@ func (e *Elixir) Init(props properties.Properties, env platform.Environment) {
 		props:      props,
 		extensions: []string{"*.ex", "*.exs"},
 		commands: []*cmd{
+			{
+				executable: "asdf",
+				args:       []string{"current", "elixir"},
+				regex:      `elixir\s+(?P<version>((?P<major>[0-9]+).(?P<minor>[0-9]+).(?P<patch>[0-9]+)))[^\s]*\s+`,
+			},
 			{
 				executable: "elixir",
 				args:       []string{"--version"},
diff --git a/website/docs/segments/elixir.mdx b/website/docs/segments/elixir.mdx
index 202ae203..572f973f 100644
--- a/website/docs/segments/elixir.mdx
+++ b/website/docs/segments/elixir.mdx
@@ -26,7 +26,7 @@ import Config from '@site/src/components/Config.js';
 | Name                   | Type      | Description                                                                                                                                                       |
 | ---------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
 | `home_enabled`         | `boolean` | display the segment in the HOME folder or not - defaults to `false`                                                                                               |
-| `fetch_version`        | `boolean` | fetch the flutter version - defaults to `true`                                                                                                                    |
+| `fetch_version`        | `boolean` | fetch the elixir version - defaults to `true`                                                                                                                     |
 | `missing_command_text` | `string`  | text to display when the command is missing - defaults to empty                                                                                                   |
 | `display_mode`         | `string`  | <ul><li>`always`: the segment is always displayed</li><li>`files`: the segment is only displayed when `*.ex` or `*.exs` files are present (**default**)</li></ul> |
 | `version_url_template` | `string`  | a go [text/template][go-text-template] [template][templates] that creates the URL of the version info / release notes                                             |


Test patch:
diff --git a/src/segments/elixir_test.go b/src/segments/elixir_test.go
index 9fe7bf89..0b9fc5e8 100644
--- a/src/segments/elixir_test.go
+++ b/src/segments/elixir_test.go
@@ -4,29 +4,56 @@ import (
 	"fmt"
 	"testing"
 
+	"github.com/jandedobbeleer/oh-my-posh/src/platform"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestElixir(t *testing.T) {
 	cases := []struct {
-		Case           string
-		ExpectedString string
-		Version        string
+		Case                string
+		ExpectedString      string
+		ElixirVersionOutput string
+		AsdfVersionOutput   string
+		HasAsdf             bool
+		AsdfExitCode        int
 	}{
 		{
-			Case:           "elixir 1.14.2",
-			ExpectedString: "1.14.2",
-			Version:        "Erlang/OTP 25 [erts-13.1.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]\n\nElixir 1.14.2 (compiled with Erlang/OTP 25)",
+			Case:                "Version without asdf",
+			ExpectedString:      "1.14.2",
+			ElixirVersionOutput: "Erlang/OTP 25 [erts-13.1.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]\n\nElixir 1.14.2 (compiled with Erlang/OTP 25)",
+		},
+		{
+			Case:                "Version with asdf",
+			ExpectedString:      "1.14.2",
+			HasAsdf:             true,
+			AsdfVersionOutput:   "elixir          1.14.2-otp-25   /path/to/.tool-versions",
+			ElixirVersionOutput: "Should not be used",
+		},
+		{
+			Case:                "Version with asdf not set: should fall back to elixir --version",
+			ExpectedString:      "1.14.2",
+			HasAsdf:             true,
+			AsdfVersionOutput:   "elixir             ______          No version is set. Run \"asdf <global|shell|local> elixir <version>\"",
+			AsdfExitCode:        126,
+			ElixirVersionOutput: "Erlang/OTP 25 [erts-13.1.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]\n\nElixir 1.14.2 (compiled with Erlang/OTP 25)",
 		},
 	}
 	for _, tc := range cases {
 		params := &mockedLanguageParams{
 			cmd:           "elixir",
 			versionParam:  "--version",
-			versionOutput: tc.Version,
+			versionOutput: tc.ElixirVersionOutput,
 			extension:     "*.ex",
 		}
 		env, props := getMockedLanguageEnv(params)
+
+		env.On("HasCommand", "asdf").Return(tc.HasAsdf)
+		var asdfErr error
+		if tc.AsdfExitCode != 0 {
+			asdfErr = &platform.CommandError{ExitCode: tc.AsdfExitCode}
+		}
+		env.On("RunCommand", "asdf", []string{"current", "elixir"}).Return(tc.AsdfVersionOutput, asdfErr)
+
 		r := &Elixir{}
 		r.Init(props, env)
 		assert.True(t, r.Enabled(), fmt.Sprintf("Failed in case: %s", tc.Case))