diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 73084ae8..866113b2 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 diff --git a/src/commands/build/mod.rs b/src/commands/build/mod.rs index c72d6ca8..776b77ea 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::info; #[cfg(feature = "web")] use crate::web::build::build_web; @@ -39,6 +41,39 @@ pub fn build(args: &mut BuildArgs) -> anyhow::Result<()> { args.apply_config(&config); + // 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; + + info!( + "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()); + + info!("automatically added `--all-features` to build examples with all features enabled"); + } + #[cfg(feature = "web")] if args.is_web() { build_web(args, &metadata)?; diff --git a/src/commands/lint/mod.rs b/src/commands/lint/mod.rs index 8bc9a50b..83c9405b 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::{error, info}; #[cfg(feature = "rustup")] use crate::commands::lint::install::install_linter; @@ -145,6 +145,39 @@ 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; + + info!( + "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()); + + info!("automatically added `--all-features` to check examples with all features enabled"); + } + 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 eb42ee58..80f7df37 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::info; + pub use self::args::*; #[cfg(feature = "web")] use crate::web::run::run_web; @@ -37,6 +39,29 @@ pub fn run(args: &mut RunArgs) -> anyhow::Result<()> { args.apply_config(&config); + // 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; + + info!( + "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);