Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework documentation generation functionality of xtask #3026

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -54,6 +54,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)]
pub struct Metadata {
example_path: PathBuf,
Expand Down Expand Up @@ -126,63 +153,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 @@ -215,6 +270,7 @@ fn apply_feature_rules(package: &Package, config: &Config) -> Vec<String> {
}
_ => {}
}

features
}

Expand Down
Loading
Loading