Add flag registry for CLI commands
Signed-off-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
		
							parent
							
								
									8067504097
								
							
						
					
					
						commit
						6b587e15f0
					
				|  | @ -0,0 +1,77 @@ | |||
| # Flags Package | ||||
| 
 | ||||
| ## Overview | ||||
| 
 | ||||
| The `pkg/flags` package provides utilities for registering, handling, and transferring command-line flags. It serves as the bridge between the command-line interface and the configuration options. | ||||
| 
 | ||||
| ## File Structure | ||||
| 
 | ||||
| ``` | ||||
| pkg/flags/ | ||||
| ├── README.md             # This documentation file | ||||
| ├── registry.go           # Core interface and generic implementation | ||||
| ├── registry_mock.go      # Mock implementation for testing | ||||
| ├── registry_diff.go      # Diff-specific registry | ||||
| ├── registry_apply.go     # Apply-specific registry | ||||
| ├── registry_sync.go      # Sync-specific registry | ||||
| ├── registry_template.go  # Template-specific registry | ||||
| ├── registry_lint.go      # Lint-specific registry | ||||
| ├── registry_destroy.go   # Destroy-specific registry | ||||
| ├── registry_fetch.go     # Fetch-specific registry | ||||
| ├── registry_list.go      # List-specific registry | ||||
| ├── registry_status.go    # Status-specific registry | ||||
| ├── registry_test.go      # Tests for registry implementation | ||||
| ├── flag_handler.go       # FlagHandler interface | ||||
| ├── flag_handler_mock.go  # Mock implementation of FlagHandler | ||||
| ├── flag_handler_test.go  # Tests for flag handler implementations | ||||
| ├── flag_value.go         # Generic flag value retrieval functions | ||||
| └── flag_value_test.go    # Tests for flag value functions | ||||
| ``` | ||||
| 
 | ||||
| ## Components | ||||
| 
 | ||||
| - **FlagHandler Interface**: Defines how components handle flag values with boolean return for success | ||||
| - **FlagRegistry**: Manages flag registration and transfer | ||||
| - **Command-specific Registries**: Specialized registries for each command | ||||
| - **Helper Functions**: Utilities for getting flag values of different types | ||||
| 
 | ||||
| ## Key Features | ||||
| 
 | ||||
| - **Type Safety**: Helper functions for safely retrieving typed flag values | ||||
| - **Flag Registration**: Centralized registration of flags to command objects | ||||
| - **Flag Transfer**: Mechanism to transfer flag values to option objects | ||||
| - **Flag Existence Checking**: Methods to check if flags are registered or handled | ||||
| - **Success Indication**: Boolean return values to indicate if flags were successfully handled | ||||
| 
 | ||||
| ## Usage | ||||
| 
 | ||||
