example showcase - pagination and can build for WebGL2 (#9168)
# Objective - Building all examples at once in CI takes too long - Tool can only build for WebGPU ## Solution - Add pagination to commands - Add option to build examples for WebGL2 - Add option to build Zola files for WebGL2
This commit is contained in:
parent
9ad546ecec
commit
ff89968ffc
@ -4,7 +4,7 @@ use clap::{Parser, ValueEnum};
|
|||||||
use xshell::{cmd, Shell};
|
use xshell::{cmd, Shell};
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, ValueEnum)]
|
#[derive(Debug, Copy, Clone, ValueEnum)]
|
||||||
enum Api {
|
enum WebApi {
|
||||||
Webgl2,
|
Webgl2,
|
||||||
Webgpu,
|
Webgpu,
|
||||||
}
|
}
|
||||||
@ -26,9 +26,9 @@ struct Args {
|
|||||||
/// Stop after this number of frames
|
/// Stop after this number of frames
|
||||||
frames: Option<usize>,
|
frames: Option<usize>,
|
||||||
|
|
||||||
#[arg(value_enum, short, long, default_value_t = Api::Webgl2)]
|
#[arg(value_enum, short, long, default_value_t = WebApi::Webgl2)]
|
||||||
/// Browser API to use for rendering
|
/// Browser API to use for rendering
|
||||||
api: Api,
|
api: WebApi,
|
||||||
|
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
/// Optimize the wasm file for size with wasm-opt
|
/// Optimize the wasm file for size with wasm-opt
|
||||||
@ -50,8 +50,8 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match cli.api {
|
match cli.api {
|
||||||
Api::Webgl2 => (),
|
WebApi::Webgl2 => (),
|
||||||
Api::Webgpu => {
|
WebApi::Webgpu => {
|
||||||
features.push("animation");
|
features.push("animation");
|
||||||
features.push("bevy_asset");
|
features.push("bevy_asset");
|
||||||
features.push("bevy_audio");
|
features.push("bevy_audio");
|
||||||
@ -95,7 +95,7 @@ fn main() {
|
|||||||
sh,
|
sh,
|
||||||
"cargo build {parameters...} --profile release --target wasm32-unknown-unknown --example {example}"
|
"cargo build {parameters...} --profile release --target wasm32-unknown-unknown --example {example}"
|
||||||
);
|
);
|
||||||
if matches!(cli.api, Api::Webgpu) {
|
if matches!(cli.api, WebApi::Webgpu) {
|
||||||
cmd = cmd.env("RUSTFLAGS", "--cfg=web_sys_unstable_apis");
|
cmd = cmd.env("RUSTFLAGS", "--cfg=web_sys_unstable_apis");
|
||||||
}
|
}
|
||||||
cmd.run().expect("Error building example");
|
cmd.run().expect("Error building example");
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
fmt::Display,
|
||||||
fs::{self, File},
|
fs::{self, File},
|
||||||
io::Write,
|
io::Write,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
@ -8,7 +9,7 @@ use std::{
|
|||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::{error::ErrorKind, CommandFactory, Parser, ValueEnum};
|
||||||
use pbr::ProgressBar;
|
use pbr::ProgressBar;
|
||||||
use toml_edit::Document;
|
use toml_edit::Document;
|
||||||
use xshell::{cmd, Shell};
|
use xshell::{cmd, Shell};
|
||||||
@ -21,6 +22,13 @@ struct Args {
|
|||||||
|
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
action: Action,
|
action: Action,
|
||||||
|
#[arg(long)]
|
||||||
|
/// Pagination control - page number. To use with --per-page
|
||||||
|
page: Option<usize>,
|
||||||
|
|
||||||
|
#[arg(long)]
|
||||||
|
/// Pagination control - number of examples per page. To use with --page
|
||||||
|
per_page: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(clap::Subcommand, Debug)]
|
#[derive(clap::Subcommand, Debug)]
|
||||||
@ -44,9 +52,13 @@ enum Action {
|
|||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
/// Path to the folder where the content should be created
|
/// Path to the folder where the content should be created
|
||||||
content_folder: String,
|
content_folder: String,
|
||||||
|
|
||||||
|
#[arg(value_enum, long, default_value_t = WebApi::Webgl2)]
|
||||||
|
/// Which API to use for rendering
|
||||||
|
api: WebApi,
|
||||||
},
|
},
|
||||||
/// BUild the examples in wasm / WebGPU
|
/// Build the examples in wasm
|
||||||
BuildWebGPUExamples {
|
BuildWasmExamples {
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
/// Path to the folder where the content should be created
|
/// Path to the folder where the content should be created
|
||||||
content_folder: String,
|
content_folder: String,
|
||||||
@ -58,12 +70,40 @@ enum Action {
|
|||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
/// Optimize the wasm file for size with wasm-opt
|
/// Optimize the wasm file for size with wasm-opt
|
||||||
optimize_size: bool,
|
optimize_size: bool,
|
||||||
|
|
||||||
|
#[arg(value_enum, long)]
|
||||||
|
/// Which API to use for rendering
|
||||||
|
api: WebApi,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, ValueEnum)]
|
||||||
|
enum WebApi {
|
||||||
|
Webgl2,
|
||||||
|
Webgpu,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for WebApi {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
WebApi::Webgl2 => write!(f, "webgl2"),
|
||||||
|
WebApi::Webgpu => write!(f, "webgpu"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let cli = Args::parse();
|
let cli = Args::parse();
|
||||||
|
|
||||||
|
if cli.page.is_none() != cli.per_page.is_none() {
|
||||||
|
let mut cmd = Args::command();
|
||||||
|
cmd.error(
|
||||||
|
ErrorKind::MissingRequiredArgument,
|
||||||
|
"page and per-page must be used together",
|
||||||
|
)
|
||||||
|
.exit();
|
||||||
|
}
|
||||||
|
|
||||||
let profile = cli.profile;
|
let profile = cli.profile;
|
||||||
|
|
||||||
match cli.action {
|
match cli.action {
|
||||||
@ -106,7 +146,16 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for to_run in examples_to_run {
|
let work_to_do = || {
|
||||||
|
examples_to_run
|
||||||
|
.iter()
|
||||||
|
.skip(cli.page.unwrap_or(0) * cli.per_page.unwrap_or(0))
|
||||||
|
.take(cli.per_page.unwrap_or(usize::MAX))
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut pb = ProgressBar::new(work_to_do().count() as u64);
|
||||||
|
|
||||||
|
for to_run in work_to_do() {
|
||||||
let sh = Shell::new().unwrap();
|
let sh = Shell::new().unwrap();
|
||||||
let example = &to_run.technical_name;
|
let example = &to_run.technical_name;
|
||||||
let extra_parameters = extra_parameters.clone();
|
let extra_parameters = extra_parameters.clone();
|
||||||
@ -143,7 +192,9 @@ fn main() {
|
|||||||
println!("took {duration:?}");
|
println!("took {duration:?}");
|
||||||
|
|
||||||
thread::sleep(Duration::from_secs(1));
|
thread::sleep(Duration::from_secs(1));
|
||||||
|
pb.inc();
|
||||||
}
|
}
|
||||||
|
pb.finish_print("done");
|
||||||
if failed_examples.is_empty() {
|
if failed_examples.is_empty() {
|
||||||
println!("All examples passed!");
|
println!("All examples passed!");
|
||||||
} else {
|
} else {
|
||||||
@ -157,7 +208,10 @@ fn main() {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Action::BuildWebsiteList { content_folder } => {
|
Action::BuildWebsiteList {
|
||||||
|
content_folder,
|
||||||
|
api,
|
||||||
|
} => {
|
||||||
let examples_to_run = parse_examples();
|
let examples_to_run = parse_examples();
|
||||||
|
|
||||||
let root_path = Path::new(&content_folder);
|
let root_path = Path::new(&content_folder);
|
||||||
@ -165,9 +219,10 @@ fn main() {
|
|||||||
let _ = fs::create_dir_all(root_path);
|
let _ = fs::create_dir_all(root_path);
|
||||||
|
|
||||||
let mut index = File::create(root_path.join("_index.md")).unwrap();
|
let mut index = File::create(root_path.join("_index.md")).unwrap();
|
||||||
index
|
if matches!(api, WebApi::Webgpu) {
|
||||||
.write_all(
|
index
|
||||||
"+++
|
.write_all(
|
||||||
|
"+++
|
||||||
title = \"Bevy Examples in WebGPU\"
|
title = \"Bevy Examples in WebGPU\"
|
||||||
template = \"examples-webgpu.html\"
|
template = \"examples-webgpu.html\"
|
||||||
sort_by = \"weight\"
|
sort_by = \"weight\"
|
||||||
@ -175,9 +230,24 @@ sort_by = \"weight\"
|
|||||||
[extra]
|
[extra]
|
||||||
header_message = \"Examples (WebGPU)\"
|
header_message = \"Examples (WebGPU)\"
|
||||||
+++"
|
+++"
|
||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
} else {
|
||||||
|
index
|
||||||
|
.write_all(
|
||||||
|
"+++
|
||||||
|
title = \"Bevy Examples in WebGL2\"
|
||||||
|
template = \"examples.html\"
|
||||||
|
sort_by = \"weight\"
|
||||||
|
|
||||||
|
[extra]
|
||||||
|
header_message = \"Examples (WebGL2)\"
|
||||||
|
+++"
|
||||||
|
.as_bytes(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
let mut categories = HashMap::new();
|
let mut categories = HashMap::new();
|
||||||
for to_show in examples_to_run {
|
for to_show in examples_to_run {
|
||||||
@ -217,43 +287,61 @@ weight = {}
|
|||||||
format!(
|
format!(
|
||||||
"+++
|
"+++
|
||||||
title = \"{}\"
|
title = \"{}\"
|
||||||
template = \"example-webgpu.html\"
|
template = \"example{}.html\"
|
||||||
weight = {}
|
weight = {}
|
||||||
description = \"{}\"
|
description = \"{}\"
|
||||||
|
|
||||||
[extra]
|
[extra]
|
||||||
technical_name = \"{}\"
|
technical_name = \"{}\"
|
||||||
link = \"{}/{}\"
|
link = \"/examples{}/{}/{}\"
|
||||||
image = \"../static/screenshots/{}/{}.png\"
|
image = \"../static/screenshots/{}/{}.png\"
|
||||||
code_path = \"content/examples-webgpu/{}\"
|
code_path = \"content/examples{}/{}\"
|
||||||
github_code_path = \"{}\"
|
github_code_path = \"{}\"
|
||||||
header_message = \"Examples (WebGPU)\"
|
header_message = \"Examples ({})\"
|
||||||
+++",
|
+++",
|
||||||
to_show.name,
|
to_show.name,
|
||||||
|
match api {
|
||||||
|
WebApi::Webgpu => "-webgpu",
|
||||||
|
WebApi::Webgl2 => "",
|
||||||
|
},
|
||||||
categories.get(&to_show.category).unwrap(),
|
categories.get(&to_show.category).unwrap(),
|
||||||
to_show.description.replace('"', "'"),
|
to_show.description.replace('"', "'"),
|
||||||
&to_show.technical_name.replace('_', "-"),
|
&to_show.technical_name.replace('_', "-"),
|
||||||
|
match api {
|
||||||
|
WebApi::Webgpu => "-webgpu",
|
||||||
|
WebApi::Webgl2 => "",
|
||||||
|
},
|
||||||
&to_show.category,
|
&to_show.category,
|
||||||
&to_show.technical_name.replace('_', "-"),
|
&to_show.technical_name.replace('_', "-"),
|
||||||
&to_show.category,
|
&to_show.category,
|
||||||
&to_show.technical_name,
|
&to_show.technical_name,
|
||||||
|
match api {
|
||||||
|
WebApi::Webgpu => "-webgpu",
|
||||||
|
WebApi::Webgl2 => "",
|
||||||
|
},
|
||||||
code_path
|
code_path
|
||||||
.components()
|
.components()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.collect::<PathBuf>()
|
.collect::<PathBuf>()
|
||||||
.display(),
|
.display(),
|
||||||
&to_show.path,
|
&to_show.path,
|
||||||
|
match api {
|
||||||
|
WebApi::Webgpu => "WebGPU",
|
||||||
|
WebApi::Webgl2 => "WebGL2",
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Action::BuildWebGPUExamples {
|
Action::BuildWasmExamples {
|
||||||
content_folder,
|
content_folder,
|
||||||
website_hacks,
|
website_hacks,
|
||||||
optimize_size,
|
optimize_size,
|
||||||
|
api,
|
||||||
} => {
|
} => {
|
||||||
|
let api = format!("{}", api);
|
||||||
let examples_to_build = parse_examples();
|
let examples_to_build = parse_examples();
|
||||||
|
|
||||||
let root_path = Path::new(&content_folder);
|
let root_path = Path::new(&content_folder);
|
||||||
@ -282,30 +370,29 @@ header_message = \"Examples (WebGPU)\"
|
|||||||
cmd!(sh, "sed -i.bak 's/asset_folder: \"assets\"/asset_folder: \"\\/assets\\/examples\\/\"/' crates/bevy_asset/src/lib.rs").run().unwrap();
|
cmd!(sh, "sed -i.bak 's/asset_folder: \"assets\"/asset_folder: \"\\/assets\\/examples\\/\"/' crates/bevy_asset/src/lib.rs").run().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut pb = ProgressBar::new(
|
let work_to_do = || {
|
||||||
examples_to_build
|
examples_to_build
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|to_build| to_build.wasm)
|
.filter(|to_build| to_build.wasm)
|
||||||
.count() as u64,
|
.skip(cli.page.unwrap_or(0) * cli.per_page.unwrap_or(0))
|
||||||
);
|
.take(cli.per_page.unwrap_or(usize::MAX))
|
||||||
for to_build in examples_to_build {
|
};
|
||||||
if !to_build.wasm {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
let mut pb = ProgressBar::new(work_to_do().count() as u64);
|
||||||
|
for to_build in work_to_do() {
|
||||||
let sh = Shell::new().unwrap();
|
let sh = Shell::new().unwrap();
|
||||||
let example = &to_build.technical_name;
|
let example = &to_build.technical_name;
|
||||||
if optimize_size {
|
if optimize_size {
|
||||||
cmd!(
|
cmd!(
|
||||||
sh,
|
sh,
|
||||||
"cargo run -p build-wasm-example -- --api webgpu {example} --optimize-size"
|
"cargo run -p build-wasm-example -- --api {api} {example} --optimize-size"
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
} else {
|
} else {
|
||||||
cmd!(
|
cmd!(
|
||||||
sh,
|
sh,
|
||||||
"cargo run -p build-wasm-example -- --api webgpu {example}"
|
"cargo run -p build-wasm-example -- --api {api} {example}"
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user