Skip to content

feat(generate): add Services section to generated project README - #2934

Merged
mikeland73 merged 1 commit into
mainfrom
claude/focused-goldberg-plk85d
Sep 14, 2026
Merged

feat(generate): add Services section to generated project README#2934
mikeland73 merged 1 commit into
mainfrom
claude/focused-goldberg-plk85d

Conversation

@mikeland73

Copy link
Copy Markdown
Collaborator

Summary

Fixes #2626.

devbox generate readme produces a project README that documents the
project's scripts, packages, environment variables, and shell init
hook
— but it never mentioned services. As the issue reporter points out,
services are as central to a Devbox environment as scripts and packages, so
their absence from the generated README both hid a useful feature and left
readers unaware that services exist at all.

This PR adds a Services section to the generated README, mirroring how
Scripts are documented:

  • Lists each service available to the project. Services are gathered the same
    way the rest of the CLI gathers them — via Devbox.Services(), which combines
    plugin-provided services with any defined in the project's
    process-compose.yaml.
  • Documents how to start (devbox services up), stop (devbox services stop),
    and list (devbox services ls) services, including targeting an individual
    service by name.
  • The section is omitted entirely when the project defines no services (the
    template guards it with {{- if .Services }}), so existing service-less
    projects generate an unchanged README.

Changes

  • internal/devbox/docgen/docgen.go — pass the project's services into the
    template data (propagating any error from Devbox.Services()).
  • internal/devbox/docgen/readme.tmpl — render the new Services section.
  • testscripts/generate/readme.test.txt — new testscript that defines two
    services via a project process-compose.yaml, runs devbox generate readme,
    and asserts the generated README lists both services and documents how to
    start/stop them.

How was it tested?

  • Added testscripts/generate/readme.test.txt covering the new behavior end to
    end (devbox initdevbox generate readme → assert the Services section and
    service names are present).
  • Rendered readme.tmpl directly against a sample data map (with and without
    services) to confirm the Services section appears when services are present,
    is omitted when they are absent, and that all other sections are unchanged.
  • go build ./..., go vet ./internal/devbox/docgen/, and gofmt are clean on
    the changed files.

cc @ametad (issue reporter) — thanks for the suggestion!

Community Contribution License

All community contributions in this pull request are licensed to the project
maintainers under the terms of the
Apache 2 License.

By creating this pull request, I represent that I have the right to license the
contributions to the project maintainers under the Apache 2 License as stated in
the
Community Contribution License.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Qgu2wVkmAdXLRKcpgevoBW


Generated by Claude Code

`devbox generate readme` documented scripts, packages, environment
variables, and the shell init hook, but never mentioned services. This
made services less discoverable in a project's generated README even
though they are a first-class part of a Devbox environment.

