docs: comprehensive build & run guide (buildAndRun.md)
This commit is contained in:
parent
aab532eb91
commit
79dc1f0a7a
473
buildAndRun.md
Normal file
473
buildAndRun.md
Normal file
@ -0,0 +1,473 @@
|
||||
# gitflow — Build & Run Guide
|
||||
|
||||
## Prerequisites
|
||||
|
||||
| Requirement | Minimum | Check with |
|
||||
|---|---|---|
|
||||
| Go toolchain | 1.24 | `go version` |
|
||||
| Git | any recent | `git --version` |
|
||||
| `make` (optional) | — | `make --version` |
|
||||
| `golangci-lint` (optional) | any recent | `golangci-lint --version` |
|
||||
|
||||
Linux, macOS, and Windows (WSL / MSYS2) are supported. The binary compiles
|
||||
for all three platforms (ARM64 on macOS verified).
|
||||
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
# Clone
|
||||
git clone https://gitea.oblak.solutions/dimitar/gitFlow.git
|
||||
cd gitFlow
|
||||
|
||||
# Build (either method)
|
||||
make build # produces ./gitflow
|
||||
# or
|
||||
go build -o gitflow ./cmd/gitflow
|
||||
|
||||
# Run
|
||||
./gitflow version # → "gitflow dev"
|
||||
./gitflow scan # scans $PWD, asks for directory if stdin is a tty
|
||||
./gitflow scan -d ~/projects
|
||||
```
|
||||
|
||||
## Make targets
|
||||
|
||||
```makefile
|
||||
make build # compile the binary, injects VERSION via ldflags
|
||||
make test # run the full test suite (go test ./...)
|
||||
make fmt # format all Go sources (gofmt)
|
||||
make vet # run go vet over all packages
|
||||
make lint # run golangci-lint (needs it on PATH)
|
||||
make install # install into $GOPATH/bin (or $GOBIN)
|
||||
make clean # remove the binary and coverage output
|
||||
```
|
||||
|
||||
**Stamped version** (optional):
|
||||
|
||||
```bash
|
||||
VERSION=v2.0.1 make build
|
||||
./gitflow version # → "gitflow v2.0.1"
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Purpose |
|
||||
|---|---|
|
||||
| `scan` | One-shot scan of repos under `--dir`, render and exit |
|
||||
| `watch` | Rescan every `--interval`, detect changes, notify, fire webhooks |
|
||||
| `tui` | Interactive terminal UI (bubbletea) with navigation, detail pane, AI panel |
|
||||
| `config` | Print the resolved configuration (flags + env + file merged) |
|
||||
| `completion` | Emit shell completions for bash, zsh, fish, or PowerShell |
|
||||
| `version` | Print version and exit |
|
||||
|
||||
Every command accepts the same flag set. Use `gitflow <cmd> --help` for
|
||||
the full list.
|
||||
|
||||
### `scan` — single pass
|
||||
|
||||
```bash
|
||||
gitflow scan # prompt for dir, table output
|
||||
gitflow scan -d ~/projects # explicit dir
|
||||
gitflow scan -d ~/projects -f json # JSON to stdout, no human-facing sections
|
||||
gitflow scan -d ~ --exclude node_modules --exclude vendor
|
||||
gitflow scan -d ~/projects --max-depth 2 --workers 16
|
||||
```
|
||||
|
||||
### `watch` — periodic scan
|
||||
|
||||
```bash
|
||||
gitflow watch -d ~/projects -i 30s # scan every 30 seconds
|
||||
gitflow watch -d ~/projects -i 5m --notify # also fire desktop notifications
|
||||
gitflow watch -d ~/projects -i 1m --theme=light --color=always
|
||||
```
|
||||
|
||||
Webhooks fire automatically when a `webhooks:` section exists in your
|
||||
config file (no flag needed — they are config-only, like custom rules).
|
||||
|
||||
### `tui` — interactive terminal UI
|
||||
|
||||
```bash
|
||||
gitflow tui -d ~/projects # one-shot scan, browse with j/k
|
||||
gitflow tui -d ~/projects -i 30s # periodic scan, countdown in bar
|
||||
gitflow tui -d ~/projects --ai --ai-provider ollama
|
||||
```
|
||||
|
||||
**TUI keybindings:**
|
||||
|
||||
```
|
||||
↑/↓ or j/k navigate repository list
|
||||
g / Home jump to top
|
||||
G / End jump to bottom
|
||||
Enter / Space toggle detail pane for selected repo
|
||||
r trigger immediate rescan
|
||||
a toggle AI suggestion panel (requires --ai)
|
||||
? toggle help overlay
|
||||
q / Ctrl-C quit
|
||||
```
|
||||
|
||||
### `config` — show effective configuration
|
||||
|
||||
```bash
|
||||
gitflow config # defaults
|
||||
gitflow config -d /tmp -f compact # with flag overrides
|
||||
GITFLOW_DIR=/tmp gitflow config # with env overrides
|
||||
```
|
||||
|
||||
### `completion` — shell integration
|
||||
|
||||
```bash
|
||||
# bash
|
||||
eval "$(gitflow completion bash)"
|
||||
|
||||
# zsh
|
||||
gitflow completion zsh > ~/.zsh/completion/_gitflow
|
||||
|
||||
# fish
|
||||
gitflow completion fish > ~/.config/fish/completions/gitflow.fish
|
||||
|
||||
# powershell
|
||||
gitflow completion powershell > gitflow.ps1
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Settings resolve with this precedence (highest first):
|
||||
|
||||
1. **CLI flags** — `--dir`, `--format`, etc.
|
||||
2. **Environment variables** — `GITFLOW_` prefix, dots replaced by
|
||||
underscores: `GITFLOW_DIR`, `GITFLOW_FORMAT`, `GITFLOW_AI_PROVIDER`, …
|
||||
3. **Config file** — `~/.gitflow.yaml` (or `./.gitflow.yaml`); override
|
||||
the path with `GITFLOW_CONFIG=/some/path.yaml`
|
||||
4. **Built-in defaults** — `.` directory, `table` format, `auto` color,
|
||||
`dark` theme, 8 workers, AI disabled, etc.
|
||||
|
||||
### Complete config file reference
|
||||
|
||||
```yaml
|
||||
# ~/.gitflow.yaml
|
||||
dir: ~/projects
|
||||
interval: 5m
|
||||
format: table # table | json | compact
|
||||
color: auto # auto | always | never
|
||||
theme: dark # dark | light
|
||||
notify: true # desktop notifications (linux notify-send, macOS osascript)
|
||||
max_depth: 3 # 0 = unlimited
|
||||
workers: 8
|
||||
exclude: # glob patterns matched against base name and full path
|
||||
- node_modules
|
||||
- vendor
|
||||
- ".cache"
|
||||
|
||||
# AI agent (requires --ai flag or enabled: true)
|
||||
ai:
|
||||
enabled: false
|
||||
provider: openai # openai | ollama | anthropic
|
||||
model: gpt-4o # empty → provider default (ollama: llama3.2, anthropic: claude-3-5-haiku-latest)
|
||||
api_key_env: OPENAI_API_KEY
|
||||
base_url: "" # override provider endpoint; empty → vendor default
|
||||
execute: false # run confirmed AI commands (experimental, allowlist-guarded)
|
||||
|
||||
# Custom threshold rules
|
||||
rules:
|
||||
- name: stale-branch
|
||||
field: behind # ahead | behind | stash | changes
|
||||
op: ">=" # == | != | < | <= | > | >=
|
||||
value: 10
|
||||
label: stale
|
||||
- name: dirty-workspace
|
||||
field: changes
|
||||
op: ">="
|
||||
value: 1
|
||||
label: dirty
|
||||
|
||||
# Webhooks (config-file-only, no CLI flags)
|
||||
webhooks:
|
||||
- name: team-slack
|
||||
type: slack # slack | discord | generic
|
||||
url: https://hooks.slack.com/services/T00/B00/TOKEN
|
||||
on_change_only: true # skip when nothing changed
|
||||
min_priority: 0 # 0 = fire on any change
|
||||
rate_limit: 5m # minimum interval between fires
|
||||
timeout: 10s # HTTP timeout per attempt
|
||||
retry:
|
||||
max_attempts: 3 # max 5
|
||||
backoff: 2s # exponential backoff start
|
||||
|
||||
- name: ops-discord
|
||||
type: discord
|
||||
url: https://discord.com/api/webhooks/...
|
||||
send_all: false # when true, include every repo, not just changed
|
||||
|
||||
- name: internal-dashboard
|
||||
type: generic
|
||||
url: https://dashboard.internal/api/gitflow
|
||||
headers:
|
||||
Authorization: Bearer ${DASHBOARD_TOKEN}
|
||||
X-Source: gitflow
|
||||
```
|
||||
|
||||
### Environment variable mapping
|
||||
|
||||
| Config key | Env var |
|
||||
|---|---|
|
||||
| `dir` | `GITFLOW_DIR` |
|
||||
| `interval` | `GITFLOW_INTERVAL` |
|
||||
| `format` | `GITFLOW_FORMAT` |
|
||||
| `color` | `GITFLOW_COLOR` |
|
||||
| `theme` | `GITFLOW_THEME` |
|
||||
| `notify` | `GITFLOW_NOTIFY` |
|
||||
| `max_depth` | `GITFLOW_MAX_DEPTH` |
|
||||
| `workers` | `GITFLOW_WORKERS` |
|
||||
| `exclude` | `GITFLOW_EXCLUDE` (comma-separated) |
|
||||
| `ai.enabled` | `GITFLOW_AI_ENABLED` |
|
||||
| `ai.provider` | `GITFLOW_AI_PROVIDER` |
|
||||
| `ai.model` | `GITFLOW_AI_MODEL` |
|
||||
| `ai.api_key_env` | `GITFLOW_AI_API_KEY_ENV` |
|
||||
| `ai.base_url` | `GITFLOW_AI_BASE_URL` |
|
||||
| `ai.execute` | `GITFLOW_AI_EXECUTE` |
|
||||
|
||||
## Output formats
|
||||
|
||||
### Table (default)
|
||||
|
||||
```
|
||||
REPOSITORY BRANCH STATUS AHEAD/BEHIND CHANGES STASH
|
||||
~/projects/api main clean - - -
|
||||
~/projects/web feat/x modified 3/0 2M 1U -
|
||||
~/projects/lib main behind 0/5 - 2
|
||||
|
||||
5 repos | 2 clean | 3 need attention | 0 errors
|
||||
```
|
||||
|
||||
Colorised per status class (`--color=auto` respected, `NO_COLOR` honoured).
|
||||
Path prefix `$HOME` collapsed to `~`.
|
||||
|
||||
### JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"scanned_at": "2026-08-02T10:00:00+02:00",
|
||||
"parent_dir": "/home/user/projects",
|
||||
"repos": [
|
||||
{
|
||||
"path": "/home/user/projects/api",
|
||||
"name": "api",
|
||||
"branch": "main",
|
||||
"status": "clean"
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"total": 5,
|
||||
"clean": 2,
|
||||
"attention": 3,
|
||||
"errored": 0,
|
||||
"staged": 0,
|
||||
"modified": 2,
|
||||
"untracked": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Status fields marshal as string labels (`"clean"`, `"modified"`, …) and
|
||||
unmarshal back from both strings and integers.
|
||||
|
||||
### Compact
|
||||
|
||||
```
|
||||
✓ ~/projects/api (main)
|
||||
✗ ~/projects/web (feat/x) +3/-0 2 change(s)
|
||||
↓ ~/projects/lib (main) +0/-5
|
||||
```
|
||||
|
||||
Status symbols: `✓ ✗ ↑ ↓ ⇄ ◉ ▢ !`.
|
||||
|
||||
## AI agent
|
||||
|
||||
Enable with `--ai` (or `ai.enabled: true` in config):
|
||||
|
||||
```bash
|
||||
# OpenAI (requires OPENAI_API_KEY exported or ai.api_key_env set)
|
||||
gitflow scan -d ~/projects --ai
|
||||
|
||||
# Local Ollama
|
||||
gitflow scan -d ~/projects --ai --ai-provider ollama --ai-model llama3.2
|
||||
|
||||
# Anthropic
|
||||
gitflow scan -d ~/projects --ai --ai-provider anthropic --ai-model claude-3-5-haiku-latest
|
||||
```
|
||||
|
||||
Suggestions render below the scan table, colour-coded by priority:
|
||||
|
||||
```
|
||||
AI SUGGESTIONS
|
||||
REPOSITORY ACTION PRIORITY MESSAGE COMMAND
|
||||
~/projects/web commit high commit the new file git add -A && git commit -m wip
|
||||
~/projects/lib pull medium pull 5 commits from origin git pull
|
||||
```
|
||||
|
||||
In JSON mode AI is skipped (machine-readable streams stay clean). In watch
|
||||
mode AI is queried only on the first frame and when something changed.
|
||||
|
||||
### `--ai-execute` (experimental)
|
||||
|
||||
Runs suggested commands after **explicit per-command y/N confirmation**,
|
||||
only for actions on an allowlist (`commit`, `push`, `pull`, `stash`,
|
||||
`checkout`). LLM output can never run arbitrary shell commands.
|
||||
|
||||
## Webhooks
|
||||
|
||||
Webhooks fire in watch mode when `webhooks:` is present in the config file.
|
||||
They run in a background goroutine and never block the scan interval.
|
||||
|
||||
Each webhook has independent rate limiting and retry with exponential
|
||||
backoff. Transient errors (5xx, timeouts) are retried; 4xx client errors
|
||||
fail immediately.
|
||||
|
||||
**Slack Block Kit payload:**
|
||||
- Header: "gitflow: scan results"
|
||||
- Section: summary line with repo counts
|
||||
- Divider + changed-repo list (when changes exist)
|
||||
- Context footer: timestamp + "gitflow"
|
||||
|
||||
**Discord embed payload:**
|
||||
- Sidebar colour: green (all clean), yellow (attention), red (errors)
|
||||
- Title: "gitflow scan"
|
||||
- Markdown body with summary + changed repos
|
||||
- Footer and timestamp
|
||||
|
||||
**Generic payload:**
|
||||
- Raw JSON POST of the `webhook.Payload` struct (`timestamp`, `parent_dir`,
|
||||
`summary`, `changed`, `all`) to any URL with custom headers.
|
||||
|
||||
## Test suite
|
||||
|
||||
```bash
|
||||
make test # all packages, no race detection
|
||||
go test -race ./... # with data-race detector (13 packages)
|
||||
go test -count=1 -race ./internal/ai ./internal/webhook # specific packages
|
||||
```
|
||||
|
||||
Coverage (latest run):
|
||||
|
||||
| Package | Coverage |
|
||||
|---|---|
|
||||
| `internal/ai` | 84.9% |
|
||||
| `internal/app` | 76.9% |
|
||||
| `internal/config` | 90.9% |
|
||||
| `internal/git` | 79.6% |
|
||||
| `internal/httpclient` | 89.1% |
|
||||
| `internal/presenter` | 86.6% |
|
||||
| `internal/rules` | 83.3% |
|
||||
| `internal/scanner` | 88.2% |
|
||||
| `internal/scheduler` | 88.9% |
|
||||
| `internal/webhook` | 91.7% |
|
||||
| `internal/tui` | 89.4% |
|
||||
| `pkg/status` | 91.1% |
|
||||
|
||||
## Project layout
|
||||
|
||||
```
|
||||
gitflow/
|
||||
├── cmd/gitflow/ CLI commands (cobra)
|
||||
│ ├── main.go entry point
|
||||
│ ├── root.go root command + version + completion
|
||||
│ ├── scan.go gitflow scan
|
||||
│ ├── watch.go gitflow watch
|
||||
│ ├── tui.go gitflow tui
|
||||
│ └── prompt.go TTY helpers (dir prompt, y/N confirmation)
|
||||
├── internal/
|
||||
│ ├── ai/ AI providers (OpenAI, Ollama, Anthropic) + prompt
|
||||
│ ├── app/ orchestration: discovery → scan → result
|
||||
│ ├── config/ flags, env, config-file resolution (viper)
|
||||
│ ├── git/ porcelain v2 git wrapper (executor pattern)
|
||||
│ ├── httpclient/ shared JSON HTTP client (timeout, bounded reads)
|
||||
│ ├── notify/ desktop notifications (notify-send / osascript)
|
||||
│ ├── presenter/ table / json / compact output + colors + themes
|
||||
│ ├── rules/ user-defined threshold rules
|
||||
│ ├── scanner/ repository discovery + concurrent status scanning
|
||||
│ ├── scheduler/ interval loop with graceful shutdown
|
||||
│ ├── tui/ interactive terminal UI (bubbletea + lipgloss)
|
||||
│ ├── version/ ldflags-injectable version
|
||||
│ └── webhook/ Slack, Discord, Generic webhook senders + dispatcher
|
||||
├── pkg/status/ shared domain model (RepoInfo, RepoStatus, ScanResult)
|
||||
├── go.mod / go.sum
|
||||
├── Makefile
|
||||
├── .golangci.yml
|
||||
├── .github/workflows/ci.yml
|
||||
├── readme.md user-facing README
|
||||
├── implementation.md original development plan + progress
|
||||
├── tui.md TUI & webhooks plan + milestone status
|
||||
└── buildAndRun.md this file
|
||||
```
|
||||
|
||||
## CI
|
||||
|
||||
GitHub Actions workflow (`.github/workflows/ci.yml`):
|
||||
|
||||
```
|
||||
jobs:
|
||||
test (matrix: go 1.24, 1.26)
|
||||
- go build ./...
|
||||
- go vet ./...
|
||||
- go test -race ./...
|
||||
lint
|
||||
- golangci-lint
|
||||
```
|
||||
|
||||
No remote pushes were made during development — branches were committed
|
||||
and merged locally with `--no-ff`.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**"not a git repository" when scanning a directory that IS a repo**
|
||||
|
||||
The repo's `.git` directory may be missing or the path might be a bare
|
||||
`.git` file pointing at a non-existent gitdir. Check `git status` manually
|
||||
in that directory.
|
||||
|
||||
**"no repositories found"**
|
||||
|
||||
The directory contains no `.git` entries. If you expected repos deeper in
|
||||
the tree, make sure `--max-depth` isn't set too low and no `--exclude`
|
||||
pattern shadows the subtree.
|
||||
|
||||
**"ai: OPENAI_API_KEY is not set"**
|
||||
|
||||
Export the key (or the env var name in `ai.api_key_env`) before running:
|
||||
|
||||
```bash
|
||||
export OPENAI_API_KEY=sk-...
|
||||
gitflow scan --ai
|
||||
```
|
||||
|
||||
**TUI doesn't launch / exits immediately**
|
||||
|
||||
The TUI requires a terminal that supports the alternate screen buffer. If
|
||||
you are piping or redirecting output, use `scan` or `watch` instead.
|
||||
|
||||
**Webhook not firing**
|
||||
|
||||
1. Check `gitflow config` shows the `webhooks:` section.
|
||||
2. Webhooks only fire in `watch` mode, not in `scan`.
|
||||
3. If `on_change_only: true`, the webhook skips when nothing changed
|
||||
between frames.
|
||||
4. If `rate_limit` is set, the webhook won't fire until the cooldown
|
||||
elapses.
|
||||
|
||||
**Shell completion "command not found" after eval**
|
||||
|
||||
Make sure `gitflow` is on your PATH (`go install` into `$GOBIN`):
|
||||
|
||||
```bash
|
||||
go install ./cmd/gitflow
|
||||
# Or
|
||||
sudo cp gitflow /usr/local/bin/
|
||||
```
|
||||
|
||||
## Cross-compilation
|
||||
|
||||
```bash
|
||||
GOOS=linux GOARCH=amd64 go build -o gitflow-linux ./cmd/gitflow
|
||||
GOOS=darwin GOARCH=arm64 go build -o gitflow-darwin ./cmd/gitflow
|
||||
GOOS=windows GOARCH=amd64 go build -o gitflow.exe ./cmd/gitflow
|
||||
```
|
||||
Loading…
Reference in New Issue
Block a user