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
2 changes: 1 addition & 1 deletion STYLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ type ConfigHandler interface {
Set(key string, value any) error
SetContextValue(key string, value any) error
Get(key string) any
SaveConfig(path string) error
SaveConfig(path string, overwrite ...bool) error
SetDefault(context v1alpha1.Context) error
GetConfig() *v1alpha1.Context
GetContext() string
Expand Down
2 changes: 1 addition & 1 deletion cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ var initCmd = &cobra.Command{
}

// Save the cli configuration
if err := configHandler.SaveConfig(cliConfigPath); err != nil {
if err := configHandler.SaveConfig(cliConfigPath, reset); err != nil {
return fmt.Errorf("Error saving config file: %w", err)
}

Expand Down
6 changes: 3 additions & 3 deletions cmd/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ func TestInitCmd(t *testing.T) {
mockConfigHandler.SetContextValueFunc = func(key string, value any) error {
return nil
}
mockConfigHandler.SaveConfigFunc = func(path string) error {
mockConfigHandler.SaveConfigFunc = func(path string, overwrite ...bool) error {
return nil
}
mocks.Controller.ResolveConfigHandlerFunc = func() config.ConfigHandler {
Expand Down Expand Up @@ -250,7 +250,7 @@ func TestInitCmd(t *testing.T) {
mockConfigHandler.SetContextValueFunc = func(key string, value any) error {
return nil
}
mockConfigHandler.SaveConfigFunc = func(path string) error {
mockConfigHandler.SaveConfigFunc = func(path string, overwrite ...bool) error {
return fmt.Errorf("save config error")
}
mocks.Controller.ResolveConfigHandlerFunc = func() config.ConfigHandler {
Expand Down Expand Up @@ -814,7 +814,7 @@ func TestInitCmd(t *testing.T) {
mockConfigHandler.GetStringFunc = func(key string, defaultValue ...string) string { return "" }
mockConfigHandler.SetDefaultFunc = func(config v1alpha1.Context) error { return nil }
mockConfigHandler.SetContextValueFunc = func(key string, value any) error { return nil }
mockConfigHandler.SaveConfigFunc = func(path string) error { return nil }
mockConfigHandler.SaveConfigFunc = func(path string, overwrite ...bool) error { return nil }
mockConfigHandler.GenerateContextIDFunc = func() error { return fmt.Errorf("generate context id error") }
mocks.Controller.ResolveConfigHandlerFunc = func() config.ConfigHandler { return mockConfigHandler }

Expand Down
2 changes: 1 addition & 1 deletion pkg/config/config_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type ConfigHandler interface {
Set(key string, value any) error
SetContextValue(key string, value any) error
Get(key string) any
SaveConfig(path string) error
SaveConfig(path string, overwrite ...bool) error
SetDefault(context v1alpha1.Context) error
GetConfig() *v1alpha1.Context
GetContext() string
Expand Down
6 changes: 3 additions & 3 deletions pkg/config/mock_config_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type MockConfigHandler struct {
GetStringMapFunc func(key string, defaultValue ...map[string]string) map[string]string
SetFunc func(key string, value any) error
SetContextValueFunc func(key string, value any) error
SaveConfigFunc func(path string) error
SaveConfigFunc func(path string, overwrite ...bool) error
GetFunc func(key string) any
SetDefaultFunc func(context v1alpha1.Context) error
GetConfigFunc func() *v1alpha1.Context
Expand Down Expand Up @@ -155,9 +155,9 @@ func (m *MockConfigHandler) Get(key string) any {
}

// SaveConfig calls the mock SaveConfigFunc if set, otherwise returns nil
func (m *MockConfigHandler) SaveConfig(path string) error {
func (m *MockConfigHandler) SaveConfig(path string, overwrite ...bool) error {
if m.SaveConfigFunc != nil {
return m.SaveConfigFunc(path)
return m.SaveConfigFunc(path, overwrite...)
}
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/config/mock_config_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ func TestMockConfigHandler_SaveConfig(t *testing.T) {
t.Run("WithPath", func(t *testing.T) {
// Given a mock config handler with SaveConfigFunc set to return an error
handler := NewMockConfigHandler()
handler.SaveConfigFunc = func(path string) error { return mockSaveErr }
handler.SaveConfigFunc = func(path string, overwrite ...bool) error { return mockSaveErr }

// When SaveConfig is called with a path
err := handler.SaveConfig("some/path")
Expand Down
16 changes: 14 additions & 2 deletions pkg/config/yaml_config_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,13 @@ func (y *YamlConfigHandler) LoadConfig(path string) error {
}

// SaveConfig saves the current configuration to the specified path. If the path is empty, it uses the previously loaded path.
// If the file does not exist, it creates an empty one.
func (y *YamlConfigHandler) SaveConfig(path string) error {
// If overwrite is false and the file exists, it will not overwrite the file
func (y *YamlConfigHandler) SaveConfig(path string, overwrite ...bool) error {
shouldOverwrite := true
if len(overwrite) > 0 {
shouldOverwrite = overwrite[0]
}

if path == "" {
if y.path == "" {
return fmt.Errorf("path cannot be empty")
Expand All @@ -92,6 +97,13 @@ func (y *YamlConfigHandler) SaveConfig(path string) error {
return fmt.Errorf("error creating directories: %w", err)
}

// Check if file exists and we should not overwrite
if !shouldOverwrite {
if _, err := y.shims.Stat(path); err == nil {
return nil
}
}

// Ensure the config version is set to "v1alpha1" before saving
y.config.Version = "v1alpha1"

Expand Down
76 changes: 76 additions & 0 deletions pkg/config/yaml_config_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,82 @@ func TestYamlConfigHandler_SaveConfig(t *testing.T) {
}
})

t.Run("OverwriteFalseWithExistingFile", func(t *testing.T) {
// Given a set of safe mocks and a YamlConfigHandler
handler, _ := setup(t)

// And a valid config path with existing file
tempDir := t.TempDir()
configPath := filepath.Join(tempDir, "existing_config.yaml")

// Create an existing file
existingContent := "existing: content"
if err := os.WriteFile(configPath, []byte(existingContent), 0644); err != nil {
t.Fatalf("Failed to create existing file: %v", err)
}

// And a key-value pair to save
handler.Set("saveKey", "newValue")

// Use real file system for this test
handler.shims = NewShims()

// When SaveConfig is called with overwrite=false
err := handler.SaveConfig(configPath, false)

// Then no error should be returned
if err != nil {
t.Errorf("Expected no error, got %v", err)
}

// And the existing file should not be modified
content, err := os.ReadFile(configPath)
if err != nil {
t.Fatalf("Failed to read file: %v", err)
}
if string(content) != existingContent {
t.Errorf("Expected file to remain unchanged, got %s", string(content))
}
})

t.Run("OverwriteTrueWithExistingFile", func(t *testing.T) {
// Given a set of safe mocks and a YamlConfigHandler
handler, _ := setup(t)

// And a valid config path with existing file
tempDir := t.TempDir()
configPath := filepath.Join(tempDir, "existing_config.yaml")

// Create an existing file
existingContent := "existing: content"
if err := os.WriteFile(configPath, []byte(existingContent), 0644); err != nil {
t.Fatalf("Failed to create existing file: %v", err)
}

// And a key-value pair to save
handler.Set("saveKey", "newValue")

// Use real file system for this test
handler.shims = NewShims()

// When SaveConfig is called with overwrite=true
err := handler.SaveConfig(configPath, true)

// Then no error should be returned
if err != nil {
t.Errorf("Expected no error, got %v", err)
}

// And the file should be overwritten with new content
content, err := os.ReadFile(configPath)
if err != nil {
t.Fatalf("Failed to read file: %v", err)
}
if string(content) == existingContent {
t.Error("Expected file to be overwritten, but it remained unchanged")
}
})

t.Run("OmitsNullValues", func(t *testing.T) {
// Given a set of safe mocks and a YamlConfigHandler
handler, _ := setup(t)
Expand Down
Loading