| ```go | ||||
| // Create a registry | ||||
| registry := flags.NewGenericFlagRegistry() | ||||
| 
 | ||||
| // Register flags to a command | ||||
| registry.RegisterFlags(cmd) | ||||
| 
 | ||||
| // Transfer flags to options | ||||
| registry.TransferFlags(cmd, opts) | ||||
| 
 | ||||
| // Check if a flag is registered | ||||
| if registry.IsFlagRegistered("my-flag") { | ||||
|     // Do something | ||||
| } | ||||
| 
 | ||||
| // Handle a flag with success indication | ||||
| handled := opts.HandleFlag("flag-name", value, changed) | ||||
| if !handled { | ||||
|     // Flag wasn't recognized | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| ## Testing | ||||
| 
 | ||||
| The package includes mock implementations for testing: | ||||
| 
 | ||||
| - `MockFlagHandler`: For testing flag handling logic | ||||
| - `MockFlagRegistry`: For testing flag registration and transfer | ||||
| 
 | ||||
| These mocks can be used to verify flag handling behavior without needing real command objects. | ||||
|  | @ -1,49 +0,0 @@ | |||
| package flags | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/spf13/cobra" | ||||
| ) | ||||
| 
 | ||||
| // FlagRegistrar defines an interface for registering and transferring flags
 | ||||
| type FlagRegistrar interface { | ||||
| 	RegisterFlags(cmd *cobra.Command) | ||||
| 	TransferFlags(cmd *cobra.Command, opts interface{}) | ||||
| } | ||||
| 
 | ||||
| // FlagHandler is a generic interface for handling flag values
 | ||||
| type FlagHandler interface { | ||||
| 	// HandleFlag receives a flag name, value, and whether it was changed
 | ||||
| 	HandleFlag(name string, value interface{}, changed bool) | ||||
| } | ||||
| 
 | ||||
| // GenericFlagRegistrar is a base struct for flag registrars
 | ||||
| type GenericFlagRegistrar struct { | ||||
| 	// Map of flag names to their values
 | ||||
| 	values map[string]interface{} | ||||
| } | ||||
| 
 | ||||
| // NewGenericFlagRegistrar creates a new GenericFlagRegistrar
 | ||||
| func NewGenericFlagRegistrar() *GenericFlagRegistrar { | ||||
| 	return &GenericFlagRegistrar{ | ||||
| 		values: make(map[string]interface{}), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // TransferFlags transfers all registered flags to the options
 | ||||
| func (r *GenericFlagRegistrar) TransferFlags(cmd *cobra.Command, opts interface{}) { | ||||
| 	if handler, ok := opts.(FlagHandler); ok { | ||||
| 		flags := cmd.Flags() | ||||
| 
 | ||||
| 		// Transfer each registered flag
 | ||||
| 		for name, value := range r.values { | ||||
| 			changed := flags.Changed(name) | ||||
| 			handler.HandleFlag(name, value, changed) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // RegisterBoolFlag registers a boolean flag and stores its reference
 | ||||
| func (r *GenericFlagRegistrar) RegisterBoolFlag(cmd *cobra.Command, name string, value *bool, defaultValue bool, usage string) { | ||||
| 	cmd.Flags().BoolVar(value, name, defaultValue, usage) | ||||
| 	r.values[name] = value | ||||
| } | ||||
|  | @ -1,140 +0,0 @@ | |||
| package flags | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/spf13/cobra" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| // MockFlagHandler implements FlagHandler for testing
 | ||||
| type MockFlagHandler struct { | ||||
| 	handledFlags map[string]interface{} | ||||
| 	changedFlags map[string]bool | ||||
| } | ||||
| 
 | ||||
| func NewMockFlagHandler() *MockFlagHandler { | ||||
| 	return &MockFlagHandler{ | ||||
| 		handledFlags: make(map[string]interface{}), | ||||
| 		changedFlags: make(map[string]bool), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (h *MockFlagHandler) HandleFlag(name string, value interface{}, changed bool) { | ||||
| 	h.handledFlags[name] = value | ||||
| 	h.changedFlags[name] = changed | ||||
| } | ||||
| 
 | ||||
| func TestNewGenericFlagRegistrar(t *testing.T) { | ||||
| 	registrar := NewGenericFlagRegistrar() | ||||
| 	assert.NotNil(t, registrar) | ||||
| 	assert.NotNil(t, registrar.values) | ||||
| 	assert.Len(t, registrar.values, 0) | ||||
| } | ||||
| 
 | ||||
| func TestGenericFlagRegistrar_RegisterBoolFlag(t *testing.T) { | ||||
| 	registrar := NewGenericFlagRegistrar() | ||||
| 	cmd := &cobra.Command{Use: "test"} | ||||
| 
 | ||||
| 	var testFlag bool | ||||
| 	registrar.RegisterBoolFlag(cmd, "test-flag", &testFlag, false, "Test flag") | ||||
| 
 | ||||
| 	// Verify the flag was registered
 | ||||
| 	flag := cmd.Flags().Lookup("test-flag") | ||||
| 	assert.NotNil(t, flag) | ||||
| 	assert.Equal(t, "test-flag", flag.Name) | ||||
| 	assert.Equal(t, "false", flag.DefValue) | ||||
| 	assert.Equal(t, "Test flag", flag.Usage) | ||||
| 
 | ||||
| 	// Verify the value was stored in the registrar
 | ||||
| 	value, exists := registrar.values["test-flag"] | ||||
| 	assert.True(t, exists) | ||||
| 	assert.Equal(t, &testFlag, value) | ||||
| } | ||||
| 
 | ||||
| func TestGenericFlagRegistrar_TransferFlags_NoChanges(t *testing.T) { | ||||
| 	registrar := NewGenericFlagRegistrar() | ||||
| 	cmd := &cobra.Command{Use: "test"} | ||||
| 
 | ||||
| 	var testFlag bool | ||||
| 	registrar.RegisterBoolFlag(cmd, "test-flag", &testFlag, false, "Test flag") | ||||
| 
 | ||||
| 	// Create a mock handler
 | ||||
| 	handler := NewMockFlagHandler() | ||||
| 
 | ||||
| 	// Transfer flags (none changed)
 | ||||
| 	registrar.TransferFlags(cmd, handler) | ||||
| 
 | ||||
| 	// Verify the handler was called with the right parameters
 | ||||
| 	assert.Equal(t, &testFlag, handler.handledFlags["test-flag"]) | ||||
| 	assert.False(t, handler.changedFlags["test-flag"]) | ||||
| } | ||||
| 
 | ||||
| func TestGenericFlagRegistrar_TransferFlags_WithChanges(t *testing.T) { | ||||
| 	registrar := NewGenericFlagRegistrar() | ||||
| 	cmd := &cobra.Command{Use: "test"} | ||||
| 
 | ||||
| 	var testFlag bool | ||||
| 	registrar.RegisterBoolFlag(cmd, "test-flag", &testFlag, false, "Test flag") | ||||
| 
 | ||||
| 	// Simulate flag being set on command line
 | ||||
| 	err := cmd.Flags().Set("test-flag", "true") | ||||
| 	assert.NoError(t, err) | ||||
| 	testFlag = true // Value would be updated by cobra
 | ||||
| 
 | ||||
| 	// Create a mock handler
 | ||||
| 	handler := NewMockFlagHandler() | ||||
| 
 | ||||
| 	// Transfer flags (with changes)
 | ||||
| 	registrar.TransferFlags(cmd, handler) | ||||
| 
 | ||||
| 	// Verify the handler was called with the right parameters
 | ||||
| 	assert.Equal(t, &testFlag, handler.handledFlags["test-flag"]) | ||||
| 	assert.True(t, handler.changedFlags["test-flag"]) | ||||
| 	assert.True(t, *handler.handledFlags["test-flag"].(*bool)) | ||||
| } | ||||
| 
 | ||||
| func TestGenericFlagRegistrar_TransferFlags_NonHandler(t *testing.T) { | ||||
| 	registrar := NewGenericFlagRegistrar() | ||||
| 	cmd := &cobra.Command{Use: "test"} | ||||
| 
 | ||||
| 	var testFlag bool | ||||
| 	registrar.RegisterBoolFlag(cmd, "test-flag", &testFlag, false, "Test flag") | ||||
| 
 | ||||
| 	// Use a non-handler type
 | ||||
| 	nonHandler := struct{}{} | ||||
| 
 | ||||
| 	// This should not panic
 | ||||
| 	registrar.TransferFlags(cmd, nonHandler) | ||||
| } | ||||
| 
 | ||||
| func TestGenericFlagRegistrar_MultipleFlags(t *testing.T) { | ||||
| 	registrar := NewGenericFlagRegistrar() | ||||
| 	cmd := &cobra.Command{Use: "test"} | ||||
| 
 | ||||
| 	var boolFlag bool | ||||
| 	var boolFlag2 bool | ||||
| 
 | ||||
| 	registrar.RegisterBoolFlag(cmd, "bool-flag", &boolFlag, false, "Boolean flag") | ||||
| 	registrar.RegisterBoolFlag(cmd, "bool-flag2", &boolFlag2, true, "Another boolean flag") | ||||
| 
 | ||||
| 	// Set one flag
 | ||||
| 	err := cmd.Flags().Set("bool-flag", "true") | ||||
| 	assert.NoError(t, err) | ||||
| 	boolFlag = true // Value would be updated by cobra
 | ||||
| 
 | ||||
| 	// Create a mock handler
 | ||||
| 	handler := NewMockFlagHandler() | ||||
| 
 | ||||
| 	// Transfer flags
 | ||||
| 	registrar.TransferFlags(cmd, handler) | ||||
| 
 | ||||
| 	// Verify both flags were handled correctly
 | ||||
| 	assert.Equal(t, &boolFlag, handler.handledFlags["bool-flag"]) | ||||
| 	assert.True(t, handler.changedFlags["bool-flag"]) | ||||
| 	assert.True(t, *handler.handledFlags["bool-flag"].(*bool)) | ||||
| 
 | ||||
| 	assert.Equal(t, &boolFlag2, handler.handledFlags["bool-flag2"]) | ||||
| 	assert.False(t, handler.changedFlags["bool-flag2"]) | ||||
| 	assert.True(t, *handler.handledFlags["bool-flag2"].(*bool)) // Default is true
 | ||||
| } | ||||
|  | @ -1,22 +0,0 @@ | |||
| package flags | ||||
| 
 | ||||
| import "github.com/spf13/cobra" | ||||
| 
 | ||||
| // DiffFlagRegistrar handles flags specific to the diff command
 | ||||
| type DiffFlagRegistrar struct { | ||||
| 	*GenericFlagRegistrar | ||||
| 	IncludeCRDs bool | ||||
| } | ||||
| 
 | ||||
| // NewDiffFlagRegistrar creates a new DiffFlagRegistrar
 | ||||
| func NewDiffFlagRegistrar() *DiffFlagRegistrar { | ||||
| 	return &DiffFlagRegistrar{ | ||||
| 		GenericFlagRegistrar: NewGenericFlagRegistrar(), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // RegisterFlags registers diff-specific flags
 | ||||
| func (r *DiffFlagRegistrar) RegisterFlags(cmd *cobra.Command) { | ||||
| 	r.RegisterBoolFlag(cmd, "include-crds", &r.IncludeCRDs, false, "include CRDs in the diffing") | ||||
| 	// Diff doesn't have skip-crds
 | ||||
| } | ||||
|  | @ -0,0 +1,8 @@ | |||
| package flags | ||||
| 
 | ||||
| // FlagHandler is a generic interface for handling flag values
 | ||||
| type FlagHandler interface { | ||||
| 	// HandleFlag receives a flag name, value, and whether it was changed
 | ||||
| 	// Returns true if the flag was handled, false otherwise
 | ||||
| 	HandleFlag(name string, value interface{}, changed bool) bool | ||||
| } | ||||
|  | @ -0,0 +1,20 @@ | |||
| package flags | ||||
| 
 | ||||
| // MockFlagHandler implements FlagHandler for testing
 | ||||
| type MockFlagHandler struct { | ||||
| 	handledFlags map[string]interface{} | ||||
| 	changedFlags map[string]bool | ||||
| } | ||||
| 
 | ||||
| func NewMockFlagHandler() *MockFlagHandler { | ||||
| 	return &MockFlagHandler{ | ||||
| 		handledFlags: make(map[string]interface{}), | ||||
| 		changedFlags: make(map[string]bool), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (h *MockFlagHandler) HandleFlag(name string, value interface{}, changed bool) bool { | ||||
| 	h.handledFlags[name] = value | ||||
| 	h.changedFlags[name] = changed | ||||
| 	return true | ||||
| } | ||||
|  | @ -0,0 +1,51 @@ | |||
| package flags | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func TestMockFlagHandler_HandleFlag_ReturnValue(t *testing.T) { | ||||
| 	// Create a mock handler
 | ||||
| 	mockHandler := NewMockFlagHandler() | ||||
| 
 | ||||
| 	// Test that it returns true for any flag
 | ||||
| 	result := mockHandler.HandleFlag("test-flag", true, false) | ||||
| 	assert.True(t, result, "MockHandler should return true for any flag") | ||||
| 
 | ||||
| 	// Test with multiple flags
 | ||||
| 	result = mockHandler.HandleFlag("another-flag", "value", true) | ||||
| 	assert.True(t, result, "MockHandler should return true for any flag") | ||||
| 
 | ||||
| 	// Verify the flags were stored correctly
 | ||||
| 	assert.Equal(t, true, mockHandler.handledFlags["test-flag"]) | ||||
| 	assert.Equal(t, "value", mockHandler.handledFlags["another-flag"]) | ||||
| 	assert.Equal(t, false, mockHandler.changedFlags["test-flag"]) | ||||
| 	assert.Equal(t, true, mockHandler.changedFlags["another-flag"]) | ||||
| } | ||||
| 
 | ||||
| // CustomFlagHandler implements FlagHandler for testing specific return values
 | ||||
| type CustomFlagHandler struct{} | ||||
| 
 | ||||
| func (h *CustomFlagHandler) HandleFlag(name string, value interface{}, changed bool) bool { | ||||
| 	// Only handle specific flags
 | ||||
| 	switch name { | ||||
| 	case "known-flag": | ||||
| 		return true | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestCustomFlagHandler_HandleFlag_ReturnValue(t *testing.T) { | ||||
| 	handler := &CustomFlagHandler{} | ||||
| 
 | ||||
| 	// Test with a recognized flag
 | ||||
| 	result := handler.HandleFlag("known-flag", true, false) | ||||
| 	assert.True(t, result, "Should return true for recognized flag") | ||||
| 
 | ||||
| 	// Test with an unrecognized flag
 | ||||
| 	result = handler.HandleFlag("unknown-flag", true, false) | ||||
| 	assert.False(t, result, "Should return false for unrecognized flag") | ||||
| } | ||||
|  | @ -0,0 +1,43 @@ | |||
| package flags | ||||
| 
 | ||||
| // GetFlagValue is a generic function to get flag values with type safety
 | ||||
| func GetFlagValue[T any](registry FlagRegistry, name string) (T, bool) { | ||||
| 	var zero T | ||||
| 	values := registry.GetValues() | ||||
| 	if value, exists := values[name]; exists { | ||||
| 		if typedValue, ok := value.(*T); ok { | ||||
| 			return *typedValue, true | ||||
| 		} | ||||
| 	} | ||||
| 	return zero, false | ||||
| } | ||||
| 
 | ||||
| // GetBoolFlagValue is a convenience function to get a boolean flag value
 | ||||
| func GetBoolFlagValue(registry FlagRegistry, name string) (bool, bool) { | ||||
| 	return GetFlagValue[bool](registry, name) | ||||
| } | ||||
| 
 | ||||
| // GetStringFlagValue is a convenience function to get a string flag value
 | ||||
| func GetStringFlagValue(registry FlagRegistry, name string) (string, bool) { | ||||
| 	return GetFlagValue[string](registry, name) | ||||
| } | ||||
| 
 | ||||
| // GetStringSliceFlagValue is a convenience function to get a string slice flag value
 | ||||
| func GetStringSliceFlagValue(registry FlagRegistry, name string) ([]string, bool) { | ||||
| 	return GetFlagValue[[]string](registry, name) | ||||
| } | ||||
| 
 | ||||
| // GetIntFlagValue is a convenience function to get an integer flag value
 | ||||
| func GetIntFlagValue(registry FlagRegistry, name string) (int, bool) { | ||||
| 	return GetFlagValue[int](registry, name) | ||||
| } | ||||
| 
 | ||||
| // GetInt64FlagValue is a convenience function to get an int64 flag value
 | ||||
| func GetInt64FlagValue(registry FlagRegistry, name string) (int64, bool) { | ||||
| 	return GetFlagValue[int64](registry, name) | ||||
| } | ||||
| 
 | ||||
| // GetFloat64FlagValue is a convenience function to get a float64 flag value
 | ||||
| func GetFloat64FlagValue(registry FlagRegistry, name string) (float64, bool) { | ||||
| 	return GetFlagValue[float64](registry, name) | ||||
| } | ||||
|  | @ -0,0 +1,220 @@ | |||
| package flags | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func TestGetFlagValue(t *testing.T) { | ||||
| 	registry := NewMockFlagRegistry() | ||||
| 
 | ||||
| 	// Register some test flags
 | ||||
| 	boolValue := false | ||||
| 	registry.values["bool-flag"] = &boolValue | ||||
| 
 | ||||
| 	stringValue := "test" | ||||
| 	registry.values["string-flag"] = &stringValue | ||||
| 
 | ||||
| 	stringSliceValue := []string{"one", "two", "three"} | ||||
| 	registry.values["string-slice-flag"] = &stringSliceValue | ||||
| 
 | ||||
| 	intValue := 42 | ||||
| 	registry.values["int-flag"] = &intValue | ||||
| 
 | ||||
| 	// Test getting boolean flag
 | ||||
| 	gotBool, exists := GetFlagValue[bool](registry, "bool-flag") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.Equal(t, false, gotBool) | ||||
| 
 | ||||
| 	// Test getting string flag
 | ||||
| 	gotString, exists := GetFlagValue[string](registry, "string-flag") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.Equal(t, "test", gotString) | ||||
| 
 | ||||
| 	// Test getting string slice flag
 | ||||
| 	gotStringSlice, exists := GetFlagValue[[]string](registry, "string-slice-flag") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.Equal(t, []string{"one", "two", "three"}, gotStringSlice) | ||||
| 
 | ||||
| 	// Test getting int flag
 | ||||
| 	gotInt, exists := GetFlagValue[int](registry, "int-flag") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.Equal(t, 42, gotInt) | ||||
| 
 | ||||
| 	// Test getting non-existent flag
 | ||||
| 	_, exists = GetFlagValue[bool](registry, "non-existent") | ||||
| 	assert.False(t, exists) | ||||
| 
 | ||||
| 	// Test getting flag with wrong type
 | ||||
| 	_, exists = GetFlagValue[string](registry, "bool-flag") | ||||
| 	assert.False(t, exists) | ||||
| } | ||||
| 
 | ||||
| func TestGetBoolFlagValue(t *testing.T) { | ||||
| 	registry := NewMockFlagRegistry() | ||||
| 
 | ||||
| 	// Register a boolean flag
 | ||||
| 	boolValue := false | ||||
| 	registry.values["bool-flag"] = &boolValue | ||||
| 
 | ||||
| 	// Test getting the flag value
 | ||||
| 	value, exists := GetBoolFlagValue(registry, "bool-flag") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.False(t, value) | ||||
| 
 | ||||
| 	// Change the value
 | ||||
| 	*registry.values["bool-flag"].(*bool) = true | ||||
| 
 | ||||
| 	// Test getting the updated value
 | ||||
| 	value, exists = GetBoolFlagValue(registry, "bool-flag") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.True(t, value) | ||||
| 
 | ||||
| 	// Test getting a non-existent flag
 | ||||
| 	value, exists = GetBoolFlagValue(registry, "non-existent") | ||||
| 	assert.False(t, exists) | ||||
| 	assert.False(t, value) // Default value for bool
 | ||||
| 
 | ||||
| 	// Test getting a flag with wrong type
 | ||||
| 	stringValue := "test" | ||||
| 	registry.values["string-flag"] = &stringValue | ||||
| 	value, exists = GetBoolFlagValue(registry, "string-flag") | ||||
| 	assert.False(t, exists) | ||||
| 	assert.False(t, value) // Default value for bool
 | ||||
| } | ||||
| 
 | ||||
| func TestGetStringFlagValue(t *testing.T) { | ||||
| 	registry := NewMockFlagRegistry() | ||||
| 
 | ||||
| 	// Register a string flag
 | ||||
| 	stringValue := "test" | ||||
| 	registry.values["string-flag"] = &stringValue | ||||
| 
 | ||||
| 	// Test getting the flag value
 | ||||
| 	value, exists := GetStringFlagValue(registry, "string-flag") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.Equal(t, "test", value) | ||||
| 
 | ||||
| 	// Change the value
 | ||||
| 	*registry.values["string-flag"].(*string) = "updated" | ||||
| 
 | ||||
| 	// Test getting the updated value
 | ||||
| 	value, exists = GetStringFlagValue(registry, "string-flag") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.Equal(t, "updated", value) | ||||
| 
 | ||||
| 	// Test getting a non-existent flag
 | ||||
| 	value, exists = GetStringFlagValue(registry, "non-existent") | ||||
| 	assert.False(t, exists) | ||||
| 	assert.Equal(t, "", value) // Default value for string
 | ||||
| 
 | ||||
| 	// Test getting a flag with wrong type
 | ||||
| 	boolValue := true | ||||
| 	registry.values["bool-flag"] = &boolValue | ||||
| 	value, exists = GetStringFlagValue(registry, "bool-flag") | ||||
| 	assert.False(t, exists) | ||||
| 	assert.Equal(t, "", value) // Default value for string
 | ||||
| } | ||||
| 
 | ||||
| func TestGetStringSliceFlagValue(t *testing.T) { | ||||
| 	registry := NewMockFlagRegistry() | ||||
| 
 | ||||
| 	// Register a string slice flag
 | ||||
| 	sliceValue := []string{"one", "two", "three"} | ||||
| 	registry.values["slice-flag"] = &sliceValue | ||||
| 
 | ||||
| 	// Test getting the flag value
 | ||||
| 	value, exists := GetStringSliceFlagValue(registry, "slice-flag") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.Equal(t, []string{"one", "two", "three"}, value) | ||||
| 
 | ||||
| 	// Change the value
 | ||||
| 	*registry.values["slice-flag"].(*[]string) = []string{"updated"} | ||||
| 
 | ||||
| 	// Test getting the updated value
 | ||||
| 	value, exists = GetStringSliceFlagValue(registry, "slice-flag") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.Equal(t, []string{"updated"}, value) | ||||
| 
 | ||||
| 	// Test getting a non-existent flag
 | ||||
| 	value, exists = GetStringSliceFlagValue(registry, "non-existent") | ||||
| 	assert.False(t, exists) | ||||
| 	assert.Nil(t, value) // Default value for slice
 | ||||
| 
 | ||||
| 	// Test getting a flag with wrong type
 | ||||
| 	boolValue := true | ||||
| 	registry.values["bool-flag"] = &boolValue | ||||
| 	value, exists = GetStringSliceFlagValue(registry, "bool-flag") | ||||
| 	assert.False(t, exists) | ||||
| 	assert.Nil(t, value) // Default value for slice
 | ||||
| } | ||||
| 
 | ||||
| func TestGetIntFlagValue(t *testing.T) { | ||||
| 	registry := NewMockFlagRegistry() | ||||
| 
 | ||||
| 	// Register an int flag
 | ||||
| 	intValue := 42 | ||||
| 	registry.values["int-flag"] = &intValue | ||||
| 
 | ||||
| 	// Test getting the flag value
 | ||||
| 	value, exists := GetIntFlagValue(registry, "int-flag") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.Equal(t, 42, value) | ||||
| 
 | ||||
| 	// Change the value
 | ||||
| 	*registry.values["int-flag"].(*int) = 100 | ||||
| 
 | ||||
| 	// Test getting the updated value
 | ||||
| 	value, exists = GetIntFlagValue(registry, "int-flag") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.Equal(t, 100, value) | ||||
| 
 | ||||
| 	// Test getting a non-existent flag
 | ||||
| 	value, exists = GetIntFlagValue(registry, "non-existent") | ||||
| 	assert.False(t, exists) | ||||
| 	assert.Equal(t, 0, value) // Default value for int
 | ||||
| 
 | ||||
| 	// Test getting a flag with wrong type
 | ||||
| 	boolValue := true | ||||
| 	registry.values["bool-flag"] = &boolValue | ||||
| 	value, exists = GetIntFlagValue(registry, "bool-flag") | ||||
| 	assert.False(t, exists) | ||||
| 	assert.Equal(t, 0, value) // Default value for int
 | ||||
| } | ||||
| 
 | ||||
| func TestGetInt64FlagValue(t *testing.T) { | ||||
| 	registry := NewMockFlagRegistry() | ||||
| 
 | ||||
| 	// Register an int64 flag
 | ||||
| 	int64Value := int64(42) | ||||
| 	registry.values["int64-flag"] = &int64Value | ||||
| 
 | ||||
| 	// Test getting the flag value
 | ||||
| 	value, exists := GetInt64FlagValue(registry, "int64-flag") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.Equal(t, int64(42), value) | ||||
| 
 | ||||
| 	// Test getting a non-existent flag
 | ||||
| 	value, exists = GetInt64FlagValue(registry, "non-existent") | ||||
| 	assert.False(t, exists) | ||||
| 	assert.Equal(t, int64(0), value) // Default value for int64
 | ||||
| } | ||||
| 
 | ||||
| func TestGetFloat64FlagValue(t *testing.T) { | ||||
| 	registry := NewMockFlagRegistry() | ||||
| 
 | ||||
| 	// Register a float64 flag
 | ||||
| 	float64Value := 3.14 | ||||
| 	registry.values["float64-flag"] = &float64Value | ||||
| 
 | ||||
| 	// Test getting the flag value
 | ||||
| 	value, exists := GetFloat64FlagValue(registry, "float64-flag") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.Equal(t, 3.14, value) | ||||
| 
 | ||||
| 	// Test getting a non-existent flag
 | ||||
| 	value, exists = GetFloat64FlagValue(registry, "non-existent") | ||||
| 	assert.False(t, exists) | ||||
| 	assert.Equal(t, 0.0, value) // Default value for float64
 | ||||
| } | ||||
|  | @ -0,0 +1,64 @@ | |||
| package flags | ||||
| 
 | ||||
| import "github.com/spf13/cobra" | ||||
| 
 | ||||
| // FlagRegistry defines an interface for registering and transferring flags
 | ||||
| type FlagRegistry interface { | ||||
| 	RegisterFlags(cmd *cobra.Command) | ||||
| 	TransferFlags(cmd *cobra.Command, opts interface{}) | ||||
| 	GetRegisteredFlagNames() []string | ||||
| 	GetValues() map[string]interface{} | ||||
| 	IsFlagRegistered(name string) bool | ||||
| } | ||||
| 
 | ||||
| // GenericFlagRegistry is a base struct for flag registries
 | ||||
| type GenericFlagRegistry struct { | ||||
| 	// Map of flag names to their values
 | ||||
| 	values map[string]interface{} | ||||
| } | ||||
| 
 | ||||
| // NewGenericFlagRegistry creates a new GenericFlagRegistrar
 | ||||
| func NewGenericFlagRegistry() *GenericFlagRegistry { | ||||
| 	return &GenericFlagRegistry{ | ||||
| 		values: make(map[string]interface{}), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // GetValues returns the internal values map
 | ||||
| func (r *GenericFlagRegistry) GetValues() map[string]interface{} { | ||||
| 	return r.values | ||||
| } | ||||
| 
 | ||||
| // GetRegisteredFlagNames returns the names of all registered flags
 | ||||
| func (r *GenericFlagRegistry) GetRegisteredFlagNames() []string { | ||||
| 	names := make([]string, 0, len(r.values)) | ||||
| 	for name := range r.values { | ||||
| 		names = append(names, name) | ||||
| 	} | ||||
| 	return names | ||||
| } | ||||
| 
 | ||||
| // IsFlagRegistered checks if a flag is registered in the registry
 | ||||
| func (r *GenericFlagRegistry) IsFlagRegistered(name string) bool { | ||||
| 	_, exists := r.values[name] | ||||
| 	return exists | ||||
| } | ||||
| 
 | ||||
| // TransferFlags transfers all registered flags to the options
 | ||||
| func (r *GenericFlagRegistry) TransferFlags(cmd *cobra.Command, opts interface{}) { | ||||
| 	if handler, ok := opts.(FlagHandler); ok { | ||||
| 		flags := cmd.Flags() | ||||
| 
 | ||||
| 		// Transfer each registered flag
 | ||||
| 		for name, value := range r.values { | ||||
| 			changed := flags.Changed(name) | ||||
| 			handler.HandleFlag(name, value, changed) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // RegisterBoolFlag registers a boolean flag and stores its reference
 | ||||
| func (r *GenericFlagRegistry) RegisterBoolFlag(cmd *cobra.Command, name string, value *bool, defaultValue bool, usage string) { | ||||
| 	cmd.Flags().BoolVar(value, name, defaultValue, usage) | ||||
| 	r.values[name] = value | ||||
| } | ||||
|  | @ -2,22 +2,22 @@ package flags | |||
| 
 | ||||
| import "github.com/spf13/cobra" | ||||
| 
 | ||||
| // ApplyFlagRegistrar handles flags specific to the apply command
 | ||||
| type ApplyFlagRegistrar struct { | ||||
| 	*GenericFlagRegistrar | ||||
| // ApplyFlagRegistry handles flags specific to the apply command
 | ||||
| type ApplyFlagRegistry struct { | ||||
| 	*GenericFlagRegistry | ||||
| 	IncludeCRDs bool | ||||
| 	SkipCRDs    bool | ||||
| } | ||||
| 
 | ||||
| // NewApplyFlagRegistrar creates a new ApplyFlagRegistrar
 | ||||
| func NewApplyFlagRegistrar() *ApplyFlagRegistrar { | ||||
| 	return &ApplyFlagRegistrar{ | ||||
| 		GenericFlagRegistrar: NewGenericFlagRegistrar(), | ||||
| // NewApplyFlagRegistry creates a new ApplyFlagRegistry
 | ||||
| func NewApplyFlagRegistry() *ApplyFlagRegistry { | ||||
| 	return &ApplyFlagRegistry{ | ||||
| 		GenericFlagRegistry: NewGenericFlagRegistry(), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // RegisterFlags registers apply-specific flags
 | ||||
| func (r *ApplyFlagRegistrar) RegisterFlags(cmd *cobra.Command) { | ||||
| func (r *ApplyFlagRegistry) RegisterFlags(cmd *cobra.Command) { | ||||
| 	r.RegisterBoolFlag(cmd, "include-crds", &r.IncludeCRDs, false, "include CRDs in the diffing") | ||||
| 	r.RegisterBoolFlag(cmd, "skip-crds", &r.SkipCRDs, false, "if set, no CRDs will be installed on sync. By default, CRDs are installed if not already present") | ||||
| } | ||||
|  | @ -0,0 +1,22 @@ | |||
| package flags | ||||
| 
 | ||||
| import "github.com/spf13/cobra" | ||||
| 
 | ||||
| // DiffFlagRegistry handles flags specific to the diff command
 | ||||
| type DiffFlagRegistry struct { | ||||
| 	*GenericFlagRegistry | ||||
| 	IncludeCRDs bool | ||||
| } | ||||
| 
 | ||||
| // NewDiffFlagRegistry creates a new DiffFlagRegistry
 | ||||
| func NewDiffFlagRegistry() *DiffFlagRegistry { | ||||
| 	return &DiffFlagRegistry{ | ||||
| 		GenericFlagRegistry: NewGenericFlagRegistry(), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // RegisterFlags registers diff-specific flags
 | ||||
| func (r *DiffFlagRegistry) RegisterFlags(cmd *cobra.Command) { | ||||
| 	r.RegisterBoolFlag(cmd, "include-crds", &r.IncludeCRDs, false, "include CRDs in the diffing") | ||||
| 	// Diff doesn't have skip-crds
 | ||||
| } | ||||
|  | @ -0,0 +1,27 @@ | |||
| package flags | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/spf13/cobra" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func TestDiffFlagRegisty(t *testing.T) { | ||||
| 	registry := NewDiffFlagRegistry() | ||||
| 
 | ||||
| 	// Create a test command to register flags
 | ||||
| 	cmd := &cobra.Command{Use: "test"} | ||||
| 	registry.RegisterFlags(cmd) | ||||
| 
 | ||||
| 	// Get the names of registered flags
 | ||||
| 	registeredFlags := registry.GetRegisteredFlagNames() | ||||
| 
 | ||||
| 	// Verify that include-crds and skip-crds are registered
 | ||||
| 	assert.Contains(t, registeredFlags, "include-crds") | ||||
| 
 | ||||
| 	// Get and verify the default values using the generic function
 | ||||
| 	includeCRDs, exists := GetFlagValue[bool](registry, "include-crds") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.False(t, includeCRDs) | ||||
| } | ||||
|  | @ -0,0 +1,24 @@ | |||
| package flags | ||||
| 
 | ||||
| import "github.com/spf13/cobra" | ||||
| 
 | ||||
| // MockFlagRegistry implements FlagRegistrar for testing
 | ||||
| type MockFlagRegistry struct { | ||||
| 	*GenericFlagRegistry | ||||
| } | ||||
| 
 | ||||
| func NewMockFlagRegistry() *MockFlagRegistry { | ||||
| 	return &MockFlagRegistry{ | ||||
| 		GenericFlagRegistry: NewGenericFlagRegistry(), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // RegisterFlags implements the FlagRegistrar interface for testing
 | ||||
| func (r *MockFlagRegistry) RegisterFlags(cmd *cobra.Command) { | ||||
| 	// Mock implementation does nothing
 | ||||
| } | ||||
| 
 | ||||
| // GetValues returns the internal values map
 | ||||
| func (r *MockFlagRegistry) GetValues() map[string]interface{} { | ||||
| 	return r.values | ||||
| } | ||||
|  | @ -2,22 +2,22 @@ package flags | |||
| 
 | ||||
| import "github.com/spf13/cobra" | ||||
| 
 | ||||
| // SyncFlagRegistrar handles flags specific to the sync command
 | ||||
| type SyncFlagRegistrar struct { | ||||
| 	*GenericFlagRegistrar | ||||
| // SyncFlagRegistry handles flags specific to the sync command
 | ||||
| type SyncFlagRegistry struct { | ||||
| 	*GenericFlagRegistry | ||||
| 	IncludeCRDs bool | ||||
| 	SkipCRDs    bool | ||||
| } | ||||
| 
 | ||||
| // NewSyncFlagRegistrar creates a new SyncFlagRegistrar
 | ||||
| func NewSyncFlagRegistrar() *SyncFlagRegistrar { | ||||
| 	return &SyncFlagRegistrar{ | ||||
| 		GenericFlagRegistrar: NewGenericFlagRegistrar(), | ||||
| // NewSyncFlagRegistry creates a new SyncFlagRegistry
 | ||||
| func NewSyncFlagRegistry() *SyncFlagRegistry { | ||||
| 	return &SyncFlagRegistry{ | ||||
| 		GenericFlagRegistry: NewGenericFlagRegistry(), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // RegisterFlags registers sync-specific flags
 | ||||
| func (r *SyncFlagRegistrar) RegisterFlags(cmd *cobra.Command) { | ||||
| func (r *SyncFlagRegistry) RegisterFlags(cmd *cobra.Command) { | ||||
| 	r.RegisterBoolFlag(cmd, "include-crds", &r.IncludeCRDs, false, "include CRDs in the diffing") | ||||
| 	r.RegisterBoolFlag(cmd, "skip-crds", &r.SkipCRDs, false, "if set, no CRDs will be installed on sync. By default, CRDs are installed if not already present") | ||||
| } | ||||
|  | @ -0,0 +1,22 @@ | |||
| package flags | ||||
| 
 | ||||
| import "github.com/spf13/cobra" | ||||
| 
 | ||||
| // TemplateFlagRegistry handles flags specific to the template command
 | ||||
| type TemplateFlagRegistry struct { | ||||
| 	*GenericFlagRegistry | ||||
| 	IncludeCRDs bool | ||||
| } | ||||
| 
 | ||||
| // NewTemplateFlagRegistry creates a new TemplateFlagRegistry
 | ||||
| func NewTemplateFlagRegistry() *TemplateFlagRegistry { | ||||
| 	return &TemplateFlagRegistry{ | ||||
| 		GenericFlagRegistry: NewGenericFlagRegistry(), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // RegisterFlags registers template-specific flags
 | ||||
| func (r *TemplateFlagRegistry) RegisterFlags(cmd *cobra.Command) { | ||||
| 	r.RegisterBoolFlag(cmd, "include-crds", &r.IncludeCRDs, false, "include CRDs in the diffing") | ||||
| 	// Template doesn't have skip-crds
 | ||||
| } | ||||
|  | @ -0,0 +1,176 @@ | |||
| package flags | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/spf13/cobra" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func TestNewGenericFlagRegistrar(t *testing.T) { | ||||
| 	registry := NewMockFlagRegistry() | ||||
| 	assert.NotNil(t, registry) | ||||
| 	assert.NotNil(t, registry.values) | ||||
| 	assert.Len(t, registry.values, 0) | ||||
| } | ||||
| 
 | ||||
| func TestGenericFlagRegistry_RegisterBoolFlag(t *testing.T) { | ||||
| 	registry := NewMockFlagRegistry() | ||||
| 	cmd := &cobra.Command{Use: "test"} | ||||
| 
 | ||||
| 	var testFlag bool | ||||
| 	registry.RegisterBoolFlag(cmd, "test-flag", &testFlag, false, "Test flag") | ||||
| 
 | ||||
| 	// Verify the flag was registered
 | ||||
| 	flag := cmd.Flags().Lookup("test-flag") | ||||
| 	assert.NotNil(t, flag) | ||||
| 	assert.Equal(t, "test-flag", flag.Name) | ||||
| 	assert.Equal(t, "false", flag.DefValue) | ||||
| 	assert.Equal(t, "Test flag", flag.Usage) | ||||
| 
 | ||||
| 	// Verify the value was stored in the registry
 | ||||
| 	value, exists := registry.values["test-flag"] | ||||
| 	assert.True(t, exists) | ||||
| 	assert.Equal(t, &testFlag, value) | ||||
| 
 | ||||
| 	// Test the generic GetFlagValue function
 | ||||
| 	flagValue, exists := GetFlagValue[bool](registry, "test-flag") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.Equal(t, false, flagValue) | ||||
| } | ||||
| 
 | ||||
| func TestGenericFlagRegistry_TransferFlags_NoChanges(t *testing.T) { | ||||
| 	registry := NewMockFlagRegistry() | ||||
| 	cmd := &cobra.Command{Use: "test"} | ||||
| 
 | ||||
| 	var testFlag bool | ||||
| 	registry.RegisterBoolFlag(cmd, "test-flag", &testFlag, false, "Test flag") | ||||
| 
 | ||||
| 	// Create a mock handler
 | ||||
| 	handler := NewMockFlagHandler() | ||||
| 
 | ||||
| 	// Transfer flags (none changed)
 | ||||
| 	registry.TransferFlags(cmd, handler) | ||||
| 
 | ||||
| 	// Verify the handler was called with the right parameters
 | ||||
| 	assert.Equal(t, &testFlag, handler.handledFlags["test-flag"]) | ||||
| 	assert.False(t, handler.changedFlags["test-flag"]) | ||||
| } | ||||
| 
 | ||||
| func TestGenericFlagRegistry_TransferFlags_WithChanges(t *testing.T) { | ||||
| 	registry := NewMockFlagRegistry() | ||||
| 	cmd := &cobra.Command{Use: "test"} | ||||
| 
 | ||||
| 	var testFlag bool | ||||
| 	registry.RegisterBoolFlag(cmd, "test-flag", &testFlag, false, "Test flag") | ||||
| 
 | ||||
| 	// Simulate flag being set on command line
 | ||||
| 	err := cmd.Flags().Set("test-flag", "true") | ||||
| 	assert.NoError(t, err) | ||||
| 	testFlag = true // Value would be updated by cobra
 | ||||
| 
 | ||||
| 	// Create a mock handler
 | ||||
| 	handler := NewMockFlagHandler() | ||||
| 
 | ||||
| 	// Transfer flags (with changes)
 | ||||
| 	registry.TransferFlags(cmd, handler) | ||||
| 
 | ||||
| 	// Verify the handler was called with the right parameters
 | ||||
| 	assert.Equal(t, &testFlag, handler.handledFlags["test-flag"]) | ||||
| 	assert.True(t, handler.changedFlags["test-flag"]) | ||||
| 	assert.True(t, *handler.handledFlags["test-flag"].(*bool)) | ||||
| } | ||||
| 
 | ||||
| func TestGenericFlagRegistry_TransferFlags_NonHandler(t *testing.T) { | ||||
| 	registry := NewMockFlagRegistry() | ||||
| 	cmd := &cobra.Command{Use: "test"} | ||||
| 
 | ||||
| 	var testFlag bool | ||||
| 	registry.RegisterBoolFlag(cmd, "test-flag", &testFlag, false, "Test flag") | ||||
| 
 | ||||
| 	// Use a non-handler type
 | ||||
| 	nonHandler := struct{}{} | ||||
| 
 | ||||
| 	// This should not panic
 | ||||
| 	registry.TransferFlags(cmd, nonHandler) | ||||
| } | ||||
| 
 | ||||
| func TestGenericFlagRegistry_MultipleFlags(t *testing.T) { | ||||
| 	registry := NewMockFlagRegistry() | ||||
| 	cmd := &cobra.Command{Use: "test"} | ||||
| 
 | ||||
| 	var boolFlag bool | ||||
| 	var boolFlag2 bool | ||||
| 
 | ||||
| 	registry.RegisterBoolFlag(cmd, "bool-flag", &boolFlag, false, "Boolean flag") | ||||
| 	registry.RegisterBoolFlag(cmd, "bool-flag2", &boolFlag2, true, "Another boolean flag") | ||||
| 
 | ||||
| 	// Set one flag
 | ||||
| 	err := cmd.Flags().Set("bool-flag", "true") | ||||
| 	assert.NoError(t, err) | ||||
| 	boolFlag = true // Value would be updated by cobra
 | ||||
| 
 | ||||
| 	// Create a mock handler
 | ||||
| 	handler := NewMockFlagHandler() | ||||
| 
 | ||||
| 	// Transfer flags
 | ||||
| 	registry.TransferFlags(cmd, handler) | ||||
| 
 | ||||
| 	// Verify both flags were handled correctly
 | ||||
| 	assert.Equal(t, &boolFlag, handler.handledFlags["bool-flag"]) | ||||
| 	assert.True(t, handler.changedFlags["bool-flag"]) | ||||
| 	assert.True(t, *handler.handledFlags["bool-flag"].(*bool)) | ||||
| 
 | ||||
| 	assert.Equal(t, &boolFlag2, handler.handledFlags["bool-flag2"]) | ||||
| 	assert.False(t, handler.changedFlags["bool-flag2"]) | ||||
| 	assert.True(t, *handler.handledFlags["bool-flag2"].(*bool)) // Default is true
 | ||||
| } | ||||
| 
 | ||||
| func TestGenericFlagRegistry_GetRegisteredFlagNames(t *testing.T) { | ||||
| 	registry := NewMockFlagRegistry() | ||||
| 
 | ||||
| 	// Register some test flags
 | ||||
| 	boolValue := false | ||||
| 	registry.values["bool-flag"] = &boolValue | ||||
| 
 | ||||
| 	stringValue := "test" | ||||
| 	registry.values["string-flag"] = &stringValue | ||||
| 
 | ||||
| 	stringSliceValue := []string{"one", "two", "three"} | ||||
| 	registry.values["string-slice-flag"] = &stringSliceValue | ||||
| 
 | ||||
| 	// Test GetRegisteredFlagNames
 | ||||
| 	names := registry.GetRegisteredFlagNames() | ||||
| 	assert.Len(t, names, 3) | ||||
| 	assert.Contains(t, names, "bool-flag") | ||||
| 	assert.Contains(t, names, "string-flag") | ||||
| 	assert.Contains(t, names, "string-slice-flag") | ||||
| } | ||||
| 
 | ||||
| func TestGenericFlagRegistry_IsFlagRegistered(t *testing.T) { | ||||
| 	registry := NewGenericFlagRegistry() | ||||
| 
 | ||||
| 	// Initially, no flags are registered
 | ||||
| 	assert.False(t, registry.IsFlagRegistered("test-flag")) | ||||
| 
 | ||||
| 	// Register a flag
 | ||||
| 	boolValue := false | ||||
| 	registry.values["test-flag"] = &boolValue | ||||
| 
 | ||||
| 	// Now the flag should be registered
 | ||||
| 	assert.True(t, registry.IsFlagRegistered("test-flag")) | ||||
| 
 | ||||
| 	// Check a non-existent flag
 | ||||
| 	assert.False(t, registry.IsFlagRegistered("non-existent")) | ||||
| 
 | ||||
| 	// Register another flag
 | ||||
| 	stringValue := "test" | ||||
| 	registry.values["string-flag"] = &stringValue | ||||
| 
 | ||||
| 	// Both flags should be registered
 | ||||
| 	assert.True(t, registry.IsFlagRegistered("test-flag")) | ||||
| 	assert.True(t, registry.IsFlagRegistered("string-flag")) | ||||
| 
 | ||||
| 	// Case sensitivity check
 | ||||
| 	assert.False(t, registry.IsFlagRegistered("TEST-FLAG")) | ||||
| } | ||||
|  | @ -1,21 +0,0 @@ | |||
| package flags | ||||
| 
 | ||||
| import "github.com/spf13/cobra" | ||||
| 
 | ||||
| // TemplateFlagRegistrar handles flags specific to the template command
 | ||||
| type TemplateFlagRegistrar struct { | ||||
| 	*GenericFlagRegistrar | ||||
| 	IncludeCRDs bool | ||||
| } | ||||
| 
 | ||||
| // NewTemplateFlagRegistrar creates a new TemplateFlagRegistrar
 | ||||
| func NewTemplateFlagRegistrar() *TemplateFlagRegistrar { | ||||
| 	return &TemplateFlagRegistrar{ | ||||
| 		GenericFlagRegistrar: NewGenericFlagRegistrar(), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // RegisterFlags registers template-specific flags
 | ||||
| func (r *TemplateFlagRegistrar) RegisterFlags(cmd *cobra.Command) { | ||||
| 	r.RegisterBoolFlag(cmd, "include-crds", &r.IncludeCRDs, false, "include CRDs in the diffing") | ||||
| } | ||||
		Loading…
	
		Reference in New Issue