diff --git a/README.md b/README.md index a7ae8fe..f1b04eb 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ FastAPI Spring Boot Android + Go Contributors

diff --git a/docs/profiles.md b/docs/profiles.md index 3201be0..262a058 100644 --- a/docs/profiles.md +++ b/docs/profiles.md @@ -18,6 +18,7 @@ Available profiles: - `android` - `react` - `vue` +- `go` ## How Agents Use Profiles diff --git a/docs/validation.md b/docs/validation.md index 7281552..d1e3128 100644 --- a/docs/validation.md +++ b/docs/validation.md @@ -44,6 +44,7 @@ Automated fixture smoke tests cover harness installation for: - Spring Boot - Android / Kotlin Gradle - Vue +- Go These tests verify that the installer preserves existing files, writes expected profile snippets, and produces runnable generic drift checks. diff --git a/scripts/apply_harness.py b/scripts/apply_harness.py index 469d1d4..43abe2e 100644 --- a/scripts/apply_harness.py +++ b/scripts/apply_harness.py @@ -71,6 +71,7 @@ def parse_args() -> argparse.Namespace: "fastapi", "react", "vue", + "go", ), default="generic", help="Optional stack profile. Profiles add reference snippets only.", diff --git a/scripts/check_docs_drift.py b/scripts/check_docs_drift.py index 7771298..ae28a41 100644 --- a/scripts/check_docs_drift.py +++ b/scripts/check_docs_drift.py @@ -50,6 +50,8 @@ "out/", "target", "target/", + "vendor", + "vendor/", "target-repo/harness-starter-kit", "scripts/check_harness.py", "tsconfig.tsbuildinfo", diff --git a/templates/generic/scripts/check_docs_drift.py b/templates/generic/scripts/check_docs_drift.py index 7771298..ae28a41 100644 --- a/templates/generic/scripts/check_docs_drift.py +++ b/templates/generic/scripts/check_docs_drift.py @@ -50,6 +50,8 @@ "out/", "target", "target/", + "vendor", + "vendor/", "target-repo/harness-starter-kit", "scripts/check_harness.py", "tsconfig.tsbuildinfo", diff --git a/templates/profiles/go/README.md b/templates/profiles/go/README.md new file mode 100644 index 0000000..5a78f5a --- /dev/null +++ b/templates/profiles/go/README.md @@ -0,0 +1,74 @@ +# Go Harness Profile + +Use these snippets when the target project is a Go module or service. + +These files are agent reference material, not automatic transformations. Merge +only the pieces that fit the target project's existing tools. + +Apply this profile by priority: always preserve the target module path, generated +file boundaries, and exact local check commands; document database, auth, or +external API setup when present; consider decision records only when changing +module boundaries, persistence approach, auth flow, or external integration +policy; use a short report/check note for narrow fixes. + +## Recommended Checks + +- `go build ./...` to verify the module compiles. +- `go vet ./...` for static analysis included in the Go toolchain. +- `golangci-lint run` when the target project has `.golangci.yml`, + `.golangci.yaml`, or `.golangci.toml`. Do not add golangci-lint if it is absent. +- `go test ./...` for unit tests. Add `-count=1` to disable test result caching + when the results must reflect the current state. +- `scripts/check_docs_drift.py` for stale documentation references. +- `scripts/check_structure.py` for temporary or drift-prone files. + +## Generated Files + +Go projects often include code generated by tools such as `sqlc`, `protoc`, +`mockgen`, `stringer`, `templ`, or similar. These files are source: do not +edit them directly and do not omit them from version control unless the +target project policy says otherwise. Record generated paths in `AGENTS.md` +so agents know not to edit them. + +If the target project has a code generation step, document the command in +`AGENTS.md` so agents can regenerate when the schema or interface changes. + +## Suggested Check Script + +Copy or adapt `check_harness.py` into the target repository's `scripts/` +directory when the project has no existing task runner. It runs `go vet`, +`golangci-lint` when the target has a golangci-lint config, and the generic +drift checks. + +## Profile Absorption Notes + +When Go is introduced after generic adoption: + +- Merge relevant ignores from `gitignore.harness.txt`, especially build + outputs, vendor directories, and the local `harness-starter-kit/` clone. +- Copy or adapt `check_harness.py` into `scripts/` only when the target has no + equivalent local verification command. +- Update `AGENTS.md` with the module path, package layout conventions, + generated file paths, and completion checks. +- Update `docs/conventions/coding.md` with package boundaries, error handling, + interface definition placement, testing approach, and any project-specific + patterns agents should repeat. +- Consider a decision record when changing or selecting the module structure, + persistence layer, auth approach, external integration policy, or code + generation tooling. When the task only follows the existing architecture or + makes a narrow fix, a final report or check note is enough. +- In the final report, list which snippets were adopted, adapted, skipped, or + deferred. + +## Go Notes + +- Keep `go.mod` and `go.sum` as source. Do not edit `go.sum` manually. +- Use `go mod tidy` after adding or removing dependencies. +- Do not commit build output binaries or the local `harness-starter-kit/` clone. +- Add `vendor/` to `.gitignore` unless the target project intentionally vendors + dependencies. +- Protect generated file directories in `AGENTS.md` so agents do not overwrite + them by hand. +- Prefer table-driven tests with `t.Run` for cases that share setup. +- Add integration or end-to-end tests only when the target project already has + a test database, container, or emulator setup in place. diff --git a/templates/profiles/go/check_harness.py b/templates/profiles/go/check_harness.py new file mode 100644 index 0000000..a807ad8 --- /dev/null +++ b/templates/profiles/go/check_harness.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +"""Run local harness checks for a Go project.""" + +from __future__ import annotations + +import argparse +import shutil +import subprocess +import sys +from pathlib import Path + + +def repo_root() -> Path: + current = Path(__file__).resolve() + if current.parent.name == "scripts": + return current.parents[1] + + cwd = Path.cwd() + if (cwd / "scripts" / "check_docs_drift.py").exists(): + return cwd + + for candidate in (current.parent, *current.parents): + if (candidate / "go.mod").exists(): + return candidate + return cwd + + +ROOT = repo_root() + + +def run(command: list[str]) -> None: + subprocess.run(command, cwd=ROOT, check=True) + + +def main() -> int: + parser = argparse.ArgumentParser(description="Run Go harness checks.") + parser.add_argument( + "--skip-tests", + action="store_true", + help="Run only vet and harness drift checks.", + ) + args = parser.parse_args() + + run(["go", "build", "./..."]) + run(["go", "vet", "./..."]) + + lint_configs = (".golangci.yml", ".golangci.yaml", ".golangci.toml") + if shutil.which("golangci-lint") and any((ROOT / name).exists() for name in lint_configs): + run(["golangci-lint", "run"]) + + if not args.skip_tests: + run(["go", "test", "-count=1", "./..."]) + + run([sys.executable, "scripts/check_docs_drift.py"]) + run([sys.executable, "scripts/check_structure.py"]) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/templates/profiles/go/gitignore.harness.txt b/templates/profiles/go/gitignore.harness.txt new file mode 100644 index 0000000..441463f --- /dev/null +++ b/templates/profiles/go/gitignore.harness.txt @@ -0,0 +1,15 @@ +# Go build outputs +/bin/ +/dist/ +*.exe +*.test +*.out + +# Dependency vendor directory (omit this line if the project vendors intentionally) +vendor/ + +# Test cache +/tmp/ + +# Harness kit reference clone +harness-starter-kit/ diff --git a/tests/fixtures/go-basic/README.md b/tests/fixtures/go-basic/README.md new file mode 100644 index 0000000..eaa92be --- /dev/null +++ b/tests/fixtures/go-basic/README.md @@ -0,0 +1,3 @@ +# Go Basic Fixture + +A minimal Go module shape used to smoke-test harness adoption. diff --git a/tests/fixtures/go-basic/go.mod b/tests/fixtures/go-basic/go.mod new file mode 100644 index 0000000..8439d86 --- /dev/null +++ b/tests/fixtures/go-basic/go.mod @@ -0,0 +1,3 @@ +module example.com/go-basic + +go 1.22.0 diff --git a/tests/test_smoke_fixtures.py b/tests/test_smoke_fixtures.py index 641c5a6..5a67596 100644 --- a/tests/test_smoke_fixtures.py +++ b/tests/test_smoke_fixtures.py @@ -38,6 +38,7 @@ class FixtureSmokeTests(unittest.TestCase): "package-scripts.harness.json", ), ), + "go-basic": ("go", ("check_harness.py", "gitignore.harness.txt")), "spring-basic": ("spring", ("check_harness.py", "gitignore.harness.txt")), "android-basic": ("android", ("check_harness.py", "gitignore.harness.txt")), "vue-basic": (