From d655b65e15b134169b9121e589706b60e0a9e191 Mon Sep 17 00:00:00 2001 From: Jesse Braham Date: Mon, 4 Mar 2024 11:05:23 -0800 Subject: [PATCH] Allow specifying an output directory when building documentation --- xtask/src/main.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 661bf6c2171..c98d9e0c23b 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,4 +1,7 @@ -use std::path::{Path, PathBuf}; +use std::{ + fs, + path::{Path, PathBuf}, +}; use anyhow::{bail, Result}; use clap::{Args, Parser}; @@ -33,6 +36,9 @@ struct BuildDocumentationArgs { /// 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, } #[derive(Debug, Args)] @@ -115,7 +121,27 @@ fn build_documentation(workspace: &Path, args: BuildDocumentationArgs) -> Result // Simply build the documentation for the specified package, targeting the // specified chip: - xtask::build_documentation(workspace, args.package, args.chip, target, args.open) + xtask::build_documentation(workspace, args.package, args.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("target") + .join(target) + .join("doc"), + ); + + let output_path = xtask::windows_safe_path(&output_path); + fs::create_dir_all(&output_path)?; + + copy_dir_all(&docs_path, &output_path)?; + } + + Ok(()) } fn build_examples(workspace: &Path, mut args: BuildExamplesArgs) -> Result<()> { @@ -244,3 +270,21 @@ fn validate_package_chip(package: &Package, chip: &Chip) -> Result<()> { Ok(()) } + +// https://stackoverflow.com/a/65192210 +fn copy_dir_all(src: impl AsRef, dst: impl AsRef) -> Result<()> { + fs::create_dir_all(&dst)?; + + for entry in fs::read_dir(src)? { + let entry = entry?; + let ty = entry.file_type()?; + + if ty.is_dir() { + copy_dir_all(entry.path(), dst.as_ref().join(entry.file_name()))?; + } else { + fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?; + } + } + + Ok(()) +}