Skip to content

fix(lint): resolve funlen findings - #894

Merged
skevetter merged 5 commits into
mainfrom
lint/funlen-findings
Aug 7, 2026
Merged

fix(lint): resolve funlen findings#894
skevetter merged 5 commits into
mainfrom
lint/funlen-findings

Conversation

@skevetter

@skevetter skevetter commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Resolves all 34 funlen findings (28 at last scan, 6 more shifted in after recent merges) across three commits, one per group:

Group A — cobra command factories / flag registration (mechanical split, 12 files):
Split each long New*Cmd/SetGlobalFlags/registerFlags into a small dispatcher calling logically-grouped register<Concern>Flags helpers, following the existing convention in cmd/workspace/up/up_flags.go. Every flag name/default/shorthand/env-binding preserved verbatim.

Group B — business logic, real extraction (11 files):
Extracted sensibly-named helpers per logical phase (same approach as the ResolvePortAttribute cyclop fix). All exported functions' callers were grep-checked before touching; no signature changes were needed anywhere. pkg/platform/form/form.go's CreateInstance/UpdateInstance and pkg/platform/kubeconfig.go's two kubeConfigFor* functions picked up genuinely shared helpers along the way, removing pre-existing duplication between sibling functions.

One suppression: pkg/inject/inject.go's Inject — confirmed this is the same legacy shell injection path already frozen/suppressed for a staticcheck (SA1019) finding in pkg/agent/inject.go; decomposing dead-end code pending AgentDelivery migration isn't worth the risk. //nolint:funlen added with that reasoning.

Group C — tests (6 files):
Preferred real structural improvement over cosmetic shrinking:

  • Independent table-driven scenarios (graph_test.go) → split into dedicated TestX_ScenarioY suite methods (also improves failure localization).
  • Single-huge-data-table tests (options_test.go, resolve_test.go — 629 lines!, config_test.go — 313 lines, types_test.go, id_test.go) → table extracted into a package var, test body reduced to just the loop. Note: for the two extreme outliers, wrapping the table in a function instead of a var doesn't fix funlen (the data itself is what's long, regardless of what holds it) — had to use a package-level var.

No test suppressions were needed — every flagged test was independent-scenario or table-driven, not genuinely sequential/stateful.

Verification: go build ./..., go vet ./... (clean aside from one pre-existing unrelated pkg/pty/ptytest finding), full test suite for every touched package (all pass, spot-checked subtest names individually, not just package exit code), and golangci-lint run --enable-only=funlen --max-same-issues=0 ./... → 0 issues.

Summary by CodeRabbit

  • New Features

    • Added clearer grouped options for cluster startup, provider initialization, workspace setup, SSH, and user-command workflows.
    • Added environment-variable support for relevant host, access, and platform settings.
    • Improved remote startup feedback with DNS guidance and reachability confirmation.
  • Bug Fixes

    • Improved workspace environment detection with fallback handling.
    • Preserved reliable cleanup during build and uninstall operations.
  • Refactor

    • Simplified command configuration and internal workflows while preserving existing behavior.

Group A of the funlen backlog: cobra command factories and flag
registration functions were long because they registered many flags in a
flat sequence. Split each into a small registerFlags dispatcher calling
logically-grouped register<Concern>Flags helpers, following the existing
convention in cmd/workspace/up/up_flags.go (registerFlags -> registerSSHFlags,
registerDotfilesFlags, etc.).

- cmd/ci/ci.go: registerFlags -> registerRunFlags/registerBuildFlags/
  registerWorkspaceFlags/registerSecretsFlags
- cmd/flags/flags.go: SetGlobalFlags -> registerCoreFlags/registerOutputFlags/
  registerVerbosityFlags/registerHiddenFlags/bindGlobalEnvVars
- cmd/internal/agentcontainer/setup.go: NewSetupContainerCmd -> registerFlags
  dispatching to registerBehaviorFlags/registerWorkspaceInfoFlags/
  registerDotfilesFlags
- cmd/internal/runusercommands.go: NewRunUserCommandsCmd -> registerFlags
  dispatching to registerTargetFlags/registerConfigFlags/registerEnvFlags/
  registerLifecycleFlags
