Repository: JanDeDobbeleer/oh-my-posh
Pull request #2387 (2022-06-05 14:37:03)

fossil
### 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: fossil segment
- docs: add flutter schema
- docs: add subversion schema + info


<!---

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/engine/segment.go b/src/engine/segment.go
index 7dd0f9d4..ef31d3f9 100644
--- a/src/engine/segment.go
+++ b/src/engine/segment.go
@@ -103,6 +103,8 @@ const (
 	EXIT SegmentType = "exit"
 	// FLUTTER writes the flutter version
 	FLUTTER SegmentType = "flutter"
+	// FOSSIL writes the fossil status
+	FOSSIL SegmentType = "fossil"
 	// GIT represents the git status and information
 	GIT SegmentType = "git"
 	// GOLANG writes which go version is currently active
@@ -268,6 +270,7 @@ func (segment *Segment) mapSegmentWithWriter(env environment.Environment) error
 		EXECUTIONTIME: &segments.Executiontime{},
 		EXIT:          &segments.Exit{},
 		FLUTTER:       &segments.Flutter{},
+		FOSSIL:        &segments.Fossil{},
 		GIT:           &segments.Git{},
 		GOLANG:        &segments.Golang{},
 		HASKELL:       &segments.Haskell{},
diff --git a/src/segments/fossil.go b/src/segments/fossil.go
new file mode 100644
index 00000000..a026672e
--- /dev/null
+++ b/src/segments/fossil.go
@@ -0,0 +1,68 @@
+package segments
+
+import "strings"
+
+// FossilStatus represents part of the status of a Svn repository
+type FossilStatus struct {
+	ScmStatus
+}
+
+func (s *FossilStatus) add(code string) {
+	switch code {
+	case "CONFLICT":
+		s.Conflicted++
+	case "DELETED":
+		s.Deleted++
+	case "ADDED":
+		s.Added++
+	case "EDITED", "UPDATED", "CHANGED":
+		s.Modified++
+	case "RENAMED":
+		s.Moved++
+	}
+}
+
+const (
+	FOSSILCOMMAND = "fossil"
+)
+
+type Fossil struct {
+	scm
+
+	Status *FossilStatus
+	Branch string
+}
+
+func (f *Fossil) Template() string {
+	return " \ufb2b {{.Branch}} {{.Status.String}} "
+}
+
+func (f *Fossil) Enabled() bool {
+	command := f.getCommand(FOSSILCOMMAND)
+	if !f.env.HasCommand(command) {
+		return false
+	}
+	// run fossil command
+	output, err := f.env.RunCommand(command, "status")
+	if err != nil {
+		return false
+	}
+	f.Status = &FossilStatus{}
+	lines := strings.Split(output, "\n")
+	for _, line := range lines {
+		if len(line) == 0 {
+			continue
+		}
+		context := strings.SplitN(line, " ", 2)
+		if len(context) < 2 {
+			continue
+		}
+		switch context[0] {
+		case "tags:":
+			f.Branch = strings.TrimSpace(context[1])
+		default:
+			f.Status.add(context[0])
+		}
+	}
+	return true
+}
diff --git a/themes/schema.json b/themes/schema.json
index 46a7f1a3..47d86e35 100644
--- a/themes/schema.json
+++ b/themes/schema.json
@@ -195,6 +195,8 @@
             "dart",
             "exit",
             "executiontime",
+            "flutter",
+            "fossil",
             "git",
             "go",
             "haskell",
@@ -224,6 +226,7 @@
             "shell",
             "sysinfo",
             "strava",
+            "svn",
             "swift",
             "time",
             "text",
@@ -565,6 +568,50 @@
             }
           }
         },
+        {
+          "if": {
+            "properties": {
+              "type": {
+                "const": "flutter"
+              }
+            }
+          },
+          "then": {
+            "title": "Flutter Segment",
+            "description": "https://ohmyposh.dev/docs/segments/flutter",
+            "properties": {
+              "properties": {
+                "properties": {
+                  "home_enabled": {
+                    "$ref": "#/definitions/home_enabled"
+                  },
+                  "fetch_version": {
+                    "$ref": "#/definitions/fetch_version"
+                  },
+                  "display_mode": {
+                    "$ref": "#/definitions/display_mode"
+                  },
+                  "missing_command_text": {
+                    "$ref": "#/definitions/missing_command_text"
+                  }
+                }
+              }
+            }
+          }
+        },
+        {
+          "if": {
+            "properties": {
+              "type": {
+                "const": "fossil"
+              }
+            }
+          },
+          "then": {
+            "title": "Fossil Segment",
+            "description": "https://ohmyposh.dev/docs/segments/fossil"
+          }
+        },
         {
           "if": {
             "properties": {
@@ -1840,6 +1887,31 @@
             }
           }
         },
