installShellFiles: Allow installManPage to take a piped input

This commit is contained in:
Ross Smyth
2025-08-12 21:52:23 -04:00
parent 6a1097d4c4
commit cf9f475350
4 changed files with 106 additions and 10 deletions
+62 -10
View File
@@ -16,35 +16,87 @@
#
# See comments on each function for more details.
# installManPage <path> [...<path>]
# installManPage [--name <path>] <path> [...<path>]
#
# Each argument is checked for its man section suffix and installed into the appropriate
# share/man/man<n>/ directory. The function returns an error if any paths don't have the man
# section suffix (with optional .gz compression).
#
# Optionally accepts pipes as input, which when provided require the `--name` argument to
# name the output file.
#
# installManPage --name foobar.1 <($out/bin/foobar --manpage)
installManPage() {
local path
for path in "$@"; do
if test -z "$path"; then
local arg name='' continueParsing=1
while { arg=$1; shift; }; do
if (( continueParsing )); then
case "$arg" in
--name)
name=$1
shift || {
nixErrorLog "${FUNCNAME[0]}: --name flag expected an argument"
return 1
}
continue;;
--name=*)
# Treat `--name=foo` that same as `--name foo`
name=${arg#--name=}
continue;;
--)
continueParsing=0
continue;;
esac
fi
nixInfoLog "${FUNCNAME[0]}: installing $arg${name:+ as $name}"
local basename
# Check if path is empty
if test -z "$arg"; then
# It is an empty string
nixErrorLog "${FUNCNAME[0]}: path cannot be empty"
return 1
fi
nixInfoLog "${FUNCNAME[0]}: installing $path"
local basename
basename=$(stripHash "$path") # use stripHash in case it's a nix store path
if test -n "$name"; then
# Provided name. Required for pipes, optional for paths
basename=$name
elif test -p "$arg"; then
# Named pipe requires a file name
nixErrorLog "${FUNCNAME[0]}: named pipe requires --name argument"
else
# Normal file without a name
basename=$(stripHash "$arg") # use stripHash in case it's a nix store path
fi
# Check that it is well-formed
local trimmed=${basename%.gz} # don't get fooled by compressed manpages
local suffix=${trimmed##*.}
if test -z "$suffix" -o "$suffix" = "$trimmed"; then
nixErrorLog "${FUNCNAME[0]}: path missing manpage section suffix: $path"
nixErrorLog "${FUNCNAME[0]}: path missing manpage section suffix: $arg"
return 1
fi
# Create the out-path
local outRoot
if test "$suffix" = 3; then
outRoot=${!outputDevman:?}
else
outRoot=${!outputMan:?}
fi
local outPath="${outRoot}/share/man/man$suffix/$basename"
install -D --mode=644 --no-target-directory "$path" "$outPath"
local outPath="${outRoot}/share/man/man$suffix/"
nixInfoLog "${FUNCNAME[0]}: installing to $outPath"
# Install
if test -p "$arg"; then
# install doesn't work with pipes on Darwin
mkdir -p "$outPath" && cat "$arg" > "$outPath/$basename"
else
install -D --mode=644 --no-target-directory -- "$arg" "$outPath/$basename"
fi
# Reset the name for the next page
name=
done
}
@@ -0,0 +1,23 @@
{
lib,
installShellFiles,
runCommandLocal,
}:
runCommandLocal "install-shell-files--install-manpage-fifo"
{
nativeBuildInputs = [ installShellFiles ];
meta.platforms = lib.platforms.all;
}
''
installManPage doc/*
installManPage \
--name foo.1 <(echo foo) \
--name=bar.2 <(echo bar) \
--name baz.3 <(echo baz)
echo "foo" | cmp - $out/share/man/man1/foo.1
echo "bar" | cmp - $out/share/man/man2/bar.2
echo "baz" | cmp - $out/share/man/man3/baz.3
''
@@ -0,0 +1,18 @@
{
lib,
installShellFiles,
runCommandLocal,
}:
runCommandLocal "install-shell-files--install-manpage"
{
nativeBuildInputs = [ installShellFiles ];
meta.platforms = lib.platforms.all;
}
''
echo foo > foo.1
installManPage --name bar.1 foo.1
cmp foo.1 $out/share/man/man1/bar.1
''
@@ -14,10 +14,13 @@ runCommandLocal "install-shell-files--install-manpage"
echo foo > doc/foo.1
echo bar > doc/bar.2.gz
echo baz > doc/baz.3
echo buzz > --name.1
installManPage doc/*
installManPage -- --name.1
cmp doc/foo.1 $out/share/man/man1/foo.1
cmp doc/bar.2.gz $out/share/man/man2/bar.2.gz
cmp doc/baz.3 $out/share/man/man3/baz.3
cmp -- --name.1 $out/share/man/man1/--name.1
''