Skip to content

Commit

Permalink
Rework documentation generation functionality of xtask (#3026)
Browse files Browse the repository at this point in the history
* Rework the `xtask` to build documentation for all packages in the repo

* Fixes for `esp-config` and `esp-storage`
  • Loading branch information
jessebraham authored Jan 27, 2025
1 parent 5139ff1 commit 570e768
Show file tree
Hide file tree
Showing 4 changed files with 258 additions and 107 deletions.
4 changes: 2 additions & 2 deletions esp-config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ This crate is guaranteed to compile when using the latest stable Rust version at

Licensed under either of:

- Apache License, Version 2.0 ([LICENSE-APACHE](../LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](../LICENSE-MIT) or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0 ([LICENSE-APACHE](../LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT license ([LICENSE-MIT](../LICENSE-MIT) or <http://opensource.org/licenses/MIT>)

at your option.

Expand Down
8 changes: 3 additions & 5 deletions resources/index.html.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -93,24 +93,22 @@
<div class="content">
<div class="logo">
<img src="esp-rs.svg" alt="esp-rs logo" />
<div>esp-rs docs</div>
<div>{{ metadata[0].package }} Documentation</div>
</div>

{%- for (package, metadata) in packages|items %}
<h2>{{ package }}</h2>
<h2>{{ metadata[0].package }}</h2>

{%- for meta in metadata %}
<div class="crate">
<span class="crate-name">
<a href="{{ meta.name }}/{{ meta.version }}/{{ meta.chip }}/{{ meta.package }}">
<a href="{{ meta.chip }}/{{ meta.package }}/index.html">
{{ meta.chip_pretty }}
</a>
</span>
<span class="crate-description">{{ meta.name }} (targeting {{ meta.chip_pretty }})</span>
<span class="crate-version">{{ meta.version }}</span>
</div>
{%- endfor %}
{%- endfor %}
</div>
</body>

Expand Down
114 changes: 85 additions & 29 deletions xtask/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,33 @@ pub enum Package {
XtensaLxRt,
}

impl Package {
/// Does the package have chip-specific cargo features?
pub fn has_chip_features(&self) -> bool {
use Package::*;

matches!(
self,
EspBacktrace
| EspHal
| EspHalEmbassy
| EspIeee802154
| EspLpHal
| EspPrintln
| EspStorage
| EspWifi
| XtensaLxRt
)
}

/// Do the package's chip-specific cargo features affect the public API?
pub fn chip_features_matter(&self) -> bool {
use Package::*;

matches!(self, EspHal | EspLpHal | EspWifi)
}
}

#[derive(Debug, Clone, Copy, Display, ValueEnum)]
#[strum(serialize_all = "lowercase")]
pub enum Version {
Expand All @@ -63,63 +90,91 @@ pub enum Version {
Patch,
}

/// Build the documentation for the specified package and device.
pub fn build_documentation(workspace: &Path, package: Package, chip: Chip) -> Result<PathBuf> {
/// Build the documentation for the specified package and, optionally, a
/// specific chip.
pub fn build_documentation(
workspace: &Path,
package: Package,
chip: Option<Chip>,
) -> Result<PathBuf> {
let package_name = package.to_string();
let package_path = windows_safe_path(&workspace.join(&package_name));

log::info!("Building '{package_name}' documentation targeting '{chip}'");

// Determine the appropriate build target for the given package and chip:
let target = target_triple(package, &chip)?;

// We need `nightly` for building the docs, unfortunately:
let toolchain = if chip.is_xtensa() { "esp" } else { "nightly" };
if let Some(chip) = chip {
log::info!("Building '{package_name}' documentation targeting '{chip}'");
} else {
log::info!("Building '{package_name}' documentation");
}

let mut features = vec![chip.to_string()];
// We require some nightly features to build the documentation:
let toolchain = if chip.is_some_and(|chip| chip.is_xtensa()) {
"esp"
} else {
"nightly"
};

let chip = Config::for_chip(&chip);
// Determine the appropriate build target for the given package and chip,
// if we're able to:
let target = if let Some(ref chip) = chip {
Some(target_triple(package, chip)?)
} else {
None
};

features.extend(apply_feature_rules(&package, chip));
let mut features = vec![];
if let Some(chip) = chip {
features.push(chip.to_string());
features.extend(apply_feature_rules(&package, Config::for_chip(&chip)));
}

// Build up an array of command-line arguments to pass to `cargo`:
let builder = CargoArgsBuilder::default()
let mut builder = CargoArgsBuilder::default()
.toolchain(toolchain)
.subcommand("doc")
.target(target)
.features(&features)
.arg("-Zbuild-std=alloc,core")
.arg("-Zrustdoc-map")
.arg("--lib")
.arg("--no-deps");

if let Some(target) = target {
builder = builder.target(target);
}

// Special case: `esp-metadata` requires `std`, and we get some really confusing
// errors if we try to pass `-Zbuild-std=core`:
if package != Package::EspMetadata {
builder = builder.arg("-Zbuild-std=alloc,core");
}

let args = builder.build();
log::debug!("{args:#?}");

let mut envs = vec![("RUSTDOCFLAGS", "--cfg docsrs --cfg not_really_docsrs")];
// Special case: `esp-storage` requires the optimization level to be 2 or 3:
if package == Package::EspStorage {
envs.push(("CARGO_PROFILE_DEBUG_OPT_LEVEL", "3"));
}

// Execute `cargo doc` from the package root:
cargo::run_with_env(
&args,
&package_path,
[("RUSTDOCFLAGS", "--cfg docsrs --cfg not_really_docsrs")],
false,
)?;
cargo::run_with_env(&args, &package_path, envs, false)?;

let docs_path = windows_safe_path(
&workspace
.join(package.to_string())
.join("target")
.join(target)
.join("doc"),
);
// Build up the path at which the built documentation can be found:
let mut docs_path = workspace.join(package.to_string()).join("target");
if let Some(target) = target {
docs_path = docs_path.join(target);
}
docs_path = docs_path.join("doc");

Ok(docs_path)
Ok(windows_safe_path(&docs_path))
}

fn apply_feature_rules(package: &Package, config: &Config) -> Vec<String> {
let chip_name = &config.name();

let mut features = vec![];
match package {
Package::EspBacktrace => features.push("defmt".to_owned()),
Package::EspConfig => features.push("build".to_owned()),
Package::EspHal => {
features.push("unstable".to_owned());
features.push("ci".to_owned());
Expand Down Expand Up @@ -152,6 +207,7 @@ fn apply_feature_rules(package: &Package, config: &Config) -> Vec<String> {
}
_ => {}
}

features
}

Expand Down
Loading

0 comments on commit 570e768

Please sign in to comment.