Repository: JanDeDobbeleer/oh-my-posh
Pull request #3253 (2022-12-27 13:50:39)

between christmas and newyear
### 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

- feat(svn): exclude branch info from fetch_status
- fix(shell): lock template cache creation
- docs(project): add .Error reference
- feat(project): add always_enabled and project type

<!---

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/platform/shell.go b/src/platform/shell.go
index 3732d667..540bacb3 100644
--- a/src/platform/shell.go
+++ b/src/platform/shell.go
@@ -708,6 +708,8 @@ func (env *Shell) Logs() string {
 }
 
 func (env *Shell) TemplateCache() *TemplateCache {
+	lock.Lock()
+	defer lock.Unlock()
 	defer env.Trace(time.Now(), "TemplateCache")
 	if env.tmplCache != nil {
 		return env.tmplCache
diff --git a/src/segments/project.go b/src/segments/project.go
index 1f57fb9e..20a6c350 100644
--- a/src/segments/project.go
+++ b/src/segments/project.go
@@ -20,18 +20,12 @@ type ProjectItem struct {
 }
 
 type ProjectData struct {
+	Type    string
 	Version string
 	Name    string
 	Target  string
 }
 
-func (p *ProjectData) enabled() bool {
-	if p == nil {
-		return false
-	}
-	return len(p.Version) > 0 || len(p.Name) > 0 || len(p.Target) > 0
-}
-
 // Rust Cargo package
 type CargoTOML struct {
 	Package ProjectData
@@ -72,10 +66,11 @@ func (n *Project) Enabled() bool {
 				continue
 			}
 			n.ProjectData = *data
-			return n.enabled()
+			n.ProjectData.Type = item.Name
+			return true
 		}
 	}
-	return false
+	return n.props.GetBool(properties.AlwaysEnabled, false)
 }
 
 func (n *Project) Template() string {
diff --git a/src/segments/svn.go b/src/segments/svn.go
index 56eb8661..108f2d4a 100644
--- a/src/segments/svn.go
+++ b/src/segments/svn.go
@@ -52,12 +52,9 @@ func (s *Svn) Enabled() bool {
 	if !s.shouldDisplay() {
 		return false
 	}
-	displayStatus := s.props.GetBool(FetchStatus, false)
-	if displayStatus {
-		s.setSvnStatus()
-	} else {
-		s.Working = &SvnStatus{}
-	}
+
+	s.setSvnStatus()
+
 	return true
 }
 
@@ -101,6 +98,12 @@ func (s *Svn) setSvnStatus() {
 	}
 
 	s.Working = &SvnStatus{}
+
+	displayStatus := s.props.GetBool(FetchStatus, false)
+	if !displayStatus {
+		return
+	}
+
 	changes := s.getSvnCommandOutput("status")
 	if len(changes) == 0 {
 		return
diff --git a/website/docs/segments/project.mdx b/website/docs/segments/project.mdx
index c777b8d6..c63e741a 100644
--- a/website/docs/segments/project.mdx
+++ b/website/docs/segments/project.mdx
@@ -18,6 +18,12 @@ Supports:
 - .NET project (`*.csproj`, `*.vbproj` or `*.fsproj`, first file match info is displayed)
 - Julia project (`JuliaProject.toml`, `Project.toml`)
 
+## Properties
+
+| Name             | Type      | Description                                   |
+| ---------------- | --------- | --------------------------------------------- |
+| `always_enabled` | `boolean` | always show the segment - defaults to `false` |
+
 ## Sample Configuration
 
 ```json
@@ -43,10 +49,12 @@ Supports:
 
 ### Properties
 
-| Name       | Type     | Description                                          |
-| ---------- | -------- | ---------------------------------------------------- |
-| `.Version` | `string` | The version of your project                          |
-| `.Target`  | `string` | The target framwork/language version of your project |
-| `.Name`    | `string` | The name of your project                             |
+| Name       | Type     | Description                                                                           |
+| ---------- | -------- | ------------------------------------------------------------------------------------- |
+| `.Type`    | `string` | The type of project (`node`, `cargo`, `poetry`, `php`, `nuspec`, `dotnet` or `julia`) |
+| `.Version` | `string` | The version of your project                                                           |
+| `.Target`  | `string` | The target framwork/language version of your project                                  |
+| `.Name`    | `string` | The name of your project                                                              |
+| `.Error`   | `string` | The error context when we can't fetch the project info                                |
 
 [templates]: /docs/configuration/templates


Test patch:
diff --git a/src/segments/project_test.go b/src/segments/project_test.go
index 861064eb..c5ce7c60 100644
--- a/src/segments/project_test.go
+++ b/src/segments/project_test.go
@@ -155,19 +155,21 @@ func TestPackage(t *testing.T) {
 		},
 		{
 			Case:            "Empty project package node.js",
-			ExpectedEnabled: false,
+			ExpectedEnabled: true,
 			Name:            "node",
 			File:            "package.json",
 			PackageContents: "{}",
 		},
 		{
 			Case:            "Empty project package cargo",
+			ExpectedEnabled: true,
 			Name:            "cargo",
 			File:            "Cargo.toml",
 			PackageContents: "",
 		},
 		{
 			Case:            "Empty project package poetry",
+			ExpectedEnabled: true,
 			Name:            "poetry",
 			File:            "pyproject.toml",
 			PackageContents: "",
@@ -263,7 +265,7 @@ func TestNuspecPackage(t *testing.T) {
 			Case:            "no info in file",
 			FileName:        "../test/empty.nuspec",
 			HasFiles:        true,
-			ExpectedEnabled: false,
+			ExpectedEnabled: true,
 		},
 		{
 			Case:            "no files",
diff --git a/src/segments/svn_test.go b/src/segments/svn_test.go
index f2696ff0..89a74540 100644
--- a/src/segments/svn_test.go
+++ b/src/segments/svn_test.go
@@ -36,6 +36,8 @@ func TestSvnEnabledInWorkingDirectory(t *testing.T) {
 	env.On("GOOS").Return("")
 	env.On("FileContent", "/dir/hello/trunk").Return("")
 	env.MockSvnCommand(fileInfo.Path, "", "info", "--tags", "--exact-match")
+	env.On("RunCommand", "svn", []string{"info", "/dir/hello", "--show-item", "revision"}).Return("", nil)
+	env.On("RunCommand", "svn", []string{"info", "/dir/hello", "--show-item", "relative-url"}).Return("", nil)
 	env.On("IsWsl").Return(false)
 	env.On("HasParentFilePath", ".svn").Return(fileInfo, nil)
 	s := &Svn{
@@ -239,8 +241,10 @@ R       Moved.File`,
 
 		s := &Svn{
 			scm: scm{
-				env:     env,
-				props:   properties.Map{},
+				env: env,
+				props: properties.Map{
+					FetchStatus: true,
+				},
 				command: SVNCOMMAND,
 			},
 		}