Skip to content

Format detailed help using markdown and auto-generate reference docs#14

Open
adamwg wants to merge 2 commits into
crossplane:mainfrom
adamwg:awg/docsdocsdocs
Open

Format detailed help using markdown and auto-generate reference docs#14
adamwg wants to merge 2 commits into
crossplane:mainfrom
adamwg:awg/docsdocsdocs

Conversation

@adamwg
Copy link
Copy Markdown
Member

@adamwg adamwg commented May 15, 2026

Description of your changes

Use the glamour library to render detailed help text using markdown. This makes it more ergonomic to write extensive help text and gives us lots of flexibility in how it's formatted. Define custom light and dark stylesheets based on glamour's defaults, using Crossplane brand colors for common elements.

With markdown-formatted help in place, we can add crossplane generate-docs, which generates a markdown file following the format of the existing CLI reference page in crossplane/docs. The generated file includes full help (summary, details, flags, etc.) for all commands. This will let us keep the reference docs up-to-date without manual toil.

I have:

adamwg added 2 commits May 15, 2026 13:43
Use the glamour library to render detailed help text using markdown. This makes
it more ergonomic to write extensive help text and gives us lots of flexibility
in how it's formatted.

Define custom light and dark stylesheets based on glamour's defaults, using
Crossplane brand colors for common elements.

Signed-off-by: Adam Wolfe Gordon <awg@upbound.io>
Add `crossplane generate-docs`, which generates a markdown file following the
format of the existing CLI reference page in crossplane/docs. The generated file
includes full help (summary, details, flags, etc.) for all commands.

Signed-off-by: Adam Wolfe Gordon <awg@upbound.io>
@adamwg adamwg requested review from a team, jcogilvie and tampakrap as code owners May 15, 2026 19:56
@adamwg adamwg requested review from haarchri and removed request for a team May 15, 2026 19:56
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR externalizes hard-coded command help text into embedded Markdown files and implements a custom Kong help printer with terminal-aware styling. A hidden docs generator subcommand produces a command-reference.md from the command tree.

Changes

Help Text Externalization and Markdown Rendering

