Add read-only git provider

Implement submodule.Provider with the git CLI so submarine reads real
repositories: `submarine [dir]`, with `--mock` for the built-in data.

- Tree reads .gitmodules recursively; Status derives presence, checkout,
  worktree, staged pin, pushed state and pin -> ref resolution from local
  git commands only (no network).
- Concurrent Status calls are bounded by runtime.NumCPU().
- scripts/make-fixture.sh builds a superproject covering every state; the
  integration tests run against it.
- theme.Ago shows "never" for a zero time.
- Docs updated; decisions D14-D16 added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Simon Franken
2026-10-21 15:32:21 +02:00
co-authored by Claude Opus 5.5
parent c84f34ee2b
commit 64fe34b5b0
15 changed files with 1076 additions and 20 deletions
+20 -3
View File
@@ -12,20 +12,37 @@ import (
zone "github.com/lrstanley/bubblezone"
"submarine/internal/submodule"
"submarine/internal/submodule/git"
"submarine/internal/submodule/mock"
"submarine/internal/tui"
)
func main() {
useMock := flag.Bool("mock", true, "use built-in mock data instead of a real repository")
useMock := flag.Bool("mock", false, "use built-in mock data instead of a real repository")
flag.Usage = func() {
fmt.Fprintln(flag.CommandLine.Output(), "usage: submarine [--mock] [dir]")
flag.PrintDefaults()
}
flag.Parse()
if flag.NArg() > 1 {
flag.Usage()
os.Exit(2)
}
var provider submodule.Provider
if *useMock {
provider = mock.New()
} else {
fmt.Fprintln(os.Stderr, "only --mock is supported in the prototype")
os.Exit(2)
dir := "."
if flag.NArg() == 1 {
dir = flag.Arg(0)
}
p, err := git.New(dir)
if err != nil {
fmt.Fprintln(os.Stderr, "submarine:", err)
os.Exit(2)
}
provider = p
}
ctx, cancel := context.WithCancel(context.Background())