Archived
Bubble Tea prototype for browsing repositories with many nested git submodules: collapsible tree, pins shown as ref + distance, summarized issue words with severity levels, detail pane, async loading via a Provider interface backed by mock data. Includes docs/ with requirements, state model, UX guide, architecture and decision log, plus AGENTS.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
115 lines
2.5 KiB
Go
115 lines
2.5 KiB
Go
// Package submodule holds the domain model for a superproject and its
|
|
// (recursively nested) git submodules. It has no UI dependencies.
|
|
package submodule
|
|
|
|
import "time"
|
|
|
|
// Repo is the superproject.
|
|
type Repo struct {
|
|
Path string
|
|
Branch string
|
|
Ahead int
|
|
Behind int
|
|
FetchedAt time.Time
|
|
Submodules []*Submodule
|
|
}
|
|
|
|
// Submodule is one node in the submodule tree.
|
|
type Submodule struct {
|
|
Name string
|
|
Path string // relative to the superproject root; unique ID
|
|
RelPath string // relative to the parent repository, e.g. "modules/foo"
|
|
URL string
|
|
Parent *Submodule
|
|
Children []*Submodule
|
|
Status *Status // nil while loading
|
|
Err error // set if loading the status failed
|
|
}
|
|
|
|
// Presence describes whether the submodule exists on disk.
|
|
type Presence int
|
|
|
|
const (
|
|
PresenceOK Presence = iota
|
|
NotInitialized
|
|
DirMissing
|
|
)
|
|
|
|
// Checkout compares the submodule's HEAD with the pinned commit.
|
|
type Checkout int
|
|
|
|
const (
|
|
CheckoutMatch Checkout = iota
|
|
CheckoutDiffers
|
|
CheckoutDetached // on the pinned commit, but detached (informational)
|
|
)
|
|
|
|
// Worktree describes uncommitted state inside the submodule.
|
|
type Worktree int
|
|
|
|
const (
|
|
WorktreeClean Worktree = iota
|
|
WorktreeModified
|
|
WorktreeUntracked
|
|
WorktreeConflict
|
|
)
|
|
|
|
// RefSource tells which rule resolved the pin to a ref.
|
|
type RefSource int
|
|
|
|
const (
|
|
RefFromGitmodules RefSource = iota
|
|
RefFromCurrentBranch
|
|
RefFromDefaultBranch
|
|
RefFromContains
|
|
RefFromTag
|
|
RefFromSHA
|
|
)
|
|
|
|
func (r RefSource) String() string {
|
|
switch r {
|
|
case RefFromGitmodules:
|
|
return ".gitmodules branch"
|
|
case RefFromCurrentBranch:
|
|
return "checked out branch"
|
|
case RefFromDefaultBranch:
|
|
return "remote default branch"
|
|
case RefFromContains:
|
|
return "branch containing pin"
|
|
case RefFromTag:
|
|
return "tag"
|
|
default:
|
|
return "commit sha"
|
|
}
|
|
}
|
|
|
|
// PinInfo relates the pinned commit to a ref.
|
|
type PinInfo struct {
|
|
Ref string // e.g. "origin/main"; empty if unresolved
|
|
Source RefSource
|
|
Ahead int // commits in pin not in ref
|
|
Behind int // commits in ref not in pin
|
|
Pushed bool // pin is reachable from some remote ref
|
|
}
|
|
|
|
// Commit is a short commit description.
|
|
type Commit struct {
|
|
SHA string
|
|
Subject string
|
|
Author string
|
|
When time.Time
|
|
}
|
|
|
|
// Status is the full state of one submodule.
|
|
type Status struct {
|
|
Presence Presence
|
|
Checkout Checkout
|
|
Worktree Worktree
|
|
PinStaged bool // pin changed in the superproject index, not committed
|
|
Pin PinInfo
|
|
Pinned *Commit
|
|
CheckedOut *Commit
|
|
Tip *Commit
|
|
Between []Commit // commits that make up the pin <-> tip difference
|
|
}
|