-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathMakefile
More file actions
288 lines (245 loc) · 9.95 KB
/
Makefile
File metadata and controls
288 lines (245 loc) · 9.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# Context CLI Makefile
#
# Common targets for Go developers
.PHONY: build test vet fmt lint lint-style lint-drift clean all release build-all help \
test-coverage smoke site site-feed site-serve site-serve-lan site-setup audit check plugin-reload \
journal journal-serve journal-serve-lan gpg-fix gpg-test register-mcp reinstall \
sync-version check-version-sync sync-why check-why sync-copilot-skills check-copilot-skills gemini-search
# Default binary name and output
BINARY := ctx
OUTPUT := $(BINARY)
# Default target
all: build
## sync-version: Stamp VERSION into embedded plugin.json
sync-version:
@V=$$(cat VERSION | tr -d '[:space:]'); \
jq --arg v "$$V" '.version = $$v' internal/assets/claude/.claude-plugin/plugin.json > internal/assets/claude/.claude-plugin/plugin.json.tmp && \
mv internal/assets/claude/.claude-plugin/plugin.json.tmp internal/assets/claude/.claude-plugin/plugin.json; \
echo "Plugin version synced to $$V"
## build: Build for current platform (syncs version + embedded docs + copilot skills first)
build: sync-version sync-why sync-copilot-skills
CGO_ENABLED=0 go build -ldflags="-X github.com/ActiveMemory/ctx/internal/bootstrap.version=$$(cat VERSION | tr -d '[:space:]')" -o $(OUTPUT) ./cmd/ctx
## test: Run tests with coverage summary
test:
@CGO_ENABLED=0 CTX_SKIP_PATH_CHECK=1 go test -cover ./...
## test-v: Run tests with verbose output
test-v:
CGO_ENABLED=0 go test -v ./...
## test-cover: Generate HTML coverage report in dist/coverage.html
test-cover:
@mkdir -p dist
@CGO_ENABLED=0 go test -coverprofile=dist/coverage.out ./...
@go tool cover -html=dist/coverage.out -o dist/coverage.html
@echo "Coverage report: dist/coverage.html"
## test-coverage: Run tests with coverage and check against target (70%)
test-coverage:
@echo "Running coverage check (target: 70%)..."
@echo ""
@CGO_ENABLED=0 go test -cover ./internal/context ./internal/cli 2>&1 | tee /tmp/ctx-coverage.txt
@echo ""
@CONTEXT_COV=$$(grep 'internal/context' /tmp/ctx-coverage.txt | grep -oE '[0-9]+\.[0-9]+%' | sed 's/%//'); \
CLI_COV=$$(grep 'internal/cli' /tmp/ctx-coverage.txt | grep -oE '[0-9]+\.[0-9]+%' | sed 's/%//'); \
echo "Coverage summary:"; \
echo " internal/context: $${CONTEXT_COV}% (target: 70%)"; \
echo " internal/cli: $${CLI_COV}% (target: 70% - aspirational)"; \
echo ""; \
if [ $$(echo "$$CONTEXT_COV < 70" | bc -l) -eq 1 ]; then \
echo "FAIL: internal/context coverage below 70%"; \
rm -f /tmp/ctx-coverage.txt; \
exit 1; \
fi; \
echo "Coverage check passed (internal/context >= 70%)"; \
rm -f /tmp/ctx-coverage.txt
## smoke: Build and run basic commands to verify binary works
smoke: build
@echo "Running smoke tests..."
@TMPDIR=$$(mktemp -d) && \
cd $$TMPDIR && \
echo " Testing: ctx --help" && \
$(CURDIR)/$(BINARY) --help > /dev/null && \
echo " Testing: ctx init" && \
CTX_SKIP_PATH_CHECK=1 $(CURDIR)/$(BINARY) init > /dev/null && \
echo " Testing: ctx status" && \
$(CURDIR)/$(BINARY) status > /dev/null && \
echo " Testing: ctx agent" && \
$(CURDIR)/$(BINARY) agent > /dev/null && \
echo " Testing: ctx drift" && \
$(CURDIR)/$(BINARY) drift > /dev/null && \
echo " Testing: ctx add task 'smoke test task'" && \
$(CURDIR)/$(BINARY) add task "smoke test task" > /dev/null && \
echo " Testing: ctx journal source" && \
$(CURDIR)/$(BINARY) journal source > /dev/null && \
echo " Testing: ctx why manifesto" && \
$(CURDIR)/$(BINARY) why manifesto > /dev/null && \
rm -rf $$TMPDIR && \
echo "" && \
echo "Smoke tests passed!"
## vet: Run go vet
vet:
go vet ./...
## fmt: Format code
fmt:
go fmt ./...
## lint: Run golangci-lint (requires golangci-lint installed)
lint:
golangci-lint run
## lint-style: Run all cosmetic/style lint scripts (advisory, not fatal)
lint-style:
@echo "==> Checking code drift..."
@./hack/lint-drift.sh
@echo "==> Checking docstrings..."
@./hack/lint-docstrings.sh
@echo "==> Checking mixed funcs..."
@./hack/lint-mixed-funcs.sh
@echo "==> Checking import conventions..."
@./hack/lint-imports.sh
@echo ""
@echo "Style checks passed!"
## lint-drift: Check for code-level drift (magic strings, literal \n, Printf)
lint-drift:
@./hack/lint-drift.sh
## audit: Run all CI checks locally (fmt, vet, lint, drift, docs, test)
audit:
@echo "==> Checking formatting..."
@test -z "$$(gofmt -l .)" || (echo "Files need formatting:"; gofmt -l .; exit 1)
@echo "==> Running go vet..."
@CGO_ENABLED=0 go vet ./...
@echo "==> Running golangci-lint..."
@golangci-lint run --timeout=5m
@echo "==> Running style checks..."
@$(MAKE) --no-print-directory lint-style
@echo "==> Checking version sync..."
@$(MAKE) --no-print-directory check-version-sync
@echo "==> Checking why docs freshness..."
@$(MAKE) --no-print-directory check-why
@echo "==> Checking Copilot skills freshness..."
@$(MAKE) --no-print-directory check-copilot-skills
@echo "==> Running tests..."
@CGO_ENABLED=0 CTX_SKIP_PATH_CHECK=1 go test ./...
@echo ""
@echo "All checks passed!"
@echo "Tip: run /ctx-check-links to verify doc links before committing."
## check: Build + audit (single entry point for build, fmt, vet, lint, test)
check: build audit
## clean: Remove build artifacts
clean:
rm -f $(BINARY)
rm -rf dist/
## release: Full release process (build, tag, push)
release:
./hack/release.sh
## build-all: Build binaries for all platforms (no tag)
build-all:
./hack/build-all.sh $$(cat VERSION | tr -d '[:space:]')
## release-notes: Generate release notes (use Claude Code slash command)
release-notes:
@echo "To generate release notes, run in Claude Code:"
@echo ""
@echo " /release-notes"
@echo ""
@echo "This will analyze commits since the last tag and write to dist/RELEASE_NOTES.md"
## install: Install to /usr/local/bin (run as: make build && sudo make install)
install:
@test -f $(BINARY) || (echo "Binary not found. Run 'make build' first, then 'sudo make install'" && exit 1)
cp $(BINARY) /usr/local/bin/$(BINARY)
@echo "Installed ctx to /usr/local/bin/ctx"
## reinstall: Build and install in one step
reinstall: build
cp -f $(BINARY) /usr/local/bin/$(BINARY) 2>/dev/null || sudo cp -f $(BINARY) /usr/local/bin/$(BINARY)
@echo "ctx reinstalled to /usr/local/bin/ctx"
## site-setup: Install zensical via pipx
site-setup:
pipx install zensical
## site: Build documentation site and generate feed
site:
zensical build
ctx site feed
## site-feed: Generate Atom feed from blog posts
site-feed:
ctx site feed
## site-serve: Serve documentation site locally
site-serve:
zensical serve
## site-serve-lan: Serve docs site on all interfaces (LAN-accessible)
site-serve-lan:
zensical serve -a 0.0.0.0:8000
## journal: Import sessions and regenerate journal site
journal:
@echo "==> Importing sessions to journal..."
@ctx journal import --all
@echo "==> Generating journal site..."
@ctx journal site --build
@echo ""
@echo "Journal site updated!"
@echo ""
@echo "Next steps (in Claude Code):"
@echo " /ctx-journal-enrich-all — exports if needed + adds metadata per entry"
@echo ""
@echo "Then re-run: make journal"
## journal-serve: Serve the journal site (port 8001; docs uses 8000)
journal-serve:
@ctx journal site
cd .context/journal-site && zensical serve -a localhost:8001
## journal-serve-lan: Serve journal site on all interfaces (LAN-accessible, port 8001)
journal-serve-lan:
cd .context/journal-site && zensical serve -a 0.0.0.0:8001
## gpg-fix: Fix GPG signing configuration
gpg-fix:
./hack/gpg-fix.sh
## gpg-test: Test GPG signing configuration
gpg-test:
./hack/gpg-fix.sh --test
## register-mcp: Register all MCP servers (gemini-search, gitnexus) with Claude Code
register-mcp:
@./hack/register-gemini-search.sh
@./hack/register-gitnexus.sh
## gemini-search: Register gemini-search MCP server with Claude Code
gemini-search:
@./hack/register-gemini-search.sh
## plugin-reload: Clear cached plugin (restart Claude Code to pick up skill/hook changes)
plugin-reload:
@./hack/plugin-reload.sh
## sync-why: Copy philosophy docs into internal/assets/why/ for embedding
sync-why:
cp docs/index.md internal/assets/why/manifesto.md
cp docs/home/about.md internal/assets/why/about.md
cp docs/reference/design-invariants.md internal/assets/why/design-invariants.md
@echo "Why docs synced."
## check-version-sync: Verify VERSION file matches embedded plugin.json
check-version-sync:
@V=$$(cat VERSION | tr -d '[:space:]'); \
PV=$$(jq -r '.version' internal/assets/claude/.claude-plugin/plugin.json); \
if [ "$$V" != "$$PV" ]; then \
echo "FAIL: VERSION ($$V) != plugin.json ($$PV) — run 'make sync-version'"; \
exit 1; \
fi; \
echo "Version sync OK ($$V)."
## sync-copilot-skills: Sync Copilot CLI skills from canonical ctx skills
sync-copilot-skills:
@./hack/sync-copilot-skills.sh
## check-copilot-skills: Verify Copilot CLI skills match ctx source skills
check-copilot-skills:
@TMPDIR=$$(mktemp -d) && \
cp -r internal/assets/integrations/copilot-cli/skills/ "$$TMPDIR/before" && \
./hack/sync-copilot-skills.sh > /dev/null && \
if ! diff -rq "$$TMPDIR/before" internal/assets/integrations/copilot-cli/skills/ > /dev/null 2>&1; then \
echo "FAIL: Copilot CLI skills are stale — run 'make sync-copilot-skills'"; \
diff -rq "$$TMPDIR/before" internal/assets/integrations/copilot-cli/skills/ || true; \
cp -r "$$TMPDIR/before/"* internal/assets/integrations/copilot-cli/skills/; \
rm -rf "$$TMPDIR"; \
exit 1; \
fi; \
rm -rf "$$TMPDIR"; \
echo "Copilot CLI skills are in sync."
## check-why: Verify embedded why docs match source docs
check-why:
@diff -q docs/index.md internal/assets/why/manifesto.md || (echo "FAIL: manifesto.md is stale — run 'make sync-why'" && exit 1)
@diff -q docs/home/about.md internal/assets/why/about.md || (echo "FAIL: about.md is stale — run 'make sync-why'" && exit 1)
@diff -q docs/reference/design-invariants.md internal/assets/why/design-invariants.md || (echo "FAIL: design-invariants.md is stale — run 'make sync-why'" && exit 1)
@echo "Why docs are in sync."
## help: Show this help
help:
@echo "Context CLI - Available targets:"
@echo ""
@grep -E '^## ' $(MAKEFILE_LIST) | sed 's/## / /'
-include Makefile.ctx