Layer / File(s) Summary
Help rendering infrastructure
cmd/crossplane/help.go, internal/style/style.go
Custom Kong help printer renders markdown-formatted help with columnar command lists and two-column flag/positional tables. Terminal-aware RenderMarkdown selects dark/light embedded styles based on terminal background or falls back to ASCII style for non-TTY output.
Top-level CLI setup and docs generation
cmd/crossplane/main.go, cmd/crossplane/help.md, cmd/crossplane/docs.go
Main binds the custom help printer, embeds top-level help content, wires help/usage handling through Kong, and registers a hidden GenerateDocs subcommand that traverses the command tree, normalizes help markdown for Hugo themes (demoting headings, converting blockquote patterns to shortcodes, wrapping tables), and writes command-reference.md.
Config and Convert command help
cmd/crossplane/config/config.go, cmd/crossplane/config/help/config.md, cmd/crossplane/convert/convert.go, cmd/crossplane/convert/help/convert.md, cmd/crossplane/convert/compositionenvironment/cmd.go, cmd/crossplane/convert/compositionenvironment/help/composition-environment.md
Config and Convert base commands embed help.md files describing config file precedence and supported conversions. The composition-environment subcommand documents the migration to function-environment-configs via embedded help.
Render command help (operation and XR)
cmd/crossplane/render/op/cmd.go, cmd/crossplane/render/op/help/render.md, cmd/crossplane/render/xr/cmd.go, cmd/crossplane/render/xr/help/render.md
Render operation and XR subcommands embed comprehensive help covering Docker-based Function execution, runtime configuration (annotations, environment variables), pipeline context/output options (context files, function results, observed resources), and detailed CLI examples for version pinning, local binary execution, and runtime overrides.
Top and Trace command help
cmd/crossplane/top/top.go, cmd/crossplane/top/help/top.md, cmd/crossplane/trace/trace.go, cmd/crossplane/trace/help/trace.md
Top command embeds help describing Kubernetes Metrics Server dependency and resource utilization reporting with -n and -s examples. Trace command embeds help documenting resource relationship tracing, output modes (tree, wide, JSON, YAML, Graphviz dot), and flags for secrets, package dependencies/revisions.
Validate command help
cmd/crossplane/validate/cmd.go, cmd/crossplane/validate/help/validate.md
Validate command embeds help describing offline schema validation against XRDs, CRDs, Providers, Functions, and Configurations; provider/configuration caching behavior; supported modes (direct schema, composition render output, CEL rules, schema directories); and cache customization options.
Xpkg command family help
cmd/crossplane/xpkg/build.go, cmd/crossplane/xpkg/help/build.md, cmd/crossplane/xpkg/init.go, cmd/crossplane/xpkg/help/init.md, cmd/crossplane/xpkg/install.go, cmd/crossplane/xpkg/help/install.md, cmd/crossplane/xpkg/push.go, cmd/crossplane/xpkg/help/push.md, cmd/crossplane/xpkg/update.go, cmd/crossplane/xpkg/help/update.md, cmd/crossplane/xpkg/xpkg.go, cmd/crossplane/xpkg/help/xpkg.md
All xpkg subcommands embed Markdown help: build describes packaging YAML manifests with runtime embedding options; init explains template initialization and init.sh execution; install documents control-plane connectivity, --wait blocking, manual activation, and pull secrets; push describes OCI registry publishing; update covers version upgrades; xpkg base explains package concepts and types.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and descriptively summarizes the main changes: formatting detailed help with markdown and auto-generating reference docs, which aligns with the primary objectives of the changeset.
Description check ✅ Passed The description is directly related to the changeset, explaining the use of glamour for markdown rendering, custom stylesheets, and the new generate-docs command that the PR implements.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Breaking Changes ✅ Passed No breaking changes detected. Help() methods have updated implementations but identical signatures. New exports are additive only. No public fields/flags removed, renamed, or made required.
Feature Gate Requirement ✅ Passed PR introduces no experimental API changes or core behavior modifications requiring feature gates. Help rendering enhancement has graceful fallback; new internal command is hidden.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cmd/crossplane/xpkg/help/xpkg.md (1)

12-12: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove or clarify the stray "12" on line 12.

Line 12 contains only the text "12", which appears to be a stray artifact or line number. This should either be removed or replaced with valid content if something is missing.

