Skip to content

Latest commit

 

History

History
268 lines (201 loc) · 12 KB

File metadata and controls

268 lines (201 loc) · 12 KB

Codebase Guide

gitm8 is a terminal UI first. It does not try to replace Git. It runs the installed git and gh commands and gives them a cleaner screen.

Upstream Docs Used By This App

These are the core library docs worth keeping open while reading the code:

Layer Map

Core Abstractions

These names show up everywhere:

tui.Model

Defined in internal/tui/model.go.

Model is the full state of the terminal UI. If something can change on screen, it probably lives on Model: selected file, current mode, repo info, loaded files, branch list, spinner state, and the current output text.

Bubble Tea repeatedly passes Model through:

Model.Update(...)
  -> returns changed Model
  -> Model.View() draws that changed state

git.Runner

Defined in internal/git/git.go.

Runner is the app's doorway to Git. The TUI should not build raw git commands itself. It should call methods like:

runner.StageOutput(...)
runner.Branches(...)

Then internal/git decides the exact command to run.

config.Config

Defined in internal/config/config.go.

Config is loaded once at startup and stored on Model. It controls things like theme, fetch-on-startup, commit graph display, and identity profiles.

Custom Bubble Tea Messages

Defined in internal/tui/model.go.

These messages are how background work reports back to Update:

  • repoLoadedMsg: repo info, changed files, and viewer text finished loading.
  • branchesLoadedMsg: branch list finished loading.
  • gitActionFinishedMsg: a Git command finished, with output or an error.

Binary Startup

Start here when you want to understand how the program launches:

The startup path is:

main.go
  -> config.Load()
  -> git.NewRunner("")
  -> tui.New(runner, cfg)
  -> tea.NewProgram(...).Run()

Terms used below:

  • Model: the struct that holds the current UI state. See Bubble Tea's Model.
  • Update: the function Bubble Tea calls when something happens, such as a key press or a finished Git command. See the Bubble Tea Update tutorial.
  • View: the function that turns the current state into terminal text. See the Bubble Tea View tutorial.
  • tea.Cmd: a background job. In this app it usually loads Git data or runs a Git command, then sends the result back to Update. See Bubble Tea's Cmd.

Configuration Layer

The config layer reads user settings and keeps them separate from UI state:

Read this layer when changing:

  • environment variables such as GITM8_THEME
  • ~/.gitm8/.gitm8rc, ~/.gitm8/gitm8rc, legacy ~/.gitm8rc, or ~/.gitm8/credentials parsing
  • profile parsing from ~/.gitm8/profiles
  • default behavior such as fetch-on-startup or commit graph display

Git Layer

The Git layer is the only place that should run git or gh. The UI asks for things like "stage this file" or "rebase this branch"; this package decides the exact command to run.

Use this layer when changing what Git command runs. Do not put raw exec.Command calls in the TUI. Add a git.Runner method instead.

TUI State Layer

The Bubble Tea model is plain on purpose. State lives in one struct. The rest of the files are split by job.

The core UI loop is:

Model.Init()
  -> starts the first background job
  -> Model.Update(message from that job or from a key press)
  -> maybe starts another background job
  -> Model.View() draws the screen

Most user actions follow this path:

key press
  -> updateKey
  -> updateDashboardKey or updateFocusedMode
  -> action(...) or load...
  -> git.Runner method
  -> result message: gitActionFinishedMsg, repoLoadedMsg, or branchesLoadedMsg
  -> handleGitActionFinished / handleRepoLoaded / handleBranchesLoaded
  -> View()

TUI Rendering Layer

Rendering is separate from key handling:

The Bubbles components are stored in Model and rendered from View:

Read these files when changing how something looks. Read internal/git when changing what Git command runs.

Installer And User Docs

When user-visible behavior changes, update the README and man page together.

When the names feel unclear, read docs/ABSTRACTIONS.md. When the control flow feels unclear, read docs/FLOWS.md. It walks through real keys like s, b, c, and r.

Common Changes

Add Or Change A Keybinding

  1. Add the key handling in internal/tui/update.go. Normal dashboard keys and one-screen-only keys both live there.
  2. Put Git operations in internal/git, not directly in the TUI.
  3. Update visible key references in internal/tui/view.go.
  4. Update README.md and docs/man/gitm8.1.

Add A Git Operation

  1. Add a method on git.Runner in the relevant internal/git file.
  2. Return output when the UI should show command details.
  3. Call the runner method from internal/tui/actions.go or the relevant mode handler.
  4. Add a focused test if the change parses text, formats text, or recovers from a failed Git command.

Change A View

  1. Update internal/tui/view.go for the main screen layout.
  2. Update internal/tui/view.go for picker content.
  3. Update internal/tui/theme.go when changing colors or style variables.
  4. Run the TUI in a real terminal after tests, because layout issues are easiest to see interactively.

Verification

Use writable Go caches in this environment:

GOCACHE=/tmp/gitm8-go-build GOMODCACHE=/tmp/gitm8-go-mod go test ./...
GOCACHE=/tmp/gitm8-go-build GOMODCACHE=/tmp/gitm8-go-mod go build ./...