Skip to content

feat(config): Add exclude field#132

Merged
tab merged 4 commits into
masterfrom
feature/exclude
May 24, 2026
Merged

feat(config): Add exclude field#132
tab merged 4 commits into
masterfrom
feature/exclude

Conversation

@tab
Copy link
Copy Markdown
Owner

@tab tab commented May 24, 2026

Add top-level exclude for suppressing services from a profile and fuku run will silently drop them at startup

Add top-level exclude for suppressing services from a profile and fuku run will silently drop them at startup
@tab tab self-assigned this May 24, 2026
@sentry
Copy link
Copy Markdown

sentry Bot commented May 24, 2026

Codecov Report

❌ Patch coverage is 96.51163% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.52%. Comparing base (7f3e43f) to head (08e6196).

Files with missing lines Patch % Lines
internal/app/cli/tui.go 86.36% 2 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #132      +/-   ##
==========================================
+ Coverage   89.31%   89.52%   +0.20%     
==========================================
  Files          63       63              
  Lines        5823     5899      +76     
==========================================
+ Hits         5201     5281      +80     
+ Misses        489      486       -3     
+ Partials      133      132       -1     
Files with missing lines Coverage Δ
cmd/main.go 46.00% <100.00%> (ø)
internal/app/discovery/discovery.go 100.00% <100.00%> (ø)
internal/config/config.go 100.00% <100.00%> (ø)
internal/config/loader.go 84.61% <100.00%> (ø)
internal/config/validate.go 100.00% <100.00%> (ø)
internal/app/cli/tui.go 93.58% <86.36%> (+4.52%) ⬆️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a top-level exclude configuration field to let fuku run suppress specific services at startup (by filtering them out during discovery), along with normalization and test coverage to ensure exclude is parsed, merged, and deduplicated consistently. The PR also refactors the TUI run loop to coordinate runner/UI shutdown more cleanly and re-enables log output after the UI exits.

Changes:

  • Add Config.Exclude plus config normalization (Normalize() / normalizeExclude) and loader/merge coverage.
  • Filter excluded services during discovery resolution so excluded names are dropped before ordering/validation.
  • Update TUI wiring to inject render.Writer and run UI/runner concurrently with coordinated shutdown and error propagation.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
internal/config/validate.go Adds profile validation to ensure referenced services exist (new behavior).
internal/config/validate_test.go Adds tests for profile reference validation scenarios.
internal/config/merge_test.go Adds YAML merge test ensuring exclude lists concatenate.
internal/config/loader.go Runs cfg.Normalize() post-unmarshal (tiers + exclude).
internal/config/loader_test.go Updates profile YAML shape in test and adds exclude parsing/override tests.
internal/config/config.go Introduces Exclude field and normalization pipeline.
internal/config/config_test.go Adds unit tests for normalizeExclude and Normalize().
internal/app/errors/errors.go Adds ErrProfileReferenceUndefined.
internal/app/discovery/discovery.go Filters out excluded services during Resolve.
internal/app/discovery/discovery_test.go Adds coverage for exclude behavior during discovery.
internal/app/cli/tui.go Injects render.Writer; runs UI and runner concurrently and restores output on exit.
internal/app/cli/tui_test.go Updates TUI tests for writer injection and new run-loop behavior.
cmd/main.go Supplies writer via FX so it can be injected into TUI.
fuku.yaml Adds example worker service.
fuku.override.yaml Demonstrates excluding worker.
examples/bookstore/worker/src/main.go Adds new example service implementation.
examples/bookstore/worker/Makefile Adds make target to run the new example worker.

Comment thread internal/config/validate.go
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated 2 comments.

Comment thread internal/config/validate.go
Comment thread internal/config/config_test.go
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 30 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

internal/config/config_test.go:233

  • The cfg := DefaultConfig() is shared across subtests and mutated in each case, which couples tests and can cause state leakage (and future flakes if subtests are parallelized or more fields are added). Create a fresh config inside each t.Run (or copy the config) so cases are isolated.
func Test_ServerListen(t *testing.T) {
	cfg := DefaultConfig()

	tests := []struct {
		name   string
		listen string
		want   string
	}{
		{
			name:   "configured address",
			listen: "127.0.0.1:9876",
			want:   "127.0.0.1:9876",
		},
		{
			name:   "empty returns empty",
			listen: "",
			want:   "",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			cfg.Server.Listen = tt.listen

			assert.Equal(t, tt.want, cfg.ServerListen())
		})
	}

internal/config/config_test.go:262

  • Same issue here: cfg := DefaultConfig() is shared and mutated across subtests. Instantiate a new config per test case to keep subtests independent and avoid hidden coupling.
func Test_ServerToken(t *testing.T) {
	cfg := DefaultConfig()

	tests := []struct {
		name  string
		token string
		want  string
	}{
		{
			name:  "configured token",
			token: "my-secret",
			want:  "my-secret",
		},
		{
			name:  "empty returns empty",
			token: "",
			want:  "",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			cfg.Server.Auth.Token = tt.token

			assert.Equal(t, tt.want, cfg.ServerToken())
		})
	}

Comment thread internal/app/discovery/discovery_test.go
Comment thread internal/app/cli/tui.go
@tab tab merged commit 5123bd9 into master May 24, 2026
11 checks passed
@tab tab deleted the feature/exclude branch May 24, 2026 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants