Skip to content

Commit c6d89eb

Browse files
Extract rain as standalone git-rain CLI
Promotes the reverse-sync command from git-fire into its own first-class project. Rain is now the root command (not a subcommand), uses the git-rain-backup-* branch prefix, config at ~/.config/git-rain/, and adds a --fetch-only flag absent from the original. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
0 parents  commit c6d89eb

23 files changed

Lines changed: 2657 additions & 0 deletions

.github/workflows/ci.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: ["**"]
6+
pull_request:
7+
branches: ["**"]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
test:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
18+
- uses: actions/setup-go@v5
19+
with:
20+
go-version-file: go.mod
21+
cache: true
22+
23+
- name: Build
24+
run: go build ./...
25+
26+
- name: Vet
27+
run: go vet ./...
28+
29+
- name: Test
30+
run: go test -race -count=1 ./...

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Built binary
2+
git-rain
3+
4+
# macOS
5+
.DS_Store

CLAUDE.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# CLAUDE.md — git-rain
2+
3+
## Project Overview
4+
5+
`git-rain` is a standalone Go CLI that syncs local git repositories _from_ their remotes — the reverse of `git-fire`. It is extracted from the `git-fire` codebase and promoted to a first-class tool.
6+
7+
Module: `github.com/git-rain/git-rain`
8+
Go version: 1.24.2
9+
Config: `~/.config/git-rain/config.toml`
10+
Registry: `~/.config/git-rain/repos.toml`
11+
Logs: `~/.cache/git-rain/` (not yet wired up)
12+
13+
---
14+
15+
## Commands
16+
17+
```bash
18+
make build # compile binary to ./git-rain
19+
make run ARGS="--dry-run" # build and run with flags
20+
make test # run all tests
21+
make test-race # run tests with race detector (used in CI)
22+
make lint # go vet ./...
23+
make install # install to $GOPATH/bin
24+
make clean # remove binary
25+
```
26+
27+
Run directly:
28+
29+
```bash
30+
go build ./...
31+
go test -race -count=1 ./...
32+
go vet ./...
33+
```
34+
35+
---
36+
37+
## Architecture
38+
39+
```
40+
main.go
41+
└── cmd/root.go # Cobra CLI: flags, orchestration (rain is the root command)
42+
├── internal/config # Load config (~/.config/git-rain/config.toml)
43+
├── internal/git # Repo scanning + git operations (shells out to git binary)
44+
├── internal/registry # Persistent repo registry (~/.config/git-rain/repos.toml)
45+
├── internal/safety # Secret detection + error/log sanitization
46+
└── internal/flavor # Rain-themed startup quotes
47+
```
48+
49+
**Key design decisions:**
50+
- Uses native `git` binary via `exec.Command` — not go-git.
51+
- Backup branch prefix: `git-rain-backup-` (was `git-fire-rain-backup-` in git-fire).
52+
- Config env prefix: `GIT_RAIN_`.
53+
- Safe mode (default): never rewrites local-only commits.
54+
- Risky mode (`--risky` / `config: global.risky_mode`): allows hard reset to upstream after creating a `git-rain-backup-*` ref.
55+
56+
---
57+
58+
## Testing
59+
60+
- Run `make test-race` before considering a change done.
61+
- Prefer table-driven tests for multi-case functions.
62+
- Integration-style tests that shell out to `git` are preferred for `internal/git`.
63+
- Use `github.com/git-fire/git-testkit` helpers.
64+
65+
---
66+
67+
## Conventions
68+
69+
- **No go-git**: all git interactions shell out to the system `git` binary.
70+
- **Cobra for CLI**: root command lives in `cmd/root.go`.
71+
- **Config via Viper/TOML**: user config at `~/.config/git-rain/config.toml`; env vars override.
72+
- **Error handling**: return errors up to the caller; only `log.Fatal`/`os.Exit` in `main.go`.

Makefile

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
BINARY := git-rain
2+
ROOT := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
3+
REPO_BIN := $(ROOT)$(BINARY)
4+
USER_BIN := $(abspath $(HOME)/.local/bin)
5+
INSTALL_BIN := $(USER_BIN)/$(BINARY)
6+
VERSION ?= $(shell git -C "$(ROOT)" describe --tags --dirty 2>/dev/null || (cd "$(ROOT)" && go list -m -f '{{.Version}}' 2>/dev/null) || echo "dev")
7+
LDFLAGS := -X github.com/git-rain/git-rain/cmd.Version=$(VERSION)
8+
LDFLAGS_RELEASE := $(LDFLAGS) -s -w
9+
10+
.PHONY: all build run test test-race lint clean install help
11+
12+
all: build
13+
14+
## build: compile binary next to this Makefile (./git-rain in repo root)
15+
build:
16+
cd "$(ROOT)" && go build -ldflags "$(LDFLAGS)" -o "$(REPO_BIN)" .
17+
18+
## run: build and run with optional ARGS (e.g. make run ARGS="--dry-run")
19+
run: build
20+
"$(REPO_BIN)" $(ARGS)
21+
22+
## test: run all tests
23+
test:
24+
cd "$(ROOT)" && go test -count=1 ./...
25+
26+
## test-race: run tests with race detector
27+
test-race:
28+
cd "$(ROOT)" && go test -race -count=1 ./...
29+
30+
## lint: vet the code
31+
lint:
32+
cd "$(ROOT)" && go vet ./...
33+
34+
## clean: remove the repo-local built binary
35+
clean:
36+
rm -f "$(REPO_BIN)"
37+
38+
## install: build and copy to ~/.local/bin (overwrites). Invoke from anywhere: make -C /path/to/git-rain install
39+
install:
40+
@mkdir -p "$(USER_BIN)"
41+
cd "$(ROOT)" && go build -ldflags "$(LDFLAGS_RELEASE)" -o "$(INSTALL_BIN)" .
42+
@chmod 755 "$(INSTALL_BIN)"
43+
@echo ""
44+
@echo "Installed: $(INSTALL_BIN)"
45+
@echo "This shell: export PATH=\"$$HOME/.local/bin:$$PATH\" && hash -r"
46+
@echo " (zsh: use rehash instead of hash -r if needed)"
47+
@echo "Permanent: add the export line to ~/.zshrc or ~/.bashrc"
48+
@echo ""
49+
50+
## help: show this help
51+
help:
52+
@grep -E '^##' Makefile | sed 's/## / /'

0 commit comments

Comments
 (0)