Skip to content

Commit ca46604

Browse files
committed
component: remove Config method
1 parent c458b38 commit ca46604

File tree

4 files changed

+40
-83
lines changed

4 files changed

+40
-83
lines changed

component/component.go

+14-48
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,12 @@ type Component interface {
5252
fmt.Stringer
5353

5454
// Setup sets up the component with the given container and configuration.
55-
Setup(Container, Config) error
55+
// If rewrite is true, the component should rewrite the configuration.
56+
Setup(c Container, cfg *Config, rewrite bool) error
5657

5758
// Logger returns the logger instance for the component.
5859
// Logger must be guranteed to return a non-nil logger instance after Setup is called.
5960
Logger() *slog.Logger
60-
61-
// Config returns the configuration of the component.
62-
Config() (Config, error)
6361
}
6462

6563
// Container represents a generic container that can hold components.
@@ -104,16 +102,8 @@ func (c *simpleComponent) Logger() *slog.Logger {
104102
return currentLogger
105103
}
106104

107-
// Config implements the Component Config method.
108-
func (c *simpleComponent) Config() (Config, error) {
109-
return Config{
110-
Name: c.name,
111-
UUID: c.uuid,
112-
}, nil
113-
}
114-
115105
// Setup implements the Component Setup method.
116-
func (c *simpleComponent) Setup(container Container, config Config) error {
106+
func (c *simpleComponent) Setup(container Container, config *Config, rewrite bool) error {
117107
c.container = container
118108
c.name = config.Name
119109
c.uuid = config.UUID
@@ -167,27 +157,14 @@ type BaseComponent[T any] struct {
167157
options T
168158
}
169159

170-
// Config implements the Component Config method.
171-
func (c *BaseComponent[T]) Config() (Config, error) {
172-
options, err := json.Marshal(c.options)
173-
if err != nil {
174-
return Config{}, err
175-
}
176-
return Config{
177-
Name: c.name,
178-
UUID: c.uuid,
179-
Options: types.NewRawObject(options),
180-
}, nil
181-
}
182-
183160
// Options returns a pointer to the component's options.
184161
func (c *BaseComponent[T]) Options() *T {
185162
return &c.options
186163
}
187164

188165
// Setup implements the Component Setup method.
189-
func (c *BaseComponent[T]) Setup(container Container, config Config) error {
190-
if err := c.simpleComponent.Setup(container, config); err != nil {
166+
func (c *BaseComponent[T]) Setup(container Container, config *Config, rewrite bool) error {
167+
if err := c.simpleComponent.Setup(container, config, rewrite); err != nil {
191168
return err
192169
}
193170
if err := config.Options.Decode(json.Unmarshal, &c.options); err != nil {
@@ -199,6 +176,13 @@ func (c *BaseComponent[T]) Setup(container Container, config Config) error {
199176
if err := loaded.OnLoaded(); err != nil {
200177
return fmt.Errorf("failed to load options: %w", err)
201178
}
179+
if rewrite {
180+
var err error
181+
config.Options, err = json.Marshal(c.options)
182+
if err != nil {
183+
return fmt.Errorf("failed to marshal options: %w", err)
184+
}
185+
}
202186
}
203187
return nil
204188
}
@@ -284,32 +268,14 @@ type BaseComponentWithRefs[T, R any] struct {
284268
refs R
285269
}
286270

287-
// Config implements the Component Config method.
288-
func (c *BaseComponentWithRefs[T, R]) Config() (Config, error) {
289-
options, err := json.Marshal(c.options)
290-
if err != nil {
291-
return Config{}, err
292-
}
293-
refs, err := json.Marshal(c.refs)
294-
if err != nil {
295-
return Config{}, err
296-
}
297-
return Config{
298-
Name: c.name,
299-
UUID: c.uuid,
300-
Refs: types.NewRawObject(refs),
301-
Options: types.NewRawObject(options),
302-
}, nil
303-
}
304-
305271
// Refs returns a pointer to the component's references.
306272
func (c *BaseComponentWithRefs[T, R]) Refs() *R {
307273
return &c.refs
308274
}
309275

310276
// Setup implements the Component Setup method.
311-
func (c *BaseComponentWithRefs[T, R]) Setup(container Container, config Config) error {
312-
if err := c.BaseComponent.Setup(container, config); err != nil {
277+
func (c *BaseComponentWithRefs[T, R]) Setup(container Container, config *Config, rewrite bool) error {
278+
if err := c.BaseComponent.Setup(container, config, rewrite); err != nil {
313279
return err
314280
}
315281
if err := config.Refs.Decode(json.Unmarshal, &c.refs); err != nil {

component/component_test.go

+22-26
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ type failingBaseComponent struct {
100100
component.BaseComponent[struct{}]
101101
}
102102

103-
func (f *failingBaseComponent) Setup(container component.Container, config component.Config) error {
103+
func (f *failingBaseComponent) Setup(container component.Container, config *component.Config, rewrite bool) error {
104104
return errors.New("setup failed")
105105
}
106106

@@ -136,10 +136,6 @@ type complexRefs struct {
136136
}
137137
}
138138

139-
type componentWithComplexRefs struct {
140-
component.BaseComponentWithRefs[struct{}, complexRefs]
141-
}
142-
143139
type failingResolver struct {
144140
component.Reference[*mockComponent]
145141
}
@@ -265,7 +261,7 @@ func TestBaseComponentSetup(t *testing.T) {
265261
mc := &mockComponent{}
266262
container := newMockContainer()
267263

268-
err := mc.Setup(container, tt.config)
264+
err := mc.Setup(container, &tt.config, false)
269265

270266
if (err != nil) != tt.wantErr {
271267
t.Errorf("Setup() error = %v, wantErr %v", err, tt.wantErr)
@@ -384,7 +380,7 @@ func TestGroup(t *testing.T) {
384380
mc := &mockComponent{}
385381
uuid := fmt.Sprintf("test-uuid-%d", i)
386382
container := newMockContainer() // Create a new container for each component
387-
err := mc.Setup(container, component.Config{Name: fmt.Sprintf("TestComponent-%d", i), UUID: uuid})
383+
err := mc.Setup(container, &component.Config{Name: fmt.Sprintf("TestComponent-%d", i), UUID: uuid}, false)
388384
if err != nil {
389385
t.Fatalf("Failed to setup mockComponent: %v", err)
390386
}
@@ -415,7 +411,7 @@ func TestGroup(t *testing.T) {
415411
t.Run("Init failure", func(t *testing.T) {
416412
group := component.NewGroup()
417413
failingComponent := &mockComponent{initError: true}
418-
failingComponent.Setup(newMockContainer(), component.Config{Name: "FailingComponent", UUID: "failing-uuid"})
414+
failingComponent.Setup(newMockContainer(), &component.Config{Name: "FailingComponent", UUID: "failing-uuid"}, false)
419415
group.AddComponent("failing-component", failingComponent)
420416

421417
err := group.Init(context.Background())
@@ -427,7 +423,7 @@ func TestGroup(t *testing.T) {
427423
t.Run("Start failure", func(t *testing.T) {
428424
group := component.NewGroup()
429425
failingComponent := &mockComponent{startError: true}
430-
failingComponent.Setup(newMockContainer(), component.Config{Name: "FailingComponent", UUID: "failing-uuid"})
426+
failingComponent.Setup(newMockContainer(), &component.Config{Name: "FailingComponent", UUID: "failing-uuid"}, false)
431427
group.AddComponent("failing-component", failingComponent)
432428

433429
if err := group.Init(context.Background()); err != nil {
@@ -441,7 +437,7 @@ func TestGroup(t *testing.T) {
441437
t.Run("Shutdown failure", func(t *testing.T) {
442438
group := component.NewGroup()
443439
failingComponent := &mockComponent{shutdownError: true}
444-
failingComponent.Setup(newMockContainer(), component.Config{Name: "FailingComponent", UUID: "failing-uuid"})
440+
failingComponent.Setup(newMockContainer(), &component.Config{Name: "FailingComponent", UUID: "failing-uuid"}, false)
445441
group.AddComponent("failing-component", failingComponent)
446442

447443
if err := group.Init(context.Background()); err != nil {
@@ -458,7 +454,7 @@ func TestGroup(t *testing.T) {
458454
t.Run("Uninit failure", func(t *testing.T) {
459455
group := component.NewGroup()
460456
failingComponent := &mockComponent{uninitError: true}
461-
failingComponent.Setup(newMockContainer(), component.Config{Name: "FailingComponent", UUID: "failing-uuid"})
457+
failingComponent.Setup(newMockContainer(), &component.Config{Name: "FailingComponent", UUID: "failing-uuid"}, false)
462458
group.AddComponent("failing-component", failingComponent)
463459

464460
if err := group.Init(context.Background()); err != nil {
@@ -619,7 +615,7 @@ func ExampleBaseComponent() {
619615
Options: types.NewRawObject(`{"Value":"example"}`),
620616
}
621617

622-
err := mc.Setup(container, config)
618+
err := mc.Setup(container, &config, false)
623619
if err != nil {
624620
fmt.Printf("Failed to setup component: %v\n", err)
625621
return
@@ -643,7 +639,7 @@ func ExampleGroup() {
643639
mc := &mockComponent{}
644640
uuid := fmt.Sprintf("example-uuid-%d", i)
645641
container := newMockContainer()
646-
_ = mc.Setup(container, component.Config{Name: fmt.Sprintf("ExampleComponent-%d", i), UUID: uuid})
642+
_ = mc.Setup(container, &component.Config{Name: fmt.Sprintf("ExampleComponent-%d", i), UUID: uuid}, false)
647643
group.AddComponent(uuid, mc)
648644
}
649645

@@ -690,7 +686,7 @@ func TestBaseComponentWithRefs(t *testing.T) {
690686
Refs: types.NewRawObject(`{"Ref1":"ref1","Ref2":"ref2"}`),
691687
}
692688

693-
err := tc.Setup(container, config)
689+
err := tc.Setup(container, &config, false)
694690
if err != nil {
695691
t.Fatalf("Failed to setup component: %v", err)
696692
}
@@ -710,7 +706,7 @@ func TestBaseComponentWithRefs(t *testing.T) {
710706
UUID: "test-uuid",
711707
Refs: types.NewRawObject(`{invalid json`),
712708
}
713-
err := tc.Setup(container, config)
709+
err := tc.Setup(container, &config, false)
714710
if err == nil || !strings.Contains(err.Error(), "failed to unmarshal refs") {
715711
t.Errorf("Expected error for invalid refs JSON, got: %v", err)
716712
}
@@ -726,7 +722,7 @@ func TestBaseComponentWithRefs(t *testing.T) {
726722
UUID: "test-uuid",
727723
Refs: types.NewRawObject(`{"Ref1":"non-existent-uuid"}`),
728724
}
729-
err := tc.Setup(mockContainer, config)
725+
err := tc.Setup(mockContainer, &config, false)
730726
if err == nil || !strings.Contains(err.Error(), "failed to resolve reference") {
731727
t.Errorf("Expected error for failed reference resolution, got: %v", err)
732728
}
@@ -757,7 +753,7 @@ func TestBaseComponentWithRefs(t *testing.T) {
757753
Refs: types.NewRawObject(`{"Ref1":"ref1","NestedStruct":{"Ref2":"ref2"}}`),
758754
}
759755

760-
err := nc.Setup(container, config)
756+
err := nc.Setup(container, &config, false)
761757
if err != nil {
762758
t.Fatalf("Failed to setup nested component: %v", err)
763759
}
@@ -794,7 +790,7 @@ func TestBaseComponentWithRefs(t *testing.T) {
794790
Refs: types.NewRawObject(`{"Ref1":"ref1","Ref2":null,"Ref3":{},"Ref4":"not-a-ref"}`),
795791
}
796792

797-
err := mixedComp.Setup(container, config)
793+
err := mixedComp.Setup(container, &config, false)
798794
if err != nil {
799795
t.Fatalf("Failed to setup mixed component: %v", err)
800796
}
@@ -816,7 +812,7 @@ func TestBaseComponentWithRefs(t *testing.T) {
816812
Name: "FailingComponent",
817813
UUID: "failing-uuid",
818814
}
819-
err := fc.Setup(newMockContainer(), config)
815+
err := fc.Setup(newMockContainer(), &config, false)
820816
if err == nil || err.Error() != "setup failed" {
821817
t.Errorf("Expected setup failed error, got: %v", err)
822818
}
@@ -829,7 +825,7 @@ func TestBaseComponentWithRefs(t *testing.T) {
829825
UUID: "test-uuid",
830826
Refs: types.NewRawObject(`{invalid json`),
831827
}
832-
err := tc.Setup(newMockContainer(), config)
828+
err := tc.Setup(newMockContainer(), &config, false)
833829
if err == nil || !strings.Contains(err.Error(), "failed to unmarshal refs") {
834830
t.Errorf("Expected error for invalid refs JSON, got: %v", err)
835831
}
@@ -842,7 +838,7 @@ func TestBaseComponentWithRefs(t *testing.T) {
842838
UUID: "non-struct-uuid",
843839
Refs: types.NewRawObject(`"string ref"`),
844840
}
845-
err := cnsr.Setup(newMockContainer(), config)
841+
err := cnsr.Setup(newMockContainer(), &config, false)
846842
if err != nil {
847843
t.Errorf("Expected no error for non-struct refs, got: %v", err)
848844
}
@@ -872,7 +868,7 @@ func TestBaseComponentWithRefs(t *testing.T) {
872868
}`),
873869
}
874870

875-
err := cdr.Setup(container, config)
871+
err := cdr.Setup(container, &config, false)
876872
if err != nil {
877873
t.Fatalf("Failed to setup component with deep refs: %v", err)
878874
}
@@ -904,7 +900,7 @@ func TestBaseComponentWithRefs(t *testing.T) {
904900
Refs: types.NewRawObject(`{"FailingRef": "some-uuid"}`),
905901
}
906902

907-
err := cfr.Setup(newMockContainer(), config)
903+
err := cfr.Setup(newMockContainer(), &config, false)
908904
if err == nil || !strings.Contains(err.Error(), "failed to resolve reference") {
909905
t.Errorf("Expected error for failing resolver, got: %v", err)
910906
}
@@ -921,7 +917,7 @@ func TestComponentLifecycle(t *testing.T) {
921917
UUID: "lifecycle-uuid",
922918
}
923919

924-
err := mc.Setup(container, config)
920+
err := mc.Setup(container, &config, false)
925921
if err != nil {
926922
t.Fatalf("Failed to setup component: %v", err)
927923
}
@@ -988,7 +984,7 @@ func TestComponentErrorHandling(t *testing.T) {
988984
UUID: "error-uuid",
989985
}
990986

991-
err := errorComponent.Setup(container, config)
987+
err := errorComponent.Setup(container, &config, false)
992988
if err != nil {
993989
t.Fatalf("Failed to setup component: %v", err)
994990
}
@@ -1022,7 +1018,7 @@ func BenchmarkComponentLifecycle(b *testing.B) {
10221018
b.ResetTimer()
10231019
for i := 0; i < b.N; i++ {
10241020
mc := &mockComponent{}
1025-
_ = mc.Setup(container, config)
1021+
_ = mc.Setup(container, &config, false)
10261022
_ = mc.Init(ctx)
10271023
_ = mc.Start(ctx)
10281024
_ = mc.Shutdown(ctx)

service/service.go

+2-7
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ func (s *BaseService[T]) setupComponents() ([]pair.Pair[component.Component, com
176176
components = append(components, pair.New(com, c))
177177
}
178178
for i := range components {
179-
if err := components[i].First.Setup(s, components[i].Second); err != nil {
179+
if err := components[i].First.Setup(s, &components[i].Second, s.flags.printConfig); err != nil {
180180
return nil, fmt.Errorf("component %q setup error: %w", components[i].First.String(), err)
181181
}
182182
}
@@ -209,12 +209,7 @@ func (s *BaseService[T]) Init(ctx context.Context) error {
209209
// generate output config after setting up components
210210
configs := make([]component.Config, 0, len(components))
211211
for _, c := range components {
212-
config, err := c.First.Config()
213-
if err != nil {
214-
fmt.Fprintf(s.stderr, "Failed to get component config: %v", err)
215-
return errkit.NewExitError(2, err.Error())
216-
}
217-
configs = append(configs, config)
212+
configs = append(configs, c.Second)
218213
}
219214
s.config.output(configs, s.stdout, s.stderr, s.encoder)
220215
return errkit.NewExitError(0)

service/service_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -627,12 +627,12 @@ func (m *mockComponent) Shutdown(ctx context.Context) error {
627627
return nil
628628
}
629629

630-
func (m *mockComponent) Setup(container component.Container, config component.Config) error {
630+
func (m *mockComponent) Setup(container component.Container, config *component.Config, rewrite bool) error {
631631
m.mu.Lock()
632632
defer m.mu.Unlock()
633633
m.setupCalled = true
634634
m.setupContainer = container
635-
m.setupConfig = config
635+
m.setupConfig = *config
636636
m.logger = slog.Default().With("component", m.String())
637637
return nil
638638
}

0 commit comments

Comments
 (0)