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"
|
import "github.com/spf13/cobra"
|
||||||
|
|
||||||
// ApplyFlagRegistrar handles flags specific to the apply command
|
// ApplyFlagRegistry handles flags specific to the apply command
|
||||||
type ApplyFlagRegistrar struct {
|
type ApplyFlagRegistry struct {
|
||||||
*GenericFlagRegistrar
|
*GenericFlagRegistry
|
||||||
IncludeCRDs bool
|
IncludeCRDs bool
|
||||||
SkipCRDs bool
|
SkipCRDs bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewApplyFlagRegistrar creates a new ApplyFlagRegistrar
|
// NewApplyFlagRegistry creates a new ApplyFlagRegistry
|
||||||
func NewApplyFlagRegistrar() *ApplyFlagRegistrar {
|
func NewApplyFlagRegistry() *ApplyFlagRegistry {
|
||||||
return &ApplyFlagRegistrar{
|
return &ApplyFlagRegistry{
|
||||||
GenericFlagRegistrar: NewGenericFlagRegistrar(),
|
GenericFlagRegistry: NewGenericFlagRegistry(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterFlags registers apply-specific flags
|
// 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, "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")
|
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"
|
import "github.com/spf13/cobra"
|
||||||
|
|
||||||
// SyncFlagRegistrar handles flags specific to the sync command
|
// SyncFlagRegistry handles flags specific to the sync command
|
||||||
type SyncFlagRegistrar struct {
|
type SyncFlagRegistry struct {
|
||||||
*GenericFlagRegistrar
|
*GenericFlagRegistry
|
||||||
IncludeCRDs bool
|
IncludeCRDs bool
|
||||||
SkipCRDs bool
|
SkipCRDs bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSyncFlagRegistrar creates a new SyncFlagRegistrar
|
// NewSyncFlagRegistry creates a new SyncFlagRegistry
|
||||||
func NewSyncFlagRegistrar() *SyncFlagRegistrar {
|
func NewSyncFlagRegistry() *SyncFlagRegistry {
|
||||||
return &SyncFlagRegistrar{
|
return &SyncFlagRegistry{
|
||||||
GenericFlagRegistrar: NewGenericFlagRegistrar(),
|
GenericFlagRegistry: NewGenericFlagRegistry(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterFlags registers sync-specific flags
|
// 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, "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")
|
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