Docs: enable SPI-hosted DocC + landing page + CI guard#275
Conversation
Three pieces: 1. **`Sources/SafeDI/SafeDI.docc/SafeDI.md`** — landing page adapted from the README pitch. Overview + code sample + three-step getting started + `## Topics` organizing the auto-generated API reference into decorator macros, configuration, and delayed-instantiation types. 2. **`.spi.yml`** — opts SafeDI into Swift Package Index's DocC hosting. No platform pin (SafeDI builds on all Apple platforms, so SPI picks what works). 3. **CI `docc` job** — runs `xcodebuild docbuild` on every PR and fails when DocC emits warnings or errors inside our own files (`SafeDI.docc/` or `/Sources/SafeDI/`). Warnings from dependency packages are tolerated because DocC analyzes the whole target graph in xcodebuild mode, and swift-syntax's internal API surface has sparse doc comments that would otherwise blow up the build. `swift-docc-plugin` would scope natively but its symbol extraction trips SafeDI's `#error` trait-conflict guard; the grep-based warning filter is the pragmatic hermetic alternative. Manual.md stays intact — the SPI-hosted DocC complements it, doesn't replace it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #275 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 41 41
Lines 6796 6796
=========================================
Hits 6796 6796 🚀 New features to boost your workflow:
|
…swift-docc-plugin **Traits refactor** The old `prebuilt` + `sourceBuild` pair needed a `#error` guard to reject the both-enabled case, which turned out to be unreachable in practice and was the reason `swift-docc-plugin` (which activates all traits during plugin resolution) tripped the build. Drop the `prebuilt` trait. The remaining `sourceBuild` trait is off-by-default; when off, `SafeDIToolBinary` provides the tool. When on, the source-built `SafeDITool` target resolves the plugin's tool lookup instead. Removing the mutual-exclusion `#error` is safe because the trait values are no longer in conflict — there's nothing to be mutually-exclusive with. `SafeDIToolBinary` is now unconditional on the plugin dependency list. SPM traits can't express "when this trait is NOT active," so we trade always-linking the artifact for clean resolution in both trait states. **DocC strict mode** With no trait conflict, we can depend on swift-docc-plugin directly. That gives us `--warnings-as-errors --target SafeDI` scoping, which the `xcodebuild docbuild` path can't offer (it walks the whole graph, so swift-syntax's internal DocC noise always fails strict mode). The CI docc job drops the grep-filter post-processor and the xcodebuild docbuild invocation — the plugin's per-target scoping replaces both. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9eaf5ccc58
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ce tool Collapsing to a single `sourceBuild` trait (with `SafeDIToolBinary` unconditional) silently broke the trait's contract: SPM's `context.tool(named: \"SafeDITool\")` resolved to the prebuilt binary whose artifact bundle exposes a tool literally named `SafeDITool`, so the source-built target was never invoked even when the trait was on. Verified with a local sentinel test — generated output showed no sentinel under `--traits sourceBuild`. Restore the original `prebuilt` + `sourceBuild` trait pair, each gating their respective plugin dependency. The `#error` mutual-exclusion guard in `SafeDIConfiguration.swift` stays removed — it was the only reason `swift-docc-plugin` (which activates both traits during resolution) tripped compilation. DocC doesn't invoke build-tool plugins, so the binary-vs-source tool resolution doesn't matter during docs builds, and normal builds activate exactly one trait so resolution stays unambiguous. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
DocC doesn't compile samples, but readers who copy-paste the landing page code hit a syntax error when the body contains a literal ellipsis character. Use a block comment so the sample compiles when pasted. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Downgrade the old `#error` mutual-exclusion guard to `#warning`. The error was removed in this PR to unblock swift-docc-plugin (which activates all traits during resolution). A warning lets us still surface the misconfiguration for users who explicitly opt into both traits (e.g. `swift build --traits prebuilt,sourceBuild`) — the prebuilt binary wins the tool-name collision, so source edits are silently ignored otherwise. The warning also fires during swift-docc-plugin symbol extraction, where it's harmless — DocC doesn't invoke the SafeDIGenerator build- tool plugin. Verified `--warnings-as-errors` on the DocC plugin continues to pass (it scopes to DocC's own documentation warnings, not swift compile warnings in the source). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Turns on Swift Package Index's DocC hosting for SafeDI and adds a CI job that fails when our own doc rot creeps in. Downgrades the
prebuilt/sourceBuildmutual-exclusion#errorto a#warningso we can depend onswift-docc-plugin.Changes
Mutual-exclusion
#error→#warningThe previous `#if prebuilt && sourceBuild #error("...")` in `Sources/SafeDI/Decorators/SafeDIConfiguration.swift` tripped whenever a dependency activated all traits during resolution — notably `swift-docc-plugin`. Downgrading to `#warning` keeps the diagnostic for users who explicitly enable both (e.g. `swift build --traits prebuilt,sourceBuild`) while letting swift-docc-plugin's symbol extraction succeed.
What actually happens with both traits enabled: the prebuilt binary wins the tool-name collision (both the artifact bundle's `SafeDITool` and the source target named `SafeDITool` are visible to `context.tool(named:)`, and SPM resolves to the binary). Source edits are silently ignored. The warning tells the user about this instead of leaving it as a mystery.
Normal paths:
Sources/SafeDI/SafeDI.docc/SafeDI.mdMinimal landing page, adapted from the README pitch:
DocC harvests `///` comments for every public symbol automatically, so this one file unlocks the whole reference tree.
.spi.ymlOpts us into SPI's DocC hosting. Only `SafeDI` is documented — `SafeDIMacros` is a compiler plugin (not user-facing); `SafeDITool` is a build tool (not library). Leaving platform unpinned lets SPI build on whatever works.
CI
doccjobUses `swift-docc-plugin` directly: `swift package generate-documentation --target SafeDI --warnings-as-errors`. The plugin's per-target scoping keeps swift-syntax's internal DocC noise out of strict mode, which `xcodebuild docbuild` can't do (it walks the whole target graph).
What this doesn't do
Verification
Next steps (separate PRs)
🤖 Generated with Claude Code