Add a Services section to the generated README that lists each service
(from the project's plugins and its process-compose.yaml) and documents
how to start, stop, and list them. The section is omitted when the
project defines no services.

Fixes #2626

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qgu2wVkmAdXLRKcpgevoBW
@ametad

ametad commented Aug 25, 2026

Copy link
Copy Markdown

Hi @mikeland73 ,

I see you picked up some of the issues I find important as well. So, thank you 👍

Do you know what is supposed to happen now, to make it into a newer version of Devbox?

@savil
savil marked this pull request as draft September 2, 2026 22:13
@mikeland73

Copy link
Copy Markdown
Collaborator Author

@claude please review this PR for correctness, and flag anything that would block merging.

@claude

claude Bot commented Sep 14, 2026

Copy link
Copy Markdown

Claude finished @mikeland73's task in 1m 36s —— View job


Review of PR #2934 — Add Services section to generated README

  • Gather context (diff, changed files, CLAUDE.md)
  • Review docgen.go changes
  • Review readme.tmpl changes
  • Review testscript
  • Post review feedback

Verdict: No correctness issues found. Nothing here blocks merging.

This is a small, well-scoped change that mirrors the existing Scripts section pattern closely, and I couldn't find anything that would break existing behavior.

Walkthrough

  • internal/devbox/docgen/docgen.go:48-51,66 — calls devbox.Services() (the same accessor used by devbox services) and passes the result into the template data as Services. It's called before os.Create(outputPath), so if it ever errored, no partial README would be written. In practice, Devbox.Services()plugin.GetServices swallows per-plugin errors internally and always returns a nil error today, so this propagation is mostly future-proofing — harmless either way.
  • internal/devbox/docgen/readme.tmpl:36-44 — new ## Services block, guarded by {{- if .Services }} so it's omitted for service-less projects (verified no other testscript exercises devbox generate readme, so no existing golden output is affected). Services is map[string]Service; Go's text/template sorts map keys for range, so iteration order is deterministic (matches how Scripts is already handled).
  • testscripts/generate/readme.test.txt — new test defines two services via an inline process-compose.yaml, runs devbox initdevbox generate readme, and asserts the Services section, both service names, and the start/stop instructions are present. Style matches sibling tests like dockerfile.test.txt.

Minor, non-blocking observations

  • The Services template loop only prints names ({{ range $name, $_ := .Services }}), not what each service does — consistent with the minimal ask in the linked issue, but a natural follow-up if more detail is ever wanted.
  • No other generated-README consumers (templates/tests) reference .Services, so this is purely additive.

Note on verification

I wasn't able to execute go build/go vet/gofmt or run the testscript in this sandbox (bash commands beyond trivial ones required approval that wasn't available). The code was reviewed by reading the full diff and tracing devbox.Services()plugin.GetServices / services.FromUserProcessCompose, and the template logic checks out against Go's text/template semantics. The PR description states these checks were run locally and passed, which lines up with what I see in the code.

Re: making it into a release — that's a maintainer/release-process question outside what I can determine from the code; a maintainer will need to weigh in on timing.

Copy link
Copy Markdown
Collaborator Author

@mikeland73 I reviewed the diff for correctness. Verdict: the change is correct and I don't see anything in the code that blocks merging. Locally go build ./..., go vet ./internal/devbox/docgen/ ./internal/services/, and gofmt are all clean.

Correctness notes

  • docgen.go: Services() is wired into the template data; the services, err := / f, err := sequence is valid Go (compiles). Services are gathered via Devbox.Services() — the same path the rest of the CLI uses — so plugin-provided services and project process-compose.yaml services both appear, in sorted order (text/template sorts map keys, and Services() already returns a sorted map).
  • The new Services() call is effectively infallible in practice: plugin.GetServices logs and skips per-plugin errors (returns nil), and FromUserProcessCompose logs and skips parse errors. So this does not introduce a new failure mode where generate readme would fail on a project that previously generated fine. The if err != nil { return err } is defensive-only.
  • readme.tmpl: the section is guarded by {{- if .Services }}, so service-less projects generate a byte-for-byte unchanged README (an empty/nil map is falsy). Verified by rendering the template with and without services.
  • No impact on the checked-in examples/**/README.md files — those come from devbox info (plugin notes), a separate mechanism, not from this template.

What actually gates merge (process, not code)

  1. The PR is currently a draft (converted by @savil) — it can't merge until marked ready. I've deliberately left it as-is rather than flip it back.
  2. CI hasn't run against this commit yet. The cli-tests / Claude Code Review workflows trigger on pull_request, and I don't see runs for 641c48c — draft PRs typically defer them. The new testscripts/generate/readme.test.txt needs Nix (like the sibling generate testscripts), so it only exercises in CI; worth letting cli-tests run before merge.

Minor, non-blocking nit (optional)

  • The section text says services are "provided by this project's packages and plugins", but a service can also come from a user-defined process-compose.yaml. Consider "…packages, plugins, or your process-compose.yaml" for accuracy. Happy to push that wording tweak if you'd like.

Generated by Claude Code

@mikeland73 mikeland73 added the ready for human review Automated review passed; needs a maintainer to review and merge label Sep 14, 2026
@mikeland73
mikeland73 marked this pull request as ready for review September 14, 2026 16:19
@mikeland73
mikeland73 merged commit 0ab7940 into main Sep 14, 2026
27 checks passed
@mikeland73
mikeland73 deleted the claude/focused-goldberg-plk85d branch September 14, 2026 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for human review Automated review passed; needs a maintainer to review and merge

Development

Successfully merging this pull request may close these issues.

Add section about services to README.md file

3 participants