mirror of
https://github.com/aphrody-labs/pdfcraft.git
synced 2026-10-14 03:29:04 +00:00
M0: label local builds in --version, About and the package release (#1529)
A build compiled with PDFCRAFT_BUILD_LABEL=<label> shows "0.7.1 (<label>)"
in `pdfcraft --version`, `pdfcraft-cli --version`, Help > About and the
first log line (pdfcraft_engine::build_info). The version itself is
unchanged, so the update check, the MCP server info and the User-Agent
still carry the release version.
packaging/linux/package.sh puts the label in the file names
(pdfcraft-0.7.1-<label>-linux-x86_64.rpm) and makes the .rpm/.deb release
`1.<label>` (nfpm `release: ${RELEASE}`, 1 when unlabelled). rpm sorts
0.7.1-1.<label> after 0.7.1-1 and before 0.7.2-1, so a locally built
package upgrades over the installed release and the next release replaces
it. packaging/env.sh accepts only letters, digits and inner dots, which
are valid in both rpm and deb release fields.
Unlabelled builds are unchanged.
Made with Claude Code (Claude Opus 5.5, medium effort). It passes the
workspace quality gates (fmt, clippy, cargo test --workspace, xtask assets)
and was checked by hand on Fedora 44, but it has not been exhaustively
regression tested.
Co-authored-by: bmh129 <11478682+bmh129@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
12 files changed
+73
-10
No files matched your search
Generated
+1
@@ -3567,6 +3567,7 @@ dependencies = [
|
||||
"egui",
|
||||
"fmv-macos-events",
|
||||
"log",
|
||||
"pdfcraft-engine",
|
||||
"pdfcraft-ui-egui",
|
||||
"pollster 1.0.1",
|
||||
"rustls-native-certs",
|
||||
|
||||
@@ -179,6 +179,7 @@ Ranked; detail and the full milestone table in [docs/roadmap.md](docs/roadmap.md
|
||||
|
||||
Newest first: the date, what moved, and the new overall estimate.
|
||||
|
||||
- **2026-10-12 (M0, build label):** A local or patched build can carry a label, set at compile time with `PDFCRAFT_BUILD_LABEL`: `pdfcraft --version`, `pdfcraft-cli --version`, About and the log show `0.7.1 (titlebar)`, and `packaging/linux/package.sh` names the files `pdfcraft-0.7.1-titlebar-…` and makes the .rpm/.deb release `1.titlebar`, which upgrades over the release of the same version (and the next release over it). The version itself is unchanged, so the update check still compares it with published releases. Unlabelled builds are as before. Estimates unchanged.
|
||||
- 2026-10-11: Organize Pages shows an editable, synchronized physical page-range selection (#1092), with bounded validation and UI/operation regression coverage; overall estimate unchanged.
|
||||
|
||||
- **2026-10-11 (M5.7, scanned signatures, #1110):** Fill & Sign ▸ Add signature has a Scan tab: a phone photo of a signature on paper is framed automatically (all words; table, sheet edge and dust ignored; a sideways signature turned upright), the frame can be moved, resized or redrawn, the photo turned, and an ink-sensitivity slider picks up faint ink. A morphological paper estimate removes shadows and uneven light, and the trimmed ink is saved and reused like an image signature. Photos and images can also be dropped on the Image and Scan tabs. Photos keep the image-signature limits (#1124: a 4 MiB file, up to 32 megapixels decoded, scaled down to 4 megapixels), so a scan never processes more than 4 megapixels. `fill_sign_add` takes `scan` and `sensitivity`. Synthetic engine, UI and automation tests; checked by hand on real phone photos. Milestone and effort estimates unchanged.
|
||||
|
||||
@@ -141,7 +141,7 @@ fn stdout_line(line: std::fmt::Arguments<'_>) -> Result<(), CliError> {
|
||||
}
|
||||
|
||||
fn version() -> Result<(), CliError> {
|
||||
stdout_line(format_args!("pdfcraft-cli {}", env!("CARGO_PKG_VERSION")))?;
|
||||
stdout_line(format_args!("pdfcraft-cli {}", pdfcraft_engine::build_info::version()))?;
|
||||
stdout_line(format_args!("Discord: {} (help and feedback)", pdfcraft_engine::links::DISCORD))?;
|
||||
stdout_line(format_args!("Web: {}", pdfcraft_engine::links::APP_PAGE))?;
|
||||
stdout_line(format_args!("Source: {}", pdfcraft_engine::links::GITHUB))?;
|
||||
|
||||
@@ -14,6 +14,8 @@ workspace = true
|
||||
ureq = { version = "3.4", default-features = false, features = ["rustls-no-provider", "_ring"] }
|
||||
rustls-native-certs = "0.8"
|
||||
pdfcraft-ui-egui = { workspace = true }
|
||||
# `build_info`: the version and compile-time build label for `--version` and the log.
|
||||
pdfcraft-engine = { workspace = true }
|
||||
# wgpu draws; OpenGL (glow) is the fallback when wgpu can't start on an old or unusual GPU or
|
||||
# driver (#461, #435, #392), and can be chosen with PDFCRAFT_RENDERER=gl.
|
||||
eframe = { workspace = true, features = ["default_fonts", "wgpu", "glow", "accesskit", "wayland", "x11", "persistence", "links"] }
|
||||
|
||||
@@ -155,7 +155,7 @@ fn main() -> eframe::Result {
|
||||
while let Some(a) = args.next() {
|
||||
match a.as_str() {
|
||||
"--version" => {
|
||||
println!("pdfcraft {}", env!("CARGO_PKG_VERSION"));
|
||||
println!("pdfcraft {}", pdfcraft_engine::build_info::version());
|
||||
return Ok(());
|
||||
}
|
||||
"--control" => control_file = args.next(),
|
||||
@@ -175,7 +175,7 @@ fn main() -> eframe::Result {
|
||||
// Records logged until now are written to it first.
|
||||
if let (Some(logger), Some(dir)) = (logger, settings_dir()) {
|
||||
match logger.attach_dir(&dir.join("logs")) {
|
||||
Ok(path) => log::info!("PdfCraft {}, log file {}", env!("CARGO_PKG_VERSION"), path.display()),
|
||||
Ok(path) => log::info!("PdfCraft {}, log file {}", pdfcraft_engine::build_info::version(), path.display()),
|
||||
// Standard error only by now (`attach_dir` gave up on the file); unlike `eprintln!`, never panics.
|
||||
Err(e) => log::warn!("no log file: {e}"),
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
//! What this build calls itself. A local or patched build sets `PDFCRAFT_BUILD_LABEL` at compile
|
||||
//! time (`PDFCRAFT_BUILD_LABEL=titlebar cargo build`, or through `packaging/linux/package.sh`), so
|
||||
//! it can be told from the release of the same version. The version itself stays the release's:
|
||||
//! the update check compares it with published releases.
|
||||
|
||||
/// The release version from the workspace `Cargo.toml`.
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
/// The compile-time build label, if any.
|
||||
pub const LABEL: Option<&str> = option_env!("PDFCRAFT_BUILD_LABEL");
|
||||
|
||||
/// The version as shown to people: `0.7.1`, or `0.7.1 (titlebar)` for a labelled build.
|
||||
pub fn version() -> String {
|
||||
describe(VERSION, LABEL)
|
||||
}
|
||||
|
||||
fn describe(version: &str, label: Option<&str>) -> String {
|
||||
match label.map(str::trim).filter(|l| !l.is_empty()) {
|
||||
Some(label) => format!("{version} ({label})"),
|
||||
None => version.to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::describe;
|
||||
|
||||
#[test]
|
||||
fn a_label_follows_the_version_and_a_blank_one_is_ignored() {
|
||||
assert_eq!(describe("0.7.1", None), "0.7.1");
|
||||
assert_eq!(describe("0.7.1", Some("")), "0.7.1");
|
||||
assert_eq!(describe("0.7.1", Some(" ")), "0.7.1");
|
||||
assert_eq!(describe("0.7.1", Some("titlebar")), "0.7.1 (titlebar)");
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
pub mod actions;
|
||||
pub mod autotag;
|
||||
pub mod build_info;
|
||||
pub mod camera;
|
||||
pub mod camera_clean;
|
||||
pub mod camera_edges;
|
||||
|
||||
@@ -1098,7 +1098,7 @@ fn dialogs(app: &mut PdfCraftApp, ctx: &egui::Context) {
|
||||
widgets::artcraft_mark(ui, 40.0);
|
||||
ui.vertical(|ui| {
|
||||
ui.label(egui::RichText::new("PdfCraft").font(theme::semibold(20.0)));
|
||||
ui.label(crate::i18n::fmt(tl!("Version {v}"), &[("v", env!("CARGO_PKG_VERSION"))]));
|
||||
ui.label(crate::i18n::fmt(tl!("Version {v}"), &[("v", &pdfcraft_engine::build_info::version())]));
|
||||
});
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
|
||||
@@ -115,5 +115,6 @@ driver's shader compilation, and explicit `PDFCRAFT_RENDERER=wgpu` still disable
|
||||
| `WGPU_POWER_PREF` | GPU choice; by default PdfCraft draws on the GPU the Wayland compositor draws with (it says so through linux-dmabuf feedback), else the GPU that drives the primary display (Windows) or the built-in panel (Linux), else the low-power (integrated) GPU. The log says which one was chosen |
|
||||
| `WGPU_BACKEND` | Graphics backend; by default Windows uses Direct3D 12, falling back to OpenGL |
|
||||
| `PDFCRAFT_RENDERER` | `gl` starts with OpenGL (glow) and never loads wgpu; `wgpu` reports a wgpu failure instead of retrying with OpenGL; unset, wgpu is retried with OpenGL when it can't start (see [Renderer fallback](#renderer-fallback)) |
|
||||
| `PDFCRAFT_BUILD_LABEL` | Build time: a label for a local or patched build (letters, digits, inner dots), shown after the version in `--version`, About and the log (`0.7.1 (titlebar)`). `packaging/linux/package.sh` also puts it in the file names and the .rpm/.deb release (`1.titlebar`), which upgrades over the release of the same version |
|
||||
| `CRAFT_FONTS_DIR` | Build time: a [craft-fonts](https://github.com/storytold/craft-fonts) checkout to embed (Japanese fonts) |
|
||||
| `PDFCRAFT_SYSTEM_FONTS` | `0` stops the desktop app from using an installed font for characters its embedded fonts lack (`cargo xtask screenshots` sets it) |
|
||||
@@ -4,6 +4,8 @@
|
||||
# Exports:
|
||||
# ROOT workspace root
|
||||
# VERSION [workspace.package] version from Cargo.toml (override: PDFCRAFT_VERSION)
|
||||
# PDFCRAFT_BUILD_LABEL optional label for a local or patched build (letters, digits, dots);
|
||||
# compiled into `--version` and About, and appended to the package release
|
||||
# DIST output directory for release artifacts (default: $ROOT/dist/release)
|
||||
# PDFCRAFT_BUILD_SHA git commit, recorded in the macOS Info.plist (PdfCraftBuildCommit)
|
||||
# PDFCRAFT_BUILD_DATE UTC build date, YYYY-MM-DD
|
||||
@@ -28,6 +30,18 @@ if [ -z "$VERSION" ]; then
|
||||
fi
|
||||
export VERSION
|
||||
|
||||
# A labelled build says so in `--version` and About (pdfcraft_engine::build_info) and in its
|
||||
# package release (packaging/linux/nfpm.yaml), so it can't be mistaken for the release.
|
||||
if [ -n "${PDFCRAFT_BUILD_LABEL:-}" ]; then
|
||||
case "$PDFCRAFT_BUILD_LABEL" in
|
||||
*[!A-Za-z0-9.]* | .* | *.)
|
||||
echo "error: PDFCRAFT_BUILD_LABEL may hold only letters, digits and inner dots: $PDFCRAFT_BUILD_LABEL" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
export PDFCRAFT_BUILD_LABEL
|
||||
fi
|
||||
|
||||
DIST="${DIST:-$ROOT/dist/release}"
|
||||
mkdir -p "$DIST"
|
||||
export DIST
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# .deb and .rpm packages (nfpm: https://nfpm.goreleaser.com). Run by package.sh, which stages
|
||||
# the file tree, substitutes its path for ${STAGE} (nfpm doesn't expand env vars in `src`) and
|
||||
# exports VERSION and NFPM_ARCH.
|
||||
# exports VERSION, RELEASE and NFPM_ARCH.
|
||||
#
|
||||
# nfpm package -f packaging/linux/nfpm.yaml -p deb -t dist/release/
|
||||
name: pdfcraft
|
||||
@@ -9,7 +9,9 @@ platform: linux
|
||||
version: ${VERSION}
|
||||
# semver: 0.2.0-rc.1 becomes 0.2.0~rc.1 in deb/rpm, so pre-releases sort before the release.
|
||||
version_schema: semver
|
||||
release: 1
|
||||
# 1 for releases; 1.<label> for a labelled local build (PDFCRAFT_BUILD_LABEL), which sorts after
|
||||
# the release of the same version and before the next one.
|
||||
release: ${RELEASE}
|
||||
section: graphics
|
||||
priority: optional
|
||||
maintainer: ${PDFCRAFT_MAINTAINER}
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
# $DIST/pdfcraft-<version>-linux-<arch>.tar.gz plain FHS-style tree (bin/, share/)
|
||||
# $DIST/pdfcraft-cli-<version>-linux-<arch>.tar.gz the headless CLI alone (servers, CI, agents)
|
||||
#
|
||||
# A local or patched build: set PDFCRAFT_BUILD_LABEL (e.g. `titlebar`). `--version` and About then
|
||||
# show `0.7.1 (titlebar)`, file names carry `-titlebar`, and the .rpm/.deb release becomes
|
||||
# `1.titlebar`, which upgrades over the release of the same version (and the next release over it).
|
||||
#
|
||||
# Cross-compiling (CI: riscv64, tar only): set CROSS_ARCH (riscv64), CROSS_TARGET (the Rust target),
|
||||
# CROSS_COMPILE (binutils prefix, for strip) and optionally EMULATOR (e.g. qemu-riscv64) to
|
||||
# smoke-test the CLI.
|
||||
@@ -30,7 +34,7 @@ while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--skip-build) SKIP_BUILD=1; shift ;;
|
||||
--formats) FORMATS="$2"; shift 2 ;;
|
||||
-h | --help) sed -n '2,20p' "$0"; exit 0 ;;
|
||||
-h | --help) sed -n '2,24p' "$0"; exit 0 ;;
|
||||
*) echo "unknown argument: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
@@ -43,9 +47,10 @@ case "$ARCH" in
|
||||
*) echo "unsupported architecture $ARCH" >&2; exit 2 ;;
|
||||
esac
|
||||
export PDFCRAFT_MAINTAINER="${PDFCRAFT_MAINTAINER:-PdfCraft maintainers <pdfcraft@storyteller.ai>}"
|
||||
BASENAME="pdfcraft-$VERSION-linux-$ARCH"
|
||||
LABEL_SUFFIX="${PDFCRAFT_BUILD_LABEL:+-$PDFCRAFT_BUILD_LABEL}"
|
||||
BASENAME="pdfcraft-$VERSION$LABEL_SUFFIX-linux-$ARCH"
|
||||
|
||||
echo "==> PdfCraft $VERSION for Linux $ARCH ($FORMATS)"
|
||||
echo "==> PdfCraft $VERSION$LABEL_SUFFIX for Linux $ARCH ($FORMATS)"
|
||||
|
||||
if [ "$SKIP_BUILD" = 0 ]; then
|
||||
if [ -n "${CROSS_TARGET:-}" ]; then
|
||||
@@ -96,7 +101,7 @@ fi
|
||||
# The stripped pdfcraft-cli (and its opt-in MCP server) with the licences, for machines that never
|
||||
# open a window. Like the other formats it needs glibc >= the build host's.
|
||||
if has cli; then
|
||||
CLI_NAME="pdfcraft-cli-$VERSION-linux-$ARCH"
|
||||
CLI_NAME="pdfcraft-cli-$VERSION$LABEL_SUFFIX-linux-$ARCH"
|
||||
CLI_DIR="$WORK/cli/$CLI_NAME"
|
||||
mkdir -p "$CLI_DIR"
|
||||
cp "$STAGE/usr/bin/pdfcraft-cli" "$CLI_DIR/"
|
||||
@@ -109,6 +114,7 @@ fi
|
||||
if has deb || has rpm; then
|
||||
command -v nfpm >/dev/null || { echo "error: nfpm not found (https://nfpm.goreleaser.com/install/)" >&2; exit 1; }
|
||||
export VERSION
|
||||
export RELEASE="1${PDFCRAFT_BUILD_LABEL:+.$PDFCRAFT_BUILD_LABEL}"
|
||||
export NFPM_ARCH="$DEB_ARCH"
|
||||
# nfpm expands env vars in fields like `version` and `arch`, but not in `contents[].src`.
|
||||
sed "s|\${STAGE}|$STAGE|g" "$HERE/nfpm.yaml" >"$WORK/nfpm.yaml"
|
||||
|
||||
Reference in new issue
Block a user