- cmd/pro/cluster/add.go: NewAddCmd's flag registration moved to new
  cmd/pro/cluster/add_flags.go (registerFlags -> registerIdentityFlags/
  registerBehaviorFlags/registerHelmFlags/registerClusterFlags)
- cmd/pro/start.go: NewStartCmd's flag registration moved to new
  cmd/pro/start_flags.go (registerFlags -> registerDockerFlags/
  registerClusterFlags/registerChartFlags/registerAuthFlags/
  registerLifecycleFlags)
- cmd/provider/init.go: NewInitCmd's flag registration moved to new
  cmd/provider/init_flags.go (registerFlags -> registerOptionFlags/
  registerTestingFlags)
- cmd/workspace/ssh.go: NewSSHCmd -> registerFlags dispatching to
  registerPortForwardingFlags/registerEnvFlags/registerSessionFlags/
  registerAgentForwardingFlags/registerServiceFlags/registerTerminalFlags
- cmd/workspace/up/up_flags.go: registerWorkspaceFlags itself split further
  into registerWorkspaceIdentityFlags/registerWorkspaceSecretsFlags/
  registerWorkspaceRuntimeFlags

Every flag name, default, shorthand, hidden marker, and env binding is
preserved verbatim; only the grouping changed.
Group B of the funlen backlog: real business-logic functions, extracted
into sensibly-named helpers per logical phase (same approach as the
ResolvePortAttribute cyclop fix). Behavior preserved exactly; callers of
every touched exported function were checked via grep before any signature
change (none required signature changes).

- cmd/internal/agentcontainer/setup.go: streamMount -> streamMountFromPlatform/
  buildPlatformDownloadRequest/streamMountFromTunnel
- cmd/pro/start.go: successRemote -> printRemoteSuccessMessage/
  printDNSConfigurationRequired/waitForHostReachable; uninstall ->
  runHelmUninstall/cleanupProResources/deleteRemainingAgentResources
- cmd/workspace/logs.go: Run -> getWorkspaceClient/injectLogsAgent
- cmd/workspace/ssh.go: startTunnel -> setupTunnelWriter/
  runInteractiveTunnelSession
- pkg/client/clientimplementation/daemonclient/form.go:
  createInstanceInteractive -> selectProjectClusterTemplate/
  resolveNewInstanceParameters/buildNewInstance
- pkg/client/clientimplementation/daemonclient/up.go: printLogs ->
  openTaskLogsStream/newLogScanner/logOutputStreams/streamLogMessages
- pkg/devcontainer/compose_build.go: buildAndExtendDockerCompose ->
  resolveComposeBuildTarget/runComposeExtendedBuild
- pkg/devcontainer/config/merge.go: MergeConfiguration (exported, all 6
  call sites verified unchanged) -> ensureImageMetadataEntries/
  newMergedDevContainerConfig/mergeRuntimeFields/mergeLifecycleHookFields/
  mergeUserAndEnvFields/mergePortsAndShutdownFields
- pkg/devcontainer/config/userenvprobe.go: ProbeUserEnv (exported, sole
  caller verified unchanged) -> resolveUserEnvProbe/probeUserEnvWithFallback
- pkg/inject/inject.go: Inject suppressed with //nolint:funlen -- this is
  the same legacy shell injection path already frozen and suppressed for
  staticcheck (SA1019) in pkg/agent/inject.go; a functional decomposition
  of dead-end code awaiting AgentDelivery migration isn't worth the risk.
- pkg/options/resolve.go: ResolveOptions -> applyResolvedProviderOptions
- pkg/platform/form/form.go: CreateInstance and UpdateInstance (exported,
  all 5 call sites verified unchanged) -> shared resolveTemplateParameters/
  runParameterForm helpers plus per-function runCreateSelectionForm/
  renderedParametersForCreate/buildCreatedInstance and
  selectUpdateTemplate; also removes pre-existing duplication between the
  two functions
- pkg/platform/kubeconfig.go: kubeConfigForSpaceInstance and
  kubeConfigForVirtualClusterInstance share a new kubeConfigViaAccessKey
  helper for their near-identical access-key path (previously duplicated),
  plus per-function directClusterEndpointKubeConfigForSpace/
  directVirtualClusterKubeConfig/newVClusterKubeConfigRequest
