lockbox

password manager
Log | Files | Refs | README | LICENSE

commit e7a39aa97079110861bbfccccf5c09e78d05421c
parent 5596d2a8798af49d3a09478cf8535b105fd267bb
Author: Sean Enck <sean@ttypty.com>
Date:   Sat, 14 Jun 2025 09:26:12 -0400

feature flags are in place

Diffstat:
MREADME.md | 12++++++++++++
Mcmd/lb/main_test.go | 13+++++++++----
Minternal/app/completions/core.go | 8++++++--
Minternal/app/help/core.go | 23+++++++++++++++++++----
4 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/README.md b/README.md @@ -127,3 +127,15 @@ just ``` _run `just check` to run tests_ + +### features + +`lb` can have some features disabled via build tags: + +- 'noclip' will disable the clipboard functionalities +- 'nototp' will disable the totp functionalities + +These are supported via the justfile +``` +just tags=noclip +``` diff --git a/cmd/lb/main_test.go b/cmd/lb/main_test.go @@ -105,8 +105,8 @@ func (r runner) raw(pipeIn, command, stdout, stderr string) error { return cmd.Run() } -func (r runner) feature(command, useBinary string) error { - text := fmt.Sprintf("%s %s >> %s 2>&1", fmt.Sprintf("%s-%s", binary, useBinary), command, r.log) +func (r runner) feature(command, useBinary, grep string) error { + text := fmt.Sprintf("%s %s %s >> %s 2>&1", fmt.Sprintf("%s-%s", binary, useBinary), command, grep, r.log) cmd := exec.Command("/bin/sh", "-c", text) return cmd.Run() } @@ -356,8 +356,13 @@ func test(profile string) error { r.run("", fmt.Sprintf("vars | sed 's#/%s#/datadir#g' | grep -v CREDENTIALS | sort", profile)) r.section("features") - r.feature("clip abc", "noclip") - r.feature("totp ls", "nototp") + feature := func(cmd, flag string) { + executable := fmt.Sprintf("no%s", flag) + r.feature(cmd, executable, "") + r.feature("help verbose", executable, fmt.Sprintf("| grep '%s'", flag)) + } + feature("clip abc", "clip") + feature("totp ls", "totp") // cleanup and diff results tmpFile := fmt.Sprintf("%s.tmp", r.log) diff --git a/internal/app/completions/core.go b/internal/app/completions/core.go @@ -69,12 +69,16 @@ func Generate(completionType, exe string) ([]string, error) { } c.Options = []string{commands.Help, commands.List, commands.Show, commands.Version, commands.JSON, commands.Groups, commands.Move, commands.Remove, commands.Insert, commands.Unset} - if features.CanClip() { + canClip := features.CanClip() + if canClip { c.Options = append(c.Options, commands.Clip) } if features.CanTOTP() { c.Options = append(c.Options, commands.TOTP) - c.TOTPSubCommands = []string{commands.TOTPMinimal, commands.TOTPOnce, commands.TOTPShow, commands.TOTPURL, commands.TOTPSeed, commands.TOTPClip} + c.TOTPSubCommands = []string{commands.TOTPMinimal, commands.TOTPOnce, commands.TOTPShow, commands.TOTPURL, commands.TOTPSeed} + if canClip { + c.TOTPSubCommands = append(c.TOTPSubCommands, commands.TOTPClip) + } } sort.Strings(c.Options) sort.Strings(c.TOTPSubCommands) diff --git a/internal/app/help/core.go b/internal/app/help/core.go @@ -76,7 +76,8 @@ func Usage(verbose bool, exe string) ([]string, error) { isGroup = "group" ) var results []string - if features.CanClip() { + canClip := features.CanClip() + if canClip { results = append(results, command(commands.Clip, isEntry, "copy the entry's value into the clipboard")) } results = append(results, command(commands.Completions, "<shell>", "generate completions via auto-detection")) @@ -96,9 +97,12 @@ func Usage(verbose bool, exe string) ([]string, error) { results = append(results, command(commands.ReKey, "", "rekey/reinitialize the database credentials")) results = append(results, command(commands.Remove, isGroup, "remove an entry from the store")) results = append(results, command(commands.Show, isEntry, "show the entry's value")) - if features.CanTOTP() { + canTOTP := features.CanTOTP() + if canTOTP { results = append(results, command(commands.TOTP, isEntry, "display an updating totp generated code")) - results = append(results, subCommand(commands.TOTP, commands.TOTPClip, isEntry, "copy totp code to clipboard")) + if canClip { + results = append(results, subCommand(commands.TOTP, commands.TOTPClip, isEntry, "copy totp code to clipboard")) + } results = append(results, subCommand(commands.TOTP, commands.TOTPList, isFilter, "list entries with totp settings")) results = append(results, subCommand(commands.TOTP, commands.TOTPOnce, isEntry, "display the first generated code")) results = append(results, subCommand(commands.TOTP, commands.TOTPMinimal, isEntry, "display one generated code (no details)")) @@ -147,7 +151,18 @@ func Usage(verbose bool, exe string) ([]string, error) { if !strings.HasSuffix(n, textFile) { continue } - header := fmt.Sprintf("[%s]", strings.TrimSuffix(filepath.Base(n), textFile)) + section := strings.TrimSuffix(filepath.Base(n), textFile) + switch section { + case "totp": + if !canTOTP { + continue + } + case "clipboard": + if !canClip { + continue + } + } + header := fmt.Sprintf("[%s]", section) s, err := processDoc(header, n, document) if err != nil { return nil, err