+        {
+          "if": {
+            "properties": {
+              "type": {
+                "const": "svn"
+              }
+            }
+          },
+          "then": {
+            "title": "SVN Segment",
+            "description": "https://ohmyposh.dev/docs/segments/svn",
+            "properties": {
+              "properties": {
+                "properties": {
+                  "fetch_status": {
+                    "type": "boolean",
+                    "title": "Display Status",
+                    "description": "Display the local changes or not",
+                    "default": true
+                  }
+                }
+              }
+            }
+          }
+        },
         {
           "if": {
             "properties": {
diff --git a/website/docs/segments/fossil.mdx b/website/docs/segments/fossil.mdx
new file mode 100644
index 00000000..52116c8e
--- /dev/null
+++ b/website/docs/segments/fossil.mdx
@@ -0,0 +1,59 @@
+---
+id: fossil
+title: Fossil
+sidebar_label: Fossil
+---
+
+## What
+
+Display [fossil][fossil] information when in a fossil repository.
+
+Local changes can also be displayed which uses the following syntax:
+
+- `+` added
+- `!` conflicted
+- `-` deleted
+- `~` modified
+- `>` moved
+
+## Sample Configuration
+
+```json
+{
+  "type": "fossil",
+  "style": "powerline",
+  "powerline_symbol": "\uE0B0",
+  "foreground": "#193549",
+  "background": "#ffeb3b"
+}
+```
+
+## Template ([info][templates])
+
+:::note default template
+
+``` template
+ \ufb2b {{.Branch}} {{.Status.String}}
+```
+
+:::
+
+### Properties
+
+- `.Status`: `FossilStatus` - changes in the worktree (see below)
+- `.Branch`: `string` - current branch
+
+### FossilStatus
+
+- `.Modified`: `int` - number of edited, updated and changed files
+- `.Deleted`: `int` - number of deleted files
+- `.Added`: `int` - number of added files
+- `.Moved`: `int` - number of renamed files
+- `.Conflicted`: `int` - number of conflicting files
+- `.Changed`: `boolean` - if the status contains changes or not
+- `.HasConflicts`: `boolean` - if the status contains conflicts or not
+- `.String`: `string` - a string representation of the changes above
+
+[fossil]: https://fossil-scm.org
+[templates]: /docs/config-templates
+[hyperlinks]: /docs/config-templates#helper-functions
diff --git a/website/docs/segments/svn.mdx b/website/docs/segments/svn.mdx
index 6fbd4a41..5111b156 100644
--- a/website/docs/segments/svn.mdx
+++ b/website/docs/segments/svn.mdx
@@ -1,12 +1,12 @@
 ---
 id: svn
-title: Svn
-sidebar_label: Svn
+title: Subversion
+sidebar_label: Subversion
 ---
 
 ## What
 
-Display svn information when in a svn repository. Also works for subfolders. For maximum compatibility,
+Display subversion information when in a subversion repository. Also works for subfolders. For maximum compatibility,
 make sure your `svn` executable is up-to-date (when branch or status information is incorrect for example).
 
 Local changes can also be displayed which uses the following syntax:
@@ -16,7 +16,6 @@ Local changes can also be displayed which uses the following syntax:
 - `-` deleted
 - `~` modified
 - `>` moved
-- `?` untracked
 
 ## Sample Configuration
 
@@ -28,10 +27,7 @@ Local changes can also be displayed which uses the following syntax:
   "foreground": "#193549",
   "background": "#ffeb3b",
   "properties": {
-    "fetch_status": true,
-    "fetch_stash_count": true,
-    "fetch_upstream_icon": true,
-    "template": " \ue0a0{{ .Branch }} r{{ .BaseRev }} {{ .Working.String }} "
+    "fetch_status": true
   }
 }
 ```
@@ -40,7 +36,7 @@ Local changes can also be displayed which uses the following syntax:
 
 ### Fetching information
 
-As doing multiple svn calls can slow down the prompt experience, we do not fetch information by default.
+As doing multiple [subversion][svn] calls can slow down the prompt experience, we do not fetch information by default.
 You can set the following properties to `true` to enable fetching additional information (and populate the template).
 
 - fetch_status: `boolean` - fetch the local changes - defaults to `false`
@@ -63,14 +59,15 @@ You can set the following properties to `true` to enable fetching additional inf
 
 ### SvnStatus
 
-- `.Untracked`: `int` - number of untracked files
+- `.Modified`: `int` - number of modified files
 - `.Deleted`: `int` - number of deleted files
 - `.Added`: `int` - number of added files
-- `.Tracked`: `int` - number of changed tracked files
+- `.Moved`: `int` - number of changed moved files
 - `.Conflicted`: `int` - number of changed tracked files with conflicts
 - `.Changed`: `boolean` - if the status contains changes or not
 - `.HasConflicts`: `boolean` - if the status contains conflicts or not
 - `.String`: `string` - a string representation of the changes above
 
+[svn]: https://subversion.apache.org
 [templates]: /docs/config-templates
 [hyperlinks]: /docs/config-templates#helper-functions
diff --git a/website/sidebars.js b/website/sidebars.js
index f6920541..f95bfb32 100644
--- a/website/sidebars.js
+++ b/website/sidebars.js
@@ -67,6 +67,7 @@ module.exports = {
         "segments/executiontime",
         "segments/exit",
         "segments/flutter",
+        "segments/fossil",
         "segments/git",
         "segments/poshgit",
         "segments/golang",
@@ -97,6 +98,7 @@ module.exports = {
         "segments/shell",
         "segments/spotify",
         "segments/strava",
+        "segments/svn",
         "segments/swift",
         "segments/sysinfo",
         "segments/terraform",


Test patch:
diff --git a/src/segments/fossil_test.go b/src/segments/fossil_test.go
new file mode 100644
index 00000000..a9879252
--- /dev/null
+++ b/src/segments/fossil_test.go
@@ -0,0 +1,73 @@
+package segments
+
+import (
+	"fmt"
+	"oh-my-posh/mock"
+	"oh-my-posh/properties"
+	"strings"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestFossilStatus(t *testing.T) {
+	cases := []struct {
+		Case             string
+		Output           string
+		OutputError      error
+		HasCommand       bool
+		ExpectedStatus   string
+		ExpectedBranch   string
+		ExpectedDisabled bool
+	}{
+		{
+			Case:             "not installed",
+			HasCommand:       false,
+			ExpectedDisabled: true,
+		},
+		{
+			Case:             "command error",
+			HasCommand:       true,
+			OutputError:      fmt.Errorf("error"),
+			ExpectedDisabled: true,
+		},
+		{
+			Case:       "default status",
+			HasCommand: true,
+			Output: `
+			repository:   /Users/jan/Downloads/myclone.fossil
+			local-root:   /Users/jan/Projects/fossil/
+			config-db:    /Users/jan/.config/fossil.db
+			checkout:     0fabc4f3566c7e7d9e528b17253de42e14dd5c7b 2022-06-05 04:06:17 UTC
+			parent:       e8a051e6a943a26c9c33a30df8ceda069c06c174 2022-06-04 23:09:02 UTC
+			tags:         trunk
+			comment:      In the /setup_skin page, add a mention of/link to /skins, per request in the forum. (user: stephan)
+			EDITED     auto.def
+			EDITED     configure
+			ADDED      test.tst
+			`,
+			ExpectedBranch: "trunk",
+			ExpectedStatus: "+1 ~2",
+		},
+	}
+	for _, tc := range cases {
+		env := new(mock.MockedEnvironment)
+		env.On("GOOS").Return("unix")
+		env.On("IsWsl").Return(false)
+		env.On("HasCommand", FOSSILCOMMAND).Return(tc.HasCommand)
+		env.On("RunCommand", FOSSILCOMMAND, []string{"status"}).Return(strings.ReplaceAll(tc.Output, "\t", ""), tc.OutputError)
+		f := &Fossil{
+			scm: scm{
+				env:   env,
+				props: properties.Map{},
+			},
+		}
+		got := f.Enabled()
+		assert.Equal(t, !tc.ExpectedDisabled, got, tc.Case)
+		if tc.ExpectedDisabled {
+			continue
+		}
+		assert.Equal(t, tc.ExpectedStatus, f.Status.String(), tc.Case)
+		assert.Equal(t, tc.ExpectedBranch, f.Branch, tc.Case)
+	}
+}