Step 21: Lock/unlock toggle commands.

garden/lock.go: Lock() and Unlock() toggle the locked flag on
existing tracked entries. Errors on untracked paths. Persists
to manifest.

cmd/sgard/lock.go: sgard lock <path>..., sgard unlock <path>...

6 tests: lock/unlock existing entry, persistence, error on untracked,
checkpoint behavior changes after lock, status changes between
drifted and modified after unlock.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-24 11:07:40 -07:00
parent 0cf81ab6a1
commit d2bba75365
5 changed files with 293 additions and 6 deletions

51
cmd/sgard/lock.go Normal file
View File

@@ -0,0 +1,51 @@
package main
import (
"fmt"
"github.com/kisom/sgard/garden"
"github.com/spf13/cobra"
)
var lockCmd = &cobra.Command{
Use: "lock <path>...",
Short: "Mark tracked files as locked (repo-authoritative)",
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
g, err := garden.Open(repoFlag)
if err != nil {
return err
}
if err := g.Lock(args); err != nil {
return err
}
fmt.Printf("Locked %d path(s).\n", len(args))
return nil
},
}
var unlockCmd = &cobra.Command{
Use: "unlock <path>...",
Short: "Remove locked flag from tracked files",
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
g, err := garden.Open(repoFlag)
if err != nil {
return err
}
if err := g.Unlock(args); err != nil {
return err
}
fmt.Printf("Unlocked %d path(s).\n", len(args))
return nil
},
}
func init() {
rootCmd.AddCommand(lockCmd)
rootCmd.AddCommand(unlockCmd)
}