mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-28 12:50:53 +00:00
Simplify building documentation, automatically generate documentation index (#1279)
This commit is contained in:
parent
1d3fa8e93b
commit
7983923b16
25
.github/scripts/build_docs.sh
vendored
25
.github/scripts/build_docs.sh
vendored
@ -1,25 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Extract the package version from `esp-hal` (using arcane methods):
|
||||
PKG_VERSION=$(
|
||||
cargo metadata --format-version=1 --no-deps --manifest-path=esp-hal/Cargo.toml \
|
||||
| jq -r '.packages[] | select(.name=="esp-hal") | .version'
|
||||
)
|
||||
|
||||
# Build the documentation for each supported cheap, namespacing by
|
||||
# package version and chip:
|
||||
CHIPS=("esp32" "esp32c2" "esp32c3" "esp32c6" "esp32h2" "esp32p4" "esp32s2" "esp32s3")
|
||||
|
||||
for CHIP in "${CHIPS[@]}"; do
|
||||
cargo xtask build-documentation \
|
||||
--output-path="docs/esp-hal/$PKG_VERSION"/"$CHIP"/ \
|
||||
esp-hal \
|
||||
"$CHIP"
|
||||
done
|
||||
|
||||
# Copy any additional resources (such as the index and our logo)
|
||||
# to the location of the built documentation as well:
|
||||
cp resources/esp-rs.svg docs/
|
||||
cp resources/index.html docs/
|
2
.github/workflows/documentation.yml
vendored
2
.github/workflows/documentation.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
||||
ldproxy: false
|
||||
|
||||
- name: Build documentation
|
||||
run: ./.github/scripts/build_docs.sh
|
||||
run: cargo xtask build-documentation esp-hal
|
||||
|
||||
# https://github.com/actions/deploy-pages/issues/303#issuecomment-1951207879
|
||||
- name: Remove problematic '.lock' files
|
||||
|
@ -1,139 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<title>esp-rs docs</title>
|
||||
|
||||
<link rel="icon" href="esp-rs.svg" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@400;500&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Source+Serif+4:ital,wght@0,400;0,600;1,400;1,600&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
<style>
|
||||
body {
|
||||
background-color: rgb(53, 53, 53);
|
||||
font-family: "Fira Sans", sans-serif;
|
||||
color: white;
|
||||
margin: 0;
|
||||
padding: 40px 20px;
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.logo {
|
||||
text-align: center;
|
||||
margin-bottom: 50px;
|
||||
font-size: 2em;
|
||||
font-weight: 500;
|
||||
}
|
||||
.logo img {
|
||||
width: 100px;
|
||||
height: auto;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.content {
|
||||
width: 900px;
|
||||
}
|
||||
.crate {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
border-bottom: 2px solid #454444;
|
||||
}
|
||||
.crate-description {
|
||||
flex: 1;
|
||||
font-family: "Source Serif 4", serif;
|
||||
color: #c0c0c0;
|
||||
text-align: center;
|
||||
}
|
||||
.crate-name {
|
||||
color: #d6991d;
|
||||
width: 120px;
|
||||
}
|
||||
/* Ensure the link color does not change after being clicked */
|
||||
.crate-name a:link,
|
||||
.crate-name a:visited,
|
||||
.crate-name a:hover,
|
||||
.crate-name a:active,
|
||||
.crate-name a:focus {
|
||||
color: #d6991d;
|
||||
}
|
||||
.crate-version {
|
||||
color: #c0c0c0;
|
||||
text-align: center;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
@media screen and (min-height: 650px) {
|
||||
body {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content">
|
||||
<div class="logo">
|
||||
<img src="esp-rs.svg" alt="esp-rs logo" />
|
||||
<div>esp-rs docs</div>
|
||||
</div>
|
||||
|
||||
<!-- TODO: Generate the index from a template, rather than hard-coding
|
||||
the package version in the URL and '.crate-version' span. -->
|
||||
|
||||
<div class="crate">
|
||||
<span class="crate-name"><a href="esp-hal/0.16.1/esp32/esp_hal/index.html">esp32</a></span>
|
||||
<span class="crate-description">esp-hal (targeting ESP32)</span>
|
||||
<span class="crate-version">0.16.1</span>
|
||||
</div>
|
||||
|
||||
<div class="crate">
|
||||
<span class="crate-name"><a href="esp-hal/0.16.1/esp32c2/esp_hal/index.html">esp32c2</a></span>
|
||||
<span class="crate-description">esp-hal (targeting ESP32-C2)</span>
|
||||
<span class="crate-version">0.16.1</span>
|
||||
</div>
|
||||
|
||||
<div class="crate">
|
||||
<span class="crate-name"><a href="esp-hal/0.16.1/esp32c3/esp_hal/index.html">esp32c3</a></span>
|
||||
<span class="crate-description">esp-hal (targeting ESP32-C3)</span>
|
||||
<span class="crate-version">0.16.1</span>
|
||||
</div>
|
||||
|
||||
<div class="crate">
|
||||
<span class="crate-name"><a href="esp-hal/0.16.1/esp32c6/esp_hal/index.html">esp32c6</a></span>
|
||||
<span class="crate-description">esp-hal (targeting ESP32-C6)</span>
|
||||
<span class="crate-version">0.16.1</span>
|
||||
</div>
|
||||
|
||||
<div class="crate">
|
||||
<span class="crate-name"><a href="esp-hal/0.16.1/esp32h2/esp_hal/index.html">esp32h2</a></span>
|
||||
<span class="crate-description">esp-hal (targeting ESP32-H2)</span>
|
||||
<span class="crate-version">0.16.1</span>
|
||||
</div>
|
||||
|
||||
<div class="crate">
|
||||
<span class="crate-name"><a href="esp-hal/0.16.1/esp32p4/esp_hal/index.html">esp32p4</a></span>
|
||||
<span class="crate-description">esp-hal (targeting ESP32-P4)</span>
|
||||
<span class="crate-version">0.16.1</span>
|
||||
</div>
|
||||
|
||||
<div class="crate">
|
||||
<span class="crate-name"><a href="esp-hal/0.16.1/esp32s2/esp_hal/index.html">esp32s2</a></span>
|
||||
<span class="crate-description">esp-hal (targeting ESP32-S2)</span>
|
||||
<span class="crate-version">0.16.1</span>
|
||||
</div>
|
||||
|
||||
<div class="crate">
|
||||
<span class="crate-name"><a href="esp-hal/0.16.1/esp32s3/esp_hal/index.html">esp32s3</a></span>
|
||||
<span class="crate-description">esp-hal (targeting ESP32-S3)</span>
|
||||
<span class="crate-version">0.16.1</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
109
resources/index.html.jinja
Normal file
109
resources/index.html.jinja
Normal file
@ -0,0 +1,109 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<title>esp-rs docs</title>
|
||||
|
||||
<link rel="icon" href="esp-rs.svg" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@400;500&display=swap" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Source+Serif+4:ital,wght@0,400;0,600;1,400;1,600&display=swap"
|
||||
rel="stylesheet" />
|
||||
|
||||
<style>
|
||||
body {
|
||||
background-color: rgb(53, 53, 53);
|
||||
font-family: "Fira Sans", sans-serif;
|
||||
color: white;
|
||||
margin: 0;
|
||||
padding: 40px 20px;
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.logo {
|
||||
text-align: center;
|
||||
margin-bottom: 50px;
|
||||
font-size: 2em;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.logo img {
|
||||
width: 100px;
|
||||
height: auto;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 900px;
|
||||
}
|
||||
|
||||
.crate {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
border-bottom: 2px solid #454444;
|
||||
}
|
||||
|
||||
.crate-description {
|
||||
flex: 1;
|
||||
font-family: "Source Serif 4", serif;
|
||||
color: #c0c0c0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.crate-name {
|
||||
color: #d6991d;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
/* Ensure the link color does not change after being clicked */
|
||||
.crate-name a:link,
|
||||
.crate-name a:visited,
|
||||
.crate-name a:hover,
|
||||
.crate-name a:active,
|
||||
.crate-name a:focus {
|
||||
color: #d6991d;
|
||||
}
|
||||
|
||||
.crate-version {
|
||||
color: #c0c0c0;
|
||||
text-align: center;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
@media screen and (min-height: 650px) {
|
||||
body {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="content">
|
||||
<div class="logo">
|
||||
<img src="esp-rs.svg" alt="esp-rs logo" />
|
||||
<div>esp-rs docs</div>
|
||||
</div>
|
||||
|
||||
{%- for crate in crates %}
|
||||
<div class="crate">
|
||||
<span class="crate-name">
|
||||
<a href="{{ crate.name }}/{{ crate.version }}/{{ crate.chip }}/{{ crate.package }}">
|
||||
{{ crate.chip_pretty }}
|
||||
</a>
|
||||
</span>
|
||||
<span class="crate-description">{{ crate.description }}</span>
|
||||
<span class="crate-version">{{ crate.version }}</span>
|
||||
</div>
|
||||
{%- endfor %}
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -5,13 +5,15 @@ edition = "2021"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.79"
|
||||
anyhow = "1.0.81"
|
||||
basic-toml = "0.1.9"
|
||||
chrono = "0.4.35"
|
||||
clap = { version = "4.5.0", features = ["derive"] }
|
||||
clap = { version = "4.5.2", features = ["derive"] }
|
||||
csv = "1.3.0"
|
||||
env_logger = "0.11.1"
|
||||
log = "0.4.20"
|
||||
semver = "1.0.21"
|
||||
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"] }
|
||||
strum = { version = "0.26.1", features = ["derive"] }
|
||||
toml_edit = "0.22.5"
|
||||
strum = { version = "0.26.2", features = ["derive"] }
|
||||
toml_edit = "0.22.7"
|
||||
|
@ -25,7 +25,7 @@ pub enum Package {
|
||||
Examples,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Display, EnumIter, ValueEnum)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Display, EnumIter, ValueEnum, serde::Serialize)]
|
||||
#[strum(serialize_all = "kebab-case")]
|
||||
pub enum Chip {
|
||||
Esp32,
|
||||
@ -369,7 +369,7 @@ pub fn bump_version(workspace: &Path, package: Package, amount: Version) -> Resu
|
||||
let manifest_path = workspace.join(package.to_string()).join("Cargo.toml");
|
||||
let manifest = fs::read_to_string(&manifest_path)?;
|
||||
|
||||
let mut manifest = manifest.parse::<toml_edit::Document>()?;
|
||||
let mut manifest = manifest.parse::<toml_edit::DocumentMut>()?;
|
||||
|
||||
let version = manifest["package"]["version"]
|
||||
.to_string()
|
||||
@ -553,6 +553,27 @@ pub fn generate_efuse_table(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Helper Functions
|
||||
|
||||
/// Parse the version from the specified package's Cargo manifest.
|
||||
pub fn package_version(workspace: &Path, package: Package) -> Result<semver::Version> {
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
pub struct Manifest {
|
||||
package: Package,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
pub struct Package {
|
||||
version: semver::Version,
|
||||
}
|
||||
|
||||
let manifest = fs::read_to_string(workspace.join(package.to_string()).join("Cargo.toml"))?;
|
||||
let manifest: Manifest = basic_toml::from_str(&manifest)?;
|
||||
|
||||
Ok(manifest.package.version)
|
||||
}
|
||||
|
||||
/// Make the path "Windows"-safe
|
||||
pub fn windows_safe_path(path: &Path) -> PathBuf {
|
||||
PathBuf::from(path.to_str().unwrap().to_string().replace("\\\\?\\", ""))
|
||||
|
@ -29,18 +29,15 @@ enum Cli {
|
||||
|
||||
#[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,
|
||||
/// Which chip to build the documentation for.
|
||||
#[arg(value_enum)]
|
||||
chip: Chip,
|
||||
/// Open the documentation in the default browser once built.
|
||||
#[arg(long)]
|
||||
open: bool,
|
||||
/// Directory in which to place the built documentation.
|
||||
#[arg(long)]
|
||||
output_path: Option<PathBuf>,
|
||||
#[arg(value_enum, default_values_t = Chip::iter())]
|
||||
chips: Vec<Chip>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
@ -125,34 +122,72 @@ fn main() -> Result<()> {
|
||||
// Subcommands
|
||||
|
||||
fn build_documentation(workspace: &Path, args: BuildDocumentationArgs) -> Result<()> {
|
||||
// Ensure that the package/chip combination provided are valid:
|
||||
validate_package_chip(&args.package, &args.chip)?;
|
||||
let output_path = workspace.join("docs");
|
||||
let resources = workspace.join("resources");
|
||||
|
||||
// Determine the appropriate build target for the given package and chip:
|
||||
let target = target_triple(&args.package, &args.chip)?;
|
||||
let package = args.package.to_string();
|
||||
let version = xtask::package_version(&workspace, args.package)?;
|
||||
|
||||
// Simply build the documentation for the specified package, targeting the
|
||||
// specified chip:
|
||||
xtask::build_documentation(workspace, args.package, args.chip, target, args.open)?;
|
||||
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)?;
|
||||
|
||||
// If an output path was specified, once the documentation has been built we
|
||||
// will copy it to the provided path, creating any required directories in the
|
||||
// process:
|
||||
if let Some(output_path) = args.output_path {
|
||||
let docs_path = xtask::windows_safe_path(
|
||||
&workspace
|
||||
.join(args.package.to_string())
|
||||
.join(package.clone())
|
||||
.join("target")
|
||||
.join(target)
|
||||
.join("doc"),
|
||||
);
|
||||
|
||||
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);
|
||||
fs::create_dir_all(&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:
|
||||
fs::copy(
|
||||
&resources.join("esp-rs.svg"),
|
||||
&output_path.join("esp-rs.svg"),
|
||||
)?;
|
||||
|
||||
// Render the index and write it out to the documentaiton's output path:
|
||||
let source = fs::read_to_string(resources.join("index.html.jinja"))?;
|
||||
|
||||
let mut env = minijinja::Environment::new();
|
||||
env.add_template("index", &source)?;
|
||||
|
||||
let tmpl = env.get_template("index")?;
|
||||
let html = tmpl.render(minijinja::context! { crates => crates })?;
|
||||
|
||||
fs::write(output_path.join("index.html"), html)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user