nixpkgs/NixOS manuals: devmode feature
Co-authored-by: Alejandro Sanchez Medina <alejandrosanchzmedina@gmail.com>
This commit is contained in:
parent
a49d40a005
commit
a064709342
5 changed files with 167 additions and 0 deletions
|
@ -23,6 +23,14 @@ $ nix-shell
|
|||
|
||||
If the build succeeds, the manual will be in `./result/share/doc/nixpkgs/manual.html`.
|
||||
|
||||
## devmode {#sec-contributing-devmode}
|
||||
|
||||
The shell in the manual source directory makes available a command, `devmode`.
|
||||
It is a daemon, that:
|
||||
1. watches the manual's source for changes and when they occur — rebuilds
|
||||
2. HTTP serves the manual, injecting a script that triggers reload on changes
|
||||
3. opens the manual in the default browser
|
||||
|
||||
## Syntax {#sec-contributing-markup}
|
||||
|
||||
As per [RFC 0072](https://github.com/NixOS/rfcs/pull/72), all new documentation content should be written in [CommonMark](https://commonmark.org/) Markdown dialect.
|
||||
|
|
20
doc/shell.nix
Normal file
20
doc/shell.nix
Normal file
|
@ -0,0 +1,20 @@
|
|||
let
|
||||
pkgs = import ../. {
|
||||
config = {};
|
||||
overlays = [];
|
||||
};
|
||||
|
||||
common = import ./common.nix;
|
||||
inherit (common) outputPath indexPath;
|
||||
|
||||
web-devmode = import ../pkgs/tools/nix/web-devmode.nix {
|
||||
inherit pkgs;
|
||||
buildArgs = "./.";
|
||||
open = "/${outputPath}/${indexPath}";
|
||||
};
|
||||
in
|
||||
pkgs.mkShell {
|
||||
packages = [
|
||||
web-devmode
|
||||
];
|
||||
}
|
|
@ -11,6 +11,8 @@ $ nix-build nixos/release.nix -A manual.x86_64-linux
|
|||
|
||||
If the build succeeds, the manual will be in `./result/share/doc/nixos/index.html`.
|
||||
|
||||
There's also [a convenient development daemon](https://nixos.org/manual/nixpkgs/unstable/#sec-contributing-devmode).
|
||||
|
||||
**Contributing to the man pages**
|
||||
|
||||
The man pages are written in [DocBook] which is XML.
|
||||
|
|
20
nixos/doc/manual/shell.nix
Normal file
20
nixos/doc/manual/shell.nix
Normal file
|
@ -0,0 +1,20 @@
|
|||
let
|
||||
pkgs = import ../../.. {
|
||||
config = {};
|
||||
overlays = [];
|
||||
};
|
||||
|
||||
common = import ./common.nix;
|
||||
inherit (common) outputPath indexPath;
|
||||
|
||||
web-devmode = import ../../../pkgs/tools/nix/web-devmode.nix {
|
||||
inherit pkgs;
|
||||
buildArgs = "../../release.nix -A manualHTML.${builtins.currentSystem}";
|
||||
open = "/${outputPath}/${indexPath}";
|
||||
};
|
||||
in
|
||||
pkgs.mkShell {
|
||||
packages = [
|
||||
web-devmode
|
||||
];
|
||||
}
|
117
pkgs/tools/nix/web-devmode.nix
Normal file
117
pkgs/tools/nix/web-devmode.nix
Normal file
|
@ -0,0 +1,117 @@
|
|||
{
|
||||
pkgs,
|
||||
# arguments to `nix-build`, e.g. `"foo.nix -A bar"`
|
||||
buildArgs,
|
||||
# what path to open a browser at
|
||||
open,
|
||||
}: let
|
||||
inherit (pkgs) lib;
|
||||
|
||||
error_page = pkgs.writeShellScriptBin "error_page" ''
|
||||
echo "<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root { filter: invert(100%); }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body><pre>$1</pre></body>
|
||||
</html>"
|
||||
'';
|
||||
|
||||
# The following would have been simpler:
|
||||
# 1. serve from `$serve`
|
||||
# 2. pass each build a `--out-link $serve/result`
|
||||
# But that way live-server does not seem to detect changes and therefore no
|
||||
# auto-reloads occur.
|
||||
# Instead, we copy the contents of each build to the `$serve` directory.
|
||||
# Using rsync here, instead of `cp`, to get as close to an atomic
|
||||
# directory copy operation as possible. `--delay-updates` should
|
||||
# also go towards that.
|
||||
build_and_copy = pkgs.writeShellScriptBin "build_and_copy" ''
|
||||
set -euxo pipefail
|
||||
|
||||
set +e
|
||||
stderr=$(2>&1 nix-build --out-link $out_link ${buildArgs})
|
||||
exit_status=$?
|
||||
set -e
|
||||
|
||||
if [ $exit_status -eq 0 ];
|
||||
then
|
||||
# setting permissions to be able to clean up
|
||||
${lib.getBin pkgs.rsync}/bin/rsync \
|
||||
--recursive \
|
||||
--chmod=u=rwX \
|
||||
--delete-before \
|
||||
--delay-updates \
|
||||
$out_link/ \
|
||||
$serve/
|
||||
else
|
||||
set +x
|
||||
${lib.getBin error_page}/bin/error_page "$stderr" > $error_page_absolute
|
||||
set -x
|
||||
|
||||
${lib.getBin pkgs.findutils}/bin/find $serve \
|
||||
-type f \
|
||||
! -name $error_page_relative \
|
||||
-delete
|
||||
fi
|
||||
'';
|
||||
|
||||
# https://watchexec.github.io/
|
||||
watcher = pkgs.writeShellScriptBin "watcher" ''
|
||||
set -euxo pipefail
|
||||
|
||||
${lib.getBin pkgs.watchexec}/bin/watchexec \
|
||||
--shell=none \
|
||||
--restart \
|
||||
--print-events \
|
||||
${lib.getBin build_and_copy}/bin/build_and_copy
|
||||
'';
|
||||
|
||||
# A Rust alternative to live-server exists, but it was not in nixpkgs.
|
||||
# `--no-css-inject`: without this it seems that only CSS is auto-reloaded.
|
||||
# https://www.npmjs.com/package/live-server
|
||||
server = pkgs.writeShellScriptBin "server" ''
|
||||
set -euxo pipefail
|
||||
|
||||
${lib.getBin pkgs.nodePackages_latest.live-server}/bin/live-server \
|
||||
--host=127.0.0.1 \
|
||||
--verbose \
|
||||
--no-css-inject \
|
||||
--entry-file=$error_page_relative \
|
||||
--open=${open} \
|
||||
$serve
|
||||
'';
|
||||
|
||||
devmode =
|
||||
pkgs.writeShellScriptBin "devmode"
|
||||
''
|
||||
set -euxo pipefail
|
||||
|
||||
function handle_exit {
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
trap handle_exit EXIT
|
||||
|
||||
export out_link="$tmpdir/result"
|
||||
export serve="$tmpdir/serve"
|
||||
mkdir $serve
|
||||
export error_page_relative=error.html
|
||||
export error_page_absolute=$serve/$error_page_relative
|
||||
${lib.getBin error_page}/bin/error_page "building …" > $error_page_absolute
|
||||
|
||||
${lib.getBin pkgs.parallel}/bin/parallel \
|
||||
--will-cite \
|
||||
--line-buffer \
|
||||
--tagstr '{/}' \
|
||||
::: \
|
||||
"${lib.getBin watcher}/bin/watcher" \
|
||||
"${lib.getBin server}/bin/server"
|
||||
'';
|
||||
in
|
||||
devmode
|
Loading…
Reference in a new issue