diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea55cbae41..56b5ba469c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,3 +34,20 @@ jobs: BUILD_DIR: . BUILD_ONLY: true TOKEN: fake-secret + + test-code: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + components: rustfmt, clippy + override: true + + - name: Install alsa and udev + run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev + + - name: Build & run tests + run: cd code-validation && cargo test diff --git a/.gitignore b/.gitignore index c18a0ec267..a01e7c0a9a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ public content/assets content/learn/errors content/examples +code-validation/target +code-validation/Cargo.lock diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f571c1b341..54a194534c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -147,3 +147,5 @@ When writing and reviewing learning material for the Bevy Book and Quick Start G 8. Examples should not use or rely on third-party plugins. These may be appropriate to link in "next steps" however at the end of the examples. 1. Third-party crates should be limited to the most essential, such as `rand`. +9. If additional code block attributes like `no_run` or `hide-lines=x-y` need to be specified, you should always order these so that the language is the last attribute. If we would specify `rust,no_run` the syntax highlighting wouldn't work, but changing it to `no_run,rust` makes it work. +10. To validate if local code changes are compiling you can `cd` into the `code-validation` folder and test your code using `cargo test`. diff --git a/code-validation/Cargo.toml b/code-validation/Cargo.toml new file mode 100644 index 0000000000..5755191513 --- /dev/null +++ b/code-validation/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "code-validation" +version = "0.1.0" +edition = "2021" + +[dependencies] +bevy = "0.6.0" diff --git a/code-validation/rustfmt.toml b/code-validation/rustfmt.toml new file mode 100644 index 0000000000..a4607a5fa4 --- /dev/null +++ b/code-validation/rustfmt.toml @@ -0,0 +1,2 @@ +use_field_init_shorthand = true +newline_style = "Unix" diff --git a/code-validation/src/lib.rs b/code-validation/src/lib.rs new file mode 100644 index 0000000000..2c92a6b3b8 --- /dev/null +++ b/code-validation/src/lib.rs @@ -0,0 +1,170 @@ +//! This crate is used to validate the rust code of the `bevy` website. +//! +//! It is currently used to validate the rust code of the offical `bevy` book. +//! The modules represents the folder structure of the website. + +mod learn { + #[doc = include_str!("../../content/learn/book/_index.md")] + mod book { + #[doc = include_str!("../../content/learn/book/assets/_index.md")] + mod assets { + #[doc = include_str!("../../content/learn/book/assets/custom-assets/_index.md")] + mod custom_assets {} + #[doc = include_str!("../../content/learn/book/assets/hot-reloading/_index.md")] + mod hot_reloading {} + #[doc = include_str!("../../content/learn/book/assets/loading-assets/_index.md")] + mod loading_assets {} + #[doc = include_str!("../../content/learn/book/assets/scenes/_index.md")] + mod scenes {} + #[doc = include_str!("../../content/learn/book/assets/working-with-handles/_index.md")] + mod working_with_handles {} + } + + #[doc = include_str!("../../content/learn/book/audio/_index.md")] + mod audio { + #[doc = include_str!("../../content/learn/book/audio/audio-basics/_index.md")] + mod audio_basics {} + } + + #[doc = include_str!("../../content/learn/book/development-practices/_index.md")] + mod development_practices { + #[doc = include_str!("../../content/learn/book/development-practices/boilerplate-reduction/_index.md")] + mod boilerplate_reduction {} + #[doc = include_str!("../../content/learn/book/development-practices/error-handling/_index.md")] + mod error_handling {} + #[doc = include_str!("../../content/learn/book/development-practices/fast-compiles/_index.md")] + mod fast_compiles {} + #[doc = include_str!("../../content/learn/book/development-practices/organizing-your-code/_index.md")] + mod organizing_your_code {} + #[doc = include_str!("../../content/learn/book/development-practices/testing/_index.md")] + mod testing {} + } + + #[doc = include_str!("../../content/learn/book/ecs/_index.md")] + mod ecs { + #[doc = include_str!("../../content/learn/book/ecs/commands/_index.md")] + mod commands {} + #[doc = include_str!("../../content/learn/book/ecs/entities-components/_index.md")] + mod entities_components {} + #[doc = include_str!("../../content/learn/book/ecs/exclusive-world-access/_index.md")] + mod exclusive_world_access {} + #[doc = include_str!("../../content/learn/book/ecs/filtering-queries/_index.md")] + mod filtering_queries {} + #[doc = include_str!("../../content/learn/book/ecs/generic-systems/_index.md")] + mod generic_systems {} + #[doc = include_str!("../../content/learn/book/ecs/reliable-change-detection/_index.md")] + mod reliable_change_detection {} + #[doc = include_str!("../../content/learn/book/ecs/resources/_index.md")] + mod resources {} + #[doc = include_str!("../../content/learn/book/ecs/systems-queries/_index.md")] + mod system_queries {} + } + + #[doc = include_str!("../../content/learn/book/game-logic/_index.md")] + mod game_logic { + #[doc = include_str!("../../content/learn/book/game-logic/async-tasks/_index.md")] + mod async_tasks {} + #[doc = include_str!("../../content/learn/book/game-logic/custom-execution/_index.md")] + mod custom_execution {} + #[doc = include_str!("../../content/learn/book/game-logic/events/_index.md")] + mod events {} + #[doc = include_str!("../../content/learn/book/game-logic/run-criteria/_index.md")] + mod run_criteria {} + #[doc = include_str!("../../content/learn/book/game-logic/states/_index.md")] + mod states {} + #[doc = include_str!("../../content/learn/book/game-logic/system-ordering/_index.md")] + mod system_ordering {} + #[doc = include_str!("../../content/learn/book/game-logic/time/_index.md")] + mod time {} + } + + #[doc = include_str!("../../content/learn/book/graphics/_index.md")] + mod graphics { + #[doc = include_str!("../../content/learn/book/graphics/2d/_index.md")] + mod two_dimensional { + #[doc = include_str!("../../content/learn/book/graphics/2d/sprite-sheets/_index.md")] + mod sprite_sheets {} + #[doc = include_str!("../../content/learn/book/graphics/2d/sprites/_index.md")] + mod sprites {} + } + #[doc = include_str!("../../content/learn/book/graphics/3d/_index.md")] + mod three_dimensional { + #[doc = include_str!("../../content/learn/book/graphics/3d/meshes/_index.md")] + mod meshes {} + #[doc = include_str!("../../content/learn/book/graphics/3d/pbr/_index.md")] + mod pbr {} + } + #[doc = include_str!("../../content/learn/book/graphics/cameras/_index.md")] + mod cameras {} + #[doc = include_str!("../../content/learn/book/graphics/parent-child-hierarchy/_index.md")] + mod parent_child_hierarchy {} + #[doc = include_str!("../../content/learn/book/graphics/rendering-internals/_index.md")] + mod rendering_internals { + #[doc = include_str!("../../content/learn/book/graphics/rendering-internals/shader-basics/_index.md")] + mod shader_basics {} + } + #[doc = include_str!("../../content/learn/book/graphics/transforms/_index.md")] + mod transforms {} + #[doc = include_str!("../../content/learn/book/graphics/windowing/_index.md")] + mod windowing {} + } + + #[doc = include_str!("../../content/learn/book/input/_index.md")] + mod input { + #[doc = include_str!("../../content/learn/book/input/gamepad/_index.md")] + mod gamepad {} + #[doc = include_str!("../../content/learn/book/input/input-basics/_index.md")] + mod input_basics {} + #[doc = include_str!("../../content/learn/book/input/keyboard/_index.md")] + mod keyboard {} + #[doc = include_str!("../../content/learn/book/input/mouse/_index.md")] + mod mouse {} + #[doc = include_str!("../../content/learn/book/input/touch/_index.md")] + mod touch {} + } + + // Not testing migration guides, because of breaking api changes. + mod migration_guides {} + + #[doc = include_str!("../../content/learn/book/next-steps/_index.md")] + mod next_steps {} + + #[doc = include_str!("../../content/learn/book/performance-optimizations/_index.md")] + mod performance_optimizations { + #[doc = include_str!("../../content/learn/book/performance-optimizations/component-storage/_index.md")] + mod component_storage {} + #[doc = include_str!("../../content/learn/book/performance-optimizations/diagnostics-benchmarking/_index.md")] + mod diagnostics_benchmarking {} + #[doc = include_str!("../../content/learn/book/performance-optimizations/indexes/_index.md")] + mod indexes {} + #[doc = include_str!("../../content/learn/book/performance-optimizations/parallel-iteration/_index.md")] + mod parallel_iteration {} + } + + #[doc = include_str!("../../content/learn/book/platforms/_index.md")] + mod platforms { + #[doc = include_str!("../../content/learn/book/platforms/android/_index.md")] + mod android {} + #[doc = include_str!("../../content/learn/book/platforms/ios/_index.md")] + mod ios {} + #[doc = include_str!("../../content/learn/book/platforms/web/_index.md")] + mod web {} + } + + #[doc = include_str!("../../content/learn/book/ui/_index.md")] + mod ui { + #[doc = include_str!("../../content/learn/book/ui/ui-basics/_index.md")] + mod ui_basics {} + } + + #[doc = include_str!("../../content/learn/book/welcome/_index.md")] + mod welcome { + #[doc = include_str!("../../content/learn/book/welcome/apps/_index.md")] + mod apps {} + #[doc = include_str!("../../content/learn/book/welcome/plugins/_index.md")] + mod plugins {} + #[doc = include_str!("../../content/learn/book/welcome/setup/_index.md")] + mod setup {} + } + } +} diff --git a/content/learn/book/audio/audio_basics/_index.md b/content/learn/book/audio/audio-basics/_index.md similarity index 100% rename from content/learn/book/audio/audio_basics/_index.md rename to content/learn/book/audio/audio-basics/_index.md diff --git a/content/learn/book/ui/ui_basics/_index.md b/content/learn/book/ui/ui-basics/_index.md similarity index 100% rename from content/learn/book/ui/ui_basics/_index.md rename to content/learn/book/ui/ui-basics/_index.md diff --git a/content/learn/book/welcome/apps/_index.md b/content/learn/book/welcome/apps/_index.md index 2b16d38dc5..62217059bc 100644 --- a/content/learn/book/welcome/apps/_index.md +++ b/content/learn/book/welcome/apps/_index.md @@ -13,16 +13,16 @@ The process is straightforward: we first create a new [`App`]. Then, we add a simple system, which prints "Hello, Bevy!" when it is run. Finally once we're done configuring the app, we call [`App`] to actually make our app *do things*. -```rust +```no_run,rust use bevy::prelude::*; -fn main(){ +fn main() { App::new() .add_system(hello) .run(); } -fn hello(){ +fn hello() { println!("Hello, Bevy!") } ``` @@ -43,7 +43,7 @@ The most basic tools are: 3. Importing other blocks of [`App`]-modifying code using [`Plugins`]. Let's write a very simple demo that shows how those work. -```rust +```no_run,rust use bevy::prelude::*; fn main() { @@ -52,9 +52,9 @@ fn main() { // imported as a single unit for organization and clarity .add_plugins(MinimalPlugins) // Resources are global singleton data stored in the `World` - .insert_resource(Message {string: "Welcome to Bevy!"}) + .insert_resource(Message {string: "Welcome to Bevy!".to_string()}) // Systems run every pass of the game loop and perform logic - .add_system(print_message_system) + .add_system(read_message_system) .run(); } @@ -65,8 +65,8 @@ struct Message { // This system reads our Message resource, // so we add `Res` to its function parameters -fn read_message(message: Res) { - println!(message.string); +fn read_message_system(message: Res) { + println!("{}", message.string); } ``` diff --git a/content/learn/book/welcome/plugins/_index.md b/content/learn/book/welcome/plugins/_index.md index 368b0f48fd..89eaef1bd7 100644 --- a/content/learn/book/welcome/plugins/_index.md +++ b/content/learn/book/welcome/plugins/_index.md @@ -18,11 +18,11 @@ There's no magic to be found here; they're just a straightforward tool for code Plugins are types that implement the [`Plugin`] trait: -```rust +```no_run,rust use bevy::prelude::*; fn main(){ - App::build() + App::new() // Adds the "default" Bevy Engine plugins. // We'll cover this in the next section. .add_plugins(DefaultPlugins) @@ -40,21 +40,21 @@ impl Plugin for ScorePlugin { // beginning at the default value of 0 .init_resource::() // Increments the score by 1 every pass of the game loop - .add_system(increment_score.system()) + .add_system(increment_score) // Prints the current value of the score - .add_system(report_score.system()); + .add_system(report_score); } } #[derive(Default, Debug)] struct Score(u8); -fn increment_score(score: ResMut){ +fn increment_score(mut score: ResMut) { score.0 += 1; } -fn report_score(score: Res){ - info!(score); +fn report_score(score: Res) { + info!("{}", score.0); } ``` @@ -69,8 +69,10 @@ Bevy's [`DefaultPlugins`] is a [`PluginGroup`] that adds the "core engine featur You can add [`DefaultPlugins`] to your app like this: -```rust -App::new().add_plugins(DefaultPlugins) +```no_run,hide-lines=1-2,rust +use bevy::prelude::*; + +App::new().add_plugins(DefaultPlugins); ``` Take a look at the [source](https://github.com/bevyengine/bevy/blob/latest/crates/bevy_internal/src/default_plugins.rs) to see a full list of what's included. diff --git a/content/learn/book/welcome/setup/_index.md b/content/learn/book/welcome/setup/_index.md index 60ce038ca9..d8f4f8d5e0 100644 --- a/content/learn/book/welcome/setup/_index.md +++ b/content/learn/book/welcome/setup/_index.md @@ -59,7 +59,7 @@ Now run `cargo run` to build and run your project. You should see `Hello, world! `main.rs` is the entry point of your program: -```rs +```rust fn main() { println!("Hello, world!"); } @@ -102,11 +102,11 @@ Now that we have our Bevy project set up, we're ready to start making our first Within `main.rs`, let's create our first app and check that all the dependencies are working correctly! -```rust +```no_run,rust use bevy::prelude::*; fn main(){ - App::build().add_plugins(DefaultPlugins).run(); + App::new().add_plugins(DefaultPlugins).run(); } ``` @@ -180,7 +180,7 @@ Take a look at these known problems and how to solve them. ### Unable to find a GPU -``` +```ignore thread 'main' panicked at 'Unable to find a GPU! Make sure you have installed required drivers!' ```