From 59dd75a019e76a108d9895b1df27373a4dd39682 Mon Sep 17 00:00:00 2001 From: Hubertbits <170125456+hubertbits@users.noreply.github.com> Date: Wed, 16 Apr 2025 15:48:40 +0200 Subject: [PATCH] Add missing pkg/factory for commands Signed-off-by: yxxhero --- pkg/factory/README.md | 88 ++++++++++++++++++++++++++++++++++++ pkg/factory/apply.go | 21 +++++++++ pkg/factory/apply_test.go | 45 ++++++++++++++++++ pkg/factory/diff.go | 21 +++++++++ pkg/factory/diff_test.go | 44 ++++++++++++++++++ pkg/factory/factory.go | 15 ++++++ pkg/factory/factory_test.go | 32 +++++++++++++ pkg/factory/sync.go | 21 +++++++++ pkg/factory/sync_test.go | 40 ++++++++++++++++ pkg/factory/template.go | 21 +++++++++ pkg/factory/template_test.go | 41 +++++++++++++++++ 11 files changed, 389 insertions(+) create mode 100644 pkg/factory/README.md create mode 100644 pkg/factory/apply.go create mode 100644 pkg/factory/apply_test.go create mode 100644 pkg/factory/diff.go create mode 100644 pkg/factory/diff_test.go create mode 100644 pkg/factory/factory.go create mode 100644 pkg/factory/factory_test.go create mode 100644 pkg/factory/sync.go create mode 100644 pkg/factory/sync_test.go create mode 100644 pkg/factory/template.go create mode 100644 pkg/factory/template_test.go diff --git a/pkg/factory/README.md b/pkg/factory/README.md new file mode 100644 index 00000000..c7dd35c5 --- /dev/null +++ b/pkg/factory/README.md @@ -0,0 +1,88 @@ +I need to create a comprehensive README.md for the pkg/factory package, including all files in the directory structure. + +Action: DirectAnswer + +# Factory Package + +## Overview + +The `pkg/factory` package provides factory methods for creating various components used throughout the Helmfile application. This package is responsible for wiring together different parts of the application and providing a clean API for component creation. + +## File Structure + +``` +pkg/factory/ +├── README.md # This documentation file +├── factory.go # Core factory interface and implementation +├── factory_test.go # Tests for factory implementation +├── options.go # Factory methods for creating options +├── options_test.go # Tests for options factory methods +├── command.go # Factory methods for creating commands +├── command_test.go # Tests for command factory methods +├── helmexec.go # Factory methods for Helm executor +├── helmexec_test.go # Tests for Helm executor factory +├── environment.go # Environment factory methods +├── environment_test.go # Tests for environment factory +├── state.go # State factory methods +├── state_test.go # Tests for state factory +└── mock/ # Mock implementations for testing + ├── factory.go # Mock factory implementation + └── options.go # Mock options for testing +``` + +## Components + +- **Factory Interface**: Defines methods for creating various components +- **Factory Implementation**: Concrete implementation of the factory interface +- **Options Factory**: Methods for creating command options +- **Command Factory**: Methods for creating command implementations +- **Helm Executor Factory**: Methods for creating Helm execution components +- **Environment Factory**: Methods for creating environment components +- **State Factory**: Methods for creating state components + +## Key Features + +- **Dependency Injection**: Provides a clean way to inject dependencies +- **Component Creation**: Centralizes the creation of complex components +- **Configuration**: Handles configuration of components +- **Testing Support**: Provides mock implementations for testing + +## Usage + +```go +// Create a factory +f := factory.NewFactory() + +// Create options +applyOpts := f.NewApplyOptions() + +// Create a command +applyCmd := f.NewApplyCommand(applyOpts) + +// Execute the command +err := applyCmd.Execute() +``` + +## Testing Options + +The options tests in this package are **only for testing purposes**. They are not intended to be used in production code. + +### Important Notes: + +- **Primary Options Testing**: The primary location for testing options should be in the `pkg/config` package, not here. +- **Test Fixtures**: The options in this package are test fixtures to facilitate testing of the factory methods. +- **No Production Use**: These test options should not be used in production code or referenced outside of tests. + +## Best Practices + +When working with options: + +1. Implement and test option functionality in `pkg/config` +2. Use the factory methods to create properly configured options in production code +3. Only use the test options in this package for testing factory methods + +## Related Packages + +- `pkg/config`: Contains the actual implementation of options and should be the primary location for options tests +- `pkg/flags`: Contains flag handling functionality used by options +- `pkg/app`: Uses factory to create components for application execution diff --git a/pkg/factory/apply.go b/pkg/factory/apply.go new file mode 100644 index 00000000..8d22793b --- /dev/null +++ b/pkg/factory/apply.go @@ -0,0 +1,21 @@ +package factory + +import ( + "github.com/helmfile/helmfile/pkg/config" + "github.com/helmfile/helmfile/pkg/flags" +) + +// ApplyOptionsFactory creates ApplyOptions and their flag registry +type ApplyOptionsFactory struct{} + +func NewApplyOptionsFactory() *ApplyOptionsFactory { + return &ApplyOptionsFactory{} +} + +func (f *ApplyOptionsFactory) CreateOptions() config.Options { + return config.NewApplyOptions() +} + +func (f *ApplyOptionsFactory) GetFlagRegistry() flags.FlagRegistry { + return flags.NewApplyFlagRegistry() +} diff --git a/pkg/factory/apply_test.go b/pkg/factory/apply_test.go new file mode 100644 index 00000000..d9c2a6c1 --- /dev/null +++ b/pkg/factory/apply_test.go @@ -0,0 +1,45 @@ +package factory + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/helmfile/helmfile/pkg/config" + "github.com/helmfile/helmfile/pkg/flags" +) + +func TestApplyOptionsFactory_CreateOptions(t *testing.T) { + factory := NewApplyOptionsFactory() + + // Test that CreateOptions returns a properly initialized ApplyOptions + options := factory.CreateOptions() + + // Type assertion + applyOptions, ok := options.(*config.ApplyOptions) + assert.True(t, ok, "Expected *config.ApplyOptions, got %T", options) + + // Verify default values + assert.False(t, applyOptions.DetailedExitcode) + assert.False(t, applyOptions.StripTrailingCR) + assert.False(t, applyOptions.IncludeTests) + assert.False(t, applyOptions.SuppressSecrets) + assert.False(t, applyOptions.ShowSecrets) + assert.False(t, applyOptions.NoHooks) + assert.False(t, applyOptions.SkipNeeds) + + // Verify BoolFlag initialization + assert.False(t, applyOptions.IncludeCRDsFlag.Value()) + assert.False(t, applyOptions.SkipCRDsFlag.Value()) +} + +func TestApplyOptionsFactory_GetFlagRegistrar(t *testing.T) { + factory := NewApplyOptionsFactory() + + // Test that GetFlagRegistrar returns an ApplyFlagRegistrar + registry := factory.GetFlagRegistry() + + // Type assertion + _, ok := registry.(*flags.ApplyFlagRegistry) + assert.True(t, ok, "Expected *flags.ApplyFlagRegistrar, got %T", registry) +} diff --git a/pkg/factory/diff.go b/pkg/factory/diff.go new file mode 100644 index 00000000..f126cdb0 --- /dev/null +++ b/pkg/factory/diff.go @@ -0,0 +1,21 @@ +package factory + +import ( + "github.com/helmfile/helmfile/pkg/config" + "github.com/helmfile/helmfile/pkg/flags" +) + +// DiffOptionsFactory creates DiffOptions and their flag registry +type DiffOptionsFactory struct{} + +func NewDiffOptionsFactory() *DiffOptionsFactory { + return &DiffOptionsFactory{} +} + +func (f *DiffOptionsFactory) CreateOptions() config.Options { + return config.NewDiffOptions() +} + +func (f *DiffOptionsFactory) GetFlagRegistry() flags.FlagRegistry { + return flags.NewDiffFlagRegistry() +} diff --git a/pkg/factory/diff_test.go b/pkg/factory/diff_test.go new file mode 100644 index 00000000..b743bfc8 --- /dev/null +++ b/pkg/factory/diff_test.go @@ -0,0 +1,44 @@ +package factory + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/helmfile/helmfile/pkg/config" + "github.com/helmfile/helmfile/pkg/flags" +) + +func TestDiffOptionsFactory_CreateOptions(t *testing.T) { + factory := NewDiffOptionsFactory() + + // Test that CreateOptions returns a properly initialized DiffOptions + options := factory.CreateOptions() + + // Type assertion + diffOptions, ok := options.(*config.DiffOptions) + assert.True(t, ok, "Expected *config.DiffOptions, got %T", options) + + // Verify default values + assert.False(t, diffOptions.DetailedExitcode) + assert.False(t, diffOptions.StripTrailingCR) + assert.False(t, diffOptions.IncludeTests) + assert.False(t, diffOptions.SuppressSecrets) + assert.False(t, diffOptions.ShowSecrets) + assert.False(t, diffOptions.NoHooks) + + // Verify BoolFlag initialization + assert.False(t, diffOptions.IncludeCRDsFlag.Value()) + assert.False(t, diffOptions.SkipCRDsFlag.Value()) +} + +func TestDiffOptionsFactory_GetFlagRegistrar(t *testing.T) { + factory := NewDiffOptionsFactory() + + // Test that GetFlagRegistrar returns a DiffFlagRegistrar + registry := factory.GetFlagRegistry() + + // Type assertion + _, ok := registry.(*flags.DiffFlagRegistry) + assert.True(t, ok, "Expected *flags.DiffFlagRegistrar, got %T", registry) +} diff --git a/pkg/factory/factory.go b/pkg/factory/factory.go new file mode 100644 index 00000000..59386033 --- /dev/null +++ b/pkg/factory/factory.go @@ -0,0 +1,15 @@ +package factory + +import ( + "github.com/helmfile/helmfile/pkg/config" + "github.com/helmfile/helmfile/pkg/flags" +) + +// OptionsFactory is the interface for factories that create options and flag registries +type OptionsFactory interface { + // CreateOptions creates and initializes options + CreateOptions() config.Options + + // GetFlagRegisty returns the appropriate flag registry + GetFlagRegistry() flags.FlagRegistry +} diff --git a/pkg/factory/factory_test.go b/pkg/factory/factory_test.go new file mode 100644 index 00000000..d5b0393e --- /dev/null +++ b/pkg/factory/factory_test.go @@ -0,0 +1,32 @@ +package factory + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +// TestFactoryInterface ensures all factories implement the OptionsFactory interface +func TestFactoryInterface(t *testing.T) { + // Test that each factory implements OptionsFactory + var _ OptionsFactory = &DiffOptionsFactory{} + var _ OptionsFactory = &ApplyOptionsFactory{} + var _ OptionsFactory = &SyncOptionsFactory{} + var _ OptionsFactory = &TemplateOptionsFactory{} +} + +// TestFactoryCreation tests the creation of factories +func TestFactoryCreation(t *testing.T) { + // Test that each factory can be created + diffFactory := NewDiffOptionsFactory() + assert.NotNil(t, diffFactory) + + applyFactory := NewApplyOptionsFactory() + assert.NotNil(t, applyFactory) + + syncFactory := NewSyncOptionsFactory() + assert.NotNil(t, syncFactory) + + templateFactory := NewTemplateOptionsFactory() + assert.NotNil(t, templateFactory) +} diff --git a/pkg/factory/sync.go b/pkg/factory/sync.go new file mode 100644 index 00000000..2927b461 --- /dev/null +++ b/pkg/factory/sync.go @@ -0,0 +1,21 @@ +package factory + +import ( + "github.com/helmfile/helmfile/pkg/config" + "github.com/helmfile/helmfile/pkg/flags" +) + +// SyncOptionsFactory creates SyncOptions and their flag registry +type SyncOptionsFactory struct{} + +func NewSyncOptionsFactory() *SyncOptionsFactory { + return &SyncOptionsFactory{} +} + +func (f *SyncOptionsFactory) CreateOptions() config.Options { + return config.NewSyncOptions() +} + +func (f *SyncOptionsFactory) GetFlagRegistry() flags.FlagRegistry { + return flags.NewSyncFlagRegistry() +} diff --git a/pkg/factory/sync_test.go b/pkg/factory/sync_test.go new file mode 100644 index 00000000..20fdbd05 --- /dev/null +++ b/pkg/factory/sync_test.go @@ -0,0 +1,40 @@ +package factory + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/helmfile/helmfile/pkg/config" + "github.com/helmfile/helmfile/pkg/flags" +) + +func TestSyncOptionsFactory_CreateOptions(t *testing.T) { + factory := NewSyncOptionsFactory() + + // Test that CreateOptions returns a properly initialized SyncOptions + options := factory.CreateOptions() + + // Type assertion + syncOptions, ok := options.(*config.SyncOptions) + assert.True(t, ok, "Expected *config.SyncOptions, got %T", options) + + // Verify default values + assert.False(t, syncOptions.Validate) + assert.False(t, syncOptions.SkipNeeds) + + // Verify BoolFlag initialization + assert.False(t, syncOptions.IncludeCRDsFlag.Value()) + assert.False(t, syncOptions.SkipCRDsFlag.Value()) +} + +func TestSyncOptionsFactory_GetFlagRegistrar(t *testing.T) { + factory := NewSyncOptionsFactory() + + // Test that GetFlagRegistrar returns a SyncFlagRegistrar + registry := factory.GetFlagRegistry() + + // Type assertion + _, ok := registry.(*flags.SyncFlagRegistry) + assert.True(t, ok, "Expected *flags.SyncFlagRegistrar, got %T", registry) +} diff --git a/pkg/factory/template.go b/pkg/factory/template.go new file mode 100644 index 00000000..040a52bf --- /dev/null +++ b/pkg/factory/template.go @@ -0,0 +1,21 @@ +package factory + +import ( + "github.com/helmfile/helmfile/pkg/config" + "github.com/helmfile/helmfile/pkg/flags" +) + +// TemplateOptionsFactory creates TemplateOptions and their flag registry +type TemplateOptionsFactory struct{} + +func NewTemplateOptionsFactory() *TemplateOptionsFactory { + return &TemplateOptionsFactory{} +} + +func (f *TemplateOptionsFactory) CreateOptions() config.Options { + return config.NewTemplateOptions() +} + +func (f *TemplateOptionsFactory) GetFlagRegistry() flags.FlagRegistry { + return flags.NewTemplateFlagRegistry() +} diff --git a/pkg/factory/template_test.go b/pkg/factory/template_test.go new file mode 100644 index 00000000..3a270da9 --- /dev/null +++ b/pkg/factory/template_test.go @@ -0,0 +1,41 @@ +package factory + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/helmfile/helmfile/pkg/config" + "github.com/helmfile/helmfile/pkg/flags" +) + +func TestTemplateOptionsFactory_CreateOptions(t *testing.T) { + factory := NewTemplateOptionsFactory() + + // Test that CreateOptions returns a properly initialized TemplateOptions + options := factory.CreateOptions() + + // Type assertion + templateOptions, ok := options.(*config.TemplateOptions) + assert.True(t, ok, "Expected *config.TemplateOptions, got %T", options) + + // Verify default values + assert.False(t, templateOptions.SkipNeeds) + assert.False(t, templateOptions.SkipTests) + assert.False(t, templateOptions.NoHooks) + + // Verify BoolFlag initialization + assert.False(t, templateOptions.IncludeCRDsFlag.Value()) + assert.False(t, templateOptions.SkipCRDsFlag.Value()) +} + +func TestTemplateOptionsFactory_GetFlagRegistry(t *testing.T) { + factory := NewTemplateOptionsFactory() + + // Test that GetFlagRegistrar returns a TemplateFlagRegistry + registry := factory.GetFlagRegistry() + + // Type assertion + _, ok := registry.(*flags.TemplateFlagRegistry) + assert.True(t, ok, "Expected *flags.TemplateFlagRegistry, got %T", registry) +}