- pkg/ssh/server/ssh.go: NewServer -> buildSSHServer
Group C of the funlen backlog: table-driven and multi-scenario tests.
Preferred real structural improvement (subtests / separate test functions
/ data extracted from logic) over cosmetic shrinking. No suppressions were
needed -- every flagged test was either a single large data table or a set
of independent scenarios, not a genuinely sequential/stateful test that
splitting would harm.

- pkg/devcontainer/graph/graph_test.go: TestEdgeCount/TestEdgeCases/
  TestTopologicalSortAdvanced were table-driven suites where every case was
  already independent; split each table entry into its own dedicated
  TestX_ScenarioY suite method (testify's SetupTest runs before each,
  matching the per-case reset the table loop used to do manually) --
  improves failure localization on top of satisfying funlen.
- pkg/options/options_test.go: TestInheritFromEnvironment's 4-case table
  extracted into a package var (inheritFromEnvironmentTestCases); the test
  itself is now just the t.Run loop.
- pkg/options/resolve_test.go: TestResolveOptions (629 lines!) is a single
  huge data table with a 5-line loop -- extracted the table into a package
  var (resolveOptionsTestCases) rather than a helper function, since a
  function returning the same literal would still itself exceed funlen
  (data length doesn't change by renaming its container). The test itself
  is now just the range+t.Run loop.
- pkg/ssh/config_test.go: TestAddHostSection (313 lines) is the same
  single-huge-table shape; same treatment -- table extracted into
  addHostSectionTestCases package var, test body reduced to the s.Run loop.
- pkg/types/types_test.go: TestLifecycleHookUnmarshalJSON's 4 JSON-shape
  scenarios extracted into lifecycleHookUnmarshalTestCases with named
  lifecycleHookUnmarshalInput/lifecycleHookUnmarshalCase types (previously
  anonymous structs); test body is now just the t.Run loop.
- pkg/workspace/id_test.go: TestToID's 10-case table extracted into
  toIDTestCases; t.Run subtests were already present, only the table
  moved out.

Every assertion, scenario, and test name preserved exactly.
@netlify

netlify Bot commented Aug 6, 2026

Copy link
Copy Markdown

Deploy Preview for devsydev canceled.

Name Link
🔨 Latest commit c132a2b
🔍 Latest deploy log https://app.netlify.com/projects/devsydev/deploys/6a7537486979570009bfe487

@netlify

netlify Bot commented Aug 6, 2026

Copy link
Copy Markdown

Deploy Preview for images-devsy-sh canceled.

Name Link
🔨 Latest commit c132a2b
🔍 Latest deploy log https://app.netlify.com/projects/images-devsy-sh/deploys/6a753748d2ad480008393dcc

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 04631f6f-0345-489b-b464-a39d7b13b466

📥 Commits

Reviewing files that changed from the base of the PR and between 89b4aa2 and c132a2b.

📒 Files selected for processing (13)
  • cmd/internal/agentcontainer/setup.go
  • cmd/internal/runusercommands.go
  • cmd/workspace/logs.go
  • cmd/workspace/ssh.go
  • pkg/client/clientimplementation/daemonclient/form.go
  • pkg/client/clientimplementation/daemonclient/up.go
  • pkg/devcontainer/compose_build.go
  • pkg/options/options_test.go
  • pkg/options/resolve.go
  • pkg/options/resolve_test.go
  • pkg/platform/form/form.go
  • pkg/platform/kubeconfig.go
  • pkg/ssh/config_test.go
🚧 Files skipped from review as they are similar to previous changes (11)
  • pkg/options/resolve.go
  • pkg/options/options_test.go
  • pkg/platform/form/form.go
  • cmd/workspace/logs.go
  • pkg/devcontainer/compose_build.go
  • cmd/workspace/ssh.go
  • pkg/client/clientimplementation/daemonclient/up.go
  • pkg/client/clientimplementation/daemonclient/form.go
  • pkg/options/resolve_test.go
  • cmd/internal/runusercommands.go
  • cmd/internal/agentcontainer/setup.go

📝 Walkthrough

Walkthrough

The pull request decomposes CLI flag registration, command workflows, platform configuration logic, Pro lifecycle handling, and test fixtures into focused helpers. Public entities remain unchanged.

Changes

CLI registration

Layer / File(s) Summary
Grouped flag registration
cmd/ci/ci.go, cmd/flags/flags.go, cmd/internal/agentcontainer/setup.go, cmd/internal/runusercommands.go, cmd/pro/cluster/*, cmd/pro/start*, cmd/provider/init*, cmd/workspace/ssh.go, cmd/workspace/up/up_flags.go
Flag definitions and environment bindings now use dedicated registration helpers.
Command workflow helpers
cmd/internal/agentcontainer/setup.go, cmd/internal/runusercommands.go, cmd/workspace/logs.go, cmd/workspace/ssh.go, pkg/client/clientimplementation/daemonclient/up.go, pkg/ssh/server/ssh.go
Setup, user-command, workspace logging, SSH tunneling, daemon logging, and SSH server construction are split into focused functions.
Configuration and resolution helpers
pkg/client/clientimplementation/daemonclient/form.go, pkg/devcontainer/*, pkg/options/resolve.go
Instance creation, Compose builds, configuration merging, environment probing, and provider option application are decomposed into helper flows.
Platform and lifecycle flows
pkg/platform/form/form.go, pkg/platform/kubeconfig.go, cmd/pro/start.go
Create/update forms, kubeconfig generation, remote success handling, and Pro uninstall cleanup are reorganized into smaller helpers.
Test organization and lint support
pkg/devcontainer/graph/graph_test.go, pkg/options/*_test.go, pkg/ssh/config_test.go, pkg/types/types_test.go, pkg/workspace/id_test.go, pkg/inject/inject.go
Existing test scenarios move to reusable tables or named tests. The legacy Inject function receives a funlen suppression.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • devsy-org/devsy#765: Both changes refactor overlapping daemon, platform, devcontainer, options, and kubeconfig flows.
  • devsy-org/devsy#764: Both changes refactor command workflows and helper extraction across CLI paths.
  • devsy-org/devsy#203: Both changes modify the RunUserCommandsCmd construction, validation, and execution flow.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.37% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the pull request's main change: resolving lint findings related to function length.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cmd/pro/start.go (1)

1491-1496: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Propagate Helm uninstall failures.

Line 1496 returns nil after helmCmd.CombinedOutput() fails. uninstall then deletes remaining resources and prints a successful uninstall message. Return the Helm error so this path cannot report success after a failed release removal.

Proposed fix
 	output, err := helmCmd.CombinedOutput()
 	if err != nil {
 		log.Errorf("error during helm command: %s (%v)", string(output), err)
+		return fmt.Errorf("helm uninstall failed: %w", err)
 	}
 
 	return nil
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/pro/start.go` around lines 1491 - 1496, Update the Helm command handling
in uninstall to return the error from helmCmd.CombinedOutput() after logging it,
instead of returning nil, so failed release removal propagates and prevents a
successful uninstall result.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/internal/agentcontainer/setup.go`:
- Around line 961-967: Remove InsecureSkipVerify from the TLS configuration used
by the httpClient in setup.go, allowing the default certificate and host
validation path. If private-CA support is required, configure the trusted CA
through tls.Config.RootCAs instead of disabling verification.
- Around line 84-88: Reorder the helper methods to satisfy funcorder by moving
cmd/internal/agentcontainer/setup.go:84-88 registerFlags, :90-118
registerBehaviorFlags, :120-138 registerWorkspaceInfoFlags, and :140-150
registerDotfilesFlags below SetupContainerCmd’s exported Run method; likewise
move cmd/internal/runusercommands.go:64-69 registerFlags, :71-93
registerTargetFlags, :95-111 registerConfigFlags, :113-129 registerEnvFlags, and
:131-172 registerLifecycleFlags below the corresponding exported Run method,
without changing their behavior.

In `@pkg/options/options_test.go`:
- Line 97: Remove the fmt.Println call from the test case execution around
t.Run; rely on t.Run to report the subtest name and leave the surrounding test
behavior unchanged.

In `@pkg/options/resolve_test.go`:
- Around line 137-146: Update the NOTEXPIRE test setup in TestResolveOptions so
its Filled timestamp is generated immediately before Resolve runs rather than
during package initialization. Use the test runner’s per-case setup or an
equivalent deferred test-case value, while preserving the existing expired
timestamp behavior for EXPIRE.

In `@pkg/options/resolve.go`:
- Around line 201-203: Move the devConfig nil check in ResolveOptions to before
the first access to devConfig, including devConfig.DefaultContext, so nil input
returns nil, nil without dereferencing it.

In `@pkg/platform/form/form.go`:
- Around line 34-54: The create flow drops the selected cluster before
constructing the instance. Update runCreateSelectionForm and its callers to
return and propagate selectedCluster, then pass it into buildCreatedInstance so
the resulting Spec.Target.Cluster matches the form selection; apply the same
change to the other affected call sites.

---

Outside diff comments:
In `@cmd/pro/start.go`:
- Around line 1491-1496: Update the Helm command handling in uninstall to return
the error from helmCmd.CombinedOutput() after logging it, instead of returning
nil, so failed release removal propagates and prevents a successful uninstall
result.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 21771e09-b81a-480c-a8c6-a400b940fe21

📥 Commits

Reviewing files that changed from the base of the PR and between 4279672 and 89b4aa2.

📒 Files selected for processing (29)
  • cmd/ci/ci.go
  • cmd/flags/flags.go
  • cmd/internal/agentcontainer/setup.go
  • cmd/internal/runusercommands.go
  • cmd/pro/cluster/add.go
  • cmd/pro/cluster/add_flags.go
  • cmd/pro/start.go
  • cmd/pro/start_flags.go
  • cmd/provider/init.go
  • cmd/provider/init_flags.go
  • cmd/workspace/logs.go
  • cmd/workspace/ssh.go
  • cmd/workspace/up/up_flags.go
  • pkg/client/clientimplementation/daemonclient/form.go
  • pkg/client/clientimplementation/daemonclient/up.go
  • pkg/devcontainer/compose_build.go
  • pkg/devcontainer/config/merge.go
  • pkg/devcontainer/config/userenvprobe.go
  • pkg/devcontainer/graph/graph_test.go
  • pkg/inject/inject.go
  • pkg/options/options_test.go
  • pkg/options/resolve.go
  • pkg/options/resolve_test.go
  • pkg/platform/form/form.go
  • pkg/platform/kubeconfig.go
  • pkg/ssh/config_test.go
  • pkg/ssh/server/ssh.go
  • pkg/types/types_test.go
  • pkg/workspace/id_test.go

Comment thread cmd/internal/agentcontainer/setup.go
Comment on lines +961 to +967
httpClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
},
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🔴 Critical | 🏗️ Heavy lift

Restore TLS certificate validation.

InsecureSkipVerify: true disables host and certificate validation for a request that sends Platform.AccessKey as a bearer token. A network attacker can intercept the request, steal the token, and replace the archive extracted into the workspace.

Use the default TLS verification path. If the platform uses a private CA, configure a trusted RootCAs pool instead of disabling verification.

🧰 Tools
🪛 ast-grep (0.45.0)

[warning] 961-965: This http.Transport is configured with a tls.Config that sets InsecureSkipVerify: true, which disables TLS certificate verification for every request made through the resulting http.Client. The server's certificate chain and host name are not validated, exposing the connection to man-in-the-middle attacks. Remove InsecureSkipVerify (or set it to false) and supply a proper RootCAs pool if you need to trust custom certificates.
Context: http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
Note: [CWE-295] Improper Certificate Validation.

(http-transport-tls-skip-verify-go)


[warning] 962-964: MinVersionis missing from this TLS configuration. By default, TLS 1.2 is currently used as the minimum when acting as a client, and TLS 1.0 when acting as a server. General purpose web applications should default to TLS 1.3 with all other protocols disabled. Only where it is known that a web server must support legacy clients with unsupported an insecure browsers (such as Internet Explorer 10), it may be necessary to enable TLS 1.0 to provide support. AddMinVersion: tls.VersionTLS13' to the TLS configuration to bump the minimum version to TLS 1.3.
Context: tls.Config{
InsecureSkipVerify: true,
}
Note: [CWE-327]: Use of a Broken or Risky Cryptographic Algorithm [OWASP A03:2017]: Sensitive Data Exposure [OWASP A02:2021]: Cryptographic Failures

(missing-ssl-minversion-go)

🪛 OpenGrep (1.26.0)

[ERROR] 963-965: TLS certificate verification is disabled via InsecureSkipVerify. This allows man-in-the-middle attacks. Remove InsecureSkipVerify or set it to false.

(coderabbit.tls.go-insecure-skip-verify)


[ERROR] 963-965: TLS certificate verification is disabled via InsecureSkipVerify. This allows man-in-the-middle attacks. Remove InsecureSkipVerify or set it to false.

(coderabbit.tls.go-insecure-skip-verify)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/internal/agentcontainer/setup.go` around lines 961 - 967, Remove
InsecureSkipVerify from the TLS configuration used by the httpClient in
setup.go, allowing the default certificate and host validation path. If
private-CA support is required, configure the trusted CA through
tls.Config.RootCAs instead of disabling verification.

Source: Linters/SAST tools

Comment thread pkg/options/options_test.go Outdated
Comment thread pkg/options/resolve_test.go
Comment thread pkg/options/resolve.go Outdated
Comment thread pkg/platform/form/form.go Outdated
Comment on lines +34 to +54
selectedProject, selectedTemplate, selectedTemplateVersion, err := runCreateSelectionForm(
ctx, baseClient, formCtx, cancelForm,
)
if err != nil {
return nil, err
}

renderedParameters, err := renderedParametersForCreate(
formCtx,
selectedTemplate,
selectedTemplateVersion,
)
if err != nil {
return nil, err
}

return buildCreatedInstance(
id, uid, source, picture,
selectedProject, selectedTemplate, selectedTemplateVersion,
renderedParameters,
), nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Preserve the selected cluster in the created instance.

The form still requires a cluster selection, but runCreateSelectionForm does not return selectedCluster. buildCreatedInstance therefore cannot set Spec.Target.Cluster. The create flow submits an instance without the selected target cluster.

Proposed fix
-	selectedProject, selectedTemplate, selectedTemplateVersion, err := runCreateSelectionForm(
+	selectedProject, selectedCluster, selectedTemplate, selectedTemplateVersion, err := runCreateSelectionForm(
 		ctx, baseClient, formCtx, cancelForm,
 	)
@@
-		selectedProject, selectedTemplate, selectedTemplateVersion,
+		selectedProject, selectedCluster, selectedTemplate, selectedTemplateVersion,
 		renderedParameters,
 	), nil
 }
@@
-) (*managementv1.Project, *managementv1.DevsyWorkspaceTemplate, string, error) {
+) (*managementv1.Project, *managementv1.Cluster, *managementv1.DevsyWorkspaceTemplate, string, error) {
@@
-		return nil, nil, "", err
+		return nil, nil, nil, "", err
@@
-	return selectedProject, selectedTemplate, selectedTemplateVersion, nil
+	return selectedProject, selectedCluster, selectedTemplate, selectedTemplateVersion, nil
 }
@@
 	id, uid, source, picture string,
 	selectedProject *managementv1.Project,
+	selectedCluster *managementv1.Cluster,
 	selectedTemplate *managementv1.DevsyWorkspaceTemplate,
@@
 				TemplateRef: &storagev1.TemplateRef{
 					Name:    selectedTemplate.GetName(),
 					Version: selectedTemplateVersion,
 				},
+				Target: storagev1.WorkspaceTarget{
+					Cluster: &storagev1.WorkspaceTargetName{
+						Name: selectedCluster.GetName(),
+					},
+				},
 				Parameters: renderedParameters,

Also applies to: 57-103, 123-155

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/platform/form/form.go` around lines 34 - 54, The create flow drops the
selected cluster before constructing the instance. Update runCreateSelectionForm
and its callers to return and propagate selectedCluster, then pass it into
buildCreatedInstance so the resulting Spec.Target.Cluster matches the form
selection; apply the same change to the other affected call sites.

The funlen extraction in the prior commits introduced real new violations
of other linters, all caught by the CI-equivalent check
(golangci-lint run --new-from-patch=$(git diff $(git merge-base HEAD
origin/main)) --new=false ./...), not just --enable-only=funlen:

- forbidigo: removed a stray fmt.Println(testCase.Name) debug print in
  pkg/options/options_test.go, pre-existing on main but only surfaced as
  'new' because relocation shifted its diff hunk; t.Run's subtest naming
  already covers this, no test coverage lost. Removed the now-unused fmt
  import too.

- funcorder: moved the register*Flags helper methods added by the Group A
  funlen commit to after Run/Close in cmd/internal/agentcontainer/setup.go,
  cmd/internal/runusercommands.go, cmd/workspace/ssh.go, and swapped
  logOutputStreams.stdout/Close order in
  pkg/client/clientimplementation/daemonclient/up.go -- exported methods
  must precede unexported ones on the same receiver.

- revive (argument-limit / function-result-limit): bundled the new
  helpers' parameters/results into <funcName>Params/Result structs,
  matching the existing convention (loginParams, waitForWorkspacePhaseParams,
  etc.) established for the dupl-findings PR -- cmd/workspace/logs.go
  (injectLogsAgent), cmd/workspace/ssh.go (runInteractiveTunnelSession),
  pkg/client/clientimplementation/daemonclient/form.go
  (selectProjectClusterTemplate, buildNewInstance), pkg/devcontainer/
  compose_build.go (resolveComposeBuildTarget), pkg/options/resolve.go
  (applyResolvedProviderOptions), pkg/platform/form/form.go
  (runCreateSelectionForm, buildCreatedInstance), pkg/platform/kubeconfig.go
  (newVClusterKubeConfigRequest, directVirtualClusterKubeConfig).
  While fixing this in pkg/client/clientimplementation/daemonclient/form.go
  I caught and fixed a self-inflicted bug: an earlier truncated read had
  caused buildNewInstance to silently drop the Target and Parameters
  fields from the constructed DevsyWorkspaceInstance -- restored, verified
  against origin/main's field list.

- gosec / lll: the two flagged spots (TLS InsecureSkipVerify and one long
  URL format string in cmd/internal/agentcontainer/setup.go) are unchanged,
  pre-existing content that only look 'new' because extraction shifted
  their indentation. Suppressed with //nolint citing this, rather than
  fixing gosec/lll findings that belong to their own future backlog PRs.

- goconst: pkg/ssh/config_test.go's relocated table now duplicates 5
  string literals that already have named constants elsewhere in the
  package (testExecPath, testHostBasic, testUser, testContextAlt,
  testWorkspaceAlt) -- swapped to reuse them. pkg/options/options_test.go
  and pkg/options/resolve_test.go's relocated tables hoisted every
  genuinely repeated literal into real named constants (not just to
  silence the linter): testOptTest, testValTest, testOptCommand,
  testRefChain34, etc. -- 26 total across both files.

Re-verified with the exact CI check (not just --enable-only=funlen):
0 issues. go build, go vet (clean aside from the same pre-existing
unrelated pkg/pty/ptytest finding from prior rounds), and the full test
suite for every touched package all pass -- spot-checked TestResolveOptions
(22 subtests) and TestInheritFromEnvironment (4 subtests) individually,
not just package exit codes.
@skevetter
skevetter marked this pull request as draft August 7, 2026 01:18
ResolveOptions dereferenced devConfig before its nil guard; move the
guard to the top of the function so a nil input returns cleanly
instead of panicking. Also stop computing the NOTEXPIRE test
timestamp at package-init time (types.Now() in a package-level var),
which could make TestResolveOptions flaky if run long after process
start; the timestamp is now generated immediately before Resolve runs.
@skevetter
skevetter marked this pull request as ready for review August 7, 2026 02:24
@skevetter
skevetter merged commit a4bb416 into main Aug 7, 2026
67 checks passed
@skevetter
skevetter deleted the lint/funlen-findings branch August 7, 2026 02:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant