Skip to content

feat: implement plinth CLI (new / doctor / version)#1

Merged
hushamsaeed merged 1 commit into
mainfrom
cli-initial
May 1, 2026
Merged

feat: implement plinth CLI (new / doctor / version)#1
hushamsaeed merged 1 commit into
mainfrom
cli-initial

Conversation

@hushamsaeed
Copy link
Copy Markdown
Contributor

Summary

  • Stdlib-only Go CLI with three subcommands: new, doctor, version.
  • plinth new <name> fetches plinth-dev/starter-{web,api} over HTTPS via GitHub's tar.gz endpoint (default ref v0.1.0), strips the codeload <repo>-<ref>/ prefix, rewrites the Go module path + bare service-name tokens, and git inits the result. Targets are <name>-api/ and <name>-web/ under --dir (default .); --module-path overrides the API module path (default github.com/example/<name>-api).
  • plinth doctor reports OK/FAIL/SKIP for go (≥1.25), git (≥2.30), node (≥20), pnpm (≥9), and docker (optional).
  • plinth version prints a Version + Commit injected at build time via -ldflags; the Makefile feeds git describe and git rev-parse --short HEAD.

Implementation notes

  • No third-party deps. Stdlib flag per subcommand; extractName pulls the positional <name> out of argv before parse so flags can come before or after.
  • Rename engine skips node_modules, .git, .next, dist, vendor, lockfiles (go.sum, pnpm-lock.yaml), and binary content (NUL-byte probe in first 8 KiB). Order-sensitive replacement: full Go module path before the bare service-name token, so github.com/plinth-dev/starter-api rewrites cleanly without corrupting github.com/plinth-dev/sdk-go/... deps.
  • Fetch extractor refuses path traversal, skips symlinks/hardlinks/devices.
  • Tests cover the rename engine (API + web fixtures, idempotency, binary skip), fetch+extract (httptest tarball fixtures + traversal rejection + non-200), the new-command happy path (both / web-only / api-only), name validation, target collisions, doctor's PASS/FAIL/SKIP states, and version printing.

End-to-end smoke

Locally scaffolded against the real plinth-dev/starter-{web,api}@v0.1.0 tags (plinth new smoketest --module-path github.com/acme/smoketest-api --no-git):

  • go vet ./... clean on the rewritten API.
  • package.json name, instrumentation-client.ts serviceName, and src/lib/env.ts SERVICE_NAME default all carry the new name; sdk-go imports untouched.

Test plan

  • CI: vet + race+cover + build smoke on Go 1.25 should pass on this branch.
  • make build && ./bin/plinth version works locally.
  • ./bin/plinth new <name> against a clean dir produces a buildable starter pair.

🤖 Generated with Claude Code

Single-binary, stdlib-only Go CLI that scaffolds modules from the
plinth-dev/starter-{web,api} tags via GitHub's tar.gz endpoint.

`plinth new <name>` fetches the starter, rewrites the Go module path
and bare service-name tokens, optionally `git init`s the result. The
rename engine skips binaries, lockfiles, and dependency dirs; the
fetch tarball extractor strips the codeload `<repo>-<ref>/` prefix
and rejects path traversal.

`plinth doctor` checks go/git/node/pnpm minimums and reports docker
as optional. `plinth version` reports a Version + Commit baked in
via -ldflags from the Makefile.

Tests cover the rename engine, fetch+extract (with httptest tarball
fixtures), the new-command happy path, name validation, target
collisions, and the doctor's PASS/FAIL/SKIP states. CI runs vet +
race+cover tests + a build smoke on Go 1.25.

End-to-end smoke against the real plinth-dev/starter-{web,api}@v0.1.0
tags scaffolds cleanly: go vet passes on the rewritten API and the
web package.json/instrumentation/env-schema all carry the new name.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hushamsaeed hushamsaeed merged commit b29def6 into main May 1, 2026
1 check passed
@hushamsaeed hushamsaeed deleted the cli-initial branch May 1, 2026 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant