From b88440336994a366bcc36d910d49f3eaa3ec0167 Mon Sep 17 00:00:00 2001 From: DaAlbrecht Date: Mon, 6 Oct 2025 21:43:19 +0200 Subject: [PATCH 1/4] feat: enabled required features from examples by default --- src/commands/build/mod.rs | 33 +++++++++++++++++++++++++++++++++ src/commands/lint/mod.rs | 33 ++++++++++++++++++++++++++++++++- src/commands/run/mod.rs | 25 +++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/src/commands/build/mod.rs b/src/commands/build/mod.rs index 046906b6..3d007a4d 100644 --- a/src/commands/build/mod.rs +++ b/src/commands/build/mod.rs @@ -1,6 +1,8 @@ //! Provides functionalities to build a Bevy app targeting either native or web platforms. pub use args::*; +use cargo_metadata::TargetKind; +use tracing::debug; #[cfg(feature = "web")] use crate::web::build::build_web; @@ -47,6 +49,37 @@ pub fn build(args: &mut BuildArgs) -> anyhow::Result<()> { args.cargo_args.target_args.example.is_some(), ); + // If a specific example was passed, extend the already present features with the + // required_features from this example. + if let Some(example) = &args.cargo_args.target_args.example + // Search in the current workspace packages for an `example` target that matches the given + // example name. + && let Some(example_target) = metadata + .workspace_packages() + .iter() + .flat_map(|p| p.targets.clone()) + .find(|t| t.name.as_str() == example && t.kind.contains(&TargetKind::Example)) + { + let required_features = example_target.required_features; + + debug!( + "enabling required_features: {:?}, for example: {example}", + required_features + ); + + args.cargo_args + .feature_args + .features + .extend(required_features); + } + // build `--examples` with all features enabled. + else if args.cargo_args.target_args.is_examples { + args.cargo_args + .feature_args + .features + .push("--all-features".to_owned()); + } + #[cfg(feature = "web")] if args.is_web() { build_web(args, &metadata, &bin_target)?; diff --git a/src/commands/lint/mod.rs b/src/commands/lint/mod.rs index b4ed1579..5dbec562 100644 --- a/src/commands/lint/mod.rs +++ b/src/commands/lint/mod.rs @@ -1,5 +1,5 @@ pub use args::*; -use tracing::error; +use tracing::{debug, error}; #[cfg(feature = "rustup")] use crate::commands::lint::install::install_linter; @@ -155,6 +155,37 @@ fn build_lint_cmd(args: &mut LintArgs) -> anyhow::Result { } } + // If a specific example was passed, extend the already present features with the + // required_features from this example. + if let Some(example) = &args.cargo_args.target_args.example + // Search in the current workspace packages for an `example` target that matches the given + // example name. + && let Some(example_target) = metadata + .workspace_packages() + .iter() + .flat_map(|p| p.targets.clone()) + .find(|t| t.name.as_str() == example && t.kind.contains(&cargo_metadata::TargetKind::Example)) + { + let required_features = example_target.required_features; + + debug!( + "enabling required_features: {:?}, for example: {example}", + required_features + ); + + args.cargo_args + .feature_args + .features + .extend(required_features); + } + // build `--examples` with all features enabled. + else if args.cargo_args.target_args.is_examples { + args.cargo_args + .feature_args + .features + .push("--all-features".to_owned()); + } + let cargo_args = args.cargo_args_builder(); cmd.args(cargo_args) diff --git a/src/commands/run/mod.rs b/src/commands/run/mod.rs index dbf5e3e7..239f4514 100644 --- a/src/commands/run/mod.rs +++ b/src/commands/run/mod.rs @@ -1,5 +1,7 @@ //! Provides functionalities to run a Bevy app targeting either native or web platforms. +use tracing::debug; + pub use self::args::*; #[cfg(feature = "web")] use crate::web::run::run_web; @@ -45,6 +47,29 @@ pub fn run(args: &mut RunArgs) -> anyhow::Result<()> { args.cargo_args.target_args.example.is_some(), ); + // Extend the already present features with the required_features from this example. + if let Some(example) = &args.cargo_args.target_args.example + // Search in the current workspace packages for an `example` target that matches the given + // example name. + && let Some(example_target) = metadata + .workspace_packages() + .iter() + .flat_map(|p| p.targets.clone()) + .find(|t| t.name.as_str() == example && t.kind.contains(&cargo_metadata::TargetKind::Example)) + { + let required_features = example_target.required_features; + + debug!( + "enabling required_features: {:?}, for example: {example}", + required_features + ); + + args.cargo_args + .feature_args + .features + .extend(required_features); + } + #[cfg(feature = "web")] if args.is_web() { return run_web(args, &metadata, &bin_target); From f21dc3033bcb88de8986bf56bd70050558e4cb41 Mon Sep 17 00:00:00 2001 From: DaAlbrecht Date: Mon, 6 Oct 2025 21:53:35 +0200 Subject: [PATCH 2/4] feat: log `enabling `--all-features` to build all examples` --- src/commands/build/mod.rs | 2 ++ src/commands/lint/mod.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/commands/build/mod.rs b/src/commands/build/mod.rs index 3d007a4d..5bce04ec 100644 --- a/src/commands/build/mod.rs +++ b/src/commands/build/mod.rs @@ -78,6 +78,8 @@ pub fn build(args: &mut BuildArgs) -> anyhow::Result<()> { .feature_args .features .push("--all-features".to_owned()); + + debug!("enabling `--all-features` to build all examples"); } #[cfg(feature = "web")] diff --git a/src/commands/lint/mod.rs b/src/commands/lint/mod.rs index 5dbec562..888a356a 100644 --- a/src/commands/lint/mod.rs +++ b/src/commands/lint/mod.rs @@ -184,6 +184,8 @@ fn build_lint_cmd(args: &mut LintArgs) -> anyhow::Result { .feature_args .features .push("--all-features".to_owned()); + + debug!("enabling `--all-features` to build all examples"); } let cargo_args = args.cargo_args_builder(); From 0a1a9bf9dae3382934c5f22433d0466325526287 Mon Sep 17 00:00:00 2001 From: DaAlbrecht Date: Tue, 7 Oct 2025 19:01:58 +0200 Subject: [PATCH 3/4] feat: switch from debug level to info --- src/commands/build/mod.rs | 6 +++--- src/commands/lint/mod.rs | 6 +++--- src/commands/run/mod.rs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/commands/build/mod.rs b/src/commands/build/mod.rs index 5bce04ec..0ec94b10 100644 --- a/src/commands/build/mod.rs +++ b/src/commands/build/mod.rs @@ -2,7 +2,7 @@ pub use args::*; use cargo_metadata::TargetKind; -use tracing::debug; +use tracing::info; #[cfg(feature = "web")] use crate::web::build::build_web; @@ -62,7 +62,7 @@ pub fn build(args: &mut BuildArgs) -> anyhow::Result<()> { { let required_features = example_target.required_features; - debug!( + info!( "enabling required_features: {:?}, for example: {example}", required_features ); @@ -79,7 +79,7 @@ pub fn build(args: &mut BuildArgs) -> anyhow::Result<()> { .features .push("--all-features".to_owned()); - debug!("enabling `--all-features` to build all examples"); + info!("automatically added `--all-features` to build examples with all features enabled"); } #[cfg(feature = "web")] diff --git a/src/commands/lint/mod.rs b/src/commands/lint/mod.rs index 888a356a..f6a33952 100644 --- a/src/commands/lint/mod.rs +++ b/src/commands/lint/mod.rs @@ -1,5 +1,5 @@ pub use args::*; -use tracing::{debug, error}; +use tracing::{error, info}; #[cfg(feature = "rustup")] use crate::commands::lint::install::install_linter; @@ -168,7 +168,7 @@ fn build_lint_cmd(args: &mut LintArgs) -> anyhow::Result { { let required_features = example_target.required_features; - debug!( + info!( "enabling required_features: {:?}, for example: {example}", required_features ); @@ -185,7 +185,7 @@ fn build_lint_cmd(args: &mut LintArgs) -> anyhow::Result { .features .push("--all-features".to_owned()); - debug!("enabling `--all-features` to build all examples"); + info!("automatically added `--all-features` to check examples with all features enabled"); } let cargo_args = args.cargo_args_builder(); diff --git a/src/commands/run/mod.rs b/src/commands/run/mod.rs index 239f4514..2ece855b 100644 --- a/src/commands/run/mod.rs +++ b/src/commands/run/mod.rs @@ -1,6 +1,6 @@ //! Provides functionalities to run a Bevy app targeting either native or web platforms. -use tracing::debug; +use tracing::info; pub use self::args::*; #[cfg(feature = "web")] @@ -59,7 +59,7 @@ pub fn run(args: &mut RunArgs) -> anyhow::Result<()> { { let required_features = example_target.required_features; - debug!( + info!( "enabling required_features: {:?}, for example: {example}", required_features ); From 5d06df46f1b6a222cadbe282a175435a09164161 Mon Sep 17 00:00:00 2001 From: DaAlbrecht Date: Tue, 7 Oct 2025 19:22:34 +0200 Subject: [PATCH 4/4] doc: add section to mdbook --- docs/src/SUMMARY.md | 1 + docs/src/cli/examples.md | 24 ++++++++++++++++++++++++ docs/src/cli/index.md | 1 + 3 files changed, 26 insertions(+) create mode 100644 docs/src/cli/examples.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index b5c77630..ba2ce3c5 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -13,6 +13,7 @@ - [`getrandom`](cli/web/getrandom.md) - [Default `index.html`](cli/web/default-index-html.md) - [Linter](cli/linter.md) +- [Running Examples](cli/examples.md) - [Configuration](cli/configuration.md) - [Configuration Reference](cli/configuration/reference.md) - [Troubleshooting](cli/troubleshooting.md) diff --git a/docs/src/cli/examples.md b/docs/src/cli/examples.md new file mode 100644 index 00000000..40ca3f16 --- /dev/null +++ b/docs/src/cli/examples.md @@ -0,0 +1,24 @@ +# Examples + +The CLI makes it easy to build, run and lint examples by automatically enabling required features of the example. + +## Build and run a specific example + +```sh +# Run the `web_asset` example from https://github.com/bevyengine/bevy that requires the feature `https`. +bevy run --example web_asset +info: enabling required_features: ["https"], for example: web_asset + +# Build the `web_asset` example in the web. +bevy build --example web_asset web +info: enabling required_features: ["https"], for example: web_asset +``` + +## Build all examples + +The CLI supports building all examples only for the native target, for the web this is not supported yet. +When building all examples, the CLI will build with `--all-features`. + +```sh +bevy build --examples +``` diff --git a/docs/src/cli/index.md b/docs/src/cli/index.md index f537d860..c74329a3 100644 --- a/docs/src/cli/index.md +++ b/docs/src/cli/index.md @@ -5,6 +5,7 @@ The CLI is a prototype tool intended to streamline common tasks when working on - [**Project Scaffolding**](scaffolding.md) - [**Build and running Bevy Web Apps**](web.md) - [**Linter Integration**](linter.md) +- [**Enabling required features for examples**](examples.md) [initial scope document]: https://hackmd.io/cCHAfbtaSviU_MDnbNHKxg [original issue]: https://github.com/bevyengine/bevy/issues/436