add Makefile, ci scripts, and pinned tooling
Root Makefile drives both the Go sidecar under sidecar/ and the Flutter app under app/ through one interface. Mirrors the pql/claudian pattern: VERSION read from project.yaml via awk and stamped into the sidecar binary via -ldflags -X, so the version the codebase claims to be and the version the binary reports cannot drift. Flutter targets (app-analyze, app-test, app-build-*) check for app/pubspec.yaml and flutter on PATH and gracefully noop when either is missing. That makes the Makefile usable today — before the app is scaffolded — without ceremony. ci/ scripts shell out to the Makefile so local dev and CI run the same commands. lint.sh includes the supply-chain gate (make security) so there is no version of "green lint, known-vulnerable dep" that CI accepts. make tools installs govulncheck, goimports, and golangci-lint at exact pinned versions — bump deliberately, never floating. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,8 @@ heading, and (b) bumping `project.yaml` `version:` in the same commit.
|
|||||||
[ADR 0002](docs/ADRs/0002-sidecar-language-go.md) — Sidecar language: Go.
|
[ADR 0002](docs/ADRs/0002-sidecar-language-go.md) — Sidecar language: Go.
|
||||||
[ADR 0003](docs/ADRs/0003-pql-as-supporter-tool.md) — pql as supporter tool; wrap, don't duplicate; pql is a Clide subsystem when present.
|
[ADR 0003](docs/ADRs/0003-pql-as-supporter-tool.md) — pql as supporter tool; wrap, don't duplicate; pql is a Clide subsystem when present.
|
||||||
[ADR 0004](docs/ADRs/0004-ignore-file-strategy.md) — Ignore file strategy (`ignore_files:` in `.pql/config.yaml`, layered).
|
[ADR 0004](docs/ADRs/0004-ignore-file-strategy.md) — Ignore file strategy (`ignore_files:` in `.pql/config.yaml`, layered).
|
||||||
|
- Root `Makefile` drives both the Go sidecar and the Flutter app under one toolchain. Version is read from `project.yaml` via awk and stamped into the sidecar via `-ldflags -X`. Flutter targets gracefully noop before the app is scaffolded so the Makefile is usable from day one. Pinned Go tooling (govulncheck, goimports, golangci-lint) installs via `make tools`.
|
||||||
|
- `ci/` entry scripts: `test.sh`, `lint.sh` (includes the supply-chain gate — no green lint without a green CVE scan), `security.sh`, `release.sh` (stub).
|
||||||
- Project identity files for the Flutter rebuild at the repo root: `project.yaml` (single source of truth for version + module path, version 2.0.0-dev), a fresh `README.md`, MIT `LICENSE`, and `.editorconfig`. The Python clide's manifest and README are preserved under `legacy/`.
|
- Project identity files for the Flutter rebuild at the repo root: `project.yaml` (single source of truth for version + module path, version 2.0.0-dev), a fresh `README.md`, MIT `LICENSE`, and `.editorconfig`. The Python clide's manifest and README are preserved under `legacy/`.
|
||||||
- [`docs/initial-plan.md`](docs/initial-plan.md) — the north-star design document for the Flutter rebuild. Captures what we kept from Python Clide (pane model, git skills, Claude-always-visible), what we took from Obsidian (canvas and graph — no vault, no bases, no plugin inheritance), what Claudian's short experiment contributed (Go sidecar, CLI-first, pql-as-subsystem, ignore-file strategy), and the tier roadmap (Tier 0 app+sidecar handshake → Tier 5 canvas+graph).
|
- [`docs/initial-plan.md`](docs/initial-plan.md) — the north-star design document for the Flutter rebuild. Captures what we kept from Python Clide (pane model, git skills, Claude-always-visible), what we took from Obsidian (canvas and graph — no vault, no bases, no plugin inheritance), what Claudian's short experiment contributed (Go sidecar, CLI-first, pql-as-subsystem, ignore-file strategy), and the tier roadmap (Tier 0 app+sidecar handshake → Tier 5 canvas+graph).
|
||||||
- [`CLAUDE.md`](CLAUDE.md) orientation doc for future Claude Code instances: project identity, guardrails as one-liners, tier ordering, parent-project pointers, commands, dependencies & supply chain, open questions. Points at the design doc and ADRs rather than restating their content.
|
- [`CLAUDE.md`](CLAUDE.md) orientation doc for future Claude Code instances: project identity, guardrails as one-liners, tier ordering, parent-project pointers, commands, dependencies & supply chain, open questions. Points at the design doc and ADRs rather than restating their content.
|
||||||
|
|||||||
@@ -0,0 +1,167 @@
|
|||||||
|
# clide — local dev targets. CI scripts in ci/ shell out to these.
|
||||||
|
#
|
||||||
|
# Two components under one Makefile:
|
||||||
|
# - Go sidecar/CLI under sidecar/
|
||||||
|
# - Flutter desktop app under app/ (scaffolded once Flutter is installed
|
||||||
|
# locally; targets gracefully noop when app/ isn't present yet).
|
||||||
|
|
||||||
|
GO ?= go
|
||||||
|
BIN_DIR ?= sidecar/bin
|
||||||
|
INSTALL_DIR ?= $(HOME)/.local/bin
|
||||||
|
|
||||||
|
# Version stamping. Source of truth: project.yaml `version:` field. Local
|
||||||
|
# builds augment with git short SHA + dirty marker (semver build metadata).
|
||||||
|
# Tagged releases are handled by goreleaser using the git tag instead.
|
||||||
|
VERSION_BASE ?= $(shell awk -F': *' '/^version:/ {gsub(/[" ]/,"",$$2); print $$2; exit}' project.yaml)
|
||||||
|
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
||||||
|
DIRTY := $(shell git diff --quiet HEAD 2>/dev/null || echo .dirty)
|
||||||
|
VERSION ?= $(VERSION_BASE)+$(COMMIT)$(DIRTY)
|
||||||
|
DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||||
|
|
||||||
|
LDFLAGS := -s -w \
|
||||||
|
-X 'git.schweitz.net/jpmschweitzer/clide/sidecar/internal/version.Version=$(VERSION)' \
|
||||||
|
-X 'git.schweitz.net/jpmschweitzer/clide/sidecar/internal/version.Commit=$(COMMIT)' \
|
||||||
|
-X 'git.schweitz.net/jpmschweitzer/clide/sidecar/internal/version.Date=$(DATE)'
|
||||||
|
|
||||||
|
GO_PACKAGES := ./...
|
||||||
|
|
||||||
|
.PHONY: help
|
||||||
|
help: ## Show this help.
|
||||||
|
@awk 'BEGIN {FS = ":.*##"} /^[a-zA-Z0-9_-]+:.*##/ {printf " \033[36m%-22s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||||
|
|
||||||
|
# -- sidecar (Go) --------------------------------------------------------
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
build: ## Build the clide sidecar/CLI binary into sidecar/bin/clide.
|
||||||
|
cd sidecar && $(GO) build -ldflags="$(LDFLAGS)" -o bin/clide ./cmd/clide
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
|
install: build ## Install sidecar/bin/clide into $(INSTALL_DIR).
|
||||||
|
install -m 0755 $(BIN_DIR)/clide $(INSTALL_DIR)/clide
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test: ## Unit tests (Go), fast.
|
||||||
|
cd sidecar && $(GO) test $(GO_PACKAGES)
|
||||||
|
|
||||||
|
.PHONY: test-race
|
||||||
|
test-race: ## Unit tests with the race detector.
|
||||||
|
cd sidecar && $(GO) test -race $(GO_PACKAGES)
|
||||||
|
|
||||||
|
.PHONY: test-integration
|
||||||
|
test-integration: build ## Integration tests (binary + fixture repos). Tag: integration.
|
||||||
|
cd sidecar && $(GO) test -tags=integration ./...
|
||||||
|
|
||||||
|
.PHONY: lint
|
||||||
|
lint: ## golangci-lint run on the sidecar.
|
||||||
|
cd sidecar && golangci-lint run
|
||||||
|
|
||||||
|
.PHONY: vuln
|
||||||
|
vuln: ## govulncheck on all sidecar packages — Go CVE gate.
|
||||||
|
cd sidecar && govulncheck ./...
|
||||||
|
|
||||||
|
.PHONY: fmt
|
||||||
|
fmt: ## gofmt + goimports on the sidecar.
|
||||||
|
cd sidecar && gofmt -w .
|
||||||
|
@command -v goimports >/dev/null && cd sidecar && goimports -w . || echo "(goimports not installed; skipping)"
|
||||||
|
|
||||||
|
.PHONY: tidy
|
||||||
|
tidy: ## go mod tidy for the sidecar.
|
||||||
|
cd sidecar && $(GO) mod tidy
|
||||||
|
|
||||||
|
.PHONY: snapshot
|
||||||
|
snapshot: ## GoReleaser snapshot build (dry-run, no publish).
|
||||||
|
goreleaser release --snapshot --clean
|
||||||
|
|
||||||
|
# -- app (Flutter) -------------------------------------------------------
|
||||||
|
|
||||||
|
# App targets gracefully noop if app/ doesn't exist yet (pre-Tier-0
|
||||||
|
# scaffold) or if flutter isn't installed locally.
|
||||||
|
APP_PRESENT := $(shell test -f app/pubspec.yaml && echo yes || echo no)
|
||||||
|
HAS_FLUTTER := $(shell command -v flutter >/dev/null && echo yes || echo no)
|
||||||
|
|
||||||
|
.PHONY: app-pubget
|
||||||
|
app-pubget: ## flutter pub get (hydrate the app's pub cache).
|
||||||
|
ifeq ($(APP_PRESENT),yes)
|
||||||
|
cd app && flutter pub get
|
||||||
|
else
|
||||||
|
@echo "(app/ not scaffolded yet; skipping)"
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: app-analyze
|
||||||
|
app-analyze: ## dart analyze on the app.
|
||||||
|
ifeq ($(APP_PRESENT),yes)
|
||||||
|
cd app && flutter analyze
|
||||||
|
else
|
||||||
|
@echo "(app/ not scaffolded yet; skipping)"
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: app-format
|
||||||
|
app-format: ## dart format on the app.
|
||||||
|
ifeq ($(APP_PRESENT),yes)
|
||||||
|
cd app && dart format --set-exit-if-changed .
|
||||||
|
else
|
||||||
|
@echo "(app/ not scaffolded yet; skipping)"
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: app-test
|
||||||
|
app-test: ## flutter test on the app.
|
||||||
|
ifeq ($(APP_PRESENT),yes)
|
||||||
|
cd app && flutter test
|
||||||
|
else
|
||||||
|
@echo "(app/ not scaffolded yet; skipping)"
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: app-build-linux
|
||||||
|
app-build-linux: ## flutter build linux.
|
||||||
|
ifeq ($(APP_PRESENT),yes)
|
||||||
|
cd app && flutter build linux
|
||||||
|
else
|
||||||
|
@echo "(app/ not scaffolded yet; skipping)"
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: app-build-macos
|
||||||
|
app-build-macos: ## flutter build macos.
|
||||||
|
ifeq ($(APP_PRESENT),yes)
|
||||||
|
cd app && flutter build macos
|
||||||
|
else
|
||||||
|
@echo "(app/ not scaffolded yet; skipping)"
|
||||||
|
endif
|
||||||
|
|
||||||
|
# -- security ------------------------------------------------------------
|
||||||
|
|
||||||
|
.PHONY: security
|
||||||
|
security: vuln ## Run all CVE gates. For now: Go (govulncheck). Dart CVE gate lands when a reliable tooling exists.
|
||||||
|
|
||||||
|
# -- tooling -------------------------------------------------------------
|
||||||
|
|
||||||
|
# Pinned Go tool versions. Bump deliberately; never floating.
|
||||||
|
GOVULNCHECK_VERSION ?= v1.1.4
|
||||||
|
GOIMPORTS_VERSION ?= v0.29.0
|
||||||
|
GOLANGCI_LINT_VERSION ?= v2.11.4
|
||||||
|
|
||||||
|
.PHONY: tools
|
||||||
|
tools: ## Install Go tooling at pinned versions (govulncheck, goimports, golangci-lint).
|
||||||
|
$(GO) install golang.org/x/vuln/cmd/govulncheck@$(GOVULNCHECK_VERSION)
|
||||||
|
$(GO) install golang.org/x/tools/cmd/goimports@$(GOIMPORTS_VERSION)
|
||||||
|
$(GO) install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)
|
||||||
|
|
||||||
|
# -- pre-push gate -------------------------------------------------------
|
||||||
|
|
||||||
|
.PHONY: push-check
|
||||||
|
push-check: lint test test-race test-integration vuln app-analyze app-test ## Full pre-push gate — everything that must pass before a push.
|
||||||
|
|
||||||
|
.PHONY: hooks
|
||||||
|
hooks: ## Install the repo's git hooks (points core.hooksPath at .githooks/).
|
||||||
|
git config core.hooksPath .githooks
|
||||||
|
@echo "hooks installed (core.hooksPath = .githooks)"
|
||||||
|
|
||||||
|
# -- housekeeping --------------------------------------------------------
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean: ## Remove build artefacts.
|
||||||
|
rm -rf sidecar/bin sidecar/dist
|
||||||
|
ifeq ($(APP_PRESENT),yes)
|
||||||
|
rm -rf app/build app/.dart_tool
|
||||||
|
endif
|
||||||
|
|
||||||
|
.DEFAULT_GOAL := help
|
||||||
Executable
+12
@@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# CI entry: lint + supply-chain gates. Security runs here too so a
|
||||||
|
# merge-blocking lint failure and a merge-blocking CVE failure share
|
||||||
|
# one CI job — there is no version of "lint passed but we shipped a
|
||||||
|
# known-vulnerable dep" that is acceptable in this repo.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
|
make lint
|
||||||
|
make app-analyze
|
||||||
|
make security
|
||||||
Executable
+9
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# CI entry: release pipeline. Stub — wire goreleaser + flutter build
|
||||||
|
# artifacts later.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
|
echo "TODO: goreleaser release (sidecar) + flutter build (app) + publish"
|
||||||
|
exit 64
|
||||||
Executable
+12
@@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# CI entry: supply-chain + CVE gate. Shells out to Makefile targets so
|
||||||
|
# local dev and CI run the same commands.
|
||||||
|
#
|
||||||
|
# See ~/.claude/projects/-var-mnt-data-projects-clide/memory/ for the
|
||||||
|
# standing requirements: Go deps must be version-locked and CVE-checked;
|
||||||
|
# Dart deps prefer zero, with what remains pinned and audited.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
|
make security
|
||||||
Executable
+9
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# CI entry: run the full test matrix. Shells out to Makefile targets.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
|
make test
|
||||||
|
make test-race
|
||||||
|
make app-test
|
||||||
Reference in New Issue
Block a user