at 23.05-pre 10 kB view raw
1{ pkgs 2, options 3, config 4, version 5, revision 6, extraSources ? [] 7, baseOptionsJSON ? null 8, warningsAreErrors ? true 9, allowDocBook ? true 10, prefix ? ../../.. 11}: 12 13with pkgs; 14 15let 16 inherit (lib) hasPrefix removePrefix; 17 18 lib = pkgs.lib; 19 20 docbook_xsl_ns = pkgs.docbook-xsl-ns.override { 21 withManOptDedupPatch = true; 22 }; 23 24 # We need to strip references to /nix/store/* from options, 25 # including any `extraSources` if some modules came from elsewhere, 26 # or else the build will fail. 27 # 28 # E.g. if some `options` came from modules in ${pkgs.customModules}/nix, 29 # you'd need to include `extraSources = [ pkgs.customModules ]` 30 prefixesToStrip = map (p: "${toString p}/") ([ prefix ] ++ extraSources); 31 stripAnyPrefixes = lib.flip (lib.foldr lib.removePrefix) prefixesToStrip; 32 33 optionsDoc = buildPackages.nixosOptionsDoc { 34 inherit options revision baseOptionsJSON warningsAreErrors allowDocBook; 35 transformOptions = opt: opt // { 36 # Clean up declaration sites to not refer to the NixOS source tree. 37 declarations = map stripAnyPrefixes opt.declarations; 38 }; 39 }; 40 41 nixos-lib = import ../../lib { }; 42 43 testOptionsDoc = let 44 eval = nixos-lib.evalTest { 45 # Avoid evaluating a NixOS config prototype. 46 config.node.type = lib.types.deferredModule; 47 options._module.args = lib.mkOption { internal = true; }; 48 }; 49 in buildPackages.nixosOptionsDoc { 50 inherit (eval) options; 51 inherit (revision); 52 transformOptions = opt: opt // { 53 # Clean up declaration sites to not refer to the NixOS source tree. 54 declarations = 55 map 56 (decl: 57 if hasPrefix (toString ../../..) (toString decl) 58 then 59 let subpath = removePrefix "/" (removePrefix (toString ../../..) (toString decl)); 60 in { url = "https://github.com/NixOS/nixpkgs/blob/master/${subpath}"; name = subpath; } 61 else decl) 62 opt.declarations; 63 }; 64 documentType = "none"; 65 variablelistId = "test-options-list"; 66 optionIdPrefix = "test-opt-"; 67 }; 68 69 sources = lib.sourceFilesBySuffices ./. [".xml"]; 70 71 modulesDoc = builtins.toFile "modules.xml" '' 72 <section xmlns:xi="http://www.w3.org/2001/XInclude" id="modules"> 73 ${(lib.concatMapStrings (path: '' 74 <xi:include href="${path}" /> 75 '') (lib.catAttrs "value" config.meta.doc))} 76 </section> 77 ''; 78 79 generatedSources = runCommand "generated-docbook" {} '' 80 mkdir $out 81 ln -s ${modulesDoc} $out/modules.xml 82 ln -s ${optionsDoc.optionsDocBook} $out/options-db.xml 83 ln -s ${testOptionsDoc.optionsDocBook} $out/test-options-db.xml 84 printf "%s" "${version}" > $out/version 85 ''; 86 87 copySources = 88 '' 89 cp -prd $sources/* . # */ 90 ln -s ${generatedSources} ./generated 91 chmod -R u+w . 92 ''; 93 94 toc = builtins.toFile "toc.xml" 95 '' 96 <toc role="chunk-toc"> 97 <d:tocentry xmlns:d="http://docbook.org/ns/docbook" linkend="book-nixos-manual"><?dbhtml filename="index.html"?> 98 <d:tocentry linkend="ch-options"><?dbhtml filename="options.html"?></d:tocentry> 99 <d:tocentry linkend="ch-release-notes"><?dbhtml filename="release-notes.html"?></d:tocentry> 100 </d:tocentry> 101 </toc> 102 ''; 103 104 manualXsltprocOptions = toString [ 105 "--param section.autolabel 1" 106 "--param section.label.includes.component.label 1" 107 "--stringparam html.stylesheet 'style.css overrides.css highlightjs/mono-blue.css'" 108 "--stringparam html.script './highlightjs/highlight.pack.js ./highlightjs/loader.js'" 109 "--param xref.with.number.and.title 1" 110 "--param toc.section.depth 0" 111 "--param generate.consistent.ids 1" 112 "--stringparam admon.style ''" 113 "--stringparam callout.graphics.extension .svg" 114 "--stringparam current.docid manual" 115 "--param chunk.section.depth 0" 116 "--param chunk.first.sections 1" 117 "--param use.id.as.filename 1" 118 "--stringparam chunk.toc ${toc}" 119 ]; 120 121 manual-combined = runCommand "nixos-manual-combined" 122 { inherit sources; 123 nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ]; 124 meta.description = "The NixOS manual as plain docbook XML"; 125 } 126 '' 127 ${copySources} 128 129 xmllint --xinclude --output ./manual-combined.xml ./manual.xml 130 xmllint --xinclude --noxincludenode \ 131 --output ./man-pages-combined.xml ./man-pages.xml 132 133 # outputs the context of an xmllint error output 134 # LEN lines around the failing line are printed 135 function context { 136 # length of context 137 local LEN=6 138 # lines to print before error line 139 local BEFORE=4 140 141 # xmllint output lines are: 142 # file.xml:1234: there was an error on line 1234 143 while IFS=':' read -r file line rest; do 144 echo 145 if [[ -n "$rest" ]]; then 146 echo "$file:$line:$rest" 147 local FROM=$(($line>$BEFORE ? $line - $BEFORE : 1)) 148 # number lines & filter context 149 nl --body-numbering=a "$file" | sed -n "$FROM,+$LEN p" 150 else 151 if [[ -n "$line" ]]; then 152 echo "$file:$line" 153 else 154 echo "$file" 155 fi 156 fi 157 done 158 } 159 160 function lintrng { 161 xmllint --debug --noout --nonet \ 162 --relaxng ${docbook5}/xml/rng/docbook/docbook.rng \ 163 "$1" \ 164 2>&1 | context 1>&2 165 # ^ redirect assumes xmllint doesnt print to stdout 166 } 167 168 mkdir $out 169 cp manual-combined.xml $out/ 170 cp man-pages-combined.xml $out/ 171 172 lintrng $out/manual-combined.xml 173 lintrng $out/man-pages-combined.xml 174 ''; 175 176 olinkDB = runCommand "manual-olinkdb" 177 { inherit sources; 178 nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ]; 179 } 180 '' 181 xsltproc \ 182 ${manualXsltprocOptions} \ 183 --stringparam collect.xref.targets only \ 184 --stringparam targets.filename "$out/manual.db" \ 185 --nonet \ 186 ${docbook_xsl_ns}/xml/xsl/docbook/xhtml/chunktoc.xsl \ 187 ${manual-combined}/manual-combined.xml 188 189 cat > "$out/olinkdb.xml" <<EOF 190 <?xml version="1.0" encoding="utf-8"?> 191 <!DOCTYPE targetset SYSTEM 192 "file://${docbook_xsl_ns}/xml/xsl/docbook/common/targetdatabase.dtd" [ 193 <!ENTITY manualtargets SYSTEM "file://$out/manual.db"> 194 ]> 195 <targetset> 196 <targetsetinfo> 197 Allows for cross-referencing olinks between the manpages 198 and manual. 199 </targetsetinfo> 200 201 <document targetdoc="manual">&manualtargets;</document> 202 </targetset> 203 EOF 204 ''; 205 206in rec { 207 inherit generatedSources; 208 209 inherit (optionsDoc) optionsJSON optionsNix optionsDocBook; 210 211 # Generate the NixOS manual. 212 manualHTML = runCommand "nixos-manual-html" 213 { inherit sources; 214 nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ]; 215 meta.description = "The NixOS manual in HTML format"; 216 allowedReferences = ["out"]; 217 } 218 '' 219 # Generate the HTML manual. 220 dst=$out/share/doc/nixos 221 mkdir -p $dst 222 xsltproc \ 223 ${manualXsltprocOptions} \ 224 --stringparam target.database.document "${olinkDB}/olinkdb.xml" \ 225 --stringparam id.warnings "1" \ 226 --nonet --output $dst/ \ 227 ${docbook_xsl_ns}/xml/xsl/docbook/xhtml/chunktoc.xsl \ 228 ${manual-combined}/manual-combined.xml \ 229 |& tee xsltproc.out 230 grep "^ID recommended on" xsltproc.out &>/dev/null && echo "error: some IDs are missing" && false 231 rm xsltproc.out 232 233 mkdir -p $dst/images/callouts 234 cp ${docbook_xsl_ns}/xml/xsl/docbook/images/callouts/*.svg $dst/images/callouts/ 235 236 cp ${../../../doc/style.css} $dst/style.css 237 cp ${../../../doc/overrides.css} $dst/overrides.css 238 cp -r ${pkgs.documentation-highlighter} $dst/highlightjs 239 240 mkdir -p $out/nix-support 241 echo "nix-build out $out" >> $out/nix-support/hydra-build-products 242 echo "doc manual $dst" >> $out/nix-support/hydra-build-products 243 ''; # */ 244 245 # Alias for backward compatibility. TODO(@oxij): remove eventually. 246 manual = manualHTML; 247 248 # Index page of the NixOS manual. 249 manualHTMLIndex = "${manualHTML}/share/doc/nixos/index.html"; 250 251 manualEpub = runCommand "nixos-manual-epub" 252 { inherit sources; 253 nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin buildPackages.zip ]; 254 } 255 '' 256 # Generate the epub manual. 257 dst=$out/share/doc/nixos 258 259 xsltproc \ 260 ${manualXsltprocOptions} \ 261 --stringparam target.database.document "${olinkDB}/olinkdb.xml" \ 262 --nonet --xinclude --output $dst/epub/ \ 263 ${docbook_xsl_ns}/xml/xsl/docbook/epub/docbook.xsl \ 264 ${manual-combined}/manual-combined.xml 265 266 mkdir -p $dst/epub/OEBPS/images/callouts 267 cp -r ${docbook_xsl_ns}/xml/xsl/docbook/images/callouts/*.svg $dst/epub/OEBPS/images/callouts # */ 268 echo "application/epub+zip" > mimetype 269 manual="$dst/nixos-manual.epub" 270 zip -0Xq "$manual" mimetype 271 cd $dst/epub && zip -Xr9D "$manual" * 272 273 rm -rf $dst/epub 274 275 mkdir -p $out/nix-support 276 echo "doc-epub manual $manual" >> $out/nix-support/hydra-build-products 277 ''; 278 279 280 # Generate the NixOS manpages. 281 manpages = runCommand "nixos-manpages" 282 { inherit sources; 283 nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ]; 284 allowedReferences = ["out"]; 285 } 286 '' 287 # Generate manpages. 288 mkdir -p $out/share/man 289 xsltproc --nonet \ 290 --maxdepth 6000 \ 291 --param man.output.in.separate.dir 1 \ 292 --param man.output.base.dir "'$out/share/man/'" \ 293 --param man.endnotes.are.numbered 0 \ 294 --param man.break.after.slash 1 \ 295 --stringparam target.database.document "${olinkDB}/olinkdb.xml" \ 296 ${docbook_xsl_ns}/xml/xsl/docbook/manpages/docbook.xsl \ 297 ${manual-combined}/man-pages-combined.xml 298 ''; 299 300}