diff --git a/cmd/commit.go b/cmd/commit.go index 2fbfb8d..554cec8 100644 --- a/cmd/commit.go +++ b/cmd/commit.go @@ -31,7 +31,7 @@ Subcommands: unpublish Make a commit private`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - // Bare `vers commit` with no args → create commit of HEAD + // Bare `vers commit` with no args -> create commit of HEAD return commitCreateCmd.RunE(cmd, args) }, } @@ -68,7 +68,7 @@ Use --format json for machine-readable output.`, if res.UsedHEAD { fmt.Printf("Using current HEAD VM: %s\n", res.VmID) } - fmt.Printf("✓ Committed VM '%s'\n", res.VmID) + fmt.Printf("Committed VM '%s'\n", res.VmID) fmt.Printf("Commit ID: %s\n", res.CommitID) } return nil @@ -139,13 +139,13 @@ Examples: CommitID: id, }) if err != nil { - fmt.Fprintf(cmd.ErrOrStderr(), "✗ Failed to delete commit %s: %v\n", id, err) + fmt.Fprintf(cmd.ErrOrStderr(), "error: failed to delete commit %s: %v\n", id, err) if firstErr == nil { firstErr = err } continue } - fmt.Printf("✓ Commit %s deleted\n", id) + fmt.Printf("Commit %s deleted\n", id) } return firstErr }, @@ -198,7 +198,7 @@ var commitPublishCmd = &cobra.Command{ if err != nil { return err } - fmt.Printf("✓ Commit %s is now public\n", info.CommitID) + fmt.Printf("Commit %s is now public\n", info.CommitID) return nil }, } @@ -219,7 +219,7 @@ var commitUnpublishCmd = &cobra.Command{ if err != nil { return err } - fmt.Printf("✓ Commit %s is now private\n", info.CommitID) + fmt.Printf("Commit %s is now private\n", info.CommitID) return nil }, } diff --git a/cmd/execute_test.go b/cmd/execute_test.go index 754d08b..9d863f5 100644 --- a/cmd/execute_test.go +++ b/cmd/execute_test.go @@ -10,9 +10,9 @@ import ( // TestExecuteCommandArgumentParsing tests the argument parsing logic for execute. // The logic uses LooksLikeVMTarget to decide if the first arg is a VM or a command: -// - UUID → treated as VM target -// - Known alias → treated as VM target -// - Anything else → treated as command, uses HEAD +// - UUID -> treated as VM target +// - Known alias -> treated as VM target +// - Anything else -> treated as command, uses HEAD func TestExecuteCommandArgumentParsing(t *testing.T) { tests := []struct { name string diff --git a/cmd/login.go b/cmd/login.go index 3ceba4e..ffdfd78 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -84,7 +84,7 @@ func loginWithGit() error { fmt.Print("Looking up git email... ") email, err := auth.GetGitEmail() if err != nil { - fmt.Println("✗") + fmt.Println("failed") return err } fmt.Println(email) @@ -93,7 +93,7 @@ func loginWithGit() error { fmt.Print("Looking up SSH public key... ") sshPubKey, _, err := auth.FindSSHPublicKey() if err != nil { - fmt.Println("✗") + fmt.Println("failed") return err } // Show truncated key for confirmation @@ -116,7 +116,7 @@ func loginWithGit() error { if initResp.AlreadyVerified { // Key is already verified — skip email, go straight to verify-key for org list - fmt.Println("SSH key already verified ✓") + fmt.Println("SSH key already verified") verifyResp, err = auth.ShellAuthCheckVerification(email, sshPubKey) if err != nil { return fmt.Errorf("failed to fetch org list: %w", err) @@ -127,16 +127,16 @@ func loginWithGit() error { } // Step 4: Wait for email verification - fmt.Printf("\n📧 Verification email sent to %s\n", email) + fmt.Printf("\nVerification email sent to %s\n", email) fmt.Println(" Click the link in the email to continue.") fmt.Print(" Waiting for verification...") verifyResp, err = auth.ShellAuthPollVerification(email, sshPubKey, 10*time.Minute) if err != nil { - fmt.Println(" ✗") + fmt.Println(" failed") return err } - fmt.Println(" ✓") + fmt.Println(" ok") } // Step 5: Select organization @@ -176,15 +176,15 @@ func loginWithGit() error { fmt.Print("Creating API key... ") keyResp, err := auth.ShellAuthCreateAPIKey(email, sshPubKey, label, orgName) if err != nil { - fmt.Println("✗") + fmt.Println("failed") return fmt.Errorf("failed to create API key: %w", err) } - fmt.Println("✓") + fmt.Println("ok") // Step 7: Validate and save fmt.Print("Validating API key... ") if err := validateAPIKey(keyResp.APIKey); err != nil { - fmt.Println("✗") + fmt.Println("failed") return err } @@ -192,7 +192,7 @@ func loginWithGit() error { return fmt.Errorf("error saving API key: %w", err) } - fmt.Printf("\n✓ Successfully authenticated with Vers (org: %s)\n", keyResp.OrgName) + fmt.Printf("\nSuccessfully authenticated with Vers (org: %s)\n", keyResp.OrgName) return nil } diff --git a/cmd/repo.go b/cmd/repo.go index 3e97591..22057d2 100644 --- a/cmd/repo.go +++ b/cmd/repo.go @@ -36,7 +36,7 @@ var repoCreateCmd = &cobra.Command{ if err != nil { return err } - fmt.Printf("✓ Repository '%s' created (%s)\n", resp.Name, resp.RepoID) + fmt.Printf("Repository '%s' created (%s)\n", resp.Name, resp.RepoID) return nil }, } @@ -138,13 +138,13 @@ Examples: Name: name, }) if err != nil { - fmt.Fprintf(cmd.ErrOrStderr(), "✗ Failed to delete repository '%s': %v\n", name, err) + fmt.Fprintf(cmd.ErrOrStderr(), "error: failed to delete repository '%s': %v\n", name, err) if firstErr == nil { firstErr = err } continue } - fmt.Printf("✓ Repository '%s' deleted\n", name) + fmt.Printf("Repository '%s' deleted\n", name) } return firstErr }, @@ -179,7 +179,7 @@ Examples: if repoVisibilityPublic { vis = "public" } - fmt.Printf("✓ Repository '%s' is now %s\n", args[0], vis) + fmt.Printf("Repository '%s' is now %s\n", args[0], vis) return nil }, } @@ -220,7 +220,7 @@ Examples: if err != nil { return err } - fmt.Printf("✓ Forked → %s\n", resp.Reference) + fmt.Printf("Forked -> %s\n", resp.Reference) fmt.Printf(" VM: %s\n", resp.VmID) fmt.Printf(" Commit: %s\n", resp.CommitID) return nil @@ -255,7 +255,7 @@ var repoTagCreateCmd = &cobra.Command{ if err != nil { return err } - fmt.Printf("✓ Tag created → %s\n", resp.Reference) + fmt.Printf("Tag created -> %s\n", resp.Reference) return nil }, } @@ -362,7 +362,7 @@ var repoTagUpdateCmd = &cobra.Command{ if err != nil { return err } - fmt.Printf("✓ Tag '%s' in '%s' updated\n", args[1], args[0]) + fmt.Printf("Tag '%s' in '%s' updated\n", args[1], args[0]) return nil }, } @@ -390,13 +390,13 @@ Examples: TagName: name, }) if err != nil { - fmt.Fprintf(cmd.ErrOrStderr(), "✗ Failed to delete tag '%s': %v\n", name, err) + fmt.Fprintf(cmd.ErrOrStderr(), "error: failed to delete tag '%s': %v\n", name, err) if firstErr == nil { firstErr = err } continue } - fmt.Printf("✓ Tag '%s' deleted from '%s'\n", name, repoName) + fmt.Printf("Tag '%s' deleted from '%s'\n", name, repoName) } return firstErr }, diff --git a/cmd/resize.go b/cmd/resize.go index 0f6d924..4caa501 100644 --- a/cmd/resize.go +++ b/cmd/resize.go @@ -44,7 +44,7 @@ Use --format json for machine-readable output.`, case pres.FormatJSON: pres.PrintJSON(map[string]interface{}{"vm_id": vmID, "fs_size_mib": resizeDiskSize}) default: - fmt.Printf("✓ Disk resized to %d MiB for VM %s\n", resizeDiskSize, vmID) + fmt.Printf("Disk resized to %d MiB for VM %s\n", resizeDiskSize, vmID) } return nil }, diff --git a/cmd/root.go b/cmd/root.go index 4dab48e..9ae22a3 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -179,17 +179,17 @@ interaction capabilities, and more.`, cmd.CalledAs() == "help" || cmd.Name() == "upgrade" - if !skipUpdateCheck { - // Synchronous update check with a tight timeout. Uses a - // disk-cached "latest known release" so the nag prints - // instantly on subsequent runs without any network I/O, - // and only refreshes once per check interval. - // - // Done synchronously (not in a goroutine) because short - // commands like `vers ps` would exit before a detached - // goroutine could finish its HTTP call, suppressing the - // nag indefinitely. - update.MaybeNotifyUpdate(cmd.Context(), Version, Repository, 800*time.Millisecond, verbose) + if !skipUpdateCheck && update.ShouldCheckForUpdate() { + // Update the check time regardless of result + update.UpdateCheckTime() + // Check for updates in background + go func() { + DebugPrint("Checking for updates...\n") + hasUpdate, latestVersion, err := update.CheckForUpdates(Version, Repository, verbose) + if err == nil && hasUpdate { + fmt.Printf("note: update available: %s -> %s (run 'vers upgrade')\n\n", Version, latestVersion) + } + }() } if cmd.Name() == "login" || cmd.Name() == "signup" || cmd.Name() == "help" || cmd.CalledAs() == "help" { diff --git a/cmd/signup.go b/cmd/signup.go index 1fd0fd3..9c97847 100644 --- a/cmd/signup.go +++ b/cmd/signup.go @@ -28,7 +28,7 @@ func signupWithGit() error { var err error email, err = auth.GetGitEmail() if err != nil { - fmt.Println("✗") + fmt.Println("failed") return err } fmt.Println(email) @@ -38,7 +38,7 @@ func signupWithGit() error { fmt.Print("Looking up SSH public key... ") sshPubKey, sshKeyPath, err := auth.FindSSHPublicKey() if err != nil { - fmt.Println("✗") + fmt.Println("failed") return err } // Show truncated key for confirmation @@ -61,7 +61,7 @@ func signupWithGit() error { if initResp.AlreadyVerified { // Key is already verified — skip email, go straight to verify-key for org list - fmt.Println("SSH key already verified ✓") + fmt.Println("SSH key already verified") verifyResp, err = auth.ShellAuthCheckVerification(email, sshPubKey) if err != nil { return fmt.Errorf("failed to fetch org list: %w", err) @@ -72,16 +72,16 @@ func signupWithGit() error { } // Step 4: Wait for email verification - fmt.Printf("\n📧 Verification email sent to %s\n", email) + fmt.Printf("\nVerification email sent to %s\n", email) fmt.Println(" Click the link in the email to continue.") fmt.Print(" Waiting for verification...") verifyResp, err = auth.ShellAuthPollVerification(email, sshPubKey, 10*time.Minute) if err != nil { - fmt.Println(" ✗") + fmt.Println(" failed") return err } - fmt.Println(" ✓") + fmt.Println(" ok") } // Step 5: Select organization @@ -127,15 +127,15 @@ func signupWithGit() error { fmt.Print("Creating API key... ") keyResp, err := auth.ShellAuthCreateAPIKey(email, sshPubKey, label, orgName) if err != nil { - fmt.Println("✗") + fmt.Println("failed") return fmt.Errorf("failed to create API key: %w", err) } - fmt.Println("✓") + fmt.Println("ok") // Step 7: Validate and save fmt.Print("Validating API key... ") if err := validateAPIKey(keyResp.APIKey); err != nil { - fmt.Println("✗") + fmt.Println("failed") return err } @@ -150,7 +150,7 @@ func signupWithGit() error { return fmt.Errorf("error saving config: %w", err) } - fmt.Printf("\n✓ Successfully authenticated with Vers (org: %s)\n", keyResp.OrgName) + fmt.Printf("\nSuccessfully authenticated with Vers (org: %s)\n", keyResp.OrgName) return nil } @@ -181,16 +181,16 @@ If you already have an account, this will log you in.`, fmt.Print("Validating API key... ") if err := validateAPIKey(apiKey); err != nil { - fmt.Println("✗") + fmt.Println("failed") return err } - fmt.Println("✓") + fmt.Println("ok") if err := auth.SaveAPIKey(apiKey); err != nil { return fmt.Errorf("error saving API key: %w", err) } - fmt.Println("\n✓ Successfully authenticated with Vers") + fmt.Println("\nSuccessfully authenticated with Vers") return nil }, } diff --git a/cmd/tag.go b/cmd/tag.go index b0a4b49..7670512 100644 --- a/cmd/tag.go +++ b/cmd/tag.go @@ -35,7 +35,7 @@ var tagCreateCmd = &cobra.Command{ if err != nil { return err } - fmt.Printf("✓ Tag '%s' created → %s\n", resp.TagName, resp.CommitID) + fmt.Printf("Tag '%s' created -> %s\n", resp.TagName, resp.CommitID) return nil }, } @@ -138,7 +138,7 @@ var tagUpdateCmd = &cobra.Command{ if err != nil { return err } - fmt.Printf("✓ Tag '%s' updated\n", args[0]) + fmt.Printf("Tag '%s' updated\n", args[0]) return nil }, } @@ -163,13 +163,13 @@ Examples: TagName: name, }) if err != nil { - fmt.Fprintf(cmd.ErrOrStderr(), "✗ Failed to delete tag '%s': %v\n", name, err) + fmt.Fprintf(cmd.ErrOrStderr(), "error: failed to delete tag '%s': %v\n", name, err) if firstErr == nil { firstErr = err } continue } - fmt.Printf("✓ Tag '%s' deleted\n", name) + fmt.Printf("Tag '%s' deleted\n", name) } return firstErr }, diff --git a/internal/auth/keys.go b/internal/auth/keys.go index d0cf7fc..3248ece 100644 --- a/internal/auth/keys.go +++ b/internal/auth/keys.go @@ -52,6 +52,6 @@ func GetOrCreateSSHKey(vmID string, client *vers.Client, apiCtx context.Context) return "", fmt.Errorf("failed to save SSH key: %w", err) } - fmt.Println("✓ SSH key cached") + fmt.Println("SSH key cached") return keyPath, nil } diff --git a/internal/handlers/kill.go b/internal/handlers/kill.go index 4b83c44..a83be97 100644 --- a/internal/handlers/kill.go +++ b/internal/handlers/kill.go @@ -43,10 +43,10 @@ func HandleKill(ctx context.Context, a *app.App, r KillReq) error { var allDeleted []string for i, target := range targets { - // Resolve alias → ID + // Resolve alias -> ID vmInfo, err := utils.ResolveVMIdentifier(ctx, a.Client, target) if err != nil { - fmt.Fprintf(a.IO.Err, "✗ Failed to resolve '%s': %v\n", target, err) + fmt.Fprintf(a.IO.Err, "error: failed to resolve '%s': %v\n", target, err) if firstErr == nil { firstErr = err } @@ -57,7 +57,7 @@ func HandleKill(ctx context.Context, a *app.App, r KillReq) error { deletedID, err := delsvc.DeleteVM(ctx, a.Client, vmInfo.ID) if err != nil { - fmt.Fprintf(a.IO.Err, "✗ Failed to delete '%s': %v\n", vmInfo.DisplayName, err) + fmt.Fprintf(a.IO.Err, "error: failed to delete '%s': %v\n", vmInfo.DisplayName, err) if firstErr == nil { firstErr = err } diff --git a/internal/handlers/upgrade.go b/internal/handlers/upgrade.go index 3036415..5ff7424 100644 --- a/internal/handlers/upgrade.go +++ b/internal/handlers/upgrade.go @@ -105,9 +105,9 @@ func performUpgrade(DebugPrint func(string, ...any), release *update.GitHubRelea if err := verifyChecksum(tempFile, checksumURL); err != nil { return fmt.Errorf("checksum verification failed: %w", err) } - fmt.Println("✓ Checksum verification passed") + fmt.Println("Checksum verification passed") } else if skipChecksum { - fmt.Println("⚠️ Skipping checksum verification (not recommended)") + fmt.Println("warning: skipping checksum verification (not recommended)") } currentExe, err := os.Executable() @@ -124,7 +124,7 @@ func performUpgrade(DebugPrint func(string, ...any), release *update.GitHubRelea return fmt.Errorf("failed to install update: %w", err) } os.Remove(backupPath) - fmt.Printf("✓ Successfully upgraded to version %s!\n", release.TagName) + fmt.Printf("Successfully upgraded to version %s!\n", release.TagName) fmt.Println("Please restart any running vers processes to use the new version.") return nil } diff --git a/internal/mcp/tools_tunnel.go b/internal/mcp/tools_tunnel.go index 753bdc9..9dced82 100644 --- a/internal/mcp/tools_tunnel.go +++ b/internal/mcp/tools_tunnel.go @@ -63,7 +63,7 @@ func registerTunnelTool(server *mcp.Server, application *app.App, opts Options) // Store the tunnel so it can be closed later storeTunnel(tunnel) - summary := fmt.Sprintf("Tunnel open: 127.0.0.1:%d → %s:%d on VM %s (established in %s)", + summary := fmt.Sprintf("Tunnel open: 127.0.0.1:%d -> %s:%d on VM %s (established in %s)", tunnel.LocalPort, remoteHost, in.RemotePort, target, duration.Truncate(time.Millisecond)) fmt.Fprintf(os.Stderr, "[mcp] tool=vers.tunnel ok dur=%s target=%s local=%d remote=%s:%d\n", duration.Truncate(time.Millisecond), target, tunnel.LocalPort, remoteHost, in.RemotePort) diff --git a/internal/presenters/branch_presenter.go b/internal/presenters/branch_presenter.go index 81d122d..c7e02b4 100644 --- a/internal/presenters/branch_presenter.go +++ b/internal/presenters/branch_presenter.go @@ -28,13 +28,13 @@ func RenderBranch(a *app.App, res BranchView) { fmt.Printf("Creating new VM from: %s\n", progressName) if numNew == 1 { - fmt.Println("✓ New VM created successfully!") + fmt.Println("New VM created successfully!") fmt.Printf("VM ID: %s\n", newIDs[0]) if res.NewAlias != "" { fmt.Printf("Alias: %s\n", res.NewAlias) } } else { - fmt.Printf("✓ %d new VMs created successfully!\n", numNew) + fmt.Printf("%d new VMs created successfully!\n", numNew) for _, id := range newIDs { fmt.Println(id) } @@ -45,7 +45,7 @@ func RenderBranch(a *app.App, res BranchView) { if display == "" { display = newIDs[0] } - fmt.Printf("✓ HEAD now points to: %s\n", display) + fmt.Printf("HEAD now points to: %s\n", display) return } diff --git a/internal/presenters/commits_presenter.go b/internal/presenters/commits_presenter.go index 96e4fbc..31779a1 100644 --- a/internal/presenters/commits_presenter.go +++ b/internal/presenters/commits_presenter.go @@ -43,9 +43,9 @@ func RenderCommitParents(_ *app.App, v CommitParentsView) { } for i, p := range v.Parents { - prefix := "├─" + prefix := "|-" if i == len(v.Parents)-1 { - prefix = "└─" + prefix = "\\-" } name := p.Name if name == "" { diff --git a/internal/presenters/deletion_presenter.go b/internal/presenters/deletion_presenter.go index 9d7da7b..89cb87c 100644 --- a/internal/presenters/deletion_presenter.go +++ b/internal/presenters/deletion_presenter.go @@ -18,7 +18,7 @@ func ProgressCounter(current, total int, action, target string) { } func SuccessMessage(message string) { - fmt.Printf("✓ %s\n", message) + fmt.Printf("%s\n", message) } func OperationCancelled() { fmt.Println("Operation cancelled") } @@ -32,9 +32,9 @@ func SectionHeader(title string) { func PrintDeletionSummary(results SummaryResults) { SectionHeader("Operation Summary") - fmt.Printf("✓ Successfully processed: %d %s\n", results.SuccessCount, results.ItemType) + fmt.Printf("Successfully processed: %d %s\n", results.SuccessCount, results.ItemType) if results.FailCount > 0 { - fmt.Printf("✗ Failed to process: %d %s\n", results.FailCount, results.ItemType) + fmt.Printf("error: failed to process: %d %s\n", results.FailCount, results.ItemType) if len(results.Errors) > 0 { fmt.Println() fmt.Println("Error details:") diff --git a/internal/presenters/pause_presenter.go b/internal/presenters/pause_presenter.go index f7eb419..27113a8 100644 --- a/internal/presenters/pause_presenter.go +++ b/internal/presenters/pause_presenter.go @@ -9,6 +9,6 @@ import ( type PauseView struct{ VMName, NewState string } func RenderPause(a *app.App, v PauseView) { - fmt.Printf("✓ VM '%s' paused successfully\n", v.VMName) + fmt.Printf("VM '%s' paused successfully\n", v.VMName) fmt.Printf("State: %s\n", v.NewState) } diff --git a/internal/presenters/resume_presenter.go b/internal/presenters/resume_presenter.go index b92694c..3b610cd 100644 --- a/internal/presenters/resume_presenter.go +++ b/internal/presenters/resume_presenter.go @@ -9,6 +9,6 @@ import ( type ResumeView struct{ VMName, NewState string } func RenderResume(a *app.App, v ResumeView) { - fmt.Printf("✓ VM '%s' resumed successfully\n", v.VMName) + fmt.Printf("VM '%s' resumed successfully\n", v.VMName) fmt.Printf("State: %s\n", v.NewState) } diff --git a/internal/presenters/tunnel_presenter.go b/internal/presenters/tunnel_presenter.go index e50c21b..e43e081 100644 --- a/internal/presenters/tunnel_presenter.go +++ b/internal/presenters/tunnel_presenter.go @@ -10,7 +10,7 @@ func RenderTunnel(a *app.App, v TunnelView) { if v.UsedHEAD { fmt.Fprintf(a.IO.Out, "Using current HEAD VM: %s\n", v.HeadID) } - fmt.Fprintf(a.IO.Out, "Forwarding 127.0.0.1:%d → %s:%d on VM %s\n", + fmt.Fprintf(a.IO.Out, "Forwarding 127.0.0.1:%d -> %s:%d on VM %s\n", v.LocalPort, v.RemoteHost, v.RemotePort, v.VMName) fmt.Fprintln(a.IO.Out, "Press Ctrl-C to stop the tunnel.") } diff --git a/internal/update/update.go b/internal/update/update.go index 6810b40..df640da 100644 --- a/internal/update/update.go +++ b/internal/update/update.go @@ -316,7 +316,7 @@ func MaybeNotifyUpdate(ctx context.Context, current, repository string, timeout } func printUpdateBanner(current, latest string) { - fmt.Fprintf(os.Stderr, "💡 vers update available: %s -> %s (run 'vers upgrade')\n\n", current, latest) + fmt.Fprintf(os.Stderr, "note: vers update available: %s -> %s (run 'vers upgrade')\n\n", current, latest) } // envFlagSet returns true if the env var is set to a "truthy" value. diff --git a/internal/update/update_test.go b/internal/update/update_test.go index 8dfbe7c..dfe98d7 100644 --- a/internal/update/update_test.go +++ b/internal/update/update_test.go @@ -164,7 +164,7 @@ type rewriteTransport struct { } func (rt *rewriteTransport) RoundTrip(r *http.Request) (*http.Response, error) { - // Rewrite api.github.com → httptest server + // Rewrite api.github.com -> httptest server if strings.Contains(r.URL.Host, "api.github.com") { u := *r.URL // httptest server URL is like http://127.0.0.1:PORT diff --git a/test/integration_repo_lifecycle_test.go b/test/integration_repo_lifecycle_test.go index 27f6272..522e171 100644 --- a/test/integration_repo_lifecycle_test.go +++ b/test/integration_repo_lifecycle_test.go @@ -8,7 +8,7 @@ import ( ) // TestRepoLifecycle exercises the full repo CRUD lifecycle against production: -// create repo → list → get → create tag → list tags → get tag → update tag → delete tag → delete repo. +// create repo -> list -> get -> create tag -> list tags -> get tag -> update tag -> delete tag -> delete repo. // Everything is cleaned up regardless of test outcome. func TestRepoLifecycle(t *testing.T) { testutil.TestEnv(t) @@ -187,7 +187,7 @@ func TestRepoLifecycle(t *testing.T) { // parseCommitID extracts a commit ID from `vers commit create` output. // Expected format: // -// ✓ Committed VM '' +// Committed VM '' // Commit ID: func parseCommitID(t *testing.T, output string) string { t.Helper() diff --git a/test/single-action/integration_branch_test.go b/test/single-action/integration_branch_test.go index 68dd5aa..11c8c35 100644 --- a/test/single-action/integration_branch_test.go +++ b/test/single-action/integration_branch_test.go @@ -58,7 +58,7 @@ func TestBranchBasic(t *testing.T) { t.Fatalf("expected 'Creating new VM from' in output, got:\n%s", out) } - t.Log("✓ VM branched successfully") + t.Log("VM branched successfully") t.Log("TestBranchBasic completed") } @@ -85,6 +85,6 @@ func TestBranchFromNonExistent(t *testing.T) { t.Logf("Warning: error message could be more specific. Got:\n%s", out) } - t.Log("✓ Branch from non-existent VM failed as expected") + t.Log("Branch from non-existent VM failed as expected") t.Log("TestBranchFromNonExistent completed") } diff --git a/test/single-action/integration_commits_test.go b/test/single-action/integration_commits_test.go index 26cff67..e046656 100644 --- a/test/single-action/integration_commits_test.go +++ b/test/single-action/integration_commits_test.go @@ -61,7 +61,7 @@ func TestCommitAndList(t *testing.T) { t.Fatalf("expected commit %s in list output, got:\n%s", commitID, out) } - t.Log("✓ Commit created and listed successfully") + t.Log("Commit created and listed successfully") } // TestCommitHistory tests the commit history (parents) command. @@ -108,7 +108,7 @@ func TestCommitHistory(t *testing.T) { t.Fatalf("expected 'Commit History' header in output, got:\n%s", out) } - t.Log("✓ Commit history retrieved successfully") + t.Log("Commit history retrieved successfully") } // TestCommitPublishUnpublish tests publishing and unpublishing a commit. @@ -160,7 +160,7 @@ func TestCommitPublishUnpublish(t *testing.T) { t.Fatalf("expected 'now private' in output, got:\n%s", out) } - t.Log("✓ Commit publish/unpublish works") + t.Log("Commit publish/unpublish works") } // TestCommitDeleteNonExistent tests that deleting a non-existent commit fails gracefully. @@ -177,7 +177,7 @@ func TestCommitDeleteNonExistent(t *testing.T) { t.Fatalf("expected error deleting non-existent commit, got success:\n%s", out) } t.Logf("Got expected error:\n%s", out) - t.Log("✓ Delete non-existent commit failed as expected") + t.Log("Delete non-existent commit failed as expected") } // TestCommitListEmpty tests that commit list works even with no commits. @@ -198,5 +198,5 @@ func TestCommitListEmpty(t *testing.T) { t.Fatalf("expected commit-related output, got:\n%s", out) } - t.Log("✓ Commit list works") + t.Log("Commit list works") } diff --git a/test/single-action/integration_connect_test.go b/test/single-action/integration_connect_test.go index 44c1f35..8cb1b16 100644 --- a/test/single-action/integration_connect_test.go +++ b/test/single-action/integration_connect_test.go @@ -126,7 +126,7 @@ func TestConnect_SSHOverTLS(t *testing.T) { t.Errorf("expected 'root' from whoami command, got: %s", lastLine) } - t.Log("✓ SSH-over-TLS connection successful") + t.Log("SSH-over-TLS connection successful") t.Log("TestConnect_SSHOverTLS completed") } @@ -203,6 +203,6 @@ func TestConnect_InvalidVM(t *testing.T) { } t.Logf("Got expected error: %v", err) - t.Log("✓ Connect correctly fails for non-existent VM") + t.Log("Connect correctly fails for non-existent VM") t.Log("TestConnect_InvalidVM completed") } diff --git a/test/single-action/integration_execute_test.go b/test/single-action/integration_execute_test.go index 519ea05..497dc0e 100644 --- a/test/single-action/integration_execute_test.go +++ b/test/single-action/integration_execute_test.go @@ -47,7 +47,7 @@ func TestExecuteBasic(t *testing.T) { t.Fatalf("expected 'hello-from-vers' in output, got:\n%s", out) } - t.Log("✓ Execute command successful") + t.Log("Execute command successful") t.Log("TestExecuteBasic completed") } @@ -90,7 +90,7 @@ func TestExecuteWithFlags(t *testing.T) { t.Fatalf("expected directory listing in output, got:\n%s", out) } - t.Log("✓ Execute with flags successful") + t.Log("Execute with flags successful") t.Log("TestExecuteWithFlags completed") } @@ -133,7 +133,7 @@ func TestExecuteQuotedCommand(t *testing.T) { t.Fatalf("expected directory listing in output, got:\n%s", out) } - t.Log("✓ Execute with quoted command successful") + t.Log("Execute with quoted command successful") t.Log("TestExecuteQuotedCommand completed") } @@ -176,7 +176,7 @@ func TestExecuteMultipleArgs(t *testing.T) { t.Fatalf("expected 'hello world from vers' in output, got:\n%s", out) } - t.Log("✓ Execute with multiple args successful") + t.Log("Execute with multiple args successful") t.Log("TestExecuteMultipleArgs completed") } @@ -206,7 +206,7 @@ func TestExecuteInvalidVM(t *testing.T) { t.Logf("Warning: error message could be more specific. Got:\n%s", out) } - t.Log("✓ Execute correctly fails for non-existent VM") + t.Log("Execute correctly fails for non-existent VM") t.Log("TestExecuteInvalidVM completed") } @@ -252,7 +252,7 @@ func TestExecuteMissingCommand(t *testing.T) { t.Fatalf("expected 'Usage:' in error output, got:\n%s", out) } - t.Log("✓ Execute correctly fails with clear error for missing command") + t.Log("Execute correctly fails with clear error for missing command") t.Log("TestExecuteMissingCommand completed") } @@ -299,6 +299,6 @@ func TestExecuteCommandWithExitCode(t *testing.T) { t.Logf("Warning: error message could mention exit code. Got:\n%s", out) } - t.Log("✓ Execute properly handles non-zero exit codes") + t.Log("Execute properly handles non-zero exit codes") t.Log("TestExecuteCommandWithExitCode completed") } diff --git a/test/single-action/integration_info_test.go b/test/single-action/integration_info_test.go index d16e88d..cec2217 100644 --- a/test/single-action/integration_info_test.go +++ b/test/single-action/integration_info_test.go @@ -49,7 +49,7 @@ func TestInfoBasic(t *testing.T) { t.Fatalf("expected Created field in output, got:\n%s", out) } - t.Log("✓ VM info retrieved successfully") + t.Log("VM info retrieved successfully") } // TestInfoWithLineage tests that a branched VM shows parent commit info. @@ -106,7 +106,7 @@ func TestInfoWithLineage(t *testing.T) { t.Logf("Note: no parent commit shown — may depend on backend behavior") } - t.Log("✓ VM info with lineage retrieved") + t.Log("VM info with lineage retrieved") } // TestInfoNonExistent tests that info for a non-existent VM fails gracefully. @@ -123,5 +123,5 @@ func TestInfoNonExistent(t *testing.T) { t.Fatalf("expected error for non-existent VM, got success:\n%s", out) } t.Logf("Got expected error:\n%s", out) - t.Log("✓ Info for non-existent VM failed as expected") + t.Log("Info for non-existent VM failed as expected") } diff --git a/test/single-action/integration_kill_test.go b/test/single-action/integration_kill_test.go index 1186268..8922734 100644 --- a/test/single-action/integration_kill_test.go +++ b/test/single-action/integration_kill_test.go @@ -38,7 +38,7 @@ func TestKillBasic(t *testing.T) { // Note: Current implementation doesn't print a success message on deletion // Success is indicated by exit code 0 (no error) and empty/minimal output - t.Log("✓ VM deleted successfully (command returned with no error)") + t.Log("VM deleted successfully (command returned with no error)") t.Log("TestKillBasic completed") } @@ -65,7 +65,7 @@ func TestKillNonExistent(t *testing.T) { t.Logf("Warning: error message could be more specific. Got:\n%s", out) } - t.Log("✓ Non-existent VM deletion failed as expected") + t.Log("Non-existent VM deletion failed as expected") t.Log("TestKillNonExistent completed") } @@ -107,7 +107,7 @@ func TestKillWithoutConfirmation(t *testing.T) { // Check if it's a timeout or prompt-related error if strings.Contains(err.Error(), "timed out") || strings.Contains(out, "confirm") || strings.Contains(out, "y/n") { - t.Logf("✓ Kill command prompted for confirmation or timed out as expected. Error: %v", err) + t.Logf("Kill command prompted for confirmation or timed out as expected. Error: %v", err) } else { t.Logf("Kill failed with error (this may be expected in non-interactive mode): %v\nOutput:\n%s", err, out) } diff --git a/test/single-action/integration_login_test.go b/test/single-action/integration_login_test.go index 3cdeb16..e28c423 100644 --- a/test/single-action/integration_login_test.go +++ b/test/single-action/integration_login_test.go @@ -79,7 +79,7 @@ func TestLoginWithValidKey(t *testing.T) { t.Fatalf("expected file permissions 0600, got %o", perm) } - t.Log("✓ Login with valid key successful") + t.Log("Login with valid key successful") t.Log("TestLoginWithValidKey completed") } @@ -122,7 +122,7 @@ func TestLoginWithInvalidKey(t *testing.T) { } } - t.Log("✓ Login correctly rejected invalid key") + t.Log("Login correctly rejected invalid key") t.Log("TestLoginWithInvalidKey completed") } @@ -166,7 +166,7 @@ func TestLoginAndUseCommands(t *testing.T) { t.Fatalf("status command failed with auth error after login. Output:\n%s", out) } - t.Log("✓ Commands work with saved API key") + t.Log("Commands work with saved API key") t.Log("TestLoginAndUseCommands completed") } @@ -224,6 +224,6 @@ func TestLoginOverwritesExistingKey(t *testing.T) { t.Fatalf("API key doesn't match new key. Expected: %s, Got: %s", apiKey, config.APIKey) } - t.Log("✓ Login correctly overwrites existing key") + t.Log("Login correctly overwrites existing key") t.Log("TestLoginOverwritesExistingKey completed") } diff --git a/test/single-action/integration_resize_test.go b/test/single-action/integration_resize_test.go index 5e8775d..94e7b54 100644 --- a/test/single-action/integration_resize_test.go +++ b/test/single-action/integration_resize_test.go @@ -42,7 +42,7 @@ func TestResizeBasic(t *testing.T) { t.Fatalf("expected '20480' in output, got:\n%s", out) } - t.Log("✓ VM disk resized successfully") + t.Log("VM disk resized successfully") } // TestResizeTooSmall tests that shrinking a disk fails. @@ -72,7 +72,7 @@ func TestResizeTooSmall(t *testing.T) { t.Fatalf("expected error when shrinking disk, got success:\n%s", out) } t.Logf("Got expected error:\n%s", out) - t.Log("✓ Resize to smaller size failed as expected") + t.Log("Resize to smaller size failed as expected") } // TestResizeMissingSize tests that --size flag is required. @@ -90,7 +90,7 @@ func TestResizeMissingSize(t *testing.T) { t.Logf("Warning: error message could mention --size requirement. Got:\n%s", out) } - t.Log("✓ Missing --size flag failed as expected") + t.Log("Missing --size flag failed as expected") } // TestResizeNonExistent tests that resizing a non-existent VM fails. @@ -107,5 +107,5 @@ func TestResizeNonExistent(t *testing.T) { t.Fatalf("expected error for non-existent VM, got success:\n%s", out) } t.Logf("Got expected error:\n%s", out) - t.Log("✓ Resize non-existent VM failed as expected") + t.Log("Resize non-existent VM failed as expected") } diff --git a/test/single-action/integration_run_test.go b/test/single-action/integration_run_test.go index 4faf2ce..1722a44 100644 --- a/test/single-action/integration_run_test.go +++ b/test/single-action/integration_run_test.go @@ -53,7 +53,7 @@ func TestRunBasic(t *testing.T) { t.Fatalf("expected 'started successfully' in output, got:\n%s", out) } - t.Log("✓ VM created successfully") + t.Log("VM created successfully") // SDK alpha.24 fixes: // - NewRoot() now returns VM ID in response // - API now returns proper content-type: application/json headers @@ -88,7 +88,7 @@ func TestRunWithCustomSpecs(t *testing.T) { // The command should succeed // Note: We can't verify the specs in the output since the new API doesn't return VM details - t.Log("✓ VM created with custom specs successfully") + t.Log("VM created with custom specs successfully") t.Log("TestRunWithCustomSpecs completed") } @@ -169,7 +169,7 @@ func TestRunSetsHEAD(t *testing.T) { t.Fatalf("HEAD contains %q, expected %q", headVM, vmID) } - t.Log("✓ vers run correctly persists HEAD") + t.Log("vers run correctly persists HEAD") // Verify `vers head` also reads it back correctly from the same directory headOut, err := testutil.RunVersInDir(t, tempDir, testutil.DefaultTimeout, "head") @@ -180,6 +180,6 @@ func TestRunSetsHEAD(t *testing.T) { t.Fatalf("vers head output doesn't contain VM ID %s:\n%s", vmID, headOut) } - t.Log("✓ vers head reads back the correct VM ID") + t.Log("vers head reads back the correct VM ID") t.Log("TestRunSetsHEAD completed") } diff --git a/test/single-action/integration_ssh_keys_test.go b/test/single-action/integration_ssh_keys_test.go index 5382c58..e755803 100644 --- a/test/single-action/integration_ssh_keys_test.go +++ b/test/single-action/integration_ssh_keys_test.go @@ -84,7 +84,7 @@ J8aHcHXRqvNKwFdF9wAAAEDummyJZD5xPH8cYmP5KkqLXQBLJ8aHcHXRqvNKwFdF t.Errorf("key file content doesn't match expected content") } - t.Log("✓ GetOrCreateSSHKey successfully returned existing key path") + t.Log("GetOrCreateSSHKey successfully returned existing key path") t.Log("TestGetOrCreateSSHKey_ExistingKey completed") } @@ -133,7 +133,7 @@ func TestGetOrCreateSSHKey_NoKey(t *testing.T) { t.Logf("Warning: error message doesn't mention 'failed to fetch'. Got: %s", err.Error()) } - t.Log("✓ GetOrCreateSSHKey correctly returns error when VM doesn't exist") + t.Log("GetOrCreateSSHKey correctly returns error when VM doesn't exist") t.Log("TestGetOrCreateSSHKey_NoKey completed") } @@ -199,7 +199,7 @@ func TestGetOrCreateSSHKey_Integration(t *testing.T) { t.Errorf("key file doesn't appear to contain a valid SSH private key. Content length: %d bytes", len(keyStr)) } - t.Logf("✓ SSH key successfully fetched and saved (%d bytes)", len(keyStr)) + t.Logf("SSH key successfully fetched and saved (%d bytes)", len(keyStr)) // Test that calling it again returns the cached key t.Log("Testing cached key retrieval...") @@ -212,6 +212,6 @@ func TestGetOrCreateSSHKey_Integration(t *testing.T) { t.Errorf("expected same key path on second call, got %s vs %s", keyPath, keyPath2) } - t.Log("✓ Cached key retrieval works") + t.Log("Cached key retrieval works") t.Log("TestGetOrCreateSSHKey_Integration completed") } diff --git a/test/single-action/integration_tags_test.go b/test/single-action/integration_tags_test.go index b17e2d4..bca1a9d 100644 --- a/test/single-action/integration_tags_test.go +++ b/test/single-action/integration_tags_test.go @@ -9,7 +9,7 @@ import ( ) // TestTagLifecycle tests the full tag CRUD lifecycle: -// create a VM → commit → tag → list → get → update → delete. +// create a VM -> commit -> tag -> list -> get -> update -> delete. func TestTagLifecycle(t *testing.T) { t.Log("Starting TestTagLifecycle...") testutil.TestEnv(t) @@ -61,7 +61,7 @@ func TestTagLifecycle(t *testing.T) { if !strings.Contains(out, commitID) { t.Fatalf("expected commit ID in output, got:\n%s", out) } - t.Log("✓ Tag created") + t.Log("Tag created") // === LIST === t.Log("Running: vers tag list") @@ -72,7 +72,7 @@ func TestTagLifecycle(t *testing.T) { if !strings.Contains(out, tagName) { t.Fatalf("expected tag %s in list output, got:\n%s", tagName, out) } - t.Log("✓ Tag listed") + t.Log("Tag listed") // === GET === t.Logf("Running: vers tag get %s", tagName) @@ -86,7 +86,7 @@ func TestTagLifecycle(t *testing.T) { if !strings.Contains(out, commitID) { t.Fatalf("expected commit ID in get output, got:\n%s", out) } - t.Log("✓ Tag retrieved") + t.Log("Tag retrieved") // === UPDATE (description) === t.Logf("Running: vers tag update %s --description 'updated desc'", tagName) @@ -97,7 +97,7 @@ func TestTagLifecycle(t *testing.T) { if !strings.Contains(out, "updated") { t.Fatalf("expected 'updated' in output, got:\n%s", out) } - t.Log("✓ Tag updated") + t.Log("Tag updated") // Verify the update took effect out, err = testutil.RunVers(t, testutil.DefaultTimeout, "tag", "get", tagName) @@ -107,7 +107,7 @@ func TestTagLifecycle(t *testing.T) { if !strings.Contains(out, "updated desc") { t.Fatalf("expected updated description in get output, got:\n%s", out) } - t.Log("✓ Tag update verified") + t.Log("Tag update verified") // === DELETE === t.Logf("Running: vers tag delete %s", tagName) @@ -118,14 +118,14 @@ func TestTagLifecycle(t *testing.T) { if !strings.Contains(out, "deleted") { t.Fatalf("expected 'deleted' in output, got:\n%s", out) } - t.Log("✓ Tag deleted") + t.Log("Tag deleted") // Verify tag is gone out, err = testutil.RunVers(t, testutil.DefaultTimeout, "tag", "get", tagName) if err == nil { t.Fatalf("expected error getting deleted tag, got success:\n%s", out) } - t.Log("✓ Deleted tag no longer accessible") + t.Log("Deleted tag no longer accessible") t.Log("TestTagLifecycle completed") } @@ -176,7 +176,7 @@ func TestTagCreateDuplicate(t *testing.T) { t.Fatalf("expected error creating duplicate tag, got success:\n%s", out) } t.Logf("Got expected error:\n%s", out) - t.Log("✓ Duplicate tag creation failed as expected") + t.Log("Duplicate tag creation failed as expected") } // TestTagGetNonExistent tests that getting a non-existent tag fails gracefully. @@ -189,7 +189,7 @@ func TestTagGetNonExistent(t *testing.T) { if err == nil { t.Fatalf("expected error getting non-existent tag, got success:\n%s", out) } - t.Log("✓ Non-existent tag get failed as expected") + t.Log("Non-existent tag get failed as expected") } // TestTagDeleteNonExistent tests that deleting a non-existent tag fails gracefully. @@ -202,7 +202,7 @@ func TestTagDeleteNonExistent(t *testing.T) { if err == nil { t.Fatalf("expected error deleting non-existent tag, got success:\n%s", out) } - t.Log("✓ Non-existent tag delete failed as expected") + t.Log("Non-existent tag delete failed as expected") } // TestTagListEmpty tests that tag list works even with no tags. @@ -220,5 +220,5 @@ func TestTagListEmpty(t *testing.T) { t.Fatalf("expected tag-related output, got:\n%s", out) } - t.Log("✓ Tag list works") + t.Log("Tag list works") } diff --git a/test/single-action/integration_tunnel_test.go b/test/single-action/integration_tunnel_test.go index 0e17bc9..6e2adb2 100644 --- a/test/single-action/integration_tunnel_test.go +++ b/test/single-action/integration_tunnel_test.go @@ -122,7 +122,7 @@ func TestTunnelBasic(t *testing.T) { t.Fatalf("expected echo %q, got %q", testMsg, response) } - t.Log("✓ Data round-tripped through tunnel successfully") + t.Log("Data round-tripped through tunnel successfully") t.Log("TestTunnelBasic completed") } @@ -140,7 +140,7 @@ func TestTunnelInvalidVM(t *testing.T) { } t.Logf("Got expected error: %v\nOutput:\n%s", err, out) - t.Log("✓ Tunnel correctly fails for non-existent VM") + t.Log("Tunnel correctly fails for non-existent VM") t.Log("TestTunnelInvalidVM completed") } @@ -170,7 +170,7 @@ func TestTunnelInvalidSpec(t *testing.T) { }) } - t.Log("✓ Tunnel correctly rejects invalid specs") + t.Log("Tunnel correctly rejects invalid specs") t.Log("TestTunnelInvalidSpec completed") } @@ -251,7 +251,7 @@ func TestTunnelUsesHEAD(t *testing.T) { } conn.Close() - t.Log("✓ Tunnel correctly uses HEAD VM") + t.Log("Tunnel correctly uses HEAD VM") t.Log("TestTunnelUsesHEAD completed") } diff --git a/test/testutil/helpers.go b/test/testutil/helpers.go index 52e9c3c..42dacf2 100644 --- a/test/testutil/helpers.go +++ b/test/testutil/helpers.go @@ -86,7 +86,7 @@ func RunVers(t TLike, timeout time.Duration, args ...string) (string, error) { cmd := exec.CommandContext(ctx, BinPath, args...) // Inherit env so VERS_URL and VERS_API_KEY are visible, but force - // the update-check off so the "💡 vers update available" banner + // the update-check off so the "note: vers update available" banner // can't contaminate command output that tests parse. cmd.Env = append(os.Environ(), "VERS_NO_UPDATE_CHECK=1") out, err := cmd.CombinedOutput()