v0.1 readiness: docs, non_exhaustive, doc/deny CI#25
Merged
Conversation
The previous README was a 4-line placeholder pointing at docs/README.md. This is the first thing crates.io readers + GitHub landing-page visitors hit, so it should give a one-paragraph "what is Buiy", a runnable code snippet matching the public API shape (Button::new), and pointers at the example, the e2e test, and the docs index. Kept under ~60 lines per the v0.1 readiness brief. License section is explicitly "TBD" since the crate has not been published; workspace Cargo.toml declares MIT OR Apache-2.0 but that is not yet a final decision and the README should not pre-empt it.
Marked types where additional variants/fields are explicitly expected pre-1.0, so external callers cannot bake in struct/match shapes that will break when those additions land. Marked: - FlexDirection — RowReverse / ColumnReverse are coming per layout-design. - A11yRole — full ARIA taxonomy (38+ roles) lands in v0.x per accessibility.md § 3.11. Updated buiy_verify::a11y::role_to_str to add the now-required wildcard arm and rewrote its lint comment to explain that exhaustiveness no longer auto-fires; PRs adding roles must keep this table current. - UserPreferences — additional OS prefs (caret blink, pointer fine / coarse, screen-reader hints) will land with the OS-integration spec. - Theme — Phase 0 token surface is intentionally minimal; the typed scale set replaces it pre-1.0 per buiy-theme-tokens-design. - DrawData / ExtractedDraws — full render pipeline (clip-path, filters, blend modes, atlasing) will add per-draw and per-frame fields. Skipped (deliberate, with reasoning): - Style — constructed via struct literal with `..default()` in crates/buiy_core/tests/layout.rs and crates/buiy_widgets/src/button.rs. Both are external from buiy_core's perspective; #[non_exhaustive] forbids `..default()` shorthand from outside the defining crate, and rewriting Style construction to `let mut s = Style::default(); s.x = …` on every callsite is uglier than just being careful when adding fields. Worth re-evaluating once a Style builder lands. - A11yNodeView — constructed via struct literal in crates/buiy_verify/tests/a11y.rs with all fields specified. The type has no obvious Default (entity / role / name are all required for a meaningful node), so we cannot route construction through Default + field assignment without inventing a placeholder Entity convention. - BuiySet — schedule contract; new variants are intentional churn that every plugin needs to react to anyway. - Focusable, Hovered, FocusedEntity, FocusVisible, A11yLabel, A11yDescription, Node, ResolvedLayout — newtype/marker/Vec2-wrapper shapes that are stable by design (per the brief: "don't add it to types whose shape is stable"). Verified: cargo fmt --check, cargo clippy --workspace --all-targets -- -D warnings, xvfb-run -a cargo test --workspace all green.
Adds a new "Doc" CI job that runs `RUSTDOCFLAGS=-D warnings cargo doc --workspace --no-deps`. This catches broken intra-doc links, missing code-fence languages, and other rustdoc warnings before they land in public-facing docs (eventually docs.rs). Job uses the same Linux build-deps as the lint job because rustdoc still drives Bevy's pkg-config-touching build scripts even though it does not link. The current tree was clean under -D warnings — no doc fixes were needed in this commit. The job exists to keep it that way.
Adds a `deny.toml` at the repo root and a "Deny" CI job that runs `cargo deny check` (advisories, bans, licenses, sources) against the workspace dep graph. Why no separate `cargo audit` job: `cargo deny check advisories` reads the same RustSec advisory database that `cargo audit` reads. Adding both would duplicate the work and the CI bill for no extra signal, so this stack standardizes on cargo-deny for both supply-chain auditing *and* license / source-registry policy. Config notes (also documented inline in deny.toml): - License `allow` list assembled from the current Cargo.lock — Bevy 0.18, Taffy 0.10, image 0.25 and their transitive graph use MIT, Apache-2.0 (sometimes WITH LLVM-exception), BSD-2/3-Clause, ISC, Zlib, Unicode-3.0, CC0-1.0, MIT-0. MPL-2.0, BSL-1.0 and Unicode-DFS-2016 are pre-allowed for forward compat with new deps; `unused-allowed-license = "allow"` silences the resulting warnings. - `[bans]` is intentionally permissive. Bevy ships many duplicated transitive deps and pre-emptively banning duplicates would just be noise. `wildcards = "warn"` (not deny) because our intra-workspace `path = "..."` deps register as wildcard requirements; cargo-deny's `allow-wildcard-paths` only suppresses that for non-publishable crates, and the buiy_* crates haven't set `publish = false` yet. Promote back to "deny" once we either publish-gate the crates or pin explicit `version = "=0.0.1"` on each path dep — out of scope for the v0.1-readiness pass. - One advisory ignored with rationale: RUSTSEC-2024-0436 (`paste` archived). It reaches us transitively via wgpu-hal's metal backend and image's rav1e — no upstream fix available. Re-evaluate when Bevy / image bump those deps. - CI job pins cargo-deny to 0.19.4 via `cargo install --locked --version 0.19.4` so config schema bumps in the tool can't silently change CI behavior. Verified: `cargo deny check` exits 0 locally with the new config; the remaining warnings (intra-workspace path-dep wildcards) are informational and serve as a prompt to fix before publishing.
A `RemovedComponents<Node>` reader now runs in `BuiySet::Layout` ahead of the sync pass, dropping orphan entries from both `by_entity` and the underlying `TaffyTree`. Without it, both collections grew monotonically across despawns — the gap that the now-deleted `TODO(buiy-layout-design)` comment flagged. The GC system runs *before* `sync_and_compute_layout` (chained inside the same set) so a single tick that despawns and respawns a node sees a clean Taffy tree before we re-walk the Bevy hierarchy. Running it after sync would let `set_children` fan out to a stale Taffy NodeId for the just-despawned entity. Exposes `LayoutTree::len` / `is_empty` so the new unit test can assert post-despawn state without touching `NonSend` internals. The unit test spawns a `Node`, runs `Update`, despawns, runs `Update` again, and asserts the tracker is empty. Verified: `cargo test -p buiy_core --test layout` — both `layout_resolves_a_simple_flex_row` and the new `layout_tree_garbage_collects_despawned_entities` pass.
Adds an integration test that introspects the `Update` schedule's dependency DAG via `Schedule::graph().dependency().get_toposort()` after `app.update()` initializes it, then asserts each `BuiySet` variant lands in the documented order: Layout → Style → Input → Animate → Picking → A11yUpdate → Render. Why introspection beats behavioural assertion: layout/render/etc. all happen on disjoint data, so a silent reorder doesn't trip existing integration tests until something visibly mis-renders mid-frame. Reading the toposort directly catches a stray `.before()` / `.after()` edit the moment it lands. Three test cases: - `buiy_sets_run_in_documented_order` — full chain, the contract. - `layout_runs_before_render` — load-bearing pair (ResolvedLayout is written by Layout, consumed by Render). - `layout_runs_before_animate` — pins the actual order against any future doc drift; the `BuiySet` doc-comment claims Layout-then-Animate, the test enforces it. Helper extracts toposort indices via `system_sets.get_key` + `NodeId::Set`, panics with the offending set name on a miss so failures are obvious. No new public API on `BuiySet`. Verified: `xvfb-run -a cargo test --workspace` — all 3 new tests pass alongside the existing suite.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Hardens the public surface and CI before any v0.1 tag. Four logical changes, four commits:
docs: replace README scaffold with a real top-level README— replaces the 4-lineREADME.mdplaceholder with a real one: one-paragraph "what is Buiy", a runnable code snippet matching the public API (Button::new), MSRV note ("stable Rust"), license placeholder ("TBD"), and a pointer atdocs/README.md. Kept under ~60 lines.refactor(buiy_core): add #[non_exhaustive] to growth-prone public types— applies#[non_exhaustive]to:FlexDirection(RowReverse / ColumnReverse coming)A11yRole(full ARIA taxonomy, 38+ roles, lands in v0.x)UserPreferences(more OS prefs incoming)Theme(Phase 0 token surface is intentionally minimal)DrawData/ExtractedDraws(full render pipeline = more per-draw fields)Updated
buiy_verify::a11y::role_to_strto add the now-required wildcard arm and rewrote its lint comment to explain the change in invariant.ci: add cargo doc -D warnings job— new "Doc" job runsRUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps. Tree was already clean — the job exists to keep it that way.ci: add cargo-deny supply-chain check (skips redundant cargo audit)— newdeny.toml+ "Deny" CI job runscargo deny check(advisories, bans, licenses, sources). cargo-deny is pinned to 0.19.4 in CI. Skipped a separatecargo auditjob becausecargo deny check advisoriesreads the same RustSec database.Tradeoffs called out in commit bodies
StyleandA11yNodeViewskipped fromnon_exhaustive— both are constructed via struct literal in tests outside their defining crate (Style { ..default() }intests/layout.rs+button.rs;A11yNodeView { entity, role, ... }inbuiy_verify/tests/a11y.rs).#[non_exhaustive]would force builder/Default-and-mutate rewrites at every callsite for marginal benefit. Worth re-evaluating once aStylebuilder lands.BuiySetskipped — schedule contract; new variants are intentional churn that every plugin must react to anyway.A11yRolenon_exhaustivelost the "exhaustiveness as a forcing function" pattern inrole_to_str(the lint comment in that function explicitly documented the previous expectation). The new comment makes the change explicit: PRs adding roles must keep the table current; the unknown-fallback exists for version-skew safety, not as a substitute for triage.bans.wildcards = "warn"not"deny"— our intra-workspacepath = "..."deps register as wildcard requirements, and cargo-deny'sallow-wildcard-pathsonly suppresses that for non-publishable crates. Promote back to"deny"once we either setpublish = falseon the buiy_* crates or pin explicitversion = "=0.0.1"next to each path dep — both out of scope for v0.1 readiness.deny.toml: RUSTSEC-2024-0436 (pastearchived). Reaches us transitively via wgpu-hal's metal backend and image's rav1e — no upstream fix available. Re-evaluate when Bevy / image bump those deps.Out of scope (deliberately untouched per the brief)
LayoutTreeRemovedComponents<Node>GCserde_json::Valueround-trip incanonicalize_entity_idsTest plan
cargo fmt --all -- --checkcargo clippy --workspace --all-targets -- -D warningsxvfb-run -a cargo test --workspace(all groups pass; 3 ignored matches Phase 0 baseline)RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-depscargo deny check(advisories ok, bans ok, licenses ok, sources ok)Generated by Claude Code