refactor: architecture hardening + template edit command#34
Merged
Conversation
Previously, API errors during template name resolution were silently swallowed. If the wizard was skipped (all fields pre-filled), this could produce VMs with no SSH keys and no user warning. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… pricing cache renderDeploymentSummary now accepts an io.Writer parameter instead of writing directly to os.Stderr, consistent with the IOStreams abstraction. ensurePricingCache now receives the parent context instead of creating context.Background(), so Ctrl+C properly cancels in-flight API calls. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Error message said 'hyphens and underscores' but underscores are actually rejected. Updated to match actual validation behavior. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…random} dedup
- ValidateName now rejects names ending with hyphens, consistent with
normalizeName which already strips them.
- Entry struct now serializes with lowercase keys in -o json mode.
- Multiple {random} placeholders now generate different words each time.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move the generic withSpinner[T] function from wizard.go to cmd/util/spinner.go as exported WithSpinner and RunWithSpinner helpers. Replace all 11 manual spinner start/stop boilerplate sites across vm command files with calls to the shared helpers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Consolidates 3 duplicate fetch+filter patterns into a single helper with spinner support. Removes filterByValidFrom in favor of shared filterByStatus. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces 5 duplicate filepath.Join(verdaDir, "templates") constructions with a single centralized helper. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ons lifecycle wizard.go: step definitions + flow builder (~776 lines) wizard_cache.go: apiCache, pricing helpers, instance type utils wizard_subflows.go: SSH key, startup script, storage interactive flows wizard_summary.go: deployment summary rendering Also adds comprehensive lifecycle documentation to createOptions struct. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- fetchInstanceVolumes now uses goroutines with bounded concurrency (max 5) instead of sequential N+1 queries. - Template Save now writes to a .tmp file then renames, preventing corruption if the process is interrupted mid-write. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- testutil_test.go: httptest-based test harness with mock API server, TestFactory in agent mode, and captured IOStreams. - create_test.go: runCreate orchestration tests for agent-mode missing flags, happy path with all flags, template pre-fill, and no-client error. - action_test.go: Tests availableActions for offline/running/provisioning and filterByStatus with multiple scenarios. - command_test.go: Tests normalizeName, parseRef, and vmResultToTemplate. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- template edit: field menu to change specific template values. Supports interactive picker when no argument given. API-backed fields (instance type, location, image, SSH keys, startup script) fetch live choices. - template show: now displays all fields including hostname_pattern, storage_skip, startup_script_skip. Shows "-" for unset, "None (skipped)" for explicitly skipped fields. - template show/delete: optional arg — interactive picker when omitted. - wizard: add Default functions to billing-type, contract, kind, instance-type, image steps for better pre-selection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reflects architecture hardening refactors: wizard split into 4 files, shared helpers (WithSpinner, fetchInstances, TemplatesBaseDir), new template edit command, interactive pickers, createOptions lifecycle, atomic writes, parallel volume fetching, and warning-based name resolution. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The --all flag now includes all command directories, not just the original subset. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
template editcommand with field menu, interactive picker forshow/delete,showdisplays all fieldsDetails
11 commits, 30 files changed, +2015 / -870 lines
Phase A: Correctness (6 fixes)
renderDeploymentSummary→io.WriterensurePricingCache→ parent contextPhase B: Structure (7 refactors)
cmdutil.WithSpinnerPhase C: Tests
testutil_test.go: httptest mock API server + TestFactorycreate_test.go: 4 runCreate orchestration testsaction_test.go: availableActions + filterByStatus testscommand_test.go: normalizeName, parseRef, vmResultToTemplateTemplate UX
verda template edit [vm/name]— field menu to change specific valuesverda template show/verda template delete— interactive picker when no argverda template show— displays all fields including hostname pattern, skip flagsTest plan
make test— all packages passmake lint— 0 issuesverda template edit— field menu works, saves correctlyverda template show— all fields displayedverda template delete— interactive picker + confirmation🤖 Generated with Claude Code