Update golangci-lint to v2.12.2 with canonical config
All checks were successful
check / check (push) Successful in 1m8s

- Replace .golangci.yml with the canonical strict config (all linters
  enabled except the standard disable list; lll 88, funlen 80/50,
  cyclop 15, dupl 100; test files now linted)
- Pin the Dockerfile lint stage to golangci/golangci-lint:v2.12.2 by
  tag and digest (Debian-based)
- Fix all ~1550 findings surfaced by the new config: line wrapping,
  wsl_v5/nlreturn blank lines, noinlineerr splits, err113 sentinel
  errors, perfsprint/modernize rewrites, goconst constants, thelper,
  testifylint, noctx CommandContext, testpackage conversions,
  t.Parallel() where safe, and complexity/dupl helper extraction
- Record the change and follow-up items in TODO.md
This commit is contained in:
2026-08-07 17:27:23 +00:00
parent 6e5e0db999
commit 9ee216f629
59 changed files with 6568 additions and 4890 deletions

View File

@@ -14,6 +14,7 @@
// - setupTestVault(): CLI test helper for vault initialization
// - Uses consistent test mnemonic for reproducible testing
//nolint:testpackage // white-box test of unexported internals
package cli
import (
@@ -32,29 +33,41 @@ import (
"github.com/stretchr/testify/require"
)
// Helper function to add a secret to vault with proper buffer protection
func addTestSecret(t *testing.T, vlt *vault.Vault, name string, value []byte, force bool) {
const (
// testMnemonic is the standard BIP39 mnemonic used for CLI tests.
//nolint:dupword // BIP39 test mnemonic intentionally repeats a word
testMnemonic = "abandon abandon abandon abandon abandon abandon " +
"abandon abandon abandon abandon abandon about"
// testStateDir is the in-memory state directory used by CLI tests.
testStateDir = "/test/state"
)
// Helper function to add a version of the "test/secret" secret to the
// vault with proper buffer protection
func addTestSecret(t *testing.T, vlt *vault.Vault, value []byte, force bool) {
t.Helper()
buffer := memguard.NewBufferFromBytes(value)
defer buffer.Destroy()
err := vlt.AddSecret(name, buffer, force)
err := vlt.AddSecret("test/secret", buffer, force)
require.NoError(t, err)
}
// Helper function to set up a vault with long-term key
func setupTestVault(t *testing.T, fs afero.Fs, stateDir string) {
// Helper function to set up a vault with long-term key in testStateDir
func setupTestVault(t *testing.T, fs afero.Fs) {
t.Helper()
// Set mnemonic for testing
testMnemonic := "abandon abandon abandon abandon abandon abandon " +
"abandon abandon abandon abandon abandon about"
t.Setenv(secret.EnvMnemonic, testMnemonic)
// Create vault
vlt, err := vault.CreateVault(fs, stateDir, "default")
vlt, err := vault.CreateVault(fs, testStateDir, "default")
require.NoError(t, err)
// Derive and store long-term key from mnemonic
mnemonic := "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
ltIdentity, err := agehd.DeriveIdentity(mnemonic, 0)
ltIdentity, err := agehd.DeriveIdentity(testMnemonic, 0)
require.NoError(t, err)
// Store long-term public key in vault
@@ -64,30 +77,32 @@ func setupTestVault(t *testing.T, fs afero.Fs, stateDir string) {
require.NoError(t, err)
// Select vault
err = vault.SelectVault(fs, stateDir, "default")
err = vault.SelectVault(fs, testStateDir, "default")
require.NoError(t, err)
}
//nolint:paralleltest // uses t.Setenv via setupTestVault
func TestListVersionsCommand(t *testing.T) {
fs := afero.NewMemMapFs()
stateDir := "/test/state"
stateDir := testStateDir
cli := NewCLIInstanceWithStateDir(fs, stateDir)
// Set up vault with long-term key
setupTestVault(t, fs, stateDir)
setupTestVault(t, fs)
// Add a secret with multiple versions
vlt, err := vault.GetCurrentVault(fs, stateDir)
require.NoError(t, err)
addTestSecret(t, vlt, "test/secret", []byte("version-1"), false)
addTestSecret(t, vlt, []byte("version-1"), false)
time.Sleep(10 * time.Millisecond)
addTestSecret(t, vlt, "test/secret", []byte("version-2"), true)
addTestSecret(t, vlt, []byte("version-2"), true)
// Create a command for output capture
cmd := newRootCmd()
var buf bytes.Buffer
cmd.SetOut(&buf)
cmd.SetErr(&buf)
@@ -112,24 +127,28 @@ func TestListVersionsCommand(t *testing.T) {
// Should have two version entries
lines := strings.Split(outputStr, "\n")
versionLines := 0
for _, line := range lines {
if strings.Contains(line, ".001") || strings.Contains(line, ".002") {
versionLines++
}
}
assert.Equal(t, 2, versionLines)
}
//nolint:paralleltest // uses t.Setenv via setupTestVault
func TestListVersionsNonExistentSecret(t *testing.T) {
fs := afero.NewMemMapFs()
stateDir := "/test/state"
stateDir := testStateDir
cli := NewCLIInstanceWithStateDir(fs, stateDir)
// Set up vault with long-term key
setupTestVault(t, fs, stateDir)
setupTestVault(t, fs)
// Create a command for output capture
cmd := newRootCmd()
var buf bytes.Buffer
cmd.SetOut(&buf)
cmd.SetErr(&buf)
@@ -140,23 +159,24 @@ func TestListVersionsNonExistentSecret(t *testing.T) {
assert.Contains(t, err.Error(), "not found")
}
//nolint:paralleltest // uses t.Setenv via setupTestVault
func TestPromoteVersionCommand(t *testing.T) {
fs := afero.NewMemMapFs()
stateDir := "/test/state"
stateDir := testStateDir
cli := NewCLIInstanceWithStateDir(fs, stateDir)
// Set up vault with long-term key
setupTestVault(t, fs, stateDir)
setupTestVault(t, fs)
// Add a secret with multiple versions
vlt, err := vault.GetCurrentVault(fs, stateDir)
require.NoError(t, err)
addTestSecret(t, vlt, "test/secret", []byte("version-1"), false)
addTestSecret(t, vlt, []byte("version-1"), false)
time.Sleep(10 * time.Millisecond)
addTestSecret(t, vlt, "test/secret", []byte("version-2"), true)
addTestSecret(t, vlt, []byte("version-2"), true)
// Get versions
vaultDir, _ := vlt.GetDirectory()
@@ -175,6 +195,7 @@ func TestPromoteVersionCommand(t *testing.T) {
// Create a command for output capture
cmd := newRootCmd()
var buf bytes.Buffer
cmd.SetOut(&buf)
cmd.SetErr(&buf)
@@ -195,22 +216,24 @@ func TestPromoteVersionCommand(t *testing.T) {
assert.Equal(t, []byte("version-1"), value)
}
//nolint:paralleltest // uses t.Setenv via setupTestVault
func TestPromoteNonExistentVersion(t *testing.T) {
fs := afero.NewMemMapFs()
stateDir := "/test/state"
stateDir := testStateDir
cli := NewCLIInstanceWithStateDir(fs, stateDir)
// Set up vault with long-term key
setupTestVault(t, fs, stateDir)
setupTestVault(t, fs)
// Add a secret
vlt, err := vault.GetCurrentVault(fs, stateDir)
require.NoError(t, err)
addTestSecret(t, vlt, "test/secret", []byte("value"), false)
addTestSecret(t, vlt, []byte("value"), false)
// Create a command for output capture
cmd := newRootCmd()
var buf bytes.Buffer
cmd.SetOut(&buf)
cmd.SetErr(&buf)
@@ -221,23 +244,24 @@ func TestPromoteNonExistentVersion(t *testing.T) {
assert.Contains(t, err.Error(), "not found")
}
//nolint:paralleltest // uses t.Setenv via setupTestVault
func TestGetSecretWithVersion(t *testing.T) {
fs := afero.NewMemMapFs()
stateDir := "/test/state"
stateDir := testStateDir
cli := NewCLIInstanceWithStateDir(fs, stateDir)
// Set up vault with long-term key
setupTestVault(t, fs, stateDir)
setupTestVault(t, fs)
// Add a secret with multiple versions
vlt, err := vault.GetCurrentVault(fs, stateDir)
require.NoError(t, err)
addTestSecret(t, vlt, "test/secret", []byte("version-1"), false)
addTestSecret(t, vlt, []byte("version-1"), false)
time.Sleep(10 * time.Millisecond)
addTestSecret(t, vlt, "test/secret", []byte("version-2"), true)
addTestSecret(t, vlt, []byte("version-2"), true)
// Get versions
vaultDir, _ := vlt.GetDirectory()
@@ -248,6 +272,7 @@ func TestGetSecretWithVersion(t *testing.T) {
// Create a command for output capture
cmd := newRootCmd()
var buf bytes.Buffer
cmd.SetOut(&buf)
@@ -258,18 +283,21 @@ func TestGetSecretWithVersion(t *testing.T) {
// Test getting specific version
buf.Reset()
firstVersion := versions[1] // Older version
err = cli.GetSecretWithVersion(cmd, "test/secret", firstVersion)
require.NoError(t, err)
assert.Equal(t, "version-1", buf.String())
}
//nolint:paralleltest // reads process environment to determine the state dir
func TestVersionCommandStructure(t *testing.T) {
// Test that version commands are properly structured
cli, err := NewCLIInstance()
if err != nil {
t.Fatalf("failed to initialize CLI: %v", err)
}
cmd := VersionCommands(cli)
assert.Equal(t, "version", cmd.Use)
@@ -285,13 +313,14 @@ func TestVersionCommandStructure(t *testing.T) {
assert.Equal(t, "Promote a specific version to current", promoteCmd.Short)
}
//nolint:paralleltest // uses t.Setenv via setupTestVault
func TestListVersionsEmptyOutput(t *testing.T) {
fs := afero.NewMemMapFs()
stateDir := "/test/state"
stateDir := testStateDir
cli := NewCLIInstanceWithStateDir(fs, stateDir)
// Set up vault with long-term key
setupTestVault(t, fs, stateDir)
setupTestVault(t, fs)
// Create a secret directory without versions (edge case)
vaultDir := stateDir + "/vaults.d/default"
@@ -301,6 +330,7 @@ func TestListVersionsEmptyOutput(t *testing.T) {
// Create a command for output capture
cmd := newRootCmd()
var buf bytes.Buffer
cmd.SetOut(&buf)
cmd.SetErr(&buf)