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
This commit is contained in:
parent
48e3e912f3
commit
ebcd26fd51
18
.github/workflows/ci.yml
vendored
18
.github/workflows/ci.yml
vendored
@ -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
|
||||
|
||||
|
||||
2
.github/workflows/documentation.yml
vendored
2
.github/workflows/documentation.yml
vendored
@ -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
|
||||
|
||||
@ -43,6 +43,10 @@
|
||||
width: 900px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
.crate {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -92,17 +96,21 @@
|
||||
<div>esp-rs docs</div>
|
||||
</div>
|
||||
|
||||
{%- for crate in crates %}
|
||||
{%- for (package, metadata) in packages|items %}
|
||||
<h2>{{ package }}</h2>
|
||||
|
||||
{%- for meta in metadata %}
|
||||
<div class="crate">
|
||||
<span class="crate-name">
|
||||
<a href="{{ crate.name }}/{{ crate.version }}/{{ crate.chip }}/{{ crate.package }}">
|
||||
{{ crate.chip_pretty }}
|
||||
<a href="{{ meta.name }}/{{ meta.version }}/{{ meta.chip }}/{{ meta.package }}">
|
||||
{{ meta.chip_pretty }}
|
||||
</a>
|
||||
</span>
|
||||
<span class="crate-description">{{ crate.description }}</span>
|
||||
<span class="crate-version">{{ crate.version }}</span>
|
||||
<span class="crate-description">{{ meta.description }}</span>
|
||||
<span class="crate-version">{{ meta.version }}</span>
|
||||
</div>
|
||||
{%- endfor %}
|
||||
{%- endfor %}
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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:#?}");
|
||||
|
||||
@ -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<Package>,
|
||||
/// 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<Chip>,
|
||||
}
|
||||
|
||||
@ -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<Vec<Value>> {
|
||||
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()));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user