From ebcd26fd5199714b9b6b0f566ff2d0dbb6668692 Mon Sep 17 00:00:00 2001 From: Jesse Braham Date: Tue, 4 Jun 2024 15:27:41 +0000 Subject: [PATCH] Update `xtask` to support generating documentation for multiple packages (#1653) * Update `xtask` dependencies * Update `xtask` to support generating documentation for multiple chips * Update CI and Documentation workflows * Fix minor mistake in documentation index template --- .github/workflows/ci.yml | 20 +---- .github/workflows/documentation.yml | 2 +- resources/index.html.jinja | 18 +++-- xtask/Cargo.toml | 14 ++-- xtask/README.md | 3 + xtask/src/lib.rs | 33 ++++---- xtask/src/main.rs | 116 ++++++++++++++++------------ 7 files changed, 113 insertions(+), 93 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 688bebc33..79d0f58af 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: env: SSID: SSID PASSWORD: PASSWORD - STATIC_IP: 1.1.1.1 + STATIC_IP: 1.1.1.1 GATEWAY_IP: 1.1.1.1 HOST_IP: 1.1.1.1 @@ -74,7 +74,7 @@ jobs: - if: ${{ !contains(fromJson('["esp32", "esp32s2", "esp32s3"]'), matrix.device.soc) }} uses: dtolnay/rust-toolchain@v1 with: - target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf,riscv32imafc-unknown-none-elf + target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf toolchain: stable components: rust-src # Install the Rust toolchain for Xtensa devices: @@ -104,9 +104,6 @@ jobs: # Build all supported examples for the specified device: - name: Build (examples) run: cargo xtask build-examples esp-hal ${{ matrix.device.soc }} - # Ensure we can build the documentation for the specified device: - - name: Build (documentation) - run: cargo xtask build-documentation esp-hal ${{ matrix.device.soc }} esp-lp-hal: runs-on: ubuntu-latest @@ -131,9 +128,6 @@ jobs: # Build all supported examples for the specified device: - name: Build examples run: cargo xtask build-examples esp-lp-hal ${{ matrix.soc }} - # Ensure we can build the documentation for the specified device: - - name: Build documentation - run: cargo xtask build-documentation esp-lp-hal ${{ matrix.soc }} esp-riscv-rt: runs-on: ubuntu-latest @@ -142,7 +136,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@v1 with: - target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf,riscv32imafc-unknown-none-elf + target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf toolchain: stable components: rust-src - uses: Swatinem/rust-cache@v2 @@ -152,18 +146,11 @@ jobs: run: cd esp-riscv-rt/ && cargo build --target=riscv32imc-unknown-none-elf - name: Build esp-riscv-rt (riscv32imac, no features) run: cd esp-riscv-rt/ && cargo build --target=riscv32imac-unknown-none-elf - - name: Build esp-riscv-rt (riscv32imafc, no features) - run: cd esp-riscv-rt/ && cargo build --target=riscv32imafc-unknown-none-elf # Build for all RISC-V targets (all features): - name: Build esp-riscv-rt (riscv32imc, all features) run: cd esp-riscv-rt/ && cargo build --target=riscv32imc-unknown-none-elf --features=ci - name: Build esp-riscv-rt (riscv32imac, all features) run: cd esp-riscv-rt/ && cargo build --target=riscv32imac-unknown-none-elf --features=ci - - name: Build esp-riscv-rt (riscv32imafc, all features) - run: cd esp-riscv-rt/ && cargo build --target=riscv32imafc-unknown-none-elf --features=ci - # Ensure documentation can be built - - name: rustdoc - run: cd esp-riscv-rt/ && cargo doc extras: runs-on: ubuntu-latest @@ -184,6 +171,7 @@ jobs: run: cd extras/esp-wifishark && cargo build - name: Build ieee802154-sniffer run: cd extras/ieee802154-sniffer && cargo build + # -------------------------------------------------------------------------- # MSRV diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 079a561f6..0e4e1d998 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -17,7 +17,7 @@ jobs: ldproxy: false - name: Build documentation - run: cargo xtask build-documentation esp-hal + run: cargo xtask build-documentation --packages=esp-hal,esp-wifi # https://github.com/actions/deploy-pages/issues/303#issuecomment-1951207879 - name: Remove problematic '.lock' files diff --git a/resources/index.html.jinja b/resources/index.html.jinja index f253aef28..c0cce6f81 100644 --- a/resources/index.html.jinja +++ b/resources/index.html.jinja @@ -43,6 +43,10 @@ width: 900px; } + h2 { + margin-top: 3rem; + } + .crate { display: flex; align-items: center; @@ -92,17 +96,21 @@
esp-rs docs
- {%- for crate in crates %} + {%- for (package, metadata) in packages|items %} +

{{ package }}

+ + {%- for meta in metadata %}
- - {{ crate.chip_pretty }} + + {{ meta.chip_pretty }} - {{ crate.description }} - {{ crate.version }} + {{ meta.description }} + {{ meta.version }}
{%- endfor %} + {%- endfor %} diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 6136203fd..8384c4487 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -5,15 +5,15 @@ edition = "2021" publish = false [dependencies] -anyhow = "1.0.81" +anyhow = "1.0.86" basic-toml = "0.1.9" -chrono = "0.4.35" -clap = { version = "4.5.2", features = ["derive"] } +chrono = "0.4.38" +clap = { version = "4.5.4", features = ["derive"] } csv = "1.3.0" env_logger = "0.11.3" log = "0.4.21" -minijinja = "1.0.12" -semver = { version = "1.0.22", features = ["serde"] } -serde = { version = "1.0.197", features = ["derive"] } +minijinja = "2.0.1" +semver = { version = "1.0.23", features = ["serde"] } +serde = { version = "1.0.203", features = ["derive"] } strum = { version = "0.26.2", features = ["derive"] } -toml_edit = "0.22.7" +toml_edit = "0.22.13" diff --git a/xtask/README.md b/xtask/README.md index 5dedd7299..1ac702cc7 100644 --- a/xtask/README.md +++ b/xtask/README.md @@ -11,11 +11,14 @@ Commands: build-documentation Build documentation for the specified chip build-examples Build all examples for the specified chip build-package Build the specified package with the given options + build-tests Build all applicable tests or the specified test for a specified chip bump-version Bump the version of the specified package(s) fmt-packages Format all packages in the workspace with rustfmt generate-efuse-fields Generate the eFuse fields source file from a CSV + lint-packages Lint all packages in the workspace with clippy run-example Run the given example for the specified chip run-tests Run all applicable tests or the specified test for a specified chip + run-elfs Run all ELFs in a folder help Print this message or the help of the given subcommand(s) Options: diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs index 4c09f2cf7..85cd7ccaa 100644 --- a/xtask/src/lib.rs +++ b/xtask/src/lib.rs @@ -15,7 +15,21 @@ use self::cargo::CargoArgsBuilder; pub mod cargo; -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Display, EnumIter, ValueEnum)] +#[derive( + Debug, + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + Display, + EnumIter, + ValueEnum, + serde::Serialize, +)] +#[serde(rename_all = "kebab-case")] #[strum(serialize_all = "kebab-case")] pub enum Package { EspAlloc, @@ -37,6 +51,7 @@ pub enum Package { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Display, EnumIter, ValueEnum, serde::Serialize)] +#[serde(rename_all = "kebab-case")] #[strum(serialize_all = "kebab-case")] pub enum Chip { Esp32, @@ -151,7 +166,6 @@ pub fn build_documentation( package: Package, chip: Chip, target: &str, - open: bool, ) -> Result<()> { let package_name = package.to_string(); let package_path = windows_safe_path(&workspace.join(&package_name)); @@ -165,20 +179,11 @@ pub fn build_documentation( } // Build up an array of command-line arguments to pass to `cargo`: - let mut builder = CargoArgsBuilder::default() + let builder = CargoArgsBuilder::default() .subcommand("doc") .target(target) - .features(&features); - - if open { - builder = builder.arg("--open"); - } - - // If targeting an Xtensa device, we must use the '+esp' toolchain modifier: - if target.starts_with("xtensa") { - builder = builder.toolchain("esp"); - builder = builder.arg("-Zbuild-std=core,alloc") - } + .features(&features) + .arg("-Zbuild-std=alloc,core"); let args = builder.build(); log::debug!("{args:#?}"); diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 018e08c10..9818878cb 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,4 +1,5 @@ use std::{ + collections::HashMap, fs, path::{Path, PathBuf}, process::Command, @@ -6,6 +7,7 @@ use std::{ use anyhow::{bail, Result}; use clap::{Args, Parser}; +use minijinja::Value; use strum::IntoEnumIterator; use xtask::{ cargo::{CargoAction, CargoArgsBuilder}, @@ -68,14 +70,11 @@ struct TestArgs { #[derive(Debug, Args)] struct BuildDocumentationArgs { - /// Open the documentation in the default browser once built. - #[arg(long)] - open: bool, /// Package to build documentation for. - #[arg(value_enum)] - package: Package, + #[arg(long, value_enum, value_delimiter(','))] + packages: Vec, /// Which chip to build the documentation for. - #[arg(value_enum, default_values_t = Chip::iter())] + #[arg(long, value_enum, value_delimiter(','), default_values_t = Chip::iter())] chips: Vec, } @@ -301,50 +300,12 @@ fn build_documentation(workspace: &Path, args: BuildDocumentationArgs) -> Result let output_path = workspace.join("docs"); let resources = workspace.join("resources"); - let package = args.package.to_string(); - let version = xtask::package_version(workspace, args.package)?; - - let mut crates = Vec::new(); - - for chip in args.chips { - // Ensure that the package/chip combination provided are valid: - validate_package_chip(&args.package, &chip)?; - - // Determine the appropriate build target for the given package and chip: - let target = target_triple(&args.package, &chip)?; - - // Build the documentation for the specified package, targeting the - // specified chip: - xtask::build_documentation(workspace, args.package, chip, target, args.open)?; - - let docs_path = xtask::windows_safe_path( - &workspace - .join(package.clone()) - .join("target") - .join(target) - .join("doc"), + let mut packages = HashMap::new(); + for package in args.packages { + packages.insert( + package, + build_documentation_for_package(workspace, package, &args.chips)?, ); - - let output_path = output_path - .join(package.clone()) - .join(version.to_string()) - .join(chip.to_string()); - let output_path = xtask::windows_safe_path(&output_path); - - // Create the output directory, and copy the built documentation into it: - fs::create_dir_all(&output_path)?; - copy_dir_all(&docs_path, &output_path)?; - - // Build the context object required for rendering this particular build's - // information on the documentation index: - crates.push(minijinja::context! { - name => package, - version => version, - chip => chip.to_string(), - chip_pretty => chip.pretty_name(), - package => package.replace('-', "_"), - description => format!("{} (targeting {})", package, chip.pretty_name()), - }); } // Copy any additional assets to the documentation's output path: @@ -357,13 +318,68 @@ fn build_documentation(workspace: &Path, args: BuildDocumentationArgs) -> Result env.add_template("index", &source)?; let tmpl = env.get_template("index")?; - let html = tmpl.render(minijinja::context! { crates => crates })?; + let html = tmpl.render(minijinja::context! { packages => packages })?; fs::write(output_path.join("index.html"), html)?; Ok(()) } +fn build_documentation_for_package( + workspace: &Path, + package: Package, + chips: &[Chip], +) -> Result> { + let output_path = workspace.join("docs"); + + let version = xtask::package_version(workspace, package)?; + + let mut metadata = Vec::new(); + + for chip in chips { + // Ensure that the package/chip combination provided are valid: + validate_package_chip(&package, chip)?; + + // Determine the appropriate build target for the given package and chip: + let target = target_triple(&package, &chip)?; + + // Build the documentation for the specified package, targeting the + // specified chip: + xtask::build_documentation(workspace, package, *chip, target)?; + + let docs_path = xtask::windows_safe_path( + &workspace + .join(package.to_string()) + .join("target") + .join(target) + .join("doc"), + ); + + let output_path = output_path + .join(package.to_string()) + .join(version.to_string()) + .join(chip.to_string()); + let output_path = xtask::windows_safe_path(&output_path); + + // Create the output directory, and copy the built documentation into it: + fs::create_dir_all(&output_path)?; + copy_dir_all(&docs_path, &output_path)?; + + // Build the context object required for rendering this particular build's + // information on the documentation index: + metadata.push(minijinja::context! { + name => package, + version => version, + chip => chip.to_string(), + chip_pretty => chip.pretty_name(), + package => package.to_string().replace('-', "_"), + description => format!("{} (targeting {})", package, chip.pretty_name()), + }); + } + + Ok(metadata) +} + fn build_package(workspace: &Path, args: BuildPackageArgs) -> Result<()> { // Absolute path of the package's root: let package_path = xtask::windows_safe_path(&workspace.join(args.package.to_string()));