Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply --verbose flag to shell commands #325

Merged
merged 5 commits into from
Dec 31, 2024
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
3 changes: 2 additions & 1 deletion cmd/down.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -58,7 +59,7 @@ var downCmd = &cobra.Command{
}

// Print success message
fmt.Println("Windsor environment torn down successfully.")
fmt.Fprintln(os.Stderr, "Windsor environment torn down successfully.")

return nil
},
Expand Down
2 changes: 1 addition & 1 deletion cmd/down_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func TestDownCmd(t *testing.T) {
mocks := setupSafeDownCmdMocks()

// When the down command is executed
output := captureStdout(func() {
output := captureStderr(func() {
rootCmd.SetArgs([]string{"down"})
if err := Execute(mocks.MockController); err != nil {
t.Fatalf("Execute() error = %v", err)
Expand Down
3 changes: 2 additions & 1 deletion cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -119,7 +120,7 @@ var initCmd = &cobra.Command{
}

// Print the success message
fmt.Println("Initialization successful")
fmt.Fprintln(os.Stderr, "Initialization successful")
return nil
},
}
Expand Down
42 changes: 23 additions & 19 deletions cmd/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func TestInitCmd(t *testing.T) {
controller := setupSafeInitCmdMocks()

// Execute the init command and capture output
output := captureStdout(func() {
output := captureStderr(func() {
rootCmd.SetArgs([]string{"init", "test-context"})
if err := Execute(controller); err != nil {
t.Fatalf("Execute() error = %v", err)
Expand All @@ -92,7 +92,7 @@ func TestInitCmd(t *testing.T) {
controller := setupSafeInitCmdMocks()

// When the init command is executed with all flags set
output := captureStdout(func() {
output := captureStderr(func() {
rootCmd.SetArgs([]string{
"init", "test-context",
"--aws-endpoint-url", "http://localhost:4566",
Expand Down Expand Up @@ -123,7 +123,7 @@ func TestInitCmd(t *testing.T) {
controller := setupSafeInitCmdMocks()

// When the init command is executed without a context
output := captureStdout(func() {
output := captureStderr(func() {
rootCmd.SetArgs([]string{"init"})
err := Execute(controller)
if err != nil {
Expand All @@ -143,7 +143,7 @@ func TestInitCmd(t *testing.T) {
controller := setupSafeInitCmdMocks()

// When the init command is executed with an empty context name
output := captureStdout(func() {
output := captureStderr(func() {
rootCmd.SetArgs([]string{"init", ""})
err := Execute(controller)
if err != nil {
Expand All @@ -163,7 +163,7 @@ func TestInitCmd(t *testing.T) {
controller := setupSafeInitCmdMocks()

// When the init command is executed with a context name provided
output := captureStdout(func() {
output := captureStderr(func() {
rootCmd.SetArgs([]string{"init", "test-context"})
err := Execute(controller)
if err != nil {
Expand Down Expand Up @@ -438,16 +438,18 @@ func TestInitCmd(t *testing.T) {
}

// When the init command is executed
rootCmd.SetArgs([]string{"init", "test-context"})
err := Execute(controller)
if err == nil {
t.Fatalf("Expected error, got nil")
}
output := captureStderr(func() {
rootCmd.SetArgs([]string{"init", "test-context"})
err := Execute(controller)
if err == nil {
t.Fatalf("Expected error, got nil")
}
})

// Then the output should indicate the error
expectedOutput := "Error initializing components: initialize components error"
if err.Error() != expectedOutput {
t.Errorf("Expected error %q, got %q", expectedOutput, err.Error())
if !strings.Contains(output, expectedOutput) {
t.Errorf("Expected output to contain %q, got %q", expectedOutput, output)
}
})

Expand All @@ -461,16 +463,18 @@ func TestInitCmd(t *testing.T) {
}

// When the init command is executed
rootCmd.SetArgs([]string{"init", "test-context"})
err := Execute(controller)
if err == nil {
t.Fatalf("Expected error, got nil")
}
output := captureStderr(func() {
rootCmd.SetArgs([]string{"init", "test-context"})
err := Execute(controller)
if err == nil {
t.Fatalf("Expected error, got nil")
}
})

// Then the output should indicate the error
expectedOutput := "Error writing configuration files: write configuration files error"
if err.Error() != expectedOutput {
t.Errorf("Expected error %q, got %q", expectedOutput, err.Error())
if !strings.Contains(output, expectedOutput) {
t.Errorf("Expected output to contain %q, got %q", expectedOutput, output)
}
})
}
6 changes: 6 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ func preRunEInitializeCommonComponents(cmd *cobra.Command, args []string) error
return fmt.Errorf("No config handler found")
}

// Set the verbosity
shell := controller.ResolveShell()
if shell != nil {
shell.SetVerbosity(verbose)
}

// If the context is local or starts with "local-", set the defaults to the default local config
if contextName == "local" || len(contextName) > 6 && contextName[:6] == "local-" {
err := configHandler.SetDefault(config.DefaultLocalConfig)
Expand Down
38 changes: 38 additions & 0 deletions cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,44 @@ func TestRoot_preRunEInitializeCommonComponents(t *testing.T) {
}
})

t.Run("SetVerbositySuccess", func(t *testing.T) {
// Mock the global controller
originalController := controller
defer func() { controller = originalController }()

// Mock the injector
injector := di.NewInjector()

// Mock the controller
mockController := ctrl.NewMockController(injector)
controller = mockController

// Mock ResolveShell to return a mock shell
mockShell := &shell.MockShell{}
mockController.ResolveShellFunc = func() shell.Shell {
return mockShell
}

// Mock SetVerbosity to verify it is called with the correct argument
var verbositySet bool
mockShell.SetVerbosityFunc = func(v bool) {
if v {
verbositySet = true
}
}

// Set the verbosity
shell := controller.ResolveShell()
if shell != nil {
shell.SetVerbosity(true)
}

// Then the verbosity should be set
if !verbositySet {
t.Fatalf("Expected verbosity to be set, but it was not")
}
})

t.Run("ErrorLoadingConfig", func(t *testing.T) {
// Mock the global controller
originalController := controller
Expand Down
3 changes: 2 additions & 1 deletion cmd/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -125,7 +126,7 @@ var upCmd = &cobra.Command{
}

// Print success message
fmt.Println("Windsor environment set up successfully.")
fmt.Fprintln(os.Stderr, "Windsor environment set up successfully.")

return nil
},
Expand Down
2 changes: 1 addition & 1 deletion cmd/up_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func TestUpCmd(t *testing.T) {
mocks := setupSafeUpCmdMocks()

// When the up command is executed
output := captureStdout(func() {
output := captureStderr(func() {
rootCmd.SetArgs([]string{"up"})
if err := Execute(mocks.MockController); err != nil {
t.Fatalf("Execute() error = %v", err)
Expand Down
6 changes: 3 additions & 3 deletions docs/install/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ This document describes how to install the windsor CLI on your development works

=== "MacOS"
```bash
curl -L -o /usr/local/bin/windsor https://github.com/windsorcli/cli/releases/download/v0.2.0/windsor-darwin-arm64
curl -L -o /usr/local/bin/windsor https://github.com/windsorcli/cli/releases/download/v0.2.1/windsor-darwin-arm64 && \
chmod +x /usr/local/bin/windsor
```

=== "Windows"
```powershell
Invoke-WebRequest -Uri "https://github.com/windsorcli/cli/releases/download/v0.2.0/windsor-windows-amd64.exe" -OutFile "C:\Program Files\Windsor\windsor.exe"
Invoke-WebRequest -Uri "https://github.com/windsorcli/cli/releases/download/v0.2.1/windsor-windows-amd64.exe" -OutFile "C:\Program Files\Windsor\windsor.exe"
```

=== "Linux"
```bash
curl -L -o /usr/local/bin/windsor https://github.com/windsorcli/cli/releases/download/v0.2.0/windsor-linux-amd64
curl -L -o /usr/local/bin/windsor https://github.com/windsorcli/cli/releases/download/v0.2.1/windsor-linux-amd64 && \
chmod +x /usr/local/bin/windsor
```

Expand Down
6 changes: 0 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -363,16 +363,10 @@ golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
google.golang.org/api v0.214.0 h1:h2Gkq07OYi6kusGOaT/9rnNljuXmqPnaig7WGPmKbwA=
google.golang.org/api v0.214.0/go.mod h1:bYPpLG8AyeMWwDU6NXoB00xC0DFkikVvd5MfwoxjLqE=
google.golang.org/genproto v0.0.0-20241223144023-3abc09e42ca8 h1:e26eS1K69yxjjNNHYqjN49y95kcaQLJ3TL5h68dcA1E=
google.golang.org/genproto v0.0.0-20241223144023-3abc09e42ca8/go.mod h1:i5btTErZyoKCCubju3HS5LVho4nZd3yFnEp6moqeUjE=
google.golang.org/genproto v0.0.0-20241230172942-26aa7a208def h1:uz2w9bZTljGBXc3ugqrL/KOsVhQuODYyLNYXUTKrh6M=
google.golang.org/genproto v0.0.0-20241230172942-26aa7a208def/go.mod h1:zNtPaqLK0Wbf5PaSZDYDR+1t5rQoBAIMh06tpzkjvY8=
google.golang.org/genproto/googleapis/api v0.0.0-20241223144023-3abc09e42ca8 h1:st3LcW/BPi75W4q1jJTEor/QWwbNlPlDG0JTn6XhZu0=
google.golang.org/genproto/googleapis/api v0.0.0-20241223144023-3abc09e42ca8/go.mod h1:klhJGKFyG8Tn50enBn7gizg4nXGXJ+jqEREdCWaPcV4=
google.golang.org/genproto/googleapis/api v0.0.0-20241230172942-26aa7a208def h1:0Km0hi+g2KXbXL0+riZzSCKz23f4MmwicuEb00JeonI=
google.golang.org/genproto/googleapis/api v0.0.0-20241230172942-26aa7a208def/go.mod h1:u2DoMSpCXjrzqLdobRccQMc9wrnMAJ1DLng0a2yqM2Q=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8 h1:TqExAhdPaB60Ux47Cn0oLV07rGnxZzIsaRhQaqS666A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241230172942-26aa7a208def h1:4P81qv5JXI/sDNae2ClVx88cgDDA6DPilADkG9tYKz8=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241230172942-26aa7a208def/go.mod h1:bdAgzvd4kFrpykc5/AC2eLUiegK9T/qxZHD4hXYf/ho=
google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
Expand Down
2 changes: 1 addition & 1 deletion pkg/network/windows_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (n *BaseNetworkManager) ConfigureHostRoute() error {

// Add route on the host to VM guest using PowerShell command
fmt.Println("🔐 Adding route on the host to VM guest")
output, err = n.shell.Exec(
output, err = n.shell.ExecSilent(
"powershell",
"-Command",
fmt.Sprintf("New-NetRoute -DestinationPrefix %s -NextHop %s -RouteMetric 1", networkCIDR, guestIP),
Expand Down
7 changes: 5 additions & 2 deletions pkg/network/windows_network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func setupWindowsNetworkManagerMocks() *WindowsNetworkManagerMocks {

// Create a mock shell
mockShell := shell.NewMockShell()
mockShell.ExecFunc = func(command string, args ...string) (string, error) {
mockShell.ExecSilentFunc = func(command string, args ...string) (string, error) {
if command == "powershell" && args[0] == "-Command" {
return "Route added successfully", nil
}
Expand Down Expand Up @@ -250,8 +250,11 @@ func TestWindowsNetworkManager_ConfigureHostRoute(t *testing.T) {
}
return ""
}
mocks.MockShell.ExecFunc = func(command string, args ...string) (string, error) {
mocks.MockShell.ExecSilentFunc = func(command string, args ...string) (string, error) {
if command == "powershell" && args[0] == "-Command" {
if args[1] == fmt.Sprintf("Get-NetRoute -DestinationPrefix %s | Where-Object { $_.NextHop -eq '%s' }", "192.168.1.0/24", "192.168.1.2") {
return "", nil // Simulate that the route does not exist
}
if args[1] == fmt.Sprintf("New-NetRoute -DestinationPrefix %s -NextHop %s -RouteMetric 1", "192.168.1.0/24", "192.168.1.2") {
return "", fmt.Errorf("mocked shell execution error")
}
Expand Down
8 changes: 8 additions & 0 deletions pkg/shell/mock_shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type MockShell struct {
ExecProgressFunc func(message string, command string, args ...string) (string, error)
ExecSudoFunc func(message string, command string, args ...string) (string, error)
InstallHookFunc func(shellName string) error
SetVerbosityFunc func(verbose bool)
}

// NewMockShell creates a new instance of MockShell. If injector is provided, it sets the injector on MockShell.
Expand Down Expand Up @@ -103,5 +104,12 @@ func (s *MockShell) InstallHook(shellName string) error {
return nil
}

// SetVerbosity calls the custom SetVerbosityFunc if provided.
func (s *MockShell) SetVerbosity(verbose bool) {
if s.SetVerbosityFunc != nil {
s.SetVerbosityFunc(verbose)
}
}

// Ensure MockShell implements the Shell interface
var _ Shell = (*MockShell)(nil)
69 changes: 69 additions & 0 deletions pkg/shell/mock_shell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,3 +363,72 @@ func TestMockShell_ExecSudo(t *testing.T) {
}
})
}

func TestMockShell_InstallHook(t *testing.T) {
t.Run("Success", func(t *testing.T) {
// Given a mock shell with a custom InstallHookFunc implementation
injector := di.NewInjector()
mockShell := NewMockShell(injector)
mockShell.InstallHookFunc = func(shellName string) error {
return nil
}
// When calling InstallHook
err := mockShell.InstallHook("bash")
// Then no error should be returned
if err != nil {
t.Errorf("InstallHook() error = %v, want nil", err)
}
})

t.Run("NotImplemented", func(t *testing.T) {
// Given a mock shell with no InstallHookFunc implementation
mockShell := NewMockShell()
// When calling InstallHook
err := mockShell.InstallHook("bash")
// Then no error should be returned
assertError(t, err, false)
})
}

func TestMockShell_SetVerbosity(t *testing.T) {
t.Run("SetVerbosityTrue", func(t *testing.T) {
// Given a mock shell with a custom SetVerbosityFunc implementation
injector := di.NewInjector()
mockShell := NewMockShell(injector)
var verbositySet bool
mockShell.SetVerbosityFunc = func(verbose bool) {
verbositySet = verbose
}
// When setting verbosity to true
mockShell.SetVerbosity(true)
// Then verbosity should be set to true
if !verbositySet {
t.Errorf("Expected verbosity to be set to true, but it was not")
}
})

t.Run("SetVerbosityFalse", func(t *testing.T) {
// Given a mock shell with a custom SetVerbosityFunc implementation
injector := di.NewInjector()
mockShell := NewMockShell(injector)
var verbositySet bool
mockShell.SetVerbosityFunc = func(verbose bool) {
verbositySet = verbose
}
// When setting verbosity to false
mockShell.SetVerbosity(false)
// Then verbosity should be set to false
if verbositySet {
t.Errorf("Expected verbosity to be set to false, but it was not")
}
})

t.Run("NotImplemented", func(t *testing.T) {
// Given a mock shell with no SetVerbosityFunc implementation
injector := di.NewInjector()
mockShell := NewMockShell(injector)
// When calling SetVerbosity
mockShell.SetVerbosity(true)
// Then no panic or error should occur
})
}
Loading
Loading