Bootstraps the empty repo into a kubebuilder go/v4 project: group crawl.example.com, version v1alpha1, kind Proxy (namespaced). Keeps the existing module path and preserves the repo's Go/testing/changelog conventions from CLAUDE.md untouched. Drops the scaffolded GitHub Actions workflows since the remote is Gitea, not GitHub. Everything else is default kubebuilder output, unmodified, so later diffs stay reviewable against a known baseline. Full implementation plan: docs/plans/2026-08-07-1747-proxy-operator.md Co-Authored-By: Claude <noreply@anthropic.com>
154 lines
6.1 KiB
Markdown
154 lines
6.1 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## What this is
|
|
|
|
A Kubernetes operator for managing egress proxies — currently an empty scaffold with
|
|
no controller code yet. Intended shape: a controller-runtime manager reconciling
|
|
custom resources (or existing workload types) to provision/configure egress proxy
|
|
infrastructure. TODO: confirm the actual CRD(s)/API group once implemented.
|
|
|
|
## Commands
|
|
|
|
No Makefile, linter, or entrypoint exists yet. Verified state as of bootstrap:
|
|
|
|
```bash
|
|
go build ./... # nothing to build yet — no .go source files exist
|
|
go test ./... # no test files exist yet
|
|
```
|
|
|
|
No linting or formatting tools are configured in this project yet — `golangci-lint`
|
|
and `gofumpt` are pre-approved in `.claude/settings.json` for when they're wired up,
|
|
but neither has a config file or CI step yet. There is no `main.go` or `cmd/`
|
|
entrypoint yet, so there's nothing to run locally.
|
|
|
|
## Architecture
|
|
|
|
Not yet built. TODO: once the controller-runtime manager and reconcile loop exist,
|
|
document the data-flow diagram and package/role table here, following the standard
|
|
reconcile-loop shape: fetch → resolve → list related → compute desired state → merge
|
|
→ patch only on diff.
|
|
|
|
## Conventions
|
|
|
|
### Go Conventions
|
|
|
|
- Use the latest stable Go version (check https://go.dev/dl/ before starting a new feature).
|
|
- Use `slog` for structured logging.
|
|
- `context.Context` is the first parameter of every function that does I/O or can be cancelled.
|
|
- No `init()` unless there is no other option.
|
|
- Error wrapping: `fmt.Errorf("...: %w", err)` for single errors; `errors.Join` for multiple.
|
|
- Prefer stdlib over third-party dependencies where reasonable.
|
|
- No vendoring unless explicitly requested.
|
|
- Fail fast, return early.
|
|
- No obvious comments.
|
|
|
|
### Testing
|
|
|
|
**All new Go code must have corresponding tests.**
|
|
|
|
- Use stdlib `testing` — no testify unless already present in the module.
|
|
- Table-driven tests are the default pattern.
|
|
- Test files live next to source: `foo.go` → `foo_test.go`.
|
|
- Name tests `Test<Function>_<scenario>` (e.g. `TestParseRoster_emptyInput`).
|
|
- Use `t.Parallel()` where safe.
|
|
- Use subtests for table entries: `t.Run(tc.name, func(t *testing.T) { ... })`.
|
|
- Test behaviour, not implementation.
|
|
- Guard slow tests with `testing.Short()`: `if testing.Short() { t.Skip() }`.
|
|
- Integration tests that need real infra (DB, network) go behind `//go:build integration`
|
|
and use `testcontainers-go` rather than mocking the infra away.
|
|
|
|
#### Useful test commands
|
|
|
|
```bash
|
|
go test ./... # all unit tests
|
|
go test -v ./... # verbose
|
|
go test -cover ./... # with coverage
|
|
go test -short ./... # skip slow/integration tests
|
|
go test -v ./internal/... # specific package tree
|
|
go test -race -v -run TestName ./path/to/package # single test, race detector on
|
|
go test -tags=integration ./... # integration tests (requires infra)
|
|
```
|
|
|
|
### Plans
|
|
|
|
When Claude Code's plan mode is used, save the plan file inside the repo at
|
|
`docs/plans/YYYY-MM-DD-HHMM-<slug>.md` instead of the default `~/.claude/plans/`
|
|
location. Get the timestamp with `date "+%Y-%m-%d-%H%M"`. The `<slug>` is a short
|
|
kebab-case summary of the plan's topic.
|
|
|
|
Include the same timestamp in the plan's header, e.g.:
|
|
|
|
# Plan: <title>
|
|
**Created:** 2026-08-07 15:30
|
|
|
|
Create `docs/plans/` on first use. Plan files are committed to the repo so other
|
|
contributors can review historical decisions.
|
|
|
|
### Changelog
|
|
|
|
Maintain a running changelog in `CHANGELOG.md` at the repo root. After every
|
|
significant change, fix, or update — once the user confirms it works — append a new
|
|
entry **at the top** of the file in this format:
|
|
|
|
## YYYY-MM-DD HH:MM TZ — short title
|
|
|
|
- One-line summary of what changed and why.
|
|
- Key files touched (optional, only if useful for traceability).
|
|
|
|
Get the timestamp with `date "+%Y-%m-%d %H:%M %Z"`. Never write a literal placeholder
|
|
like `HH:MM` — always run `date` first to get the real current time. Skip trivial edits
|
|
(typos, formatting, comment tweaks); only log changes a future reader would care about.
|
|
|
|
### Branching & Merge Requests
|
|
|
|
The remote is Gitea (`gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator`). For
|
|
**features**, do not commit to `main` directly. Use a branch + merge request flow:
|
|
|
|
1. **Create a branch off `main`** before starting work:
|
|
- `feat/<slug>` for features (e.g. `feat/roster-import`)
|
|
- `fix/<slug>` for bug-fix branches the user explicitly asks for
|
|
- `<slug>` is short kebab-case
|
|
2. **Commit on the branch** following the commit conventions below.
|
|
3. **Push the branch** to `origin` with `-u` so it tracks.
|
|
4. **Open the MR with `tea`** rather than printing a compare URL:
|
|
|
|
```bash
|
|
tea pr create \
|
|
--title "<short title>" \
|
|
--description "<body>" \
|
|
--base main \
|
|
--head <branch>
|
|
```
|
|
|
|
`tea` is already authenticated against the Gitea instance; just run it. Print the
|
|
resulting PR URL for the user. If `tea` is unavailable, fall back to printing the
|
|
compare URL (`gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator/compare/main...<branch>`)
|
|
and let the user open the MR manually.
|
|
5. **Do not merge or delete the branch** from the CLI — neither via `tea`, `gh`, nor
|
|
`git push --delete`. The user does that in Gitea.
|
|
|
|
**Exceptions — committing straight to `main` is fine for:**
|
|
- Small bug fixes / hotfixes the user describes as such.
|
|
- Typo / comment / formatting tweaks.
|
|
- Edits the user explicitly says to push to `main`.
|
|
|
|
When uncertain whether something is a feature or a small fix, ask before branching.
|
|
|
|
### Git Commits
|
|
|
|
Always append a `Co-Authored-By` trailer to indicate AI assistance:
|
|
|
|
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
|
|
TODO: no `.gitea/workflows/` CI pipeline exists yet — add a CI/CD subsection here once
|
|
one is set up.
|
|
|
|
## Gotchas
|
|
|
|
- This repo currently contains only `go.mod` (module
|
|
`gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator`) — no controller code,
|
|
`main.go`, Dockerfile, k8s manifests, Makefile, or CI config exist yet. Nothing in
|
|
this file describes working software; it's the convention scaffold to build against.
|