📝 Proposed fix
 See [the Crossplane packages
 documentation](https://docs.crossplane.io/latest/concepts/packages) for more
 information.
-12

As per coding guidelines: Ensure Markdown files follow proper structure and are helpful for users.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/crossplane/xpkg/help/xpkg.md` at line 12, Remove the stray "12" text
found on line 12 of xpkg.md (the orphaned numeric artifact) — either delete that
line entirely or replace it with the intended heading/content if something was
accidentally removed; ensure the resulting Markdown has valid structure and
reads correctly for the xpkg help page.
🧹 Nitpick comments (2)
cmd/crossplane/trace/help/trace.md (1)

42-42: 💤 Low value

Consider wrapping this shell command to comply with the 100-column guideline.

This line exceeds 100 characters. As per coding guidelines, Markdown files should wrap at 100 columns (longer lines are only allowed for links to improve readability).

You could wrap it with a backslash continuation:

crossplane resource trace cluster.aws.platformref.upbound.io \
  platform-ref-aws -o dot | dot -Tpng -o graph.png

However, I recognize there's a trade-off here — single-line shell commands are easier to copy-paste. If you feel the copy-paste convenience outweighs strict guideline compliance for this example, that's understandable. What's your preference?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/crossplane/trace/help/trace.md` at line 42, The example shell command in
the trace.md code block exceeds the 100-column guideline; update the code block
to wrap the long command (the line containing "crossplane resource trace
cluster.aws.platformref.upbound.io platform-ref-aws -o dot | dot -Tpng -o
graph.png") using a shell continuation (backslash) or by breaking before the
pipe into two indented lines so the rendered Markdown stays within 100 columns
while preserving exact command semantics for copy-paste.
cmd/crossplane/render/op/help/render.md (1)

1-12: ⚡ Quick win

Could we confirm top-level heading behavior for this help page?

Really nice intro section. Quick check: does the help renderer inject the command title automatically? If not,
adding an H1 would make heading structure clearer for direct Markdown consumption.

As per coding guidelines, "Check for proper heading structure, clear language, and that documentation is
helpful for users."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/crossplane/render/op/help/render.md` around lines 1 - 12, Confirm whether
the help renderer auto-injects the command title for the "operation render" help
page; if it does not, add a top-level H1 (e.g., "operation render" or "Operation
Render") at the start of cmd/crossplane/render/op/help/render.md so the document
has a clear heading hierarchy; update the file header and run the help renderer
locally to verify the final rendered output includes a single top-level heading
and that downstream tooling still formats the page correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@cmd/crossplane/convert/compositionenvironment/help/composition-environment.md`:
- Around line 16-17: Update the example command invocations that incorrectly
include an extra "composition" token: replace every occurrence of the string
"crossplane composition convert composition-environment" with the correct
"crossplane convert composition-environment" in the composition-environment.md
examples (the three examples that show piping, stdout and
--function-environment-configs-ref usage); ensure the changed command appears
consistently in the examples that currently read "cat composition.yaml |
crossplane composition convert composition-environment" and in the two multiline
examples that begin with "crossplane composition convert composition-environment
composition.yaml \".
- Around line 1-2: The description text currently uses the incorrect command
name "composition convert composition-environment"; update that phrase to the
correct command name "crossplane convert composition-environment" (or simply
"convert composition-environment" in context) wherever it appears in the README
text to accurately reflect the CLI invocation for converting a Composition to
use function-environment-configs.

In `@cmd/crossplane/convert/help/convert.md`:
- Around line 1-2: Update the description to correctly reference the command
name and avoid confusion: change the sentence that currently says "The
`composition convert` command" so it either says "The `crossplane convert`
command converts a Crossplane composition..." or "The `convert` command converts
a Crossplane composition..." (keeping "composition" as the object, not part of
the command name). Edit the sentence in convert.md so the command identifier is
`crossplane convert` or `convert` and the rest of the sentence clarifies it
operates on compositions.

In `@cmd/crossplane/help.go`:
- Around line 244-248: newHelpWriter currently ignores the error returned by
term.GetSize which can yield wrapWidth==0 and break wrapping; modify the call in
newHelpWriter to capture the error from term.GetSize and provide a sensible
fallback (e.g., 80) when GetSize returns an error or width==0, then apply
min(wrapWidth, 120) as before so downstream calls like doc.ToText receive a
valid positive width.

In `@cmd/crossplane/render/op/help/render.md`:
- Around line 19-25: The table rows for annotation keys (e.g.,
render.crossplane.io/runtime, render.crossplane.io/runtime-development-target,
render.crossplane.io/runtime-docker-cleanup,
render.crossplane.io/runtime-docker-name,
render.crossplane.io/runtime-docker-pull-policy,
render.crossplane.io/runtime-docker-publish-address,
render.crossplane.io/runtime-docker-target) exceed 100 columns; reflow those
entries so no source line is longer than 100 chars by either converting each
table row to wrapped bullet points or splitting long cell content into multiple
shorter sentences/lines, ensuring each annotation key stays present and its
description is wrapped to <=100 columns while preserving the meaning and
examples (like localhost:9443, dns:///example.org:7443, 0.0.0.0,
Always/Never/IfNotPresent).

In `@cmd/crossplane/xpkg/help/install.md`:
- Around line 49-53: The long shell command in the install example exceeds 100
columns; update the example in install.md so the command is split with a
backslash continuation: put "crossplane xpkg install provider" on the first line
and break the package identifier onto the next indented line with the backslash
(preserving the "--wait=1m" flag at the end), matching the proposed fix style so
the block stays within the 100-column guideline.

In `@internal/style/style.go`:
- Around line 33-36: RenderMarkdown currently calls term.GetSize and passes
wrapWidth directly to glamour.WithWordWrap, but if term.GetSize fails wrapWidth
can be 0 which breaks wrapping; update RenderMarkdown to check the returned
wrapWidth from term.GetSize (in function RenderMarkdown) and if it's <= 0 or an
error occurred, set a sensible fallback (e.g. 80 or 120) before calling
glamour.WithWordWrap so word wrapping never receives 0.

---

Outside diff comments:
In `@cmd/crossplane/xpkg/help/xpkg.md`:
- Line 12: Remove the stray "12" text found on line 12 of xpkg.md (the orphaned
numeric artifact) — either delete that line entirely or replace it with the
intended heading/content if something was accidentally removed; ensure the
resulting Markdown has valid structure and reads correctly for the xpkg help
page.

---

Nitpick comments:
In `@cmd/crossplane/render/op/help/render.md`:
- Around line 1-12: Confirm whether the help renderer auto-injects the command
title for the "operation render" help page; if it does not, add a top-level H1
(e.g., "operation render" or "Operation Render") at the start of
cmd/crossplane/render/op/help/render.md so the document has a clear heading
hierarchy; update the file header and run the help renderer locally to verify
the final rendered output includes a single top-level heading and that
downstream tooling still formats the page correctly.

In `@cmd/crossplane/trace/help/trace.md`:
- Line 42: The example shell command in the trace.md code block exceeds the
100-column guideline; update the code block to wrap the long command (the line
containing "crossplane resource trace cluster.aws.platformref.upbound.io
platform-ref-aws -o dot | dot -Tpng -o graph.png") using a shell continuation
(backslash) or by breaking before the pipe into two indented lines so the
rendered Markdown stays within 100 columns while preserving exact command
semantics for copy-paste.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9c355fe3-594b-47db-95b1-77b409a66889

📥 Commits

Reviewing files that changed from the base of the PR and between aea2a5b and 339e408.

⛔ Files ignored due to path filters (6)
  • cmd/crossplane/docs-templates/command-reference.md.tmpl is excluded by none and included by none
  • go.mod is excluded by none and included by none
  • go.sum is excluded by !**/*.sum and included by none
  • gomod2nix.toml is excluded by none and included by none
  • internal/style/dark.json is excluded by none and included by none
  • internal/style/light.json is excluded by none and included by none
📒 Files selected for processing (33)
  • cmd/crossplane/config/config.go
  • cmd/crossplane/config/help/config.md
  • cmd/crossplane/convert/compositionenvironment/cmd.go
  • cmd/crossplane/convert/compositionenvironment/help/composition-environment.md
  • cmd/crossplane/convert/convert.go
  • cmd/crossplane/convert/help/convert.md
  • cmd/crossplane/docs.go
  • cmd/crossplane/help.go
  • cmd/crossplane/help.md
  • cmd/crossplane/main.go
  • cmd/crossplane/render/op/cmd.go
  • cmd/crossplane/render/op/help/render.md
  • cmd/crossplane/render/xr/cmd.go
  • cmd/crossplane/render/xr/help/render.md
  • cmd/crossplane/top/help/top.md
  • cmd/crossplane/top/top.go
  • cmd/crossplane/trace/help/trace.md
  • cmd/crossplane/trace/trace.go
  • cmd/crossplane/validate/cmd.go
  • cmd/crossplane/validate/help/validate.md
  • cmd/crossplane/xpkg/build.go
  • cmd/crossplane/xpkg/help/build.md
  • cmd/crossplane/xpkg/help/init.md
  • cmd/crossplane/xpkg/help/install.md
  • cmd/crossplane/xpkg/help/push.md
  • cmd/crossplane/xpkg/help/update.md
  • cmd/crossplane/xpkg/help/xpkg.md
  • cmd/crossplane/xpkg/init.go
  • cmd/crossplane/xpkg/install.go
  • cmd/crossplane/xpkg/push.go
  • cmd/crossplane/xpkg/update.go
  • cmd/crossplane/xpkg/xpkg.go
  • internal/style/style.go

Comment thread cmd/crossplane/convert/help/convert.md
Comment thread cmd/crossplane/help.go
Comment thread cmd/crossplane/render/op/help/render.md
Comment thread cmd/crossplane/xpkg/help/install.md
Comment thread internal/style/style.go
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.

2 participants