diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc4f2beeea01e..2d27e60ef8458 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -283,12 +283,14 @@ jobs: ~/.cargo/git/db/ target/ key: ${{ runner.os }}-check-doc-${{ hashFiles('**/Cargo.toml') }} - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.NIGHTLY_TOOLCHAIN }} - name: Install alsa and udev run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev - name: Build and check doc # See tools/ci/src/main.rs for the commands this runs - run: cargo run -p ci -- doc + run: cargo run -p ci -- doc-check --nightly env: CARGO_INCREMENTAL: 0 RUSTFLAGS: "-C debuginfo=0" @@ -300,6 +302,30 @@ jobs: # run: cargo deadlinks --dir target/doc/bevy # continue-on-error: true + check-doc-test: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-check-doc-test-${{ hashFiles('**/Cargo.toml') }} + - uses: dtolnay/rust-toolchain@stable + - name: Install alsa and udev + run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev + - name: Build and check doc + # See tools/ci/src/main.rs for the commands this runs + run: cargo run -p ci -- doc-test + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-C debuginfo=0" + check-missing-examples-in-docs: runs-on: ubuntu-latest timeout-minutes: 30 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 5f163f757d5e9..2400f8376d61e 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -49,10 +49,7 @@ jobs: echo "" > header.html - name: Build docs - env: - # needs to be in sync with [package.metadata.docs.rs] - RUSTDOCFLAGS: -Zunstable-options --cfg=docsrs - run: cargo doc --all-features --no-deps -p bevy -Zunstable-options -Zrustdoc-scrape-examples + run: cargo run -p ci -- doc-check --nightly --deploy-docs # This adds the following: # - A top level redirect to the bevy crate documentation diff --git a/Cargo.toml b/Cargo.toml index 019ce0c6e9059..ff79fe9808d43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1158,6 +1158,7 @@ wasm = true [[example]] name = "log_layers" path = "examples/app/log_layers.rs" +doc-scrape-examples = true [package.metadata.example.log_layers] name = "Log layers" @@ -1168,6 +1169,7 @@ wasm = false [[example]] name = "log_layers_ecs" path = "examples/app/log_layers_ecs.rs" +doc-scrape-examples = true [package.metadata.example.log_layers_ecs] name = "Advanced log layers" diff --git a/crates/bevy_winit/src/winit_config.rs b/crates/bevy_winit/src/winit_config.rs index 3400e86ba27da..674479fb6716e 100644 --- a/crates/bevy_winit/src/winit_config.rs +++ b/crates/bevy_winit/src/winit_config.rs @@ -58,6 +58,8 @@ impl Default for WinitSettings { } } +// rustdoc mistakenly thinks `App` does not need an explicit link. +#[allow(rustdoc::redundant_explicit_links)] /// Determines how frequently an [`App`](bevy_app::App) should update. /// /// **Note:** This setting is independent of VSync. VSync is controlled by a window's diff --git a/examples/2d/mesh2d.rs b/examples/2d/mesh2d.rs index e21350fcf0b39..51c2c6c5da2dd 100644 --- a/examples/2d/mesh2d.rs +++ b/examples/2d/mesh2d.rs @@ -1,6 +1,4 @@ -//! Shows how to render a polygonal [`Mesh`], generated from a [`Quad`] primitive, in a 2D scene. -//! -//! [`Quad`]: shape::Quad +//! Shows how to render a polygonal [`Mesh`], generated from a [`Rectangle`] primitive, in a 2D scene. use bevy::{color::palettes::basic::PURPLE, prelude::*, sprite::MaterialMesh2dBundle}; diff --git a/examples/2d/mesh2d_vertex_color_texture.rs b/examples/2d/mesh2d_vertex_color_texture.rs index f0a41c60c951a..654c8e118d957 100644 --- a/examples/2d/mesh2d_vertex_color_texture.rs +++ b/examples/2d/mesh2d_vertex_color_texture.rs @@ -1,7 +1,5 @@ -//! Shows how to render a polygonal [`Mesh`], generated from a [`Quad`] primitive, in a 2D scene. +//! Shows how to render a polygonal [`Mesh`], generated from a [`Rectangle`] primitive, in a 2D scene. //! Adds a texture and colored vertices, giving per-vertex tinting. -//! -//! [`Quad`]: shape::Quad use bevy::{ prelude::*, diff --git a/examples/app/log_layers_ecs.rs b/examples/app/log_layers_ecs.rs index 9c4ad4ee6e134..fe2ab0ee91faa 100644 --- a/examples/app/log_layers_ecs.rs +++ b/examples/app/log_layers_ecs.rs @@ -3,12 +3,12 @@ //! The way we will do this is via a [`mpsc`] channel. [`mpsc`] channels allow 2 unrelated //! parts of the program to communicate (in this case, [`Layer`]s and Bevy's ECS). //! -//! Inside the [`update_subscriber`] function we will create a [`mpsc::Sender`] and a [`mpsc::Receiver`] from a -//! [`mpsc::channel`]. The [`Sender`](mpsc::Sender) will go into the [`AdvancedLayer`] and the [`Receiver`](mpsc::Receiver) will -//! go into a non-send resource called [`LogEvents`] (It has to be non-send because [`Receiver`](mpsc::Receiver) is [`!Sync`](Sync)). -//! From there we will use [`transfer_log_events`] to transfer log events from [`LogEvents`] to an ECS event called [`LogEvent`]. +//! Inside the `update_subscriber` function we will create a [`mpsc::Sender`] and a [`mpsc::Receiver`] from a +//! [`mpsc::channel`]. The [`Sender`](mpsc::Sender) will go into the `AdvancedLayer` and the [`Receiver`](mpsc::Receiver) will +//! go into a non-send resource called `LogEvents` (It has to be non-send because [`Receiver`](mpsc::Receiver) is [`!Sync`](Sync)). +//! From there we will use `transfer_log_events` to transfer log events from `LogEvents` to an ECS event called `LogEvent`. //! -//! Finally, after all that we can access the [`LogEvent`] event from our systems and use it. +//! Finally, after all that we can access the `LogEvent` event from our systems and use it. //! In this example we build a simple log viewer. use std::sync::mpsc; @@ -32,7 +32,7 @@ struct LogEvent { #[derive(Deref, DerefMut)] struct CapturedLogEvents(mpsc::Receiver); -/// Transfers information from the [`LogEvents`] resource to [`Events`](LogEvent). +/// Transfers information from the `LogEvents` resource to [`Events`](LogEvent). fn transfer_log_events( receiver: NonSend, mut log_events: EventWriter, @@ -77,6 +77,7 @@ impl tracing::field::Visit for CaptureLayerVisitor<'_> { } } } + fn update_subscriber(app: &mut App, subscriber: BoxedSubscriber) -> BoxedSubscriber { let (sender, receiver) = mpsc::channel(); diff --git a/examples/asset/asset_decompression.rs b/examples/asset/asset_decompression.rs index f003471a72bb7..13bbb0d05895c 100644 --- a/examples/asset/asset_decompression.rs +++ b/examples/asset/asset_decompression.rs @@ -24,7 +24,7 @@ struct GzAssetLoader; /// Possible errors that can be produced by [`GzAssetLoader`] #[non_exhaustive] #[derive(Debug, Error)] -pub enum GzAssetLoaderError { +enum GzAssetLoaderError { /// An [IO](std::io) Error #[error("Could not load asset: {0}")] Io(#[from] std::io::Error), diff --git a/examples/asset/custom_asset.rs b/examples/asset/custom_asset.rs index b3167bbd1d8bb..31e75414a8762 100644 --- a/examples/asset/custom_asset.rs +++ b/examples/asset/custom_asset.rs @@ -20,7 +20,7 @@ struct CustomAssetLoader; /// Possible errors that can be produced by [`CustomAssetLoader`] #[non_exhaustive] #[derive(Debug, Error)] -pub enum CustomAssetLoaderError { +enum CustomAssetLoaderError { /// An [IO](std::io) Error #[error("Could not load asset: {0}")] Io(#[from] std::io::Error), @@ -58,10 +58,10 @@ struct Blob { #[derive(Default)] struct BlobAssetLoader; -/// Possible errors that can be produced by [`CustomAssetLoader`] +/// Possible errors that can be produced by [`BlobAssetLoader`] #[non_exhaustive] #[derive(Debug, Error)] -pub enum BlobAssetLoaderError { +enum BlobAssetLoaderError { /// An [IO](std::io) Error #[error("Could not load file: {0}")] Io(#[from] std::io::Error), diff --git a/examples/asset/processing/asset_processing.rs b/examples/asset/processing/asset_processing.rs index f99fc4769a4ca..41f9af1e1b512 100644 --- a/examples/asset/processing/asset_processing.rs +++ b/examples/asset/processing/asset_processing.rs @@ -51,7 +51,7 @@ fn main() { /// It also defines an asset processor that will load [`CoolText`], resolve embedded dependencies, and write the resulting /// output to a "normal" plain text file. When the processed asset is loaded, it is loaded as a Text (plaintext) asset. /// This illustrates that when you process an asset, you can change its type! However you don't _need_ to change the type. -pub struct TextPlugin; +struct TextPlugin; impl Plugin for TextPlugin { fn build(&self, app: &mut App) { diff --git a/examples/ecs/custom_query_param.rs b/examples/ecs/custom_query_param.rs index 4df666bf337e5..43b02df732527 100644 --- a/examples/ecs/custom_query_param.rs +++ b/examples/ecs/custom_query_param.rs @@ -1,4 +1,4 @@ -//! This example illustrates the usage of the [`WorldQuery`] derive macro, which allows +//! This example illustrates the usage of the [`QueryData`] derive macro, which allows //! defining custom query and filter types. //! //! While regular tuple queries work great in most of simple scenarios, using custom queries @@ -10,7 +10,7 @@ //! - Named structs enable the composition pattern, that makes query types easier to re-use. //! - You can bypass the limit of 15 components that exists for query tuples. //! -//! For more details on the `WorldQuery` derive macro, see the trait documentation. +//! For more details on the [`QueryData`] derive macro, see the trait documentation. use bevy::{ ecs::query::{QueryData, QueryFilter}, @@ -77,11 +77,11 @@ fn print_components_read_only( println!(); } -// If you are going to mutate the data in a query, you must mark it with the `mutable` attribute. -// The `WorldQuery` derive macro will still create a read-only version, which will be have `ReadOnly` -// suffix. -// Note: if you want to use derive macros with read-only query variants, you need to pass them with -// using the `derive` attribute. +/// If you are going to mutate the data in a query, you must mark it with the `mutable` attribute. +/// The [`QueryData`] derive macro will still create a read-only version, which will be have `ReadOnly` +/// suffix. +/// Note: if you want to use derive macros with read-only query variants, you need to pass them with +/// using the `derive` attribute. #[derive(QueryData)] #[query_data(mutable, derive(Debug))] struct CustomQuery { diff --git a/src/lib.rs b/src/lib.rs index 6c90ff1a0b903..9ceedc72f458c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,7 @@ +#![doc( + html_logo_url = "https://bevyengine.org/assets/icon.png", + html_favicon_url = "https://bevyengine.org/assets/icon.png" +)] #![allow(clippy::single_component_path_imports)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] @@ -40,11 +44,8 @@ //! If you prefer, you can also consume the individual bevy crates directly. //! Each module in the root of this crate, except for the prelude, can be found on crates.io //! with `bevy_` appended to the front, e.g. `app` -> [`bevy_app`](https://docs.rs/bevy_app/*/bevy_app/). + #![doc = include_str!("../docs/cargo_features.md")] -#![doc( - html_logo_url = "https://bevyengine.org/assets/icon.png", - html_favicon_url = "https://bevyengine.org/assets/icon.png" -)] pub use bevy_internal::*; diff --git a/tools/ci/src/main.rs b/tools/ci/src/main.rs index 617f96f7f7da8..dcfdafe95357c 100644 --- a/tools/ci/src/main.rs +++ b/tools/ci/src/main.rs @@ -24,7 +24,9 @@ bitflags! { bitflags! { #[derive(Clone, Copy, Debug, PartialEq, Eq)] struct Flag: u32 { - const KEEP_GOING = 0b00000001; + const NIGHTLY = 0b00000001; + const KEEP_GOING = 0b00000010; + const DEPLOY_DOCS = 0b00000100; } } @@ -68,7 +70,11 @@ fn main() { ("doc-test", Check::DOC_TEST), ]; - let flag_arguments = [("--keep-going", Flag::KEEP_GOING)]; + let flag_arguments = [ + ("--nightly", Flag::KEEP_GOING), + ("--keep-going", Flag::KEEP_GOING), + ("--deploy-docs", Flag::DEPLOY_DOCS), + ]; // Parameters are parsed disregarding their order. Note that the first arg is generally the name of // the executable, so it is ignored. Any parameter may either be a flag or the name of a battery of tests @@ -221,12 +227,23 @@ fn main() { if checks.contains(Check::DOC_CHECK) { // Check that building docs work and does not emit warnings - let mut args = vec![ - "--workspace", - "--all-features", - "--no-deps", - "--document-private-items", - ]; + let mut args = vec!["--workspace", "--all-features", "--no-deps"]; + let mut rust_doc_flags = "-D warnings"; + let mut docs_type = vec!["doc"]; + + if flags.contains(Flag::NIGHTLY) { + docs_type.insert(0, "+nightly"); + rust_doc_flags = "-D warnings -Zunstable-options --cfg=docsrs"; + args.push("-Zunstable-options"); + args.push("-Zrustdoc-scrape-examples"); + } + + if flags.contains(Flag::DEPLOY_DOCS) { + args.remove(args.iter().position(|&arg| arg == "--workspace").unwrap()); + args.push("-p"); + args.push("bevy"); + } + if flags.contains(Flag::KEEP_GOING) { args.push("--keep-going"); } @@ -234,10 +251,10 @@ fn main() { test_suite.insert( Check::DOC_CHECK, vec![CITest { - command: cmd!(sh, "cargo doc {args...}"), + command: cmd!(sh, "cargo {docs_type...} {args...}"), failure_message: "Please fix doc warnings in output above.", subdir: None, - env_vars: vec![("RUSTDOCFLAGS", "-D warnings")], + env_vars: vec![("RUSTDOCFLAGS", rust_doc_flags)], }], ); } @@ -296,7 +313,7 @@ fn main() { ); } - if checks.contains(Check::CFG_CHECK) { + if checks.contains(Check::CFG_CHECK) && flags.contains(Flag::NIGHTLY) { // Check cfg and imports let mut args = vec!["-Zcheck-cfg", "--workspace"]; if flags.contains(Flag::KEEP_GOING) {