Skip to content

Commit 4c310c1

Browse files
committed
Move manpages generation to an xtask
PR #596 brought forward automatic generation of Linux manual pages for Oxipng, which is executed every time Oxipng is built. However, while building manpages on every build is convenient for Oxipng development and doing so didn't catch my attention initially, it introduces noticeable inefficiencies for crates using Oxipng as a library: during their build, Oxipng manpages are also built, even though most dependent crates won't use such artifacts, as they are not considered part of the public Oxipng crate API or even appropriate for non-human consumption. Moreover, generating manpages depends on `clap`, which is a heavyweight dependency: according to a fresh `cargo build --timings --release` on my development workstation, its `clap_builder` dependency is the third most time consuming unit to build, totalling 1.5 s (out of 11.7 s, or 12.8%). And there is no way for dependent crates to turn this off: [`build-dependencies` cannot be conditional on crate features](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#platform-specific-dependencies). Potentially using other `cfg` hacks to either enable or disable manpage generation is unergonomic, if not outright disallowed. Besides reducing their compilation time cost, dependent crates may also want to trim the size of their dependency tree, avoiding unnecessary dependency downloads in the process. Therefore, a better solution to conditionally build manpages in a way convenient for both Oxipng maintainers and downstream consumers is needed. My proposal implemented in this PR is to leverage the [`cargo-xtask`](https://github.com/matklad/cargo-xtask) convention to define an auxiliary crate to move the manpage generation logic and dependencies to, which is to be used exclusively by Oxipng maintainers and not part of the `oxipng` crate published on `crates.io`. That way Oxipng maintainers and packagers can still generate manpages at request with ease, without any automation being noticeable to uninterested crate consumers. And as a side benefit, Oxipng maintainers can also benefit from slightly faster iteration times due to the lack of a build script for the main crate. The new `mangen` xtask can be run at any time with `cargo xtask mangen`. The generated manpages are now available at `target/xtask/mangen/manpages`. Existing deployment scripts were updated accordingly.
1 parent e7f1c04 commit 4c310c1

File tree

9 files changed

+242
-63
lines changed

9 files changed

+242
-63
lines changed

.cargo/config.toml

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
[alias]
2+
xtask = "run --manifest-path xtask/Cargo.toml --"
3+
14
[target.'cfg(all(target_os = "linux", target_arch = "aarch64"))']
25
runner = "qemu-aarch64" # May need to remove this if targeting AArch64 from an AArch64 Linux box
36

.github/workflows/deploy.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ jobs:
9090
run: |
9191
mkdir -p "target/${{ matrix.target }}/release"
9292
mv target/oxipng "target/${{ matrix.target }}/release"
93-
mv target/debug/assets "target/${{ matrix.target }}/release"
93+
mv target/xtask/mangen/manpages "target/${{ matrix.target }}/release"
9494
cargo install --locked cargo-deb
9595
cargo deb --target "${{ matrix.target }}" --no-build --no-strip
9696

Cargo.lock

-17
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ exclude = [
1313
"Dockerfile",
1414
"scripts/*",
1515
"tests/*",
16+
"xtask/*",
1617
]
1718
homepage = "https://github.com/shssoichiro/oxipng"
1819
license = "MIT"
@@ -77,10 +78,6 @@ default-features = false
7778
features = ["png"]
7879
version = "0.25.5"
7980

80-
[build-dependencies]
81-
clap = "4.5.21"
82-
clap_mangen = "0.2.24"
83-
8481
[features]
8582
binary = ["dep:clap", "dep:glob", "dep:env_logger"]
8683
default = ["binary", "parallel", "zopfli", "filetime"]
@@ -105,7 +102,7 @@ panic = "abort"
105102
[package.metadata.deb]
106103
assets = [
107104
["target/release/oxipng", "usr/bin/", "755"],
108-
["target/release/assets/oxipng.1", "usr/share/man/man1/", "644"],
105+
["target/release/manpages/oxipng.1", "usr/share/man/man1/", "644"],
109106
["README.md", "usr/share/doc/oxipng/", "644"],
110107
["CHANGELOG.md", "usr/share/doc/oxipng/", "644"],
111108
]

build.rs

-40
This file was deleted.

scripts/manual.sh

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/bin/bash
22
cargo build
3+
cargo xstask mangen
34

45
./target/debug/oxipng -V > MANUAL.txt
56
#Redirect all streams to prevent detection of the terminal width and force an internal default of 100

xtask/Cargo.lock

+200
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

xtask/Cargo.toml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "xtask"
3+
description = "xtasks for the Oxipng project: https://github.com/matklad/cargo-xtask"
4+
edition = "2021"
5+
publish = false
6+
7+
[dependencies]
8+
clap = "4.5.21"
9+
clap_mangen = "0.2.24"

xtask/src/main.rs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use std::{env, error::Error, fs, fs::File, io::BufWriter};
2+
3+
use clap_mangen::Man;
4+
5+
include!("../../src/cli.rs");
6+
7+
fn main() -> Result<(), Box<dyn Error>> {
8+
match &*env::args().nth(1).ok_or("No xtask to run provided")? {
9+
"mangen" => build_manpages(),
10+
_ => Err("Unknown xtask".into()),
11+
}
12+
}
13+
14+
fn build_manpages() -> Result<(), Box<dyn Error>> {
15+
// Put manpages in <working directory>/target/xtask/mangen/manpages. Our working directory is
16+
// expected to be the root of the repository due to the xtask invocation alias
17+
let manpages_dir = env::current_dir()?.join("target/xtask/mangen/manpages");
18+
fs::create_dir_all(&manpages_dir)?;
19+
20+
let mut man_file = BufWriter::new(File::create(manpages_dir.join("oxipng.1"))?);
21+
Man::new(build_command()).render(&mut man_file)?;
22+
23+
println!("Manpages generated in {}", manpages_dir.display());
24+
25+
Ok(())
26+
}

0 commit comments

Comments
 (0)