From 26c94eb3db62ec6eebbf8d22c11afe691d9520c4 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sun, 13 Sep 2026 02:31:32 +0200 Subject: krino: release 0.0.1 — man pages, install, examples, cross and release, README, changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also: undo removes the directories its run created; a hardlink is never a duplicate of its own other name; a flag written before "undo" is honoured; --version prints no leading v. Duplicate conditions with different scopes not sharing an original is documented as a known limitation. --- scripts/deps | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ scripts/man-lint | 68 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100755 scripts/deps create mode 100755 scripts/man-lint (limited to 'scripts') diff --git a/scripts/deps b/scripts/deps new file mode 100755 index 0000000..06faaa2 --- /dev/null +++ b/scripts/deps @@ -0,0 +1,99 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-3.0-or-later +# +# scripts/deps: install krino's optional content extractors with the host's +# system package manager, per docs/design.md §14. +# +# --print prints the exact command this script would run (and the reason, +# when one platform's package list differs from the others), then exits +# without running anything and without asking for privileges. `make deps` +# calls this script with no flag; plain `make`/`make build` never calls it +# at all, so plain `make` never asks for privileges (§14). +# +# Detection: +# - Debian family - /etc/os-release's ID *or* ID_LIKE names "debian" as +# one of its (possibly multi-word) values. Devuan is ID=devuan, +# ID_LIKE=debian: keying on ID=debian alone would leave it unrecognised. +# -> apt-get install poppler-utils catdoc antiword +# - FreeBSD (uname -s) -> pkg install poppler-utils antiword. catdoc is +# left out on purpose: it pulls in tcl/tk. +# - OpenBSD (uname -s) -> pkg_add poppler-utils catdoc antiword +# - anything else: print what is needed and exit non-zero. This script +# never guesses a package manager. +# +# Privileges: doas if present, else sudo; if neither exists (and we are not +# already root), the command is printed for the user to run as root +# themselves, rather than attempting it unprivileged and failing silently. + +set -eu + +print_only=0 +case "${1:-}" in + --print) print_only=1 ;; + "") ;; + *) + echo "usage: $0 [--print]" >&2 + exit 2 + ;; +esac + +# is_debian_family: true if /etc/os-release's ID or ID_LIKE contains +# "debian" as one of its space-separated words. +is_debian_family() { + [ -r /etc/os-release ] || return 1 + ( + . /etc/os-release + for word in ${ID:-} ${ID_LIKE:-}; do + [ "$word" = "debian" ] && exit 0 + done + exit 1 + ) +} + +# privileged CMD...: CMD prefixed with doas or sudo, whichever is found +# first; unprefixed if we are already root or if neither exists (the +# caller decides what to do in that last case). +privileged() { + if [ "$(id -u)" = 0 ]; then + printf '%s\n' "$*" + elif command -v doas >/dev/null 2>&1; then + printf 'doas %s\n' "$*" + elif command -v sudo >/dev/null 2>&1; then + printf 'sudo %s\n' "$*" + else + printf '%s\n' "$*" + fi +} + +note="" +if is_debian_family; then + pkgcmd="apt-get install poppler-utils catdoc antiword" +elif [ "$(uname -s)" = "FreeBSD" ]; then + pkgcmd="pkg install poppler-utils antiword" + note="catdoc left out on FreeBSD: it pulls in tcl/tk." +elif [ "$(uname -s)" = "OpenBSD" ]; then + pkgcmd="pkg_add poppler-utils catdoc antiword" +else + echo "krino's optional extractors: poppler-utils (pdftotext), catdoc, antiword" >&2 + echo "no supported package manager detected (uname -s: $(uname -s), no debian-family /etc/os-release)" >&2 + echo "install them yourself with whatever this system uses" >&2 + exit 1 +fi + +cmd=$(privileged $pkgcmd) + +[ -n "$note" ] && echo "$note" + +if [ "$print_only" = 1 ]; then + echo "$cmd" + exit 0 +fi + +if [ "$(id -u)" != 0 ] && ! command -v doas >/dev/null 2>&1 && ! command -v sudo >/dev/null 2>&1; then + echo "neither doas nor sudo found; run this yourself as root:" >&2 + echo "$cmd" >&2 + exit 1 +fi + +echo "$cmd" +exec $cmd diff --git a/scripts/man-lint b/scripts/man-lint new file mode 100755 index 0000000..7b563b7 --- /dev/null +++ b/scripts/man-lint @@ -0,0 +1,68 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-3.0-or-later +# +# man-lint: check the mdoc man pages for real errors, not just "did it run". +# +# Prefers `mandoc -Tlint -Wwarning`. -W sets the lowest message level that +# mandoc reports and counts in its exit status, so this fails (exit 2 or +# higher) on any WARNING, ERROR or UNSUPP message. STYLE and BASE messages +# (for example "referenced manual not found" for pages not yet installed) +# are below that level: not shown, and never a failure. -Werror would not +# do: it hides warnings and exits 0 on them. +# +# Falls back to `groff -ww -z -mdoc` when mandoc is not installed. Two traps +# with that fallback, both deliberate here: +# - the pages are written in the mdoc macro package, not man(7), so this +# must ask groff for -mdoc specifically; the wrong package produces +# noise (or silently accepts things mdoc would reject); +# - groff exits 0 whether or not it complained - -z asks it to run only +# the diagnostics pass (no formatted output), so anything at all on its +# stderr, not its exit code, is what "failed" means here. +# +# Skips with a printed notice, exit 0, when neither tool is installed: a +# machine with no man toolchain must not fail this gate, the same way +# internal/ignore's git-oracle test skips itself when git is absent. +# +# Usage: scripts/man-lint [FILE...] (default: man/*.[15]) + +set -eu + +cd "$(git rev-parse --show-toplevel)" + +if [ "$#" -gt 0 ]; then + # shellcheck disable=SC2124 # deliberately captured as one word list below + files="$*" +else + files='man/*.[15]' +fi +# shellcheck disable=SC2086 # $files is a glob pattern or an arg list, meant to split/expand +set -- $files +if [ "$#" -eq 0 ] || [ ! -e "$1" ]; then + echo "man-lint: no man pages found ($files)" >&2 + exit 1 +fi + +if command -v mandoc >/dev/null 2>&1; then + echo "man-lint: mandoc -Tlint -Wwarning $*" + exec mandoc -Tlint -Wwarning "$@" +fi + +if command -v groff >/dev/null 2>&1; then + fail=0 + for f in "$@"; do + echo "man-lint: groff -ww -z -mdoc $f" + out=$(groff -ww -z -mdoc "$f" 2>&1 >/dev/null) || true + if [ -n "$out" ]; then + printf 'man-lint: %s:\n%s\n' "$f" "$out" | sed '2,$s/^/ /' >&2 + fail=1 + fi + done + if [ "$fail" -ne 0 ]; then + echo "man-lint: groff reported the warnings above; it exits 0 regardless, so stderr output alone is the failure signal here" >&2 + exit 1 + fi + exit 0 +fi + +echo "man-lint: neither mandoc nor groff is installed; skipping man page lint" >&2 +exit 0 -- cgit v1.3