Skip to content

Commit

Permalink
feat(segment): firebase segment
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-the-terrible authored and JanDeDobbeleer committed Apr 18, 2024
1 parent a9966f5 commit 7fc2b70
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 32 deletions.
3 changes: 3 additions & 0 deletions src/engine/segment.go
Expand Up @@ -146,6 +146,8 @@ const (
FOSSIL SegmentType = "fossil"
// GCP writes the active GCP context
GCP SegmentType = "gcp"
// FIREBASE writes the active firebase project
FIREBASE SegmentType = "firebase"
// GIT represents the git status and information
GIT SegmentType = "git"
// GITVERSION represents the gitversion information
Expand Down Expand Up @@ -296,6 +298,7 @@ var Segments = map[SegmentType]func() SegmentWriter{
FLUTTER: func() SegmentWriter { return &segments.Flutter{} },
FOSSIL: func() SegmentWriter { return &segments.Fossil{} },
GCP: func() SegmentWriter { return &segments.Gcp{} },
FIREBASE: func() SegmentWriter { return &segments.Firebase{} },
GIT: func() SegmentWriter { return &segments.Git{} },
GITVERSION: func() SegmentWriter { return &segments.GitVersion{} },
GOLANG: func() SegmentWriter { return &segments.Golang{} },
Expand Down
83 changes: 83 additions & 0 deletions src/segments/firebase.go
@@ -0,0 +1,83 @@
package segments

import (
"encoding/json"
"errors"
"path/filepath"

"github.com/jandedobbeleer/oh-my-posh/src/platform"
"github.com/jandedobbeleer/oh-my-posh/src/properties"
)

const (
FIREBASENOACTIVECONFIG = "NO ACTIVE CONFIG FOUND"
)

type Firebase struct {
props properties.Properties
env platform.Environment

Project string
}

type FirebaseData struct {
ActiveProject map[string]string `json:"activeProjects"`
}

func (f *Firebase) Template() string {
return " {{ .Project}} "
}

func (f *Firebase) Init(props properties.Properties, env platform.Environment) {
f.props = props
f.env = env
}

func (f *Firebase) Enabled() bool {
cfgDir := filepath.Join(f.env.Home(), ".config", "configstore")
configFile, err := f.getActiveConfig(cfgDir)
if err != nil {
f.env.Error(err)
return false
}

data, err := f.getFirebaseData(configFile)
if err != nil {
f.env.Error(err)
return false
}

// Within the activeProjects is a key value pair
// of the path to the project and the project name

// Test if the current directory is a project path
// and if it is, return the project name
for key, value := range data.ActiveProject {
if key == f.env.Pwd() {
f.Project = value
return true
}
}

return false
}

func (f *Firebase) getActiveConfig(cfgDir string) (string, error) {
activeConfigFile := filepath.Join(cfgDir, "firebase-tools.json")
activeConfigData := f.env.FileContent(activeConfigFile)
if len(activeConfigData) == 0 {
return "", errors.New(FIREBASENOACTIVECONFIG)
}
return activeConfigData, nil
}

func (f *Firebase) getFirebaseData(configFile string) (*FirebaseData, error) {
var data FirebaseData

err := json.Unmarshal([]byte(configFile), &data)
if err != nil {
return nil, err
}

return &data, nil
}
107 changes: 107 additions & 0 deletions src/segments/firebase_test.go
@@ -0,0 +1,107 @@
package segments

import (
"path/filepath"
"testing"

"github.com/jandedobbeleer/oh-my-posh/src/mock"
"github.com/stretchr/testify/assert"
mock2 "github.com/stretchr/testify/mock"
)

func TestFirebaseSegment(t *testing.T) {
cases := []struct {
Case string
CfgData string
ActiveConfig string
ExpectedEnabled bool
ExpectedString string
}{
{
Case: "happy path",
ExpectedEnabled: true,
ActiveConfig: `{
"activeProjects": {
"path": "project-name"
}
}`,
ExpectedString: "project-name",
},
{
Case: "no active config",
ExpectedEnabled: false,
},
{
Case: "empty config",
ActiveConfig: "{}",
ExpectedEnabled: false,
},
{
Case: "bad config",
ActiveConfig: "{bad}",
ExpectedEnabled: false,
},
}

for _, tc := range cases {
env := new(mock.MockedEnvironment)
env.On("Home").Return("home")
env.On("Pwd").Return("path")
fcPath := filepath.Join("home", ".config", "configstore", "firebase-tools.json")
env.On("FileContent", fcPath).Return(tc.ActiveConfig)
env.On("Error", mock2.Anything).Return()
f := Firebase{
env: env,
}
f.Enabled()
assert.Equal(t, tc.ExpectedEnabled, f.Enabled())
if tc.ExpectedEnabled {
assert.Equal(t, tc.ExpectedString, renderTemplate(env, f.Template(), f), tc.Case)
}
}
}

func TestGetFirebaseActiveConfig(t *testing.T) {
data :=
`{
"activeProjects": {
"path": "project-name"
}
}`
cases := []struct {
Case string
ActiveConfig string
ExpectedString string
ExpectedError string
}{
{
Case: "happy path",
ActiveConfig: data,
ExpectedString: data,
},
{
Case: "no active config",
ActiveConfig: "",
ExpectedError: FIREBASENOACTIVECONFIG,
},
}

for _, tc := range cases {
env := new(mock.MockedEnvironment)
env.On("Home").Return("home")
configPath := filepath.Join("home", ".config", "configstore")
contentPath := filepath.Join(configPath, "firebase-tools.json")
env.On("FileContent", contentPath).Return(tc.ActiveConfig)
env.On("Error", mock2.Anything).Return()
f := Firebase{
env: env,
}
got, err := f.getActiveConfig(configPath)
assert.Equal(t, tc.ExpectedString, got, tc.Case)
if len(tc.ExpectedError) > 0 {
assert.EqualError(t, err, tc.ExpectedError, tc.Case)
} else {
assert.NoError(t, err, tc.Case)
}
}
}
9 changes: 9 additions & 0 deletions themes/cloud-context.omp.json
Expand Up @@ -7,6 +7,7 @@
"cloud-text-amazon": "#4285F4",
"cloud-text-azure": "#4285F4",
"cloud-text-gcp": "#4285F4",
"cloud-text-firebase": "#FFA000",
"error-background": "#dd0033",
"error-text": "#242424",
"git-text": "#238636",
Expand Down Expand Up @@ -76,6 +77,14 @@
"template": " <p:symbol-color>\ue7b2</> {{ .Project }}",
"type": "gcp"
},
{
"background": "p:background-color",
"foreground": "p:cloud-text-firebase",
"style": "powerline",
"powerline_symbol": "\ue0b4",
"template": " <p:symbol-color>\udb82\udd67</> {{ .Project }}",
"type": "firebase"
},
{
"background": "p:background-color",
"foreground": "p:git-text",
Expand Down
54 changes: 22 additions & 32 deletions themes/schema.json
Expand Up @@ -314,6 +314,7 @@
"flutter",
"fossil",
"gcp",
"firebase",
"git",
"gitversion",
"go",
Expand Down Expand Up @@ -629,11 +630,7 @@
"title": "Source",
"description": "https://ohmyposh.dev/docs/segments/az#properties",
"default": "first_match",
"enum": [
"first_match",
"cli",
"pwsh"
]
"enum": ["first_match", "cli", "pwsh"]
}
}
}
Expand Down Expand Up @@ -727,7 +724,7 @@
"description": "The icon representing Bazel's logo",
"default": "\ue63a"
},
"extensions":{
"extensions": {
"type": "array",
"title": "Extensions",
"description": "The extensions to look for when determining if a folder is a Bazel workspace",
Expand All @@ -747,11 +744,7 @@
"type": "array",
"title": "Folders",
"description": "The folders to look for when determining if a folder is a Bazel workspace",
"default": [
"bazel-bin",
"bazel-out",
"bazel-testlogs"
],
"default": ["bazel-bin", "bazel-out", "bazel-testlogs"],
"items": {
"type": "string"
}
Expand Down Expand Up @@ -890,12 +883,7 @@
"type": "string",
"title": "Connection type",
"description": "The connection type to display",
"enum": [
"ethernet",
"wifi",
"cellular",
"bluetooth"
],
"enum": ["ethernet", "wifi", "cellular", "bluetooth"],
"default": "wifi|ethernet"
},
"unit": {
Expand Down Expand Up @@ -1131,9 +1119,7 @@
"type": "array",
"title": "Folders",
"description": "The folders to look for when determining if a folder is a Flutter workspace",
"default": [
".dart_tool"
],
"default": [".dart_tool"],
"items": {
"type": "string"
}
Expand Down Expand Up @@ -1469,9 +1455,7 @@
"type": "array",
"title": "Folders",
"description": "The folders to look for when determining if a folder is a Dart workspace",
"default": [
".dart_tool"
],
"default": [".dart_tool"],
"items": {
"type": "string"
}
Expand Down Expand Up @@ -2909,11 +2893,7 @@
"title": "units",
"description": "Units of measurement. Available values are standard (kelvin), metric (celsius), and imperial (fahrenheit). Default is standard",
"default": "standard",
"enum": [
"standard",
"metric",
"imperial"
]
"enum": ["standard", "metric", "imperial"]
},
"http_timeout": {
"$ref": "#/definitions/http_timeout"
Expand Down Expand Up @@ -3185,10 +3165,7 @@
"type": "array",
"title": "Extensions",
"description": "The extensions to look for when determining if the current directory is an Angular project",
"default":
[
"angular.json"
],
"default": ["angular.json"],
"items": {
"type": "string"
}
Expand Down Expand Up @@ -4296,6 +4273,19 @@
"description": "https://ohmyposh.dev/docs/segments/gcp"
}
},
{
"if": {
"properties": {
"type": {
"const": "firebase"
}
}
},
"then": {
"title": "Firebase Segment",
"description": "https://ohmyposh.dev/docs/segments/firebase"
}
},
{
"if": {
"properties": {
Expand Down

0 comments on commit 7fc2b70

Please sign in to comment.