Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,6 @@ lstk update
# Show resolved config file path
lstk config path

# Show version info
lstk version
```

## Reporting bugs
Expand Down
1 change: 1 addition & 0 deletions cmd/help_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func TestRootHelpOutputTemplate(t *testing.T) {
assertContains(t, out, "Options:")
assertNotContains(t, out, "Available Commands:")
assertNotContains(t, out, `Use "lstk [command] --help" for more information about a command.`)
assertNotContains(t, out, "\n version ")
}

func TestSubcommandHelpUsesSubcommandUsageLine(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions cmd/non_interactive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func TestNonInteractiveFlagAppearsInStopHelp(t *testing.T) {
func TestNonInteractiveFlagBindsToCfg(t *testing.T) {
cfg := &env.Env{}
root := NewRootCmd(cfg, telemetry.New("", true))
root.SetArgs([]string{"--non-interactive", "version"})
root.SetArgs([]string{"--non-interactive", "--version"})
_ = root.Execute()

Comment on lines 47 to 52
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Assert that Execute() succeeds in these flag-binding tests.

Both tests can still flip cfg.NonInteractive during flag parsing even if --version is broken, so they may pass while the user-facing path fails. Please check the returned error before asserting on cfg.

Suggested tightening
 func TestNonInteractiveFlagBindsToCfg(t *testing.T) {
 	cfg := &env.Env{}
 	root := NewRootCmd(cfg, telemetry.New("", true))
 	root.SetArgs([]string{"--non-interactive", "--version"})
-	_ = root.Execute()
+	if err := root.Execute(); err != nil {
+		t.Fatalf("expected Execute to succeed, got %v", err)
+	}

 	if !cfg.NonInteractive {
 		t.Fatal("expected cfg.NonInteractive to be true after --non-interactive flag")
 	}
 }
@@
 func TestNonInteractiveFlagDefaultIsOff(t *testing.T) {
 	cfg := &env.Env{}
 	root := NewRootCmd(cfg, telemetry.New("", true))
 	root.SetArgs([]string{"--version"})
-	_ = root.Execute()
+	if err := root.Execute(); err != nil {
+		t.Fatalf("expected Execute to succeed, got %v", err)
+	}

 	if cfg.NonInteractive {
 		t.Fatal("expected cfg.NonInteractive to be false when flag is not set")
 	}
 }

Also applies to: 58-62

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/non_interactive_test.go` around lines 47 - 52, The tests
TestNonInteractiveFlagBindsToCfg (and the similar test at 58-62) currently
ignore the error from root.Execute() and then assert on cfg.NonInteractive;
change them to check the returned error first (e.g., require.NoError(t, err) or
if err != nil { t.Fatalf(...)}), then assert cfg.NonInteractive so a failing
Execute() (such as broken --version handling) will fail the test instead of
producing a false positive; locate root := NewRootCmd(...) and the subsequent
root.Execute() call and update the test to capture and assert on the error
before inspecting cfg.NonInteractive.

