mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-09 03:51:20 -03:00
Build man pages in separate crate
Building man pages takes significant time due to Sphinx running for several seconds, even when no updates are required. Previously, we added custom logic to avoid calling `sphinx-build` if the inputs to `sphinx-build` had not changed since a cached timestamp. By moving this into its own crate, we can tell cargo to rebuild when the input files changed and unrelated changes will have no effect on this crate. This allows us to get rid of the custom code for tracking whether to recompile, while keeping the effect of only calling `sphinx-build` when appropriate. In order to avoid code duplication, a new `build-helper` crate is added, which contains some functionality for use in `build.rs`. Closes #11737
This commit is contained in:
committed by
Johannes Altmanninger
parent
32e5fa0c03
commit
e96300b08e
12
crates/build-helper/Cargo.toml
Normal file
12
crates/build-helper/Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "fish-build-helper"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
version = "0.0.0"
|
||||
repository.workspace = true
|
||||
|
||||
[dependencies]
|
||||
rsconf.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
26
crates/build-helper/src/lib.rs
Normal file
26
crates/build-helper/src/lib.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
use std::{
|
||||
env,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
pub fn canonicalize<P: AsRef<Path>>(path: P) -> PathBuf {
|
||||
std::fs::canonicalize(path).unwrap()
|
||||
}
|
||||
|
||||
pub fn get_repo_root() -> PathBuf {
|
||||
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
canonicalize(manifest_dir.ancestors().nth(2).unwrap())
|
||||
}
|
||||
|
||||
pub fn get_target_dir() -> PathBuf {
|
||||
option_env!("CARGO_TARGET_DIR")
|
||||
.map(canonicalize)
|
||||
.unwrap_or(get_repo_root().join("target"))
|
||||
}
|
||||
|
||||
// TODO Move this to rsconf
|
||||
pub fn rebuild_if_paths_changed<P: AsRef<Path>, I: IntoIterator<Item = P>>(paths: I) {
|
||||
for path in paths {
|
||||
rsconf::rebuild_if_path_changed(path.as_ref().to_str().unwrap());
|
||||
}
|
||||
}
|
||||
13
crates/build-man-pages/Cargo.toml
Normal file
13
crates/build-man-pages/Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "fish-build-man-pages"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
version = "0.0.0"
|
||||
repository.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
fish-build-helper.workspace = true
|
||||
rsconf.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
82
crates/build-man-pages/build.rs
Normal file
82
crates/build-man-pages/build.rs
Normal file
@@ -0,0 +1,82 @@
|
||||
#[cfg(not(clippy))]
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let cargo_target_dir = fish_build_helper::get_target_dir();
|
||||
let mandir = cargo_target_dir.join("fish-man");
|
||||
let sec1dir = mandir.join("man1");
|
||||
// Running `cargo clippy` on a clean build directory panics, because when rust-embed tries to
|
||||
// embed a directory which does not exist it will panic.
|
||||
let _ = std::fs::create_dir_all(sec1dir.to_str().unwrap());
|
||||
|
||||
#[cfg(not(clippy))]
|
||||
build_man(&mandir);
|
||||
}
|
||||
|
||||
#[cfg(not(clippy))]
|
||||
fn build_man(man_dir: &Path) {
|
||||
use std::{env, process::Command};
|
||||
|
||||
let repo_root_dir = fish_build_helper::get_repo_root();
|
||||
|
||||
let man_str = man_dir.to_str().unwrap();
|
||||
|
||||
let sec1_dir = man_dir.join("man1");
|
||||
let sec1_str = sec1_dir.to_str().unwrap();
|
||||
|
||||
let docsrc_dir = repo_root_dir.join("doc_src");
|
||||
let docsrc_str = docsrc_dir.to_str().unwrap();
|
||||
|
||||
let sphinx_doc_sources = [
|
||||
repo_root_dir.join("CHANGELOG.rst"),
|
||||
repo_root_dir.join("CONTRIBUTING.rst"),
|
||||
docsrc_dir.clone(),
|
||||
];
|
||||
fish_build_helper::rebuild_if_paths_changed(sphinx_doc_sources);
|
||||
|
||||
let args = &[
|
||||
"-j", "auto", "-q", "-b", "man", "-c", docsrc_str,
|
||||
// doctree path - put this *above* the man1 dir to exclude it.
|
||||
// this is ~6M
|
||||
"-d", man_str, docsrc_str, sec1_str,
|
||||
];
|
||||
let _ = std::fs::create_dir_all(sec1_str);
|
||||
|
||||
rsconf::rebuild_if_env_changed("FISH_BUILD_DOCS");
|
||||
if env::var("FISH_BUILD_DOCS") == Ok("0".to_string()) {
|
||||
println!("cargo:warning=Skipping man pages because $FISH_BUILD_DOCS is set to 0");
|
||||
return;
|
||||
}
|
||||
|
||||
// We run sphinx to build the man pages.
|
||||
// Every error here is fatal so cargo doesn't cache the result
|
||||
// - if we skipped the docs with sphinx not installed, installing it would not then build the docs.
|
||||
// That means you need to explicitly set $FISH_BUILD_DOCS=0 (`FISH_BUILD_DOCS=0 cargo install --path .`),
|
||||
// which is unfortunate - but the docs are pretty important because they're also used for --help.
|
||||
match Command::new("sphinx-build").args(args).spawn() {
|
||||
Err(x) if x.kind() == std::io::ErrorKind::NotFound => {
|
||||
if env::var("FISH_BUILD_DOCS") == Ok("1".to_string()) {
|
||||
panic!("Could not find sphinx-build to build man pages.\nInstall sphinx or disable building the docs by setting $FISH_BUILD_DOCS=0.");
|
||||
}
|
||||
println!("cargo:warning=Cannot find sphinx-build to build man pages.");
|
||||
println!("cargo:warning=If you install it now you need to run `cargo clean` and rebuild, or set $FISH_BUILD_DOCS=1 explicitly.");
|
||||
}
|
||||
Err(x) => {
|
||||
// Another error - permissions wrong etc
|
||||
panic!("Error starting sphinx-build to build man pages: {:?}", x);
|
||||
}
|
||||
Ok(mut x) => match x.wait() {
|
||||
Err(err) => {
|
||||
panic!(
|
||||
"Error waiting for sphinx-build to build man pages: {:?}",
|
||||
err
|
||||
);
|
||||
}
|
||||
Ok(out) => {
|
||||
if !out.success() {
|
||||
panic!("sphinx-build failed to build the man pages.");
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
1
crates/build-man-pages/src/lib.rs
Normal file
1
crates/build-man-pages/src/lib.rs
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user