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

@@ -1,21 +1,22 @@
package cli
import (
"encoding/json"
"path/filepath"
"strings"
"git.eeqj.de/sneak/secret/internal/secret"
"git.eeqj.de/sneak/secret/internal/vault"
"github.com/spf13/afero"
"github.com/spf13/cobra"
)
// getSecretNamesCompletionFunc returns a completion function that provides secret names
// getSecretNamesCompletionFunc returns a completion function that provides
// secret names
func getSecretNamesCompletionFunc(fs afero.Fs, stateDir string) func(
cmd *cobra.Command, args []string, toComplete string,
) ([]string, cobra.ShellCompDirective) {
return func(_ *cobra.Command, _ []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return func(
_ *cobra.Command, _ []string, toComplete string,
) ([]string, cobra.ShellCompDirective) {
// Get current vault
vlt, err := vault.GetCurrentVault(fs, stateDir)
if err != nil {
@@ -30,6 +31,7 @@ func getSecretNamesCompletionFunc(fs afero.Fs, stateDir string) func(
// Filter secrets based on what user has typed
var completions []string
for _, secret := range secrets {
if strings.HasPrefix(secret, toComplete) {
completions = append(completions, secret)
@@ -40,11 +42,14 @@ func getSecretNamesCompletionFunc(fs afero.Fs, stateDir string) func(
}
}
// getUnlockerIDsCompletionFunc returns a completion function that provides unlocker IDs
// getUnlockerIDsCompletionFunc returns a completion function that provides
// unlocker IDs
func getUnlockerIDsCompletionFunc(fs afero.Fs, stateDir string) func(
cmd *cobra.Command, args []string, toComplete string,
) ([]string, cobra.ShellCompDirective) {
return func(_ *cobra.Command, _ []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return func(
_ *cobra.Command, _ []string, toComplete string,
) ([]string, cobra.ShellCompDirective) {
// Get current vault
vlt, err := vault.GetCurrentVault(fs, stateDir)
if err != nil {
@@ -66,61 +71,13 @@ func getUnlockerIDsCompletionFunc(fs afero.Fs, stateDir string) func(
// Collect unlocker IDs
var completions []string
unlockersDir := filepath.Join(vaultDir, "unlockers.d")
for _, metadata := range unlockerMetadataList {
// Get the actual unlocker ID by creating the unlocker instance
unlockersDir := filepath.Join(vaultDir, "unlockers.d")
files, err := afero.ReadDir(fs, unlockersDir)
if err != nil {
secret.Warn("Could not read unlockers directory during completion", "error", err)
continue
}
for _, file := range files {
if !file.IsDir() {
continue
}
unlockerDir := filepath.Join(unlockersDir, file.Name())
metadataPath := filepath.Join(unlockerDir, "unlocker-metadata.json")
// Check if this is the right unlocker by comparing metadata
metadataBytes, err := afero.ReadFile(fs, metadataPath)
if err != nil {
secret.Warn("Could not read unlocker metadata during completion", "path", metadataPath, "error", err)
continue
}
var diskMetadata secret.UnlockerMetadata
if err := json.Unmarshal(metadataBytes, &diskMetadata); err != nil {
secret.Warn("Could not parse unlocker metadata during completion", "path", metadataPath, "error", err)
continue
}
// Match by type and creation time
if diskMetadata.Type == metadata.Type && diskMetadata.CreatedAt.Equal(metadata.CreatedAt) {
// Create the appropriate unlocker instance
var unlocker secret.Unlocker
switch metadata.Type {
case "passphrase":
unlocker = secret.NewPassphraseUnlocker(fs, unlockerDir, diskMetadata)
case "keychain":
unlocker = secret.NewKeychainUnlocker(fs, unlockerDir, diskMetadata)
case "pgp":
unlocker = secret.NewPGPUnlocker(fs, unlockerDir, diskMetadata)
}
if unlocker != nil {
id := unlocker.GetID()
if strings.HasPrefix(id, toComplete) {
completions = append(completions, id)
}
}
break
}
id := findUnlockerIDByMetadata(fs, unlockersDir, metadata, false)
if id != "" && strings.HasPrefix(id, toComplete) {
completions = append(completions, id)
}
}
@@ -128,17 +85,21 @@ func getUnlockerIDsCompletionFunc(fs afero.Fs, stateDir string) func(
}
}
// getVaultNamesCompletionFunc returns a completion function that provides vault names
// getVaultNamesCompletionFunc returns a completion function that provides
// vault names
func getVaultNamesCompletionFunc(fs afero.Fs, stateDir string) func(
cmd *cobra.Command, args []string, toComplete string,
) ([]string, cobra.ShellCompDirective) {
return func(_ *cobra.Command, _ []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return func(
_ *cobra.Command, _ []string, toComplete string,
) ([]string, cobra.ShellCompDirective) {
vaults, err := vault.ListVaults(fs, stateDir)
if err != nil {
return nil, cobra.ShellCompDirectiveNoFileComp
}
var completions []string
for _, v := range vaults {
if strings.HasPrefix(v, toComplete) {
completions = append(completions, v)
@@ -149,57 +110,81 @@ func getVaultNamesCompletionFunc(fs afero.Fs, stateDir string) func(
}
}
// getVaultSecretCompletionFunc returns a completion function for vault:secret format
// It completes vault names with ":" suffix, and after ":" it completes secrets from that vault
// completeVaultQualifiedSecrets completes "vault:secret" references once a
// colon is present in the input
func completeVaultQualifiedSecrets(
fs afero.Fs, stateDir, toComplete string,
) []string {
var completions []string
// Complete secret names for the specified vault
parts := strings.SplitN(toComplete, ":", vaultSecretParts)
vaultName := parts[0]
secretPrefix := parts[1]
vlt := vault.NewVault(fs, stateDir, vaultName)
secrets, err := vlt.ListSecrets()
if err == nil {
for _, secretName := range secrets {
if strings.HasPrefix(secretName, secretPrefix) {
completions = append(completions, vaultName+":"+secretName)
}
}
}
return completions
}
// completeUnqualifiedVaultSecrets completes vault names (with a ":"
// suffix) and secrets from the current vault
func completeUnqualifiedVaultSecrets(
fs afero.Fs, stateDir, toComplete string,
) []string {
var completions []string
// Complete vault names with ":" suffix
vaults, err := vault.ListVaults(fs, stateDir)
if err == nil {
for _, v := range vaults {
if strings.HasPrefix(v, toComplete) {
completions = append(completions, v+":")
}
}
}
// Also complete secrets from current vault (for within-vault moves)
currentVlt, err := vault.GetCurrentVault(fs, stateDir)
if err == nil {
secrets, err := currentVlt.ListSecrets()
if err == nil {
for _, secretName := range secrets {
if strings.HasPrefix(secretName, toComplete) {
completions = append(completions, secretName)
}
}
}
}
return completions
}
// getVaultSecretCompletionFunc returns a completion function for the
// vault:secret format. It completes vault names with ":" suffix, and
// after ":" it completes secrets from that vault.
func getVaultSecretCompletionFunc(fs afero.Fs, stateDir string) func(
cmd *cobra.Command, args []string, toComplete string,
) ([]string, cobra.ShellCompDirective) {
return func(_ *cobra.Command, _ []string, toComplete string) ([]string, cobra.ShellCompDirective) {
var completions []string
return func(
_ *cobra.Command, _ []string, toComplete string,
) ([]string, cobra.ShellCompDirective) {
// Check if we're completing after a vault: prefix
if strings.Contains(toComplete, ":") {
// Complete secret names for the specified vault
const vaultSecretParts = 2
parts := strings.SplitN(toComplete, ":", vaultSecretParts)
vaultName := parts[0]
secretPrefix := parts[1]
vlt := vault.NewVault(fs, stateDir, vaultName)
secrets, err := vlt.ListSecrets()
if err == nil {
for _, secretName := range secrets {
if strings.HasPrefix(secretName, secretPrefix) {
completions = append(completions, vaultName+":"+secretName)
}
}
}
return completions, cobra.ShellCompDirectiveNoFileComp
return completeVaultQualifiedSecrets(fs, stateDir, toComplete),
cobra.ShellCompDirectiveNoFileComp
}
// Complete vault names with ":" suffix
vaults, err := vault.ListVaults(fs, stateDir)
if err == nil {
for _, v := range vaults {
if strings.HasPrefix(v, toComplete) {
completions = append(completions, v+":")
}
}
}
// Also complete secrets from current vault (for within-vault moves)
if currentVlt, err := vault.GetCurrentVault(fs, stateDir); err == nil {
secrets, err := currentVlt.ListSecrets()
if err == nil {
for _, secretName := range secrets {
if strings.HasPrefix(secretName, toComplete) {
completions = append(completions, secretName)
}
}
}
}
return completions, cobra.ShellCompDirectiveNoSpace
return completeUnqualifiedVaultSecrets(fs, stateDir, toComplete),
cobra.ShellCompDirectiveNoSpace
}
}