if !cfg.NonInteractive {
Expand All @@ -58,7 +58,7 @@ func TestNonInteractiveFlagBindsToCfg(t *testing.T) {
func TestNonInteractiveFlagDefaultIsOff(t *testing.T) {
cfg := &env.Env{}
root := NewRootCmd(cfg, telemetry.New("", true))
root.SetArgs([]string{"version"})
root.SetArgs([]string{"--version"})
_ = root.Execute()

if cfg.NonInteractive {
Expand Down
3 changes: 1 addition & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ func NewRootCmd(cfg *env.Env, tel *telemetry.Client) *cobra.Command {
}

root.Version = version.Version()
root.SetVersionTemplate(versionLine() + "\n")
root.SilenceErrors = true
root.SilenceUsage = true

Expand All @@ -44,6 +43,7 @@ func NewRootCmd(cfg *env.Env, tel *telemetry.Client) *cobra.Command {

root.InitDefaultVersionFlag()
root.Flags().Lookup("version").Usage = "Show version"
root.SetVersionTemplate(versionTemplate())
Comment on lines 44 to +46
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether this repository explicitly wires a -v shorthand for the version flag.
set -euo pipefail

echo "== uses of InitDefaultVersionFlag =="
rg -nP --type=go '\bInitDefaultVersionFlag\s*\('

echo
echo "== explicit version shorthand registrations =="
rg -nP --type=go 'Bool(?:Var)?P\([^)]*"version"\s*,\s*"v"'
rg -nP --type=go 'Lookup\("version"\)\.Shorthand|Shorthand\s*=\s*"v"'

Repository: localstack/lstk

Length of output: 189


🏁 Script executed:

fd -type f -name "*test*.go" cmd/ | head -20

Repository: localstack/lstk

Length of output: 229


🏁 Script executed:

rg -nP --type=go "TestVersionFlagsPrintSameOutput" --context=5

Repository: localstack/lstk

Length of output: 583


🏁 Script executed:

# Also check the git diff or PR changes to understand context
git log --oneline -10

Repository: localstack/lstk

Length of output: 110


🏁 Script executed:

# Check if there are any recent changes to cmd/root.go
git log --oneline cmd/root.go | head -5

Repository: localstack/lstk

Length of output: 110


🏁 Script executed:

cat -n cmd/version_test.go

Repository: localstack/lstk

Length of output: 1034


🏁 Script executed:

# Also check for any calls to root command with -v flag
rg -nP --type=go '"\-v"' cmd/ | head -20

Repository: localstack/lstk

Length of output: 124


🏁 Script executed:

cat -n cmd/root.go | head -80

Repository: localstack/lstk

Length of output: 2695


🏁 Script executed:

# Search for any other version-related wiring in the codebase
rg -nP --type=go "version" cmd/root.go | head -20

Repository: localstack/lstk

Length of output: 303


Wire the -v shorthand for the version flag.

The test at cmd/version_test.go:16 expects both -v and --version flags to produce identical output (lines 17, 22, 30-32), but the current code only registers --version. Cobra's InitDefaultVersionFlag() does not include a shorthand; the -v flag must be explicitly registered.

Suggested fix
-	root.InitDefaultVersionFlag()
-	root.Flags().Lookup("version").Usage = "Show version"
+	root.Flags().BoolP("version", "v", false, "Show version")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/root.go` around lines 44 - 46, The version flag only has the long form;
add the -v shorthand after calling root.InitDefaultVersionFlag() by setting the
shorthand on the existing flag (e.g., use
root.Flags().Lookup("version").Shorthand = "v" and ensure its Usage remains
"Show version") so both -v and --version behave identically; this touches the
block using root.InitDefaultVersionFlag(), root.Flags().Lookup("version").Usage
and root.SetVersionTemplate(versionTemplate()).


root.AddCommand(
newStartCmd(cfg, tel),
Expand All @@ -52,7 +52,6 @@ func NewRootCmd(cfg *env.Env, tel *telemetry.Client) *cobra.Command {
newLogoutCmd(cfg),
newLogsCmd(),
newConfigCmd(),
newVersionCmd(),
newUpdateCmd(cfg),
)

Expand Down
15 changes: 3 additions & 12 deletions cmd/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,12 @@ import (
"fmt"

"github.com/localstack/lstk/internal/version"
"github.com/spf13/cobra"
)

func newVersionCmd() *cobra.Command {
return &cobra.Command{
Use: "version",
Short: "Show version",
Long: "Print version information for the lstk binary.",
RunE: func(cmd *cobra.Command, args []string) error {
_, err := fmt.Fprintln(cmd.OutOrStdout(), versionLine())
return err
},
}
func versionTemplate() string {
return versionLine() + "\n"
}

func versionLine() string {
return fmt.Sprintf("lstk %s (%s, %s)", version.Version(), version.Commit(), version.BuildDate())
return fmt.Sprintf("lstk %s", version.Version())
}
32 changes: 24 additions & 8 deletions cmd/version_test.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
package cmd

import (
"strings"
"testing"
)
import "testing"

func TestVersionLine(t *testing.T) {
got := versionLine()

if !strings.HasPrefix(got, "lstk ") {
t.Fatalf("versionLine() = %q, should start with 'lstk '", got)
if got == "" {
t.Fatal("versionLine() should not be empty")
}
if !strings.Contains(got, "(") || !strings.Contains(got, ")") {
t.Fatalf("versionLine() = %q, should contain parentheses with commit and date", got)
if got != "lstk dev" {
t.Fatalf("versionLine() = %q, want %q", got, "lstk dev")
}
}

func TestVersionFlagsPrintSameOutput(t *testing.T) {
longOut, err := executeWithArgs(t, "--version")
if err != nil {
t.Fatalf("expected no error from --version, got %v", err)
}

shortOut, err := executeWithArgs(t, "-v")
if err != nil {
t.Fatalf("expected no error from -v, got %v", err)
}

if longOut != versionTemplate() {
t.Fatalf("--version output = %q, want %q", longOut, versionTemplate())
}
if shortOut != longOut {
t.Fatalf("-v output = %q, want %q", shortOut, longOut)
}
}
5 changes: 2 additions & 3 deletions internal/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ var (
version = "dev"
commit = "none"
buildDate = "unknown"
_, _ = commit, buildDate
)

func Version() string { return version }
func Commit() string { return commit }
func BuildDate() string { return buildDate }
func Version() string { return version }
6 changes: 3 additions & 3 deletions test/integration/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func TestUpdateBinaryInPlace(t *testing.T) {
require.NoError(t, err, "go build failed: %s", string(out))

// Verify it reports the fake version
verCmd := exec.CommandContext(ctx, tmpBinary, "version")
verCmd := exec.CommandContext(ctx, tmpBinary, "--version")
verOut, err := verCmd.CombinedOutput()
require.NoError(t, err)
assert.Contains(t, string(verOut), "0.0.1")
Expand All @@ -132,7 +132,7 @@ func TestUpdateBinaryInPlace(t *testing.T) {
assert.Contains(t, updateStr, "Updated to", "should complete the update")

// Verify the binary was actually replaced
verCmd2 := exec.CommandContext(ctx, tmpBinary, "version")
verCmd2 := exec.CommandContext(ctx, tmpBinary, "--version")
verOut2, err := verCmd2.CombinedOutput()
require.NoError(t, err)
assert.NotContains(t, string(verOut2), "0.0.1", "binary should no longer be the old version")
Expand Down Expand Up @@ -183,7 +183,7 @@ func TestUpdateHomebrew(t *testing.T) {
require.NoError(t, err, "go build failed: %s", string(out))

// Verify it reports the fake version
verCmd := exec.CommandContext(ctx, caskBinary, "version")
verCmd := exec.CommandContext(ctx, caskBinary, "--version")
verOut, err := verCmd.CombinedOutput()
require.NoError(t, err)
assert.Contains(t, string(verOut), "0.0.1")
Expand Down
Loading