From f9a94728500f1b3ead8d5d318c6b820136f099cf Mon Sep 17 00:00:00 2001 From: Anthony HAMON Date: Fri, 3 May 2024 01:08:18 +0200 Subject: [PATCH] Fix load and run, add environment variable * Fix load and run for sh, bash and zsh * Add 2 environment variables with the name of the workspace and the workspace environment --- workspace/workspace.go | 56 ++++++++++++++++++++++---- workspace/workspace_test.go | 78 ++++++++++++++++++++++++++++++------- 2 files changed, 113 insertions(+), 21 deletions(-) diff --git a/workspace/workspace.go b/workspace/workspace.go index 7994dce..3462cbc 100644 --- a/workspace/workspace.go +++ b/workspace/workspace.go @@ -18,6 +18,12 @@ import ( ) const configDir = ".config/wo" +const envVariablePrefix = "WO" + +const bash = "bash" +const fish = "fish" +const sh = "sh" +const zsh = "zsh" type Workspace struct { Name string @@ -130,15 +136,23 @@ func (s WorkspaceManager) Edit(name string) error { } func (s WorkspaceManager) EditEnv(name string, env string) error { + err := s.createWorkspaceEnvFolder(name) + if err != nil { + return err + } + err = s.createWorkspaceDefaultEnv(name) + if err != nil { + return err + } return s.edit(s.resolveWorkspaceEnvFile(name, env)) } func (s WorkspaceManager) Load(name string, env string) error { - return s.execCommand(s.appendLoadStatement(name, env)...) + return s.execCommand(s.appendLoadStatement(name, env, []string{})...) } func (s WorkspaceManager) RunFunction(name string, env string, functionAndArgs []string) error { - return s.execCommand(s.appendLoadStatement(name, env, "-c", strings.Join(functionAndArgs, " "))...) + return s.execCommand(s.appendLoadStatement(name, env, functionAndArgs)...) } func (s WorkspaceManager) Remove(name string) error { @@ -149,15 +163,31 @@ func (s WorkspaceManager) Remove(name string) error { return errors.Join(os.Remove(s.resolveFunctionFile(name)), os.RemoveAll(s.getWorkspaceEnvDir(name))) } -func (s WorkspaceManager) appendLoadStatement(name string, env string, cmds ...string) []string { - stmts := []string{} +func (s WorkspaceManager) appendLoadStatement(name string, env string, functionAndArgs []string) []string { + data := []string{} + data = append(data, s.createEnvVariableStatement(fmt.Sprintf("%s_NAME", envVariablePrefix), name)) + data = append(data, s.createEnvVariableStatement(fmt.Sprintf("%s_ENV", envVariablePrefix), s.resolveEnv(env))) envFile := s.resolveWorkspaceEnvFile(name, env) _, eerr := os.Stat(envFile) if eerr == nil { - stmts = append(stmts, "-C", fmt.Sprintf("source %s", envFile)) + data = append(data, fmt.Sprintf("source %s", envFile)) + } + data = append(data, fmt.Sprintf("source %s", s.resolveFunctionFile(name))) + stmts := []string{} + switch s.shell { + case bash, sh, zsh: + if len(functionAndArgs) > 0 { + data = append(data, strings.Join(functionAndArgs, " ")) + } + stmts = append(stmts, "-c", strings.Join(data, " && ")) + case fish: + for _, d := range data { + stmts = append(stmts, "-C", d) + } + if len(functionAndArgs) > 0 { + stmts = append(stmts, "-c", strings.Join(functionAndArgs, " ")) + } } - stmts = append(stmts, "-C", fmt.Sprintf("source %s", s.resolveFunctionFile(name))) - stmts = append(stmts, cmds...) return stmts } @@ -199,7 +229,7 @@ func (s WorkspaceManager) resolveWorkspaceEnvFile(name string, env string) strin } func (s WorkspaceManager) getExtension() string { - for _, shell := range []string{"fish", "bash", "zsh", "sh"} { + for _, shell := range []string{fish, bash, zsh, sh} { if strings.Contains(s.shellBin, shell) { return shell } @@ -236,6 +266,16 @@ func (s WorkspaceManager) getWorkspaceEnvDir(name string) string { return fmt.Sprintf("%s/%s", s.getEnvDir(), name) } +func (s WorkspaceManager) createEnvVariableStatement(name string, value string) string { + switch s.shell { + case bash, sh, zsh: + return fmt.Sprintf("export %s=%s", name, value) + case fish: + return fmt.Sprintf("set -x -g %s %s", name, value) + } + return "" +} + func execCommand(shellBin string) func(args ...string) error { return func(args ...string) error { command := exec.Command(shellBin, args...) diff --git a/workspace/workspace_test.go b/workspace/workspace_test.go index c2a0098..03f9631 100644 --- a/workspace/workspace_test.go +++ b/workspace/workspace_test.go @@ -294,24 +294,49 @@ func TestLoad(t *testing.T) { } scenarios := []scenario{ { - "Load workspace", + "Load workspace with a bash shell", "", func() { + os.Setenv("SHELL", "bash") + }, + func(args []string) { + assert.Equal(t, []string{"-c", "export WO_NAME=test && export WO_ENV=default && source " + getHomePath(t) + "/.config/wo/functions/bash/test.bash"}, args) + }, + }, + { + "Load workspace with a fish shell", + "", + func() { + os.Setenv("SHELL", "fish") }, func(args []string) { - assert.Equal(t, []string{"-C", "source " + getHomePath(t) + "/.config/wo/functions/bash/test.bash"}, args) + assert.Equal(t, []string{"-C", "set -x -g WO_NAME test", "-C", "set -x -g WO_ENV default", "-C", "source " + getHomePath(t) + "/.config/wo/functions/fish/test.fish"}, args) }, }, { - "Load workspace with an env defined", + "Load workspace with an env defined and a bash shell", "prod", func() { envPath := getConfigPath(t) + "/envs/bash" assert.NoError(t, os.MkdirAll(envPath+"/test", 0777)) assert.NoError(t, os.WriteFile(envPath+"/test/prod.bash", []byte{}, 0777)) + os.Setenv("SHELL", "bash") + }, + func(args []string) { + assert.Equal(t, []string{"-c", "export WO_NAME=test && export WO_ENV=prod && source " + getHomePath(t) + "/.config/wo/envs/bash/test/prod.bash && source " + getHomePath(t) + "/.config/wo/functions/bash/test.bash"}, args) + }, + }, + { + "Load workspace with an env defined and a fish shell", + "prod", + func() { + envPath := getConfigPath(t) + "/envs/fish" + assert.NoError(t, os.MkdirAll(envPath+"/test", 0777)) + assert.NoError(t, os.WriteFile(envPath+"/test/prod.fish", []byte{}, 0777)) + os.Setenv("SHELL", "fish") }, func(args []string) { - assert.Equal(t, []string{"-C", "source " + getHomePath(t) + "/.config/wo/envs/bash/test/prod.bash", "-C", "source " + getHomePath(t) + "/.config/wo/functions/bash/test.bash"}, args) + assert.Equal(t, []string{"-C", "set -x -g WO_NAME test", "-C", "set -x -g WO_ENV prod", "-C", "source " + getHomePath(t) + "/.config/wo/envs/fish/test/prod.fish", "-C", "source " + getHomePath(t) + "/.config/wo/functions/fish/test.fish"}, args) }, }, } @@ -320,7 +345,8 @@ func TestLoad(t *testing.T) { os.RemoveAll(getConfigPath(t)) os.Setenv("VISUAL", "emacs") os.Setenv("EDITOR", "emacs") - os.Setenv("SHELL", "bash") + os.Unsetenv("SHELL") + s.setup() w, err := NewWorkspaceManager() args := []string{} w.execCommand = func(a ...string) error { @@ -328,7 +354,6 @@ func TestLoad(t *testing.T) { return nil } assert.NoError(t, err) - s.setup() assert.NoError(t, w.Load("test", s.env)) s.test(args) }) @@ -345,35 +370,63 @@ func TestRunFunction(t *testing.T) { } scenarios := []scenario{ { - "Run function", + "Run a function with a bash shell", []string{"run-db"}, "", func() { + os.Setenv("SHELL", "/bin/bash") }, func(args []string) { - assert.Equal(t, []string{"-C", "source " + getHomePath(t) + "/.config/wo/functions/bash/test.bash", "-c", "run-db"}, args) + assert.Equal(t, []string{"-c", "export WO_NAME=test && export WO_ENV=default && source " + getHomePath(t) + "/.config/wo/functions/bash/test.bash && run-db"}, args) }, }, { - "Run a function with an env defined", - []string{"run-db", "--watch"}, + "Run a function with a fish shell", + []string{"run-db"}, + "", + func() { + os.Setenv("SHELL", "/bin/fish") + }, + func(args []string) { + assert.Equal(t, []string{"-C", "set -x -g WO_NAME test", "-C", "set -x -g WO_ENV default", "-C", "source " + getHomePath(t) + "/.config/wo/functions/fish/test.fish", "-c", "run-db"}, args) + }, + }, + { + "Run a function with an env defined and a bash shell", + []string{"run-db", "watch"}, "prod", func() { envPath := getConfigPath(t) + "/envs/bash" assert.NoError(t, os.MkdirAll(envPath+"/test", 0777)) assert.NoError(t, os.WriteFile(envPath+"/test/prod.bash", []byte{}, 0777)) + os.Setenv("SHELL", "/bin/bash") }, func(args []string) { - assert.Equal(t, []string{"-C", "source " + getHomePath(t) + "/.config/wo/envs/bash/test/prod.bash", "-C", "source " + getHomePath(t) + "/.config/wo/functions/bash/test.bash", "-c", "run-db --watch"}, args) + assert.Equal(t, []string{"-c", "export WO_NAME=test && export WO_ENV=prod && source " + getHomePath(t) + "/.config/wo/envs/bash/test/prod.bash && source " + getHomePath(t) + "/.config/wo/functions/bash/test.bash && run-db watch"}, args) + }, + }, + { + "Run a function with an env defined and a fish shell", + []string{"run-db", "watch"}, + "prod", + func() { + envPath := getConfigPath(t) + "/envs/fish" + assert.NoError(t, os.MkdirAll(envPath+"/test", 0777)) + assert.NoError(t, os.WriteFile(envPath+"/test/prod.fish", []byte{}, 0777)) + os.Setenv("SHELL", "/bin/fish") + }, + func(args []string) { + assert.Equal(t, []string{"-C", "set -x -g WO_NAME test", "-C", "set -x -g WO_ENV prod", "-C", "source " + getHomePath(t) + "/.config/wo/envs/fish/test/prod.fish", "-C", "source " + getHomePath(t) + "/.config/wo/functions/fish/test.fish", "-c", "run-db watch"}, args) }, }, } for _, s := range scenarios { t.Run(s.name, func(t *testing.T) { os.RemoveAll(getConfigPath(t)) + os.Unsetenv("SHELL") os.Setenv("VISUAL", "emacs") os.Setenv("EDITOR", "emacs") - os.Setenv("SHELL", "bash") + s.setup() w, err := NewWorkspaceManager() args := []string{} w.execCommand = func(a ...string) error { @@ -381,7 +434,6 @@ func TestRunFunction(t *testing.T) { return nil } assert.NoError(t, err) - s.setup() assert.NoError(t, w.RunFunction("test", s.env, s.functionAndArgs)) s.test(args) })