diff --git a/doc/hooks/installShellFiles.section.md b/doc/hooks/installShellFiles.section.md index 26ccf29f2fdb..697ac955e23a 100644 --- a/doc/hooks/installShellFiles.section.md +++ b/doc/hooks/installShellFiles.section.md @@ -43,11 +43,42 @@ The manpages must have a section suffix, and may optionally be compressed (with nativeBuildInputs = [ installShellFiles ]; # Sometimes the manpage file has an undersirable name; e.g. it conflicts with - # another software with an equal name. It should be renamed before being - # installed via installManPage + # another software with an equal name. To install it with a different name, + # the installed name must be provided before the path to the file. + # + # Below install a manpage "foobar.1" from the source file "./foobar.1", and + # also installs the manpage "fromsea.3" from the source file "./delmar.3". postInstall = '' - mv fromsea.3 delmar.3 - installManPage foobar.1 delmar.3 + installManPage \ + foobar.1 \ + --name fromsea.3 delmar.3 + ''; +} +``` + +The manpage may be the result of a piped input (e.g. `<(cmd)`), in which +case the name must be provided before the pipe with the `--name` flag. + +```nix +{ + nativeBuildInputs = [ installShellFiles ]; + + postInstall = '' + installManPage --name foobar.1 <($out/bin/foobar --manpage) + ''; +} +``` + +If no parsing of arguments is desired, pass `--` to opt-out of all subsequent +arguments. + +```nix +{ + nativeBuildInputs = [ installShellFiles ]; + + # Installs a manpage from a file called "--name" + postInstall = '' + installManPage -- --name ''; } ``` diff --git a/doc/release-notes/rl-2511.section.md b/doc/release-notes/rl-2511.section.md index f64c5c024273..604561c3422a 100644 --- a/doc/release-notes/rl-2511.section.md +++ b/doc/release-notes/rl-2511.section.md @@ -20,6 +20,8 @@ - The `offrss` package was removed due to lack of upstream maintenance since 2012. It's recommended for users to migrate to another RSS reader +- `installShellFiles`: Allow installManPage to take a piped input, add the `--name` flag for renaming the file when installed. Can also append `--` to opt-out of all subsequent parsing. + - `base16-builder` node package has been removed due to lack of upstream maintenance. - `gentium` package now provides `Gentium-*.ttf` files, and not `GentiumPlus-*.ttf` files like before. The font identifiers `Gentium Plus*` are available in the `gentium-plus` package, and if you want to use the more recently updated package `gentium` [by sil](https://software.sil.org/gentium/), you should update your configuration files to use the `Gentium` font identifier. - `space-orbit` package has been removed due to lack of upstream maintenance. Debian upstream stopped tracking it in 2011. diff --git a/pkgs/by-name/in/installShellFiles/setup-hook.sh b/pkgs/by-name/in/installShellFiles/setup-hook.sh index 94231824222c..7835e320b6cb 100644 --- a/pkgs/by-name/in/installShellFiles/setup-hook.sh +++ b/pkgs/by-name/in/installShellFiles/setup-hook.sh @@ -16,35 +16,87 @@ # # See comments on each function for more details. -# installManPage [...] +# installManPage [--name ] [...] # # Each argument is checked for its man section suffix and installed into the appropriate # share/man/man/ 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 } diff --git a/pkgs/by-name/in/installShellFiles/tests/install-manpage-fifo.nix b/pkgs/by-name/in/installShellFiles/tests/install-manpage-fifo.nix new file mode 100644 index 000000000000..b0b50ad709d6 --- /dev/null +++ b/pkgs/by-name/in/installShellFiles/tests/install-manpage-fifo.nix @@ -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 + '' diff --git a/pkgs/by-name/in/installShellFiles/tests/install-manpage-named.nix b/pkgs/by-name/in/installShellFiles/tests/install-manpage-named.nix new file mode 100644 index 000000000000..afc94f0e4b5e --- /dev/null +++ b/pkgs/by-name/in/installShellFiles/tests/install-manpage-named.nix @@ -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 + '' diff --git a/pkgs/by-name/in/installShellFiles/tests/install-manpage.nix b/pkgs/by-name/in/installShellFiles/tests/install-manpage.nix index 7b67d0aed94c..abcbb7ac6a08 100644 --- a/pkgs/by-name/in/installShellFiles/tests/install-manpage.nix +++ b/pkgs/by-name/in/installShellFiles/tests/install-manpage.nix @@ -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 ''