Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions cmd/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"context"
"fmt"
"os"

"github.com/spf13/cobra"
"github.com/windsorcli/cli/pkg/di"
Expand All @@ -22,6 +23,13 @@ var envCmd = &cobra.Command{
hook, _ := cmd.Flags().GetBool("hook")
decrypt, _ := cmd.Flags().GetBool("decrypt")

// Set NO_CACHE=true unless --hook is specified or NO_CACHE is already set
if !hook && os.Getenv("NO_CACHE") == "" {
if err := os.Setenv("NO_CACHE", "true"); err != nil {
return fmt.Errorf("failed to set NO_CACHE environment variable: %w", err)
}
}

// Create execution context with flags
ctx := cmd.Context()
if decrypt {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ require (
github.com/spf13/pflag v1.0.6
github.com/zclconf/go-cty v1.16.3
golang.org/x/crypto v0.40.0
golang.org/x/sys v0.34.0
k8s.io/api v0.33.3
k8s.io/apimachinery v0.33.3
k8s.io/client-go v0.33.3
Expand Down Expand Up @@ -196,6 +195,7 @@ require (
golang.org/x/net v0.41.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.16.0 // indirect
golang.org/x/sys v0.34.0 // indirect
golang.org/x/term v0.33.0 // indirect
golang.org/x/text v0.27.0 // indirect
golang.org/x/time v0.11.0 // indirect
Expand Down
2 changes: 1 addition & 1 deletion pkg/env/aws_env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ func TestAwsEnv_Print(t *testing.T) {

// Mock PrintEnvVarsFunc to capture printed vars
var capturedEnvVars map[string]string
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string) {
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {
capturedEnvVars = envVars
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/env/azure_env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func TestAzureEnv_Print(t *testing.T) {
t.Fatalf("Failed to get config root: %v", err)
}
var capturedEnvVars map[string]string
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string) {
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {
capturedEnvVars = envVars
}
err = printer.Print()
Expand Down
2 changes: 1 addition & 1 deletion pkg/env/docker_env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ func TestDockerEnvPrinter_Print(t *testing.T) {

// And PrintEnvVarsFunc is mocked
var capturedEnvVars map[string]string
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string) {
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {
capturedEnvVars = envVars
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func (e *BaseEnvPrinter) Print(customVars ...map[string]string) error {
e.SetManagedEnv(key)
}

e.shell.PrintEnvVars(envVars)
e.shell.PrintEnvVars(envVars, true)
return nil
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/env/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ func TestEnv_Print(t *testing.T) {

// And a mock PrintEnvVarsFunc
var capturedEnvVars map[string]string
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string) {
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {
capturedEnvVars = envVars
}

Expand All @@ -256,7 +256,7 @@ func TestEnv_Print(t *testing.T) {

// And a mock PrintEnvVarsFunc
var capturedEnvVars map[string]string
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string) {
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {
capturedEnvVars = envVars
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/env/omni_env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ func TestOmniEnvPrinter_Print(t *testing.T) {

// And PrintEnvVarsFunc is mocked
var capturedEnvVars map[string]string
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string) {
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {
capturedEnvVars = envVars
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/env/talos_env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func TestTalosEnv_Print(t *testing.T) {

// And PrintEnvVarsFunc is mocked
var capturedEnvVars map[string]string
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string) {
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {
capturedEnvVars = envVars
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/env/terraform_env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ func TestTerraformEnv_Print(t *testing.T) {
printer, mocks := setup(t)

var capturedEnvVars map[string]string
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string) {
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {
capturedEnvVars = envVars
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/env/windsor_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,8 @@ func (e *WindsorEnvPrinter) parseAndCheckSecrets(strValue string) string {
return strValue
}

// shouldUseCache determines if the cache should be used based on the current and Windsor context.
// shouldUseCache determines if the cache should be used based on NO_CACHE environment variable.
// Cache is enabled by default and can be disabled by setting NO_CACHE=1 or NO_CACHE=true.
func (e *WindsorEnvPrinter) shouldUseCache() bool {
noCache, _ := e.shims.LookupEnv("NO_CACHE")
return noCache == "" || noCache == "0" || noCache == "false" || noCache == "False"
Expand Down
2 changes: 1 addition & 1 deletion pkg/env/windsor_env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ func TestWindsorEnv_Print(t *testing.T) {

// And a mock PrintEnvVars function
var capturedEnvVars map[string]string
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string) {
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {
capturedEnvVars = envVars
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/pipelines/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func (p *EnvPipeline) Execute(ctx context.Context) error {
}

if !quiet {
p.shell.PrintEnvVars(allEnvVars)
p.shell.PrintEnvVars(allEnvVars, hook)

var firstError error
for _, envPrinter := range p.envPrinters {
Expand Down
12 changes: 6 additions & 6 deletions pkg/pipelines/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func setupEnvMocks(t *testing.T, opts ...*SetupOptions) *EnvMocks {
baseMocks.Shell.CheckTrustedDirectoryFunc = func() error { return nil }
baseMocks.Shell.CheckResetFlagsFunc = func() (bool, error) { return false, nil }
baseMocks.Shell.GetSessionTokenFunc = func() (string, error) { return "test-token", nil }
baseMocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string) {}
baseMocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {}
baseMocks.Shell.ResetFunc = func(args ...bool) {}

return &EnvMocks{
Expand Down Expand Up @@ -521,7 +521,7 @@ func TestEnvPipeline_Execute(t *testing.T) {
}

printCalled := false
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string) {
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {
printCalled = true
}

Expand Down Expand Up @@ -562,7 +562,7 @@ func TestEnvPipeline_Execute(t *testing.T) {
}

printCalled := false
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string) {
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {
printCalled = true
}

Expand Down Expand Up @@ -594,7 +594,7 @@ func TestEnvPipeline_Execute(t *testing.T) {
return nil
}

mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string) {}
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {}

mockEnvPrinter := env.NewMockEnvPrinter()
mockEnvPrinter.PostEnvHookFunc = func(directory ...string) error {
Expand Down Expand Up @@ -628,7 +628,7 @@ func TestEnvPipeline_Execute(t *testing.T) {
return nil
}

mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string) {}
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {}

mockEnvPrinter := env.NewMockEnvPrinter()
mockEnvPrinter.PostEnvHookFunc = func(directory ...string) error {
Expand Down Expand Up @@ -780,7 +780,7 @@ func TestEnvPipeline_Execute(t *testing.T) {
pipeline.envPrinters = []env.EnvPrinter{mockEnvPrinter1, mockEnvPrinter2}

var capturedEnvVars map[string]string
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string) {
mocks.Shell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {
capturedEnvVars = envVars
}

Expand Down
6 changes: 3 additions & 3 deletions pkg/shell/mock_shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
type MockShell struct {
DefaultShell
InitializeFunc func() error
PrintEnvVarsFunc func(envVars map[string]string)
PrintEnvVarsFunc func(envVars map[string]string, export bool)
PrintAliasFunc func(envVars map[string]string)
GetProjectRootFunc func() (string, error)
ExecFunc func(command string, args ...string) (string, error)
Expand Down Expand Up @@ -71,9 +71,9 @@ func (s *MockShell) Initialize() error {
}

// PrintEnvVars calls the custom PrintEnvVarsFunc if provided.
func (s *MockShell) PrintEnvVars(envVars map[string]string) {
func (s *MockShell) PrintEnvVars(envVars map[string]string, export bool) {
if s.PrintEnvVarsFunc != nil {
s.PrintEnvVarsFunc(envVars)
s.PrintEnvVarsFunc(envVars, export)
}
}

Expand Down
6 changes: 3 additions & 3 deletions pkg/shell/mock_shell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1029,15 +1029,15 @@ func TestMockShell_PrintEnvVars(t *testing.T) {
mockShell := setupMockShellMocks(t)
called := false
expectedEnvVars := map[string]string{"TEST": "value"}
mockShell.PrintEnvVarsFunc = func(envVars map[string]string) {
mockShell.PrintEnvVarsFunc = func(envVars map[string]string, export bool) {
called = true
if envVars["TEST"] != "value" {
t.Errorf("Expected envVars[TEST] = value, got %v", envVars["TEST"])
}
}

// When PrintEnvVars is called
mockShell.PrintEnvVars(expectedEnvVars)
mockShell.PrintEnvVars(expectedEnvVars, true)

// Then the mock function should be called
if !called {
Expand All @@ -1051,7 +1051,7 @@ func TestMockShell_PrintEnvVars(t *testing.T) {

// When PrintEnvVars is called
// Then it should not panic
mockShell.PrintEnvVars(map[string]string{"TEST": "value"})
mockShell.PrintEnvVars(map[string]string{"TEST": "value"}, false)
})
}

Expand Down
30 changes: 29 additions & 1 deletion pkg/shell/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path"
"path/filepath"
"slices"
"sort"
"strings"
"sync"

Expand Down Expand Up @@ -46,7 +47,7 @@ type HookContext struct {
type Shell interface {
Initialize() error
SetVerbosity(verbose bool)
PrintEnvVars(envVars map[string]string)
PrintEnvVars(envVars map[string]string, export bool)
PrintAlias(envVars map[string]string)
GetProjectRoot() (string, error)
Exec(command string, args ...string) (string, error)
Expand Down Expand Up @@ -668,6 +669,33 @@ func (s *DefaultShell) scrubString(input string) string {
return result
}

// PrintEnvVars is a platform-specific method that will be implemented by Unix/Windows-specific files
// The export parameter controls whether to use OS-specific export commands or plain KEY=value format
func (s *DefaultShell) PrintEnvVars(envVars map[string]string, export bool) {
if export {
s.printEnvVarsWithExport(envVars)
} else {
s.printEnvVarsPlain(envVars)
}
}

// printEnvVarsPlain prints environment variables in plain KEY=value format, sorted by key.
// If a value is empty, it prints KEY= with no value. Used for non-export output scenarios.
func (s *DefaultShell) printEnvVarsPlain(envVars map[string]string) {
keys := make([]string, 0, len(envVars))
for k := range envVars {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
if envVars[k] == "" {
fmt.Printf("%s=\n", k)
} else {
fmt.Printf("%s=%s\n", k, envVars[k])
}
}
}

// Ensure DefaultShell implements the Shell interface
var _ Shell = (*DefaultShell)(nil)

Expand Down
40 changes: 10 additions & 30 deletions pkg/shell/unix_shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,76 +18,56 @@ import (
// Public Methods
// =============================================================================

// PrintEnvVars prints the provided environment variables in a sorted order.
// If the value of an environment variable is an empty string, it will print an unset command.
func (s *DefaultShell) PrintEnvVars(envVars map[string]string) {
// Create a slice to hold the keys of the envVars map
// printEnvVarsWithExport prints environment variables in sorted order using export commands.
// If a variable's value is empty, it prints an unset command instead.
func (s *DefaultShell) printEnvVarsWithExport(envVars map[string]string) {
keys := make([]string, 0, len(envVars))

// Append each key from the envVars map to the keys slice
for k := range envVars {
keys = append(keys, k)
}

// Sort the keys slice to ensure the environment variables are printed in order
sort.Strings(keys)

// Iterate over the sorted keys and print the corresponding environment variable
for _, k := range keys {
if envVars[k] == "" {
// Print unset command if the value is an empty string
fmt.Printf("unset %s\n", k)
} else {
// Print export command with the key and value
fmt.Printf("export %s=\"%s\"\n", k, envVars[k])
}
}
}

// PrintAlias prints the aliases for the shell.
// PrintAlias prints sorted aliases. Empty values print unalias; non-empty print alias with key and value.
func (s *DefaultShell) PrintAlias(aliases map[string]string) {
// Create a slice to hold the keys of the aliases map
keys := make([]string, 0, len(aliases))

// Append each key from the aliases map to the keys slice
for k := range aliases {
keys = append(keys, k)
}

// Sort the keys slice to ensure the aliases are printed in order
sort.Strings(keys)

// Iterate over the sorted keys and print the corresponding alias
for _, k := range keys {
if aliases[k] == "" {
// Print unset command if the value is an empty string
fmt.Printf("unalias %s\n", k)
} else {
// Print alias command with the key and value
fmt.Printf("alias %s=\"%s\"\n", k, aliases[k])
}
}
}

// UnsetEnvs generates a command to unset multiple environment variables.
// For Unix shells, this produces a single 'unset' command with all variables in one line.
// UnsetEnvs generates a single unset command for multiple environment variables in Unix shells.
// It prints a single 'unset' command with all provided variable names separated by spaces.
// If the input slice is empty, no output is produced.
func (s *DefaultShell) UnsetEnvs(envVars []string) {
if len(envVars) == 0 {
return
}

// Create a single unset command with all environment variables
fmt.Printf("unset %s\n", strings.Join(envVars, " "))
}

// UnsetAlias generates commands to unset multiple aliases.
// For Unix shells, this produces a separate 'unalias' command for each alias.
// UnsetAlias generates individual unalias commands for each alias in Unix shells.
// It prints a separate 'unalias' command for each alias name provided.
// If the input slice is empty, no output is produced.
func (s *DefaultShell) UnsetAlias(aliases []string) {
if len(aliases) == 0 {
return
}

// Print individual unalias commands for each alias
for _, alias := range aliases {
fmt.Printf("unalias %s\n", alias)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/shell/unix_shell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func TestDefaultShell_PrintEnvVars(t *testing.T) {

// When capturing the output of PrintEnvVars
output := captureStdout(t, func() {
shell.PrintEnvVars(envVars)
shell.PrintEnvVars(envVars, true)
})

// Then the output should match the expected output
Expand Down
Loading
Loading