Merge remote-tracking branch 'nixos/master' into readFile-scan-references

This commit is contained in:
Théophane Hufschmitt 2022-11-14 15:00:05 +01:00
commit 8b4352d79b
56 changed files with 1342 additions and 438 deletions

5
.github/assign-by-files.yml vendored Normal file
View file

@ -0,0 +1,5 @@
---
# This files is used by https://github.com/marketplace/actions/auto-assign-reviewer-by-files
# to assign maintainers
"doc/**/*":
- fricklerhandwerk

12
.github/workflows/assign-reviewer.yml vendored Normal file
View file

@ -0,0 +1,12 @@
name: "Auto Assign"
on:
- pull_request
jobs:
assign_reviewer:
runs-on: ubuntu-latest
steps:
- uses: shufo/auto-assign-reviewer-by-files@v1.1.4
with:
config: ".github/assign-by-files.yml"
token: ${{ secrets.GITHUB_TOKEN }}

View file

@ -19,9 +19,9 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: cachix/install-nix-action@v17 - uses: cachix/install-nix-action@v18
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV - run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
- uses: cachix/cachix-action@v10 - uses: cachix/cachix-action@v12
if: needs.check_secrets.outputs.cachix == 'true' if: needs.check_secrets.outputs.cachix == 'true'
with: with:
name: '${{ env.CACHIX_NAME }}' name: '${{ env.CACHIX_NAME }}'
@ -58,8 +58,8 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV - run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
- uses: cachix/install-nix-action@v17 - uses: cachix/install-nix-action@v18
- uses: cachix/cachix-action@v10 - uses: cachix/cachix-action@v12
with: with:
name: '${{ env.CACHIX_NAME }}' name: '${{ env.CACHIX_NAME }}'
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
@ -77,7 +77,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV - run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
- uses: cachix/install-nix-action@v17 - uses: cachix/install-nix-action@v18
with: with:
install_url: '${{needs.installer.outputs.installerURL}}' install_url: '${{needs.installer.outputs.installerURL}}'
install_options: "--tarball-url-prefix https://${{ env.CACHIX_NAME }}.cachix.org/serve" install_options: "--tarball-url-prefix https://${{ env.CACHIX_NAME }}.cachix.org/serve"
@ -102,10 +102,10 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: cachix/install-nix-action@v17 - uses: cachix/install-nix-action@v18
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV - run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
- run: echo NIX_VERSION="$(nix --experimental-features 'nix-command flakes' eval .\#default.version | tr -d \")" >> $GITHUB_ENV - run: echo NIX_VERSION="$(nix --experimental-features 'nix-command flakes' eval .\#default.version | tr -d \")" >> $GITHUB_ENV
- uses: cachix/cachix-action@v10 - uses: cachix/cachix-action@v12
if: needs.check_secrets.outputs.cachix == 'true' if: needs.check_secrets.outputs.cachix == 'true'
with: with:
name: '${{ env.CACHIX_NAME }}' name: '${{ env.CACHIX_NAME }}'

View file

@ -1,11 +1,11 @@
{ command }: { toplevel }:
with builtins; with builtins;
with import ./utils.nix; with import ./utils.nix;
let let
showCommand = { command, details, filename }: showCommand = { command, details, filename, toplevel }:
let let
result = '' result = ''
> **Warning** \ > **Warning** \
@ -57,14 +57,15 @@ let
maybeOptions = if details.flags == {} then "" else '' maybeOptions = if details.flags == {} then "" else ''
# Options # Options
${showOptions details.flags} ${showOptions details.flags toplevel.flags}
''; '';
showOptions = options: showOptions = options: commonOptions:
let let
allOptions = options // commonOptions;
showCategory = cat: '' showCategory = cat: ''
${if cat != "" then "**${cat}:**" else ""} ${if cat != "" then "**${cat}:**" else ""}
${listOptions (filterAttrs (n: v: v.category == cat) options)} ${listOptions (filterAttrs (n: v: v.category == cat) allOptions)}
''; '';
listOptions = opts: concatStringsSep "\n" (attrValues (mapAttrs showOption opts)); listOptions = opts: concatStringsSep "\n" (attrValues (mapAttrs showOption opts));
showOption = name: option: showOption = name: option:
@ -76,30 +77,33 @@ let
${option.description} ${option.description}
''; '';
categories = sort builtins.lessThan (unique (map (cmd: cmd.category) (attrValues options))); categories = sort builtins.lessThan (unique (map (cmd: cmd.category) (attrValues allOptions)));
in concatStrings (map showCategory categories); in concatStrings (map showCategory categories);
in squash result; in squash result;
appendName = filename: name: (if filename == "nix" then "nix3" else filename) + "-" + name; appendName = filename: name: (if filename == "nix" then "nix3" else filename) + "-" + name;
processCommand = { command, details, filename }: processCommand = { command, details, filename, toplevel }:
let let
cmd = { cmd = {
inherit command; inherit command;
name = filename + ".md"; name = filename + ".md";
value = showCommand { inherit command details filename; }; value = showCommand { inherit command details filename toplevel; };
}; };
subcommand = subCmd: processCommand { subcommand = subCmd: processCommand {
command = command + " " + subCmd; command = command + " " + subCmd;
details = details.commands.${subCmd}; details = details.commands.${subCmd};
filename = appendName filename subCmd; filename = appendName filename subCmd;
inherit toplevel;
}; };
in [ cmd ] ++ concatMap subcommand (attrNames details.commands or {}); in [ cmd ] ++ concatMap subcommand (attrNames details.commands or {});
parsedToplevel = builtins.fromJSON toplevel;
manpages = processCommand { manpages = processCommand {
command = "nix"; command = "nix";
details = builtins.fromJSON command; details = parsedToplevel;
filename = "nix"; filename = "nix";
toplevel = parsedToplevel;
}; };
tableOfContents = let tableOfContents = let

View file

@ -11,16 +11,16 @@ concatStrings (map
+ concatStrings (map (s: " ${s}\n") (splitLines option.description)) + "\n\n" + concatStrings (map (s: " ${s}\n") (splitLines option.description)) + "\n\n"
+ (if option.documentDefault + (if option.documentDefault
then " **Default:** " + ( then " **Default:** " + (
if option.value == "" || option.value == [] if option.defaultValue == "" || option.defaultValue == []
then "*empty*" then "*empty*"
else if isBool option.value else if isBool option.defaultValue
then (if option.value then "`true`" else "`false`") then (if option.defaultValue then "`true`" else "`false`")
else else
# n.b. a StringMap value type is specified as a string, but # n.b. a StringMap value type is specified as a string, but
# this shows the value type. The empty stringmap is "null" in # this shows the value type. The empty stringmap is "null" in
# JSON, but that converts to "{ }" here. # JSON, but that converts to "{ }" here.
(if isAttrs option.value then "`\"\"`" (if isAttrs option.defaultValue then "`\"\"`"
else "`" + toString option.value + "`")) + "\n\n" else "`" + toString option.defaultValue + "`")) + "\n\n"
else " **Default:** *machine-specific*\n") else " **Default:** *machine-specific*\n")
+ (if option.aliases != [] + (if option.aliases != []
then " **Deprecated alias:** " + (concatStringsSep ", " (map (s: "`${s}`") option.aliases)) + "\n\n" then " **Deprecated alias:** " + (concatStringsSep ", " (map (s: "`${s}`") option.aliases)) + "\n\n"

View file

@ -50,7 +50,7 @@ $(d)/src/SUMMARY.md: $(d)/src/SUMMARY.md.in $(d)/src/command-ref/new-cli
$(d)/src/command-ref/new-cli: $(d)/nix.json $(d)/generate-manpage.nix $(bindir)/nix $(d)/src/command-ref/new-cli: $(d)/nix.json $(d)/generate-manpage.nix $(bindir)/nix
@rm -rf $@ @rm -rf $@
$(trace-gen) $(nix-eval) --write-to $@ --expr 'import doc/manual/generate-manpage.nix { command = builtins.readFile $<; }' $(trace-gen) $(nix-eval) --write-to $@ --expr 'import doc/manual/generate-manpage.nix { toplevel = builtins.readFile $<; }'
$(d)/src/command-ref/conf-file.md: $(d)/conf-file.json $(d)/generate-options.nix $(d)/src/command-ref/conf-file-prefix.md $(bindir)/nix $(d)/src/command-ref/conf-file.md: $(d)/conf-file.json $(d)/generate-options.nix $(d)/src/command-ref/conf-file-prefix.md $(bindir)/nix
@cat doc/manual/src/command-ref/conf-file-prefix.md > $@.tmp @cat doc/manual/src/command-ref/conf-file-prefix.md > $@.tmp

View file

@ -1,330 +1,424 @@
// Redirects from old DocBook manual. // redirect rules for anchors ensure backwards compatibility of URLs.
var redirects = { // this must be done on the client side, as web servers do not see the anchor part of the URL.
"#part-advanced-topics": "advanced-topics/advanced-topics.html",
"#chap-tuning-cores-and-jobs": "advanced-topics/cores-vs-jobs.html", // redirections are declared as follows:
"#chap-diff-hook": "advanced-topics/diff-hook.html", // each entry has as its key a path matching the requested URL path, relative to the mdBook document root.
"#check-dirs-are-unregistered": "advanced-topics/diff-hook.html#check-dirs-are-unregistered", //
"#chap-distributed-builds": "advanced-topics/distributed-builds.html", // IMPORTANT: it must specify the full path with file name and suffix
"#chap-post-build-hook": "advanced-topics/post-build-hook.html", //
"#chap-post-build-hook-caveats": "advanced-topics/post-build-hook.html#implementation-caveats", // each entry is itself a set of key-value pairs, where
"#part-command-ref": "command-ref/command-ref.html", // - keys are anchors on the matched path.
"#conf-allow-import-from-derivation": "command-ref/conf-file.html#conf-allow-import-from-derivation", // - values are redirection targets relative to the current path.
"#conf-allow-new-privileges": "command-ref/conf-file.html#conf-allow-new-privileges",
"#conf-allowed-uris": "command-ref/conf-file.html#conf-allowed-uris", const redirects = {
"#conf-allowed-users": "command-ref/conf-file.html#conf-allowed-users", "index.html": {
"#conf-auto-optimise-store": "command-ref/conf-file.html#conf-auto-optimise-store", "part-advanced-topics": "advanced-topics/advanced-topics.html",
"#conf-binary-cache-public-keys": "command-ref/conf-file.html#conf-binary-cache-public-keys", "chap-tuning-cores-and-jobs": "advanced-topics/cores-vs-jobs.html",
"#conf-binary-caches": "command-ref/conf-file.html#conf-binary-caches", "chap-diff-hook": "advanced-topics/diff-hook.html",
"#conf-build-compress-log": "command-ref/conf-file.html#conf-build-compress-log", "check-dirs-are-unregistered": "advanced-topics/diff-hook.html#check-dirs-are-unregistered",
"#conf-build-cores": "command-ref/conf-file.html#conf-build-cores", "chap-distributed-builds": "advanced-topics/distributed-builds.html",
"#conf-build-extra-chroot-dirs": "command-ref/conf-file.html#conf-build-extra-chroot-dirs", "chap-post-build-hook": "advanced-topics/post-build-hook.html",
"#conf-build-extra-sandbox-paths": "command-ref/conf-file.html#conf-build-extra-sandbox-paths", "chap-post-build-hook-caveats": "advanced-topics/post-build-hook.html#implementation-caveats",
"#conf-build-fallback": "command-ref/conf-file.html#conf-build-fallback", "part-command-ref": "command-ref/command-ref.html",
"#conf-build-max-jobs": "command-ref/conf-file.html#conf-build-max-jobs", "conf-allow-import-from-derivation": "command-ref/conf-file.html#conf-allow-import-from-derivation",
"#conf-build-max-log-size": "command-ref/conf-file.html#conf-build-max-log-size", "conf-allow-new-privileges": "command-ref/conf-file.html#conf-allow-new-privileges",
"#conf-build-max-silent-time": "command-ref/conf-file.html#conf-build-max-silent-time", "conf-allowed-uris": "command-ref/conf-file.html#conf-allowed-uris",
"#conf-build-repeat": "command-ref/conf-file.html#conf-build-repeat", "conf-allowed-users": "command-ref/conf-file.html#conf-allowed-users",
"#conf-build-timeout": "command-ref/conf-file.html#conf-build-timeout", "conf-auto-optimise-store": "command-ref/conf-file.html#conf-auto-optimise-store",
"#conf-build-use-chroot": "command-ref/conf-file.html#conf-build-use-chroot", "conf-binary-cache-public-keys": "command-ref/conf-file.html#conf-binary-cache-public-keys",
"#conf-build-use-sandbox": "command-ref/conf-file.html#conf-build-use-sandbox", "conf-binary-caches": "command-ref/conf-file.html#conf-binary-caches",
"#conf-build-use-substitutes": "command-ref/conf-file.html#conf-build-use-substitutes", "conf-build-compress-log": "command-ref/conf-file.html#conf-build-compress-log",
"#conf-build-users-group": "command-ref/conf-file.html#conf-build-users-group", "conf-build-cores": "command-ref/conf-file.html#conf-build-cores",
"#conf-builders": "command-ref/conf-file.html#conf-builders", "conf-build-extra-chroot-dirs": "command-ref/conf-file.html#conf-build-extra-chroot-dirs",
"#conf-builders-use-substitutes": "command-ref/conf-file.html#conf-builders-use-substitutes", "conf-build-extra-sandbox-paths": "command-ref/conf-file.html#conf-build-extra-sandbox-paths",
"#conf-compress-build-log": "command-ref/conf-file.html#conf-compress-build-log", "conf-build-fallback": "command-ref/conf-file.html#conf-build-fallback",
"#conf-connect-timeout": "command-ref/conf-file.html#conf-connect-timeout", "conf-build-max-jobs": "command-ref/conf-file.html#conf-build-max-jobs",
"#conf-cores": "command-ref/conf-file.html#conf-cores", "conf-build-max-log-size": "command-ref/conf-file.html#conf-build-max-log-size",
"#conf-diff-hook": "command-ref/conf-file.html#conf-diff-hook", "conf-build-max-silent-time": "command-ref/conf-file.html#conf-build-max-silent-time",
"#conf-enforce-determinism": "command-ref/conf-file.html#conf-enforce-determinism", "conf-build-repeat": "command-ref/conf-file.html#conf-build-repeat",
"#conf-env-keep-derivations": "command-ref/conf-file.html#conf-env-keep-derivations", "conf-build-timeout": "command-ref/conf-file.html#conf-build-timeout",
"#conf-extra-binary-caches": "command-ref/conf-file.html#conf-extra-binary-caches", "conf-build-use-chroot": "command-ref/conf-file.html#conf-build-use-chroot",
"#conf-extra-platforms": "command-ref/conf-file.html#conf-extra-platforms", "conf-build-use-sandbox": "command-ref/conf-file.html#conf-build-use-sandbox",
"#conf-extra-sandbox-paths": "command-ref/conf-file.html#conf-extra-sandbox-paths", "conf-build-use-substitutes": "command-ref/conf-file.html#conf-build-use-substitutes",
"#conf-extra-substituters": "command-ref/conf-file.html#conf-extra-substituters", "conf-build-users-group": "command-ref/conf-file.html#conf-build-users-group",
"#conf-fallback": "command-ref/conf-file.html#conf-fallback", "conf-builders": "command-ref/conf-file.html#conf-builders",
"#conf-fsync-metadata": "command-ref/conf-file.html#conf-fsync-metadata", "conf-builders-use-substitutes": "command-ref/conf-file.html#conf-builders-use-substitutes",
"#conf-gc-keep-derivations": "command-ref/conf-file.html#conf-gc-keep-derivations", "conf-compress-build-log": "command-ref/conf-file.html#conf-compress-build-log",
"#conf-gc-keep-outputs": "command-ref/conf-file.html#conf-gc-keep-outputs", "conf-connect-timeout": "command-ref/conf-file.html#conf-connect-timeout",
"#conf-hashed-mirrors": "command-ref/conf-file.html#conf-hashed-mirrors", "conf-cores": "command-ref/conf-file.html#conf-cores",
"#conf-http-connections": "command-ref/conf-file.html#conf-http-connections", "conf-diff-hook": "command-ref/conf-file.html#conf-diff-hook",
"#conf-keep-build-log": "command-ref/conf-file.html#conf-keep-build-log", "conf-enforce-determinism": "command-ref/conf-file.html#conf-enforce-determinism",
"#conf-keep-derivations": "command-ref/conf-file.html#conf-keep-derivations", "conf-env-keep-derivations": "command-ref/conf-file.html#conf-env-keep-derivations",
"#conf-keep-env-derivations": "command-ref/conf-file.html#conf-keep-env-derivations", "conf-extra-binary-caches": "command-ref/conf-file.html#conf-extra-binary-caches",
"#conf-keep-outputs": "command-ref/conf-file.html#conf-keep-outputs", "conf-extra-platforms": "command-ref/conf-file.html#conf-extra-platforms",
"#conf-max-build-log-size": "command-ref/conf-file.html#conf-max-build-log-size", "conf-extra-sandbox-paths": "command-ref/conf-file.html#conf-extra-sandbox-paths",
"#conf-max-free": "command-ref/conf-file.html#conf-max-free", "conf-extra-substituters": "command-ref/conf-file.html#conf-extra-substituters",
"#conf-max-jobs": "command-ref/conf-file.html#conf-max-jobs", "conf-fallback": "command-ref/conf-file.html#conf-fallback",
"#conf-max-silent-time": "command-ref/conf-file.html#conf-max-silent-time", "conf-fsync-metadata": "command-ref/conf-file.html#conf-fsync-metadata",
"#conf-min-free": "command-ref/conf-file.html#conf-min-free", "conf-gc-keep-derivations": "command-ref/conf-file.html#conf-gc-keep-derivations",
"#conf-narinfo-cache-negative-ttl": "command-ref/conf-file.html#conf-narinfo-cache-negative-ttl", "conf-gc-keep-outputs": "command-ref/conf-file.html#conf-gc-keep-outputs",
"#conf-narinfo-cache-positive-ttl": "command-ref/conf-file.html#conf-narinfo-cache-positive-ttl", "conf-hashed-mirrors": "command-ref/conf-file.html#conf-hashed-mirrors",
"#conf-netrc-file": "command-ref/conf-file.html#conf-netrc-file", "conf-http-connections": "command-ref/conf-file.html#conf-http-connections",
"#conf-plugin-files": "command-ref/conf-file.html#conf-plugin-files", "conf-keep-build-log": "command-ref/conf-file.html#conf-keep-build-log",
"#conf-post-build-hook": "command-ref/conf-file.html#conf-post-build-hook", "conf-keep-derivations": "command-ref/conf-file.html#conf-keep-derivations",
"#conf-pre-build-hook": "command-ref/conf-file.html#conf-pre-build-hook", "conf-keep-env-derivations": "command-ref/conf-file.html#conf-keep-env-derivations",
"#conf-repeat": "command-ref/conf-file.html#conf-repeat", "conf-keep-outputs": "command-ref/conf-file.html#conf-keep-outputs",
"#conf-require-sigs": "command-ref/conf-file.html#conf-require-sigs", "conf-max-build-log-size": "command-ref/conf-file.html#conf-max-build-log-size",
"#conf-restrict-eval": "command-ref/conf-file.html#conf-restrict-eval", "conf-max-free": "command-ref/conf-file.html#conf-max-free",
"#conf-run-diff-hook": "command-ref/conf-file.html#conf-run-diff-hook", "conf-max-jobs": "command-ref/conf-file.html#conf-max-jobs",
"#conf-sandbox": "command-ref/conf-file.html#conf-sandbox", "conf-max-silent-time": "command-ref/conf-file.html#conf-max-silent-time",
"#conf-sandbox-dev-shm-size": "command-ref/conf-file.html#conf-sandbox-dev-shm-size", "conf-min-free": "command-ref/conf-file.html#conf-min-free",
"#conf-sandbox-paths": "command-ref/conf-file.html#conf-sandbox-paths", "conf-narinfo-cache-negative-ttl": "command-ref/conf-file.html#conf-narinfo-cache-negative-ttl",
"#conf-secret-key-files": "command-ref/conf-file.html#conf-secret-key-files", "conf-narinfo-cache-positive-ttl": "command-ref/conf-file.html#conf-narinfo-cache-positive-ttl",
"#conf-show-trace": "command-ref/conf-file.html#conf-show-trace", "conf-netrc-file": "command-ref/conf-file.html#conf-netrc-file",
"#conf-stalled-download-timeout": "command-ref/conf-file.html#conf-stalled-download-timeout", "conf-plugin-files": "command-ref/conf-file.html#conf-plugin-files",
"#conf-substitute": "command-ref/conf-file.html#conf-substitute", "conf-post-build-hook": "command-ref/conf-file.html#conf-post-build-hook",
"#conf-substituters": "command-ref/conf-file.html#conf-substituters", "conf-pre-build-hook": "command-ref/conf-file.html#conf-pre-build-hook",
"#conf-system": "command-ref/conf-file.html#conf-system", "conf-repeat": "command-ref/conf-file.html#conf-repeat",
"#conf-system-features": "command-ref/conf-file.html#conf-system-features", "conf-require-sigs": "command-ref/conf-file.html#conf-require-sigs",
"#conf-tarball-ttl": "command-ref/conf-file.html#conf-tarball-ttl", "conf-restrict-eval": "command-ref/conf-file.html#conf-restrict-eval",
"#conf-timeout": "command-ref/conf-file.html#conf-timeout", "conf-run-diff-hook": "command-ref/conf-file.html#conf-run-diff-hook",
"#conf-trace-function-calls": "command-ref/conf-file.html#conf-trace-function-calls", "conf-sandbox": "command-ref/conf-file.html#conf-sandbox",
"#conf-trusted-binary-caches": "command-ref/conf-file.html#conf-trusted-binary-caches", "conf-sandbox-dev-shm-size": "command-ref/conf-file.html#conf-sandbox-dev-shm-size",
"#conf-trusted-public-keys": "command-ref/conf-file.html#conf-trusted-public-keys", "conf-sandbox-paths": "command-ref/conf-file.html#conf-sandbox-paths",
"#conf-trusted-substituters": "command-ref/conf-file.html#conf-trusted-substituters", "conf-secret-key-files": "command-ref/conf-file.html#conf-secret-key-files",
"#conf-trusted-users": "command-ref/conf-file.html#conf-trusted-users", "conf-show-trace": "command-ref/conf-file.html#conf-show-trace",
"#extra-sandbox-paths": "command-ref/conf-file.html#extra-sandbox-paths", "conf-stalled-download-timeout": "command-ref/conf-file.html#conf-stalled-download-timeout",
"#sec-conf-file": "command-ref/conf-file.html", "conf-substitute": "command-ref/conf-file.html#conf-substitute",
"#env-NIX_PATH": "command-ref/env-common.html#env-NIX_PATH", "conf-substituters": "command-ref/conf-file.html#conf-substituters",
"#env-common": "command-ref/env-common.html", "conf-system": "command-ref/conf-file.html#conf-system",
"#envar-remote": "command-ref/env-common.html#env-NIX_REMOTE", "conf-system-features": "command-ref/conf-file.html#conf-system-features",
"#sec-common-env": "command-ref/env-common.html", "conf-tarball-ttl": "command-ref/conf-file.html#conf-tarball-ttl",
"#ch-files": "command-ref/files.html", "conf-timeout": "command-ref/conf-file.html#conf-timeout",
"#ch-main-commands": "command-ref/main-commands.html", "conf-trace-function-calls": "command-ref/conf-file.html#conf-trace-function-calls",
"#opt-out-link": "command-ref/nix-build.html#opt-out-link", "conf-trusted-binary-caches": "command-ref/conf-file.html#conf-trusted-binary-caches",
"#sec-nix-build": "command-ref/nix-build.html", "conf-trusted-public-keys": "command-ref/conf-file.html#conf-trusted-public-keys",
"#sec-nix-channel": "command-ref/nix-channel.html", "conf-trusted-substituters": "command-ref/conf-file.html#conf-trusted-substituters",
"#sec-nix-collect-garbage": "command-ref/nix-collect-garbage.html", "conf-trusted-users": "command-ref/conf-file.html#conf-trusted-users",
"#sec-nix-copy-closure": "command-ref/nix-copy-closure.html", "extra-sandbox-paths": "command-ref/conf-file.html#extra-sandbox-paths",
"#sec-nix-daemon": "command-ref/nix-daemon.html", "sec-conf-file": "command-ref/conf-file.html",
"#refsec-nix-env-install-examples": "command-ref/nix-env.html#examples", "env-NIX_PATH": "command-ref/env-common.html#env-NIX_PATH",
"#rsec-nix-env-install": "command-ref/nix-env.html#operation---install", "env-common": "command-ref/env-common.html",
"#rsec-nix-env-set": "command-ref/nix-env.html#operation---set", "envar-remote": "command-ref/env-common.html#env-NIX_REMOTE",
"#rsec-nix-env-set-flag": "command-ref/nix-env.html#operation---set-flag", "sec-common-env": "command-ref/env-common.html",
"#rsec-nix-env-upgrade": "command-ref/nix-env.html#operation---upgrade", "ch-files": "command-ref/files.html",
"#sec-nix-env": "command-ref/nix-env.html", "ch-main-commands": "command-ref/main-commands.html",
"#ssec-version-comparisons": "command-ref/nix-env.html#versions", "opt-out-link": "command-ref/nix-build.html#opt-out-link",
"#sec-nix-hash": "command-ref/nix-hash.html", "sec-nix-build": "command-ref/nix-build.html",
"#sec-nix-instantiate": "command-ref/nix-instantiate.html", "sec-nix-channel": "command-ref/nix-channel.html",
"#sec-nix-prefetch-url": "command-ref/nix-prefetch-url.html", "sec-nix-collect-garbage": "command-ref/nix-collect-garbage.html",
"#sec-nix-shell": "command-ref/nix-shell.html", "sec-nix-copy-closure": "command-ref/nix-copy-closure.html",
"#ssec-nix-shell-shebang": "command-ref/nix-shell.html#use-as-a--interpreter", "sec-nix-daemon": "command-ref/nix-daemon.html",
"#nixref-queries": "command-ref/nix-store.html#queries", "refsec-nix-env-install-examples": "command-ref/nix-env.html#examples",
"#opt-add-root": "command-ref/nix-store.html#opt-add-root", "rsec-nix-env-install": "command-ref/nix-env.html#operation---install",
"#refsec-nix-store-dump": "command-ref/nix-store.html#operation---dump", "rsec-nix-env-set": "command-ref/nix-env.html#operation---set",
"#refsec-nix-store-export": "command-ref/nix-store.html#operation---export", "rsec-nix-env-set-flag": "command-ref/nix-env.html#operation---set-flag",
"#refsec-nix-store-import": "command-ref/nix-store.html#operation---import", "rsec-nix-env-upgrade": "command-ref/nix-env.html#operation---upgrade",
"#refsec-nix-store-query": "command-ref/nix-store.html#operation---query", "sec-nix-env": "command-ref/nix-env.html",
"#refsec-nix-store-verify": "command-ref/nix-store.html#operation---verify", "ssec-version-comparisons": "command-ref/nix-env.html#versions",
"#rsec-nix-store-gc": "command-ref/nix-store.html#operation---gc", "sec-nix-hash": "command-ref/nix-hash.html",
"#rsec-nix-store-generate-binary-cache-key": "command-ref/nix-store.html#operation---generate-binary-cache-key", "sec-nix-instantiate": "command-ref/nix-instantiate.html",
"#rsec-nix-store-realise": "command-ref/nix-store.html#operation---realise", "sec-nix-prefetch-url": "command-ref/nix-prefetch-url.html",
"#rsec-nix-store-serve": "command-ref/nix-store.html#operation---serve", "sec-nix-shell": "command-ref/nix-shell.html",
"#sec-nix-store": "command-ref/nix-store.html", "ssec-nix-shell-shebang": "command-ref/nix-shell.html#use-as-a--interpreter",
"#opt-I": "command-ref/opt-common.html#opt-I", "nixref-queries": "command-ref/nix-store.html#queries",
"#opt-attr": "command-ref/opt-common.html#opt-attr", "opt-add-root": "command-ref/nix-store.html#opt-add-root",
"#opt-common": "command-ref/opt-common.html", "refsec-nix-store-dump": "command-ref/nix-store.html#operation---dump",
"#opt-cores": "command-ref/opt-common.html#opt-cores", "refsec-nix-store-export": "command-ref/nix-store.html#operation---export",
"#opt-log-format": "command-ref/opt-common.html#opt-log-format", "refsec-nix-store-import": "command-ref/nix-store.html#operation---import",
"#opt-max-jobs": "command-ref/opt-common.html#opt-max-jobs", "refsec-nix-store-query": "command-ref/nix-store.html#operation---query",
"#opt-max-silent-time": "command-ref/opt-common.html#opt-max-silent-time", "refsec-nix-store-verify": "command-ref/nix-store.html#operation---verify",
"#opt-timeout": "command-ref/opt-common.html#opt-timeout", "rsec-nix-store-gc": "command-ref/nix-store.html#operation---gc",
"#sec-common-options": "command-ref/opt-common.html", "rsec-nix-store-generate-binary-cache-key": "command-ref/nix-store.html#operation---generate-binary-cache-key",
"#ch-utilities": "command-ref/utilities.html", "rsec-nix-store-realise": "command-ref/nix-store.html#operation---realise",
"#chap-hacking": "contributing/hacking.html", "rsec-nix-store-serve": "command-ref/nix-store.html#operation---serve",
"#adv-attr-allowSubstitutes": "language/advanced-attributes.html#adv-attr-allowSubstitutes", "sec-nix-store": "command-ref/nix-store.html",
"#adv-attr-allowedReferences": "language/advanced-attributes.html#adv-attr-allowedReferences", "opt-I": "command-ref/opt-common.html#opt-I",
"#adv-attr-allowedRequisites": "language/advanced-attributes.html#adv-attr-allowedRequisites", "opt-attr": "command-ref/opt-common.html#opt-attr",
"#adv-attr-disallowedReferences": "language/advanced-attributes.html#adv-attr-disallowedReferences", "opt-common": "command-ref/opt-common.html",
"#adv-attr-disallowedRequisites": "language/advanced-attributes.html#adv-attr-disallowedRequisites", "opt-cores": "command-ref/opt-common.html#opt-cores",
"#adv-attr-exportReferencesGraph": "language/advanced-attributes.html#adv-attr-exportReferencesGraph", "opt-log-format": "command-ref/opt-common.html#opt-log-format",
"#adv-attr-impureEnvVars": "language/advanced-attributes.html#adv-attr-impureEnvVars", "opt-max-jobs": "command-ref/opt-common.html#opt-max-jobs",
"#adv-attr-outputHash": "language/advanced-attributes.html#adv-attr-outputHash", "opt-max-silent-time": "command-ref/opt-common.html#opt-max-silent-time",
"#adv-attr-outputHashAlgo": "language/advanced-attributes.html#adv-attr-outputHashAlgo", "opt-timeout": "command-ref/opt-common.html#opt-timeout",
"#adv-attr-outputHashMode": "language/advanced-attributes.html#adv-attr-outputHashMode", "sec-common-options": "command-ref/opt-common.html",
"#adv-attr-passAsFile": "language/advanced-attributes.html#adv-attr-passAsFile", "ch-utilities": "command-ref/utilities.html",
"#adv-attr-preferLocalBuild": "language/advanced-attributes.html#adv-attr-preferLocalBuild", "chap-hacking": "contributing/hacking.html",
"#fixed-output-drvs": "language/advanced-attributes.html#adv-attr-outputHash", "adv-attr-allowSubstitutes": "language/advanced-attributes.html#adv-attr-allowSubstitutes",
"#sec-advanced-attributes": "language/advanced-attributes.html", "adv-attr-allowedReferences": "language/advanced-attributes.html#adv-attr-allowedReferences",
"#builtin-abort": "language/builtins.html#builtins-abort", "adv-attr-allowedRequisites": "language/advanced-attributes.html#adv-attr-allowedRequisites",
"#builtin-add": "language/builtins.html#builtins-add", "adv-attr-disallowedReferences": "language/advanced-attributes.html#adv-attr-disallowedReferences",
"#builtin-all": "language/builtins.html#builtins-all", "adv-attr-disallowedRequisites": "language/advanced-attributes.html#adv-attr-disallowedRequisites",
"#builtin-any": "language/builtins.html#builtins-any", "adv-attr-exportReferencesGraph": "language/advanced-attributes.html#adv-attr-exportReferencesGraph",
"#builtin-attrNames": "language/builtins.html#builtins-attrNames", "adv-attr-impureEnvVars": "language/advanced-attributes.html#adv-attr-impureEnvVars",
"#builtin-attrValues": "language/builtins.html#builtins-attrValues", "adv-attr-outputHash": "language/advanced-attributes.html#adv-attr-outputHash",
"#builtin-baseNameOf": "language/builtins.html#builtins-baseNameOf", "adv-attr-outputHashAlgo": "language/advanced-attributes.html#adv-attr-outputHashAlgo",
"#builtin-bitAnd": "language/builtins.html#builtins-bitAnd", "adv-attr-outputHashMode": "language/advanced-attributes.html#adv-attr-outputHashMode",
"#builtin-bitOr": "language/builtins.html#builtins-bitOr", "adv-attr-passAsFile": "language/advanced-attributes.html#adv-attr-passAsFile",
"#builtin-bitXor": "language/builtins.html#builtins-bitXor", "adv-attr-preferLocalBuild": "language/advanced-attributes.html#adv-attr-preferLocalBuild",
"#builtin-builtins": "language/builtins.html#builtins-builtins", "fixed-output-drvs": "language/advanced-attributes.html#adv-attr-outputHash",
"#builtin-compareVersions": "language/builtins.html#builtins-compareVersions", "sec-advanced-attributes": "language/advanced-attributes.html",
"#builtin-concatLists": "language/builtins.html#builtins-concatLists", "builtin-abort": "language/builtins.html#builtins-abort",
"#builtin-concatStringsSep": "language/builtins.html#builtins-concatStringsSep", "builtin-add": "language/builtins.html#builtins-add",
"#builtin-currentSystem": "language/builtins.html#builtins-currentSystem", "builtin-all": "language/builtins.html#builtins-all",
"#builtin-deepSeq": "language/builtins.html#builtins-deepSeq", "builtin-any": "language/builtins.html#builtins-any",
"#builtin-derivation": "language/builtins.html#builtins-derivation", "builtin-attrNames": "language/builtins.html#builtins-attrNames",
"#builtin-dirOf": "language/builtins.html#builtins-dirOf", "builtin-attrValues": "language/builtins.html#builtins-attrValues",
"#builtin-div": "language/builtins.html#builtins-div", "builtin-baseNameOf": "language/builtins.html#builtins-baseNameOf",
"#builtin-elem": "language/builtins.html#builtins-elem", "builtin-bitAnd": "language/builtins.html#builtins-bitAnd",
"#builtin-elemAt": "language/builtins.html#builtins-elemAt", "builtin-bitOr": "language/builtins.html#builtins-bitOr",
"#builtin-fetchGit": "language/builtins.html#builtins-fetchGit", "builtin-bitXor": "language/builtins.html#builtins-bitXor",
"#builtin-fetchTarball": "language/builtins.html#builtins-fetchTarball", "builtin-builtins": "language/builtins.html#builtins-builtins",
"#builtin-fetchurl": "language/builtins.html#builtins-fetchurl", "builtin-compareVersions": "language/builtins.html#builtins-compareVersions",
"#builtin-filterSource": "language/builtins.html#builtins-filterSource", "builtin-concatLists": "language/builtins.html#builtins-concatLists",
"#builtin-foldl-prime": "language/builtins.html#builtins-foldl-prime", "builtin-concatStringsSep": "language/builtins.html#builtins-concatStringsSep",
"#builtin-fromJSON": "language/builtins.html#builtins-fromJSON", "builtin-currentSystem": "language/builtins.html#builtins-currentSystem",
"#builtin-functionArgs": "language/builtins.html#builtins-functionArgs", "builtin-deepSeq": "language/builtins.html#builtins-deepSeq",
"#builtin-genList": "language/builtins.html#builtins-genList", "builtin-derivation": "language/builtins.html#builtins-derivation",
"#builtin-getAttr": "language/builtins.html#builtins-getAttr", "builtin-dirOf": "language/builtins.html#builtins-dirOf",
"#builtin-getEnv": "language/builtins.html#builtins-getEnv", "builtin-div": "language/builtins.html#builtins-div",
"#builtin-hasAttr": "language/builtins.html#builtins-hasAttr", "builtin-elem": "language/builtins.html#builtins-elem",
"#builtin-hashFile": "language/builtins.html#builtins-hashFile", "builtin-elemAt": "language/builtins.html#builtins-elemAt",
"#builtin-hashString": "language/builtins.html#builtins-hashString", "builtin-fetchGit": "language/builtins.html#builtins-fetchGit",
"#builtin-head": "language/builtins.html#builtins-head", "builtin-fetchTarball": "language/builtins.html#builtins-fetchTarball",
"#builtin-import": "language/builtins.html#builtins-import", "builtin-fetchurl": "language/builtins.html#builtins-fetchurl",
"#builtin-intersectAttrs": "language/builtins.html#builtins-intersectAttrs", "builtin-filterSource": "language/builtins.html#builtins-filterSource",
"#builtin-isAttrs": "language/builtins.html#builtins-isAttrs", "builtin-foldl-prime": "language/builtins.html#builtins-foldl-prime",
"#builtin-isBool": "language/builtins.html#builtins-isBool", "builtin-fromJSON": "language/builtins.html#builtins-fromJSON",
"#builtin-isFloat": "language/builtins.html#builtins-isFloat", "builtin-functionArgs": "language/builtins.html#builtins-functionArgs",
"#builtin-isFunction": "language/builtins.html#builtins-isFunction", "builtin-genList": "language/builtins.html#builtins-genList",
"#builtin-isInt": "language/builtins.html#builtins-isInt", "builtin-getAttr": "language/builtins.html#builtins-getAttr",
"#builtin-isList": "language/builtins.html#builtins-isList", "builtin-getEnv": "language/builtins.html#builtins-getEnv",
"#builtin-isNull": "language/builtins.html#builtins-isNull", "builtin-hasAttr": "language/builtins.html#builtins-hasAttr",
"#builtin-isString": "language/builtins.html#builtins-isString", "builtin-hashFile": "language/builtins.html#builtins-hashFile",
"#builtin-length": "language/builtins.html#builtins-length", "builtin-hashString": "language/builtins.html#builtins-hashString",
"#builtin-lessThan": "language/builtins.html#builtins-lessThan", "builtin-head": "language/builtins.html#builtins-head",
"#builtin-listToAttrs": "language/builtins.html#builtins-listToAttrs", "builtin-import": "language/builtins.html#builtins-import",
"#builtin-map": "language/builtins.html#builtins-map", "builtin-intersectAttrs": "language/builtins.html#builtins-intersectAttrs",
"#builtin-match": "language/builtins.html#builtins-match", "builtin-isAttrs": "language/builtins.html#builtins-isAttrs",
"#builtin-mul": "language/builtins.html#builtins-mul", "builtin-isBool": "language/builtins.html#builtins-isBool",
"#builtin-parseDrvName": "language/builtins.html#builtins-parseDrvName", "builtin-isFloat": "language/builtins.html#builtins-isFloat",
"#builtin-path": "language/builtins.html#builtins-path", "builtin-isFunction": "language/builtins.html#builtins-isFunction",
"#builtin-pathExists": "language/builtins.html#builtins-pathExists", "builtin-isInt": "language/builtins.html#builtins-isInt",
"#builtin-placeholder": "language/builtins.html#builtins-placeholder", "builtin-isList": "language/builtins.html#builtins-isList",
"#builtin-readDir": "language/builtins.html#builtins-readDir", "builtin-isNull": "language/builtins.html#builtins-isNull",
"#builtin-readFile": "language/builtins.html#builtins-readFile", "builtin-isString": "language/builtins.html#builtins-isString",
"#builtin-removeAttrs": "language/builtins.html#builtins-removeAttrs", "builtin-length": "language/builtins.html#builtins-length",
"#builtin-replaceStrings": "language/builtins.html#builtins-replaceStrings", "builtin-lessThan": "language/builtins.html#builtins-lessThan",
"#builtin-seq": "language/builtins.html#builtins-seq", "builtin-listToAttrs": "language/builtins.html#builtins-listToAttrs",
"#builtin-sort": "language/builtins.html#builtins-sort", "builtin-map": "language/builtins.html#builtins-map",
"#builtin-split": "language/builtins.html#builtins-split", "builtin-match": "language/builtins.html#builtins-match",
"#builtin-splitVersion": "language/builtins.html#builtins-splitVersion", "builtin-mul": "language/builtins.html#builtins-mul",
"#builtin-stringLength": "language/builtins.html#builtins-stringLength", "builtin-parseDrvName": "language/builtins.html#builtins-parseDrvName",
"#builtin-sub": "language/builtins.html#builtins-sub", "builtin-path": "language/builtins.html#builtins-path",
"#builtin-substring": "language/builtins.html#builtins-substring", "builtin-pathExists": "language/builtins.html#builtins-pathExists",
"#builtin-tail": "language/builtins.html#builtins-tail", "builtin-placeholder": "language/builtins.html#builtins-placeholder",
"#builtin-throw": "language/builtins.html#builtins-throw", "builtin-readDir": "language/builtins.html#builtins-readDir",
"#builtin-toFile": "language/builtins.html#builtins-toFile", "builtin-readFile": "language/builtins.html#builtins-readFile",
"#builtin-toJSON": "language/builtins.html#builtins-toJSON", "builtin-removeAttrs": "language/builtins.html#builtins-removeAttrs",
"#builtin-toPath": "language/builtins.html#builtins-toPath", "builtin-replaceStrings": "language/builtins.html#builtins-replaceStrings",
"#builtin-toString": "language/builtins.html#builtins-toString", "builtin-seq": "language/builtins.html#builtins-seq",
"#builtin-toXML": "language/builtins.html#builtins-toXML", "builtin-sort": "language/builtins.html#builtins-sort",
"#builtin-trace": "language/builtins.html#builtins-trace", "builtin-split": "language/builtins.html#builtins-split",
"#builtin-tryEval": "language/builtins.html#builtins-tryEval", "builtin-splitVersion": "language/builtins.html#builtins-splitVersion",
"#builtin-typeOf": "language/builtins.html#builtins-typeOf", "builtin-stringLength": "language/builtins.html#builtins-stringLength",
"#ssec-builtins": "language/builtins.html", "builtin-sub": "language/builtins.html#builtins-sub",
"#attr-system": "language/derivations.html#attr-system", "builtin-substring": "language/builtins.html#builtins-substring",
"#ssec-derivation": "language/derivations.html", "builtin-tail": "language/builtins.html#builtins-tail",
"#ch-expression-language": "language/index.html", "builtin-throw": "language/builtins.html#builtins-throw",
"#sec-constructs": "language/constructs.html", "builtin-toFile": "language/builtins.html#builtins-toFile",
"#sect-let-language": "language/constructs.html#let-language", "builtin-toJSON": "language/builtins.html#builtins-toJSON",
"#ss-functions": "language/constructs.html#functions", "builtin-toPath": "language/builtins.html#builtins-toPath",
"#sec-language-operators": "language/operators.html", "builtin-toString": "language/builtins.html#builtins-toString",
"#table-operators": "language/operators.html", "builtin-toXML": "language/builtins.html#builtins-toXML",
"#ssec-values": "language/values.html", "builtin-trace": "language/builtins.html#builtins-trace",
"#gloss-closure": "glossary.html#gloss-closure", "builtin-tryEval": "language/builtins.html#builtins-tryEval",
"#gloss-derivation": "glossary.html#gloss-derivation", "builtin-typeOf": "language/builtins.html#builtins-typeOf",
"#gloss-deriver": "glossary.html#gloss-deriver", "ssec-builtins": "language/builtins.html",
"#gloss-nar": "glossary.html#gloss-nar", "attr-system": "language/derivations.html#attr-system",
"#gloss-output-path": "glossary.html#gloss-output-path", "ssec-derivation": "language/derivations.html",
"#gloss-profile": "glossary.html#gloss-profile", "ch-expression-language": "language/index.html",
"#gloss-reachable": "glossary.html#gloss-reachable", "sec-constructs": "language/constructs.html",
"#gloss-reference": "glossary.html#gloss-reference", "sect-let-language": "language/constructs.html#let-language",
"#gloss-substitute": "glossary.html#gloss-substitute", "ss-functions": "language/constructs.html#functions",
"#gloss-user-env": "glossary.html#gloss-user-env", "sec-language-operators": "language/operators.html",
"#gloss-validity": "glossary.html#gloss-validity", "table-operators": "language/operators.html",
"#part-glossary": "glossary.html", "ssec-values": "language/values.html",
"#sec-building-source": "installation/building-source.html", "gloss-closure": "glossary.html#gloss-closure",
"#ch-env-variables": "installation/env-variables.html", "gloss-derivation": "glossary.html#gloss-derivation",
"#sec-installer-proxy-settings": "installation/env-variables.html#proxy-environment-variables", "gloss-deriver": "glossary.html#gloss-deriver",
"#sec-nix-ssl-cert-file": "installation/env-variables.html#nix_ssl_cert_file", "gloss-nar": "glossary.html#gloss-nar",
"#sec-nix-ssl-cert-file-with-nix-daemon-and-macos": "installation/env-variables.html#nix_ssl_cert_file-with-macos-and-the-nix-daemon", "gloss-output-path": "glossary.html#gloss-output-path",
"#chap-installation": "installation/installation.html", "gloss-profile": "glossary.html#gloss-profile",
"#ch-installing-binary": "installation/installing-binary.html", "gloss-reachable": "glossary.html#gloss-reachable",
"#sect-macos-installation": "installation/installing-binary.html#macos-installation", "gloss-reference": "glossary.html#gloss-reference",
"#sect-macos-installation-change-store-prefix": "installation/installing-binary.html#macos-installation", "gloss-substitute": "glossary.html#gloss-substitute",
"#sect-macos-installation-encrypted-volume": "installation/installing-binary.html#macos-installation", "gloss-user-env": "glossary.html#gloss-user-env",
"#sect-macos-installation-recommended-notes": "installation/installing-binary.html#macos-installation", "gloss-validity": "glossary.html#gloss-validity",
"#sect-macos-installation-symlink": "installation/installing-binary.html#macos-installation", "part-glossary": "glossary.html",
"#sect-multi-user-installation": "installation/installing-binary.html#multi-user-installation", "sec-building-source": "installation/building-source.html",
"#sect-nix-install-binary-tarball": "installation/installing-binary.html#installing-from-a-binary-tarball", "ch-env-variables": "installation/env-variables.html",
"#sect-nix-install-pinned-version-url": "installation/installing-binary.html#installing-a-pinned-nix-version-from-a-url", "sec-installer-proxy-settings": "installation/env-variables.html#proxy-environment-variables",
"#sect-single-user-installation": "installation/installing-binary.html#single-user-installation", "sec-nix-ssl-cert-file": "installation/env-variables.html#nix_ssl_cert_file",
"#ch-installing-source": "installation/installing-source.html", "sec-nix-ssl-cert-file-with-nix-daemon-and-macos": "installation/env-variables.html#nix_ssl_cert_file-with-macos-and-the-nix-daemon",
"#ssec-multi-user": "installation/multi-user.html", "chap-installation": "installation/installation.html",
"#ch-nix-security": "installation/nix-security.html", "ch-installing-binary": "installation/installing-binary.html",
"#sec-obtaining-source": "installation/obtaining-source.html", "sect-macos-installation": "installation/installing-binary.html#macos-installation",
"#sec-prerequisites-source": "installation/prerequisites-source.html", "sect-macos-installation-change-store-prefix": "installation/installing-binary.html#macos-installation",
"#sec-single-user": "installation/single-user.html", "sect-macos-installation-encrypted-volume": "installation/installing-binary.html#macos-installation",
"#ch-supported-platforms": "installation/supported-platforms.html", "sect-macos-installation-recommended-notes": "installation/installing-binary.html#macos-installation",
"#ch-upgrading-nix": "installation/upgrading.html", "sect-macos-installation-symlink": "installation/installing-binary.html#macos-installation",
"#ch-about-nix": "introduction.html", "sect-multi-user-installation": "installation/installing-binary.html#multi-user-installation",
"#chap-introduction": "introduction.html", "sect-nix-install-binary-tarball": "installation/installing-binary.html#installing-from-a-binary-tarball",
"#ch-basic-package-mgmt": "package-management/basic-package-mgmt.html", "sect-nix-install-pinned-version-url": "installation/installing-binary.html#installing-a-pinned-nix-version-from-a-url",
"#ssec-binary-cache-substituter": "package-management/binary-cache-substituter.html", "sect-single-user-installation": "installation/installing-binary.html#single-user-installation",
"#sec-channels": "package-management/channels.html", "ch-installing-source": "installation/installing-source.html",
"#ssec-copy-closure": "package-management/copy-closure.html", "ssec-multi-user": "installation/multi-user.html",
"#sec-garbage-collection": "package-management/garbage-collection.html", "ch-nix-security": "installation/nix-security.html",
"#ssec-gc-roots": "package-management/garbage-collector-roots.html", "sec-obtaining-source": "installation/obtaining-source.html",
"#chap-package-management": "package-management/package-management.html", "sec-prerequisites-source": "installation/prerequisites-source.html",
"#sec-profiles": "package-management/profiles.html", "sec-single-user": "installation/single-user.html",
"#ssec-s3-substituter": "package-management/s3-substituter.html", "ch-supported-platforms": "installation/supported-platforms.html",
"#ssec-s3-substituter-anonymous-reads": "package-management/s3-substituter.html#anonymous-reads-to-your-s3-compatible-binary-cache", "ch-upgrading-nix": "installation/upgrading.html",
"#ssec-s3-substituter-authenticated-reads": "package-management/s3-substituter.html#authenticated-reads-to-your-s3-binary-cache", "ch-about-nix": "introduction.html",
"#ssec-s3-substituter-authenticated-writes": "package-management/s3-substituter.html#authenticated-writes-to-your-s3-compatible-binary-cache", "chap-introduction": "introduction.html",
"#sec-sharing-packages": "package-management/sharing-packages.html", "ch-basic-package-mgmt": "package-management/basic-package-mgmt.html",
"#ssec-ssh-substituter": "package-management/ssh-substituter.html", "ssec-binary-cache-substituter": "package-management/binary-cache-substituter.html",
"#chap-quick-start": "quick-start.html", "sec-channels": "package-management/channels.html",
"#sec-relnotes": "release-notes/release-notes.html", "ssec-copy-closure": "package-management/copy-closure.html",
"#ch-relnotes-0.10.1": "release-notes/rl-0.10.1.html", "sec-garbage-collection": "package-management/garbage-collection.html",
"#ch-relnotes-0.10": "release-notes/rl-0.10.html", "ssec-gc-roots": "package-management/garbage-collector-roots.html",
"#ssec-relnotes-0.11": "release-notes/rl-0.11.html", "chap-package-management": "package-management/package-management.html",
"#ssec-relnotes-0.12": "release-notes/rl-0.12.html", "sec-profiles": "package-management/profiles.html",
"#ssec-relnotes-0.13": "release-notes/rl-0.13.html", "ssec-s3-substituter": "package-management/s3-substituter.html",
"#ssec-relnotes-0.14": "release-notes/rl-0.14.html", "ssec-s3-substituter-anonymous-reads": "package-management/s3-substituter.html#anonymous-reads-to-your-s3-compatible-binary-cache",
"#ssec-relnotes-0.15": "release-notes/rl-0.15.html", "ssec-s3-substituter-authenticated-reads": "package-management/s3-substituter.html#authenticated-reads-to-your-s3-binary-cache",
"#ssec-relnotes-0.16": "release-notes/rl-0.16.html", "ssec-s3-substituter-authenticated-writes": "package-management/s3-substituter.html#authenticated-writes-to-your-s3-compatible-binary-cache",
"#ch-relnotes-0.5": "release-notes/rl-0.5.html", "sec-sharing-packages": "package-management/sharing-packages.html",
"#ch-relnotes-0.6": "release-notes/rl-0.6.html", "ssec-ssh-substituter": "package-management/ssh-substituter.html",
"#ch-relnotes-0.7": "release-notes/rl-0.7.html", "chap-quick-start": "quick-start.html",
"#ch-relnotes-0.8.1": "release-notes/rl-0.8.1.html", "sec-relnotes": "release-notes/release-notes.html",
"#ch-relnotes-0.8": "release-notes/rl-0.8.html", "ch-relnotes-0.10.1": "release-notes/rl-0.10.1.html",
"#ch-relnotes-0.9.1": "release-notes/rl-0.9.1.html", "ch-relnotes-0.10": "release-notes/rl-0.10.html",
"#ch-relnotes-0.9.2": "release-notes/rl-0.9.2.html", "ssec-relnotes-0.11": "release-notes/rl-0.11.html",
"#ch-relnotes-0.9": "release-notes/rl-0.9.html", "ssec-relnotes-0.12": "release-notes/rl-0.12.html",
"#ssec-relnotes-1.0": "release-notes/rl-1.0.html", "ssec-relnotes-0.13": "release-notes/rl-0.13.html",
"#ssec-relnotes-1.1": "release-notes/rl-1.1.html", "ssec-relnotes-0.14": "release-notes/rl-0.14.html",
"#ssec-relnotes-1.10": "release-notes/rl-1.10.html", "ssec-relnotes-0.15": "release-notes/rl-0.15.html",
"#ssec-relnotes-1.11.10": "release-notes/rl-1.11.10.html", "ssec-relnotes-0.16": "release-notes/rl-0.16.html",
"#ssec-relnotes-1.11": "release-notes/rl-1.11.html", "ch-relnotes-0.5": "release-notes/rl-0.5.html",
"#ssec-relnotes-1.2": "release-notes/rl-1.2.html", "ch-relnotes-0.6": "release-notes/rl-0.6.html",
"#ssec-relnotes-1.3": "release-notes/rl-1.3.html", "ch-relnotes-0.7": "release-notes/rl-0.7.html",
"#ssec-relnotes-1.4": "release-notes/rl-1.4.html", "ch-relnotes-0.8.1": "release-notes/rl-0.8.1.html",
"#ssec-relnotes-1.5.1": "release-notes/rl-1.5.1.html", "ch-relnotes-0.8": "release-notes/rl-0.8.html",
"#ssec-relnotes-1.5.2": "release-notes/rl-1.5.2.html", "ch-relnotes-0.9.1": "release-notes/rl-0.9.1.html",
"#ssec-relnotes-1.5": "release-notes/rl-1.5.html", "ch-relnotes-0.9.2": "release-notes/rl-0.9.2.html",
"#ssec-relnotes-1.6.1": "release-notes/rl-1.6.1.html", "ch-relnotes-0.9": "release-notes/rl-0.9.html",
"#ssec-relnotes-1.6.0": "release-notes/rl-1.6.html", "ssec-relnotes-1.0": "release-notes/rl-1.0.html",
"#ssec-relnotes-1.7": "release-notes/rl-1.7.html", "ssec-relnotes-1.1": "release-notes/rl-1.1.html",
"#ssec-relnotes-1.8": "release-notes/rl-1.8.html", "ssec-relnotes-1.10": "release-notes/rl-1.10.html",
"#ssec-relnotes-1.9": "release-notes/rl-1.9.html", "ssec-relnotes-1.11.10": "release-notes/rl-1.11.10.html",
"#ssec-relnotes-2.0": "release-notes/rl-2.0.html", "ssec-relnotes-1.11": "release-notes/rl-1.11.html",
"#ssec-relnotes-2.1": "release-notes/rl-2.1.html", "ssec-relnotes-1.2": "release-notes/rl-1.2.html",
"#ssec-relnotes-2.2": "release-notes/rl-2.2.html", "ssec-relnotes-1.3": "release-notes/rl-1.3.html",
"#ssec-relnotes-2.3": "release-notes/rl-2.3.html" "ssec-relnotes-1.4": "release-notes/rl-1.4.html",
"ssec-relnotes-1.5.1": "release-notes/rl-1.5.1.html",
"ssec-relnotes-1.5.2": "release-notes/rl-1.5.2.html",
"ssec-relnotes-1.5": "release-notes/rl-1.5.html",
"ssec-relnotes-1.6.1": "release-notes/rl-1.6.1.html",
"ssec-relnotes-1.6.0": "release-notes/rl-1.6.html",
"ssec-relnotes-1.7": "release-notes/rl-1.7.html",
"ssec-relnotes-1.8": "release-notes/rl-1.8.html",
"ssec-relnotes-1.9": "release-notes/rl-1.9.html",
"ssec-relnotes-2.0": "release-notes/rl-2.0.html",
"ssec-relnotes-2.1": "release-notes/rl-2.1.html",
"ssec-relnotes-2.2": "release-notes/rl-2.2.html",
"ssec-relnotes-2.3": "release-notes/rl-2.3.html"
},
"language/values.html": {
"simple-values": "#primitives",
"lists": "#list",
"strings": "#string",
"lists": "#list",
"attribute-sets": "#attribute-set"
}
}; };
var isRoot = (document.location.pathname.endsWith('/') || document.location.pathname.endsWith('/index.html')) && path_to_root === ''; // the following code matches the current page's URL against the set of redirects.
if (isRoot && redirects[document.location.hash]) { //
document.location.href = path_to_root + redirects[document.location.hash]; // it is written to minimize the latency between page load and redirect.
// therefore we avoid function calls, copying data, and unnecessary loops.
// IMPORTANT: we use stateful array operations and their order matters!
//
// matching URLs is more involved than it should be:
//
// 1. `document.location.pathname` can have an arbitrary prefix.
//
// 2. `path_to_root` is set by mdBook. it consists only of `../`s and
// determines the depth of `<path>` relative to the prefix:
//
// `document.location.pathname`
// |------------------------------|
// /<prefix>/<path>/[<file>[.html]][#<anchor>]
// |----|
// `path_to_root` has same number of path segments
//
// source: https://phaiax.github.io/mdBook/format/theme/index-hbs.html#data
//
// 3. the following paths are equivalent:
//
// /foo/bar/
// /foo/bar/index.html
// /foo/bar/index
//
// 4. the following paths are also equivalent:
//
// /foo/bar/baz
// /foo/bar/baz.html
//
let segments = document.location.pathname.split('/');
let file = segments.pop();
// normalize file name
if (file === '') { file = "index.html"; }
else if (!file.endsWith('.html')) { file = file + '.html'; }
segments.push(file);
// use `path_to_root` to discern prefix from path.
const depth = path_to_root.split('/').length;
// remove segments containing prefix. the following works because
// 1. the original `document.location.pathname` is absolute,
// hence first element of `segments` is always empty.
// 2. last element of splitting `path_to_root` is also always empty.
// 3. last element of `segments` is the file name.
//
// visual example:
//
// '/foo/bar/baz.html'.split('/') -> [ '', 'foo', 'bar', 'baz.html' ]
// '../'.split('/') -> [ '..', '' ]
//
// the following operations will then result in
//
// path = 'bar/baz.html'
//
segments.splice(0, segments.length - depth);
const path = segments.join('/');
// anchor starts with the hash character (`#`),
// but our redirect declarations don't, so we strip it.
// example:
// document.location.hash -> '#foo'
// document.location.hash.substring(1) -> 'foo'
const anchor = document.location.hash.substring(1);
const redirect = redirects[path];
if (redirect) {
const target = redirect[anchor];
if (target) {
document.location.href = target;
}
} }

View file

@ -8,6 +8,6 @@
# Description # Description
The Nix daemon is necessary in multi-user Nix installations. It performs The Nix daemon is necessary in multi-user Nix installations. It runs
build actions and other operations on the Nix store on behalf of build tasks and other operations on the Nix store on behalf of
unprivileged users. unprivileged users.

View file

@ -71,7 +71,7 @@ paths. Realisation is a somewhat overloaded term:
outputs are already valid, in which case we are done outputs are already valid, in which case we are done
immediately. Otherwise, there may be [substitutes](../glossary.md) immediately. Otherwise, there may be [substitutes](../glossary.md)
that produce the outputs (e.g., by downloading them). Finally, the that produce the outputs (e.g., by downloading them). Finally, the
outputs can be produced by performing the build action described outputs can be produced by running the build task described
by the derivation. by the derivation.
- If the store path is not a derivation, realisation ensures that the - If the store path is not a derivation, realisation ensures that the

View file

@ -1,7 +1,7 @@
# Glossary # Glossary
- [derivation]{#gloss-derivation}\ - [derivation]{#gloss-derivation}\
A description of a build action. The result of a derivation is a A description of a build task. The result of a derivation is a
store object. Derivations are typically specified in Nix expressions store object. Derivations are typically specified in Nix expressions
using the [`derivation` primitive](language/derivations.md). These are using the [`derivation` primitive](language/derivations.md). These are
translated into low-level *store derivations* (implicitly by translated into low-level *store derivations* (implicitly by
@ -53,8 +53,8 @@
A file that is an immediate child of the Nix store directory. These A file that is an immediate child of the Nix store directory. These
can be regular files, but also entire directory trees. Store objects can be regular files, but also entire directory trees. Store objects
can be sources (objects copied from outside of the store), can be sources (objects copied from outside of the store),
derivation outputs (objects produced by running a build action), or derivation outputs (objects produced by running a build task), or
derivations (files describing a build action). derivations (files describing a build task).
- [input-addressed store object]{#gloss-input-addressed-store-object}\ - [input-addressed store object]{#gloss-input-addressed-store-object}\
A store object produced by building a A store object produced by building a

View file

@ -88,10 +88,24 @@ extension. The installer will also create `/etc/profile.d/nix.sh`.
### Linux ### Linux
```console Remove files created by Nix:
sudo rm -rf /etc/profile/nix.sh /etc/nix /nix ~root/.nix-profile ~root/.nix-defexpr ~root/.nix-channels ~/.nix-profile ~/.nix-defexpr ~/.nix-channels
# If you are on Linux with systemd, you will need to run: ```console
sudo rm -rf /nix /etc/nix /etc/profile/nix.sh ~root/.nix-profile ~root/.nix-defexpr ~root/.nix-channels ~/.nix-profile ~/.nix-defexpr ~/.nix-channels
```
Remove build users and their group:
```console
for i in $(seq 30001 30032); do
sudo userdel $i
done
sudo groupdel 30000
```
If you are on Linux with systemd, remove the Nix daemon service:
```console
sudo systemctl stop nix-daemon.socket sudo systemctl stop nix-daemon.socket
sudo systemctl stop nix-daemon.service sudo systemctl stop nix-daemon.service
sudo systemctl disable nix-daemon.socket sudo systemctl disable nix-daemon.socket
@ -99,8 +113,13 @@ sudo systemctl disable nix-daemon.service
sudo systemctl daemon-reload sudo systemctl daemon-reload
``` ```
There may also be references to Nix in `/etc/profile`, `/etc/bashrc`, There may also be references to Nix in
and `/etc/zshrc` which you may remove.
- `/etc/profile`
- `/etc/bashrc`
- `/etc/zshrc`
which you may remove.
### macOS ### macOS

View file

@ -104,7 +104,7 @@ a currently running program.
Packages are built from _Nix expressions_, which is a simple Packages are built from _Nix expressions_, which is a simple
functional language. A Nix expression describes everything that goes functional language. A Nix expression describes everything that goes
into a package build action (a “derivation”): other packages, sources, into a package build task (a “derivation”): other packages, sources,
the build script, environment variables for the build script, etc. the build script, environment variables for the build script, etc.
Nix tries very hard to ensure that Nix expressions are Nix tries very hard to ensure that Nix expressions are
_deterministic_: building a Nix expression twice should yield the same _deterministic_: building a Nix expression twice should yield the same

View file

@ -1,7 +1,7 @@
# Derivations # Derivations
The most important built-in function is `derivation`, which is used to The most important built-in function is `derivation`, which is used to
describe a single derivation (a build action). It takes as input a set, describe a single derivation (a build task). It takes as input a set,
the attributes of which specify the inputs of the build. the attributes of which specify the inputs of the build.
- There must be an attribute named [`system`]{#attr-system} whose value must be a - There must be an attribute named [`system`]{#attr-system} whose value must be a

View file

@ -31,3 +31,551 @@ The Nix language is
Type errors are only detected when expressions are evaluated. Type errors are only detected when expressions are evaluated.
# Overview
This is an incomplete overview of language features, by example.
<table>
<tr>
<th>
Example
</th>
<th>
Description
</th>
</tr>
<tr>
<td>
*Basic values*
</td>
<td>
</td>
</tr>
<tr>
<td>
`"hello world"`
</td>
<td>
A string
</td>
</tr>
<tr>
<td>
```
''
multi
line
string
''
```
</td>
<td>
A multi-line string. Strips common prefixed whitespace. Evaluates to `"multi\n line\n string"`.
</td>
</tr>
<tr>
<td>
`"hello ${ { a = "world" }.a }"`
`"1 2 ${3}"`
`"${pkgs.bash}/bin/sh"`
</td>
<td>
String interpolation (expands to `"hello world"`, `"1 2 3"`, `"/nix/store/<hash>-bash-<version>/bin/sh"`)
</td>
</tr>
<tr>
<td>
`true`, `false`
</td>
<td>
Booleans
</td>
</tr>
<tr>
<td>
`null`
</td>
<td>
Null value
</td>
</tr>
<tr>
<td>
`123`
</td>
<td>
An integer
</td>
</tr>
<tr>
<td>
`3.141`
</td>
<td>
A floating point number
</td>
</tr>
<tr>
<td>
`/etc`
</td>
<td>
An absolute path
</td>
</tr>
<tr>
<td>
`./foo.png`
</td>
<td>
A path relative to the file containing this Nix expression
</td>
</tr>
<tr>
<td>
`~/.config`
</td>
<td>
A home path. Evaluates to the `"<user's home directory>/.config"`.
</td>
</tr>
<tr>
<td>
<nixpkgs>
</td>
<td>
Search path. Value determined by [`$NIX_PATH` environment variable](../command-ref/env-common.md#env-NIX_PATH).
</td>
</tr>
<tr>
<td>
*Compound values*
</td>
<td>
</td>
</tr>
<tr>
<td>
`{ x = 1; y = 2; }`
</td>
<td>
A set with attributes named `x` and `y`
</td>
</tr>
<tr>
<td>
`{ foo.bar = 1; }`
</td>
<td>
A nested set, equivalent to `{ foo = { bar = 1; }; }`
</td>
</tr>
<tr>
<td>
`rec { x = "foo"; y = x + "bar"; }`
</td>
<td>
A recursive set, equivalent to `{ x = "foo"; y = "foobar"; }`
</td>
</tr>
<tr>
<td>
`[ "foo" "bar" "baz" ]`
`[ 1 2 3 ]`
`[ (f 1) { a = 1; b = 2; } [ "c" ] ]`
</td>
<td>
Lists with three elements.
</td>
</tr>
<tr>
<td>
*Operators*
</td>
<td>
</td>
</tr>
<tr>
<td>
`"foo" + "bar"`
</td>
<td>
String concatenation
</td>
</tr>
<tr>
<td>
`1 + 2`
</td>
<td>
Integer addition
</td>
</tr>
<tr>
<td>
`"foo" == "f" + "oo"`
</td>
<td>
Equality test (evaluates to `true`)
</td>
</tr>
<tr>
<td>
`"foo" != "bar"`
</td>
<td>
Inequality test (evaluates to `true`)
</td>
</tr>
<tr>
<td>
`!true`
</td>
<td>
Boolean negation
</td>
</tr>
<tr>
<td>
`{ x = 1; y = 2; }.x`
</td>
<td>
Attribute selection (evaluates to `1`)
</td>
</tr>
<tr>
<td>
`{ x = 1; y = 2; }.z or 3`
</td>
<td>
Attribute selection with default (evaluates to `3`)
</td>
</tr>
<tr>
<td>
`{ x = 1; y = 2; } // { z = 3; }`
</td>
<td>
Merge two sets (attributes in the right-hand set taking precedence)
</td>
</tr>
<tr>
<td>
*Control structures*
</td>
<td>
</td>
</tr>
<tr>
<td>
`if 1 + 1 == 2 then "yes!" else "no!"`
</td>
<td>
Conditional expression
</td>
</tr>
<tr>
<td>
`assert 1 + 1 == 2; "yes!"`
</td>
<td>
Assertion check (evaluates to `"yes!"`).
</td>
</tr>
<tr>
<td>
`let x = "foo"; y = "bar"; in x + y`
</td>
<td>
Variable definition
</td>
</tr>
<tr>
<td>
`with builtins; head [ 1 2 3 ]`
</td>
<td>
Add all attributes from the given set to the scope (evaluates to `1`)
</td>
</tr>
<tr>
<td>
*Functions (lambdas)*
</td>
<td>
</td>
</tr>
<tr>
<td>
`x: x + 1`
</td>
<td>
A function that expects an integer and returns it increased by 1
</td>
</tr>
<tr>
<td>
`x: y: x + y`
</td>
<td>
Curried function, equivalent to `x: (y: x + y)`. Can be used like a function that takes two arguments and returns their sum.
</td>
</tr>
<tr>
<td>
`(x: x + 1) 100`
</td>
<td>
A function call (evaluates to 101)
</td>
</tr>
<tr>
<td>
`let inc = x: x + 1; in inc (inc (inc 100))`
</td>
<td>
A function bound to a variable and subsequently called by name (evaluates to 103)
</td>
</tr>
<tr>
<td>
`{ x, y }: x + y`
</td>
<td>
A function that expects a set with required attributes `x` and `y` and concatenates them
</td>
</tr>
<tr>
<td>
`{ x, y ? "bar" }: x + y`
</td>
<td>
A function that expects a set with required attribute `x` and optional `y`, using `"bar"` as default value for `y`
</td>
</tr>
<tr>
<td>
`{ x, y, ... }: x + y`
</td>
<td>
A function that expects a set with required attributes `x` and `y` and ignores any other attributes
</td>
</tr>
<tr>
<td>
`{ x, y } @ args: x + y`
`args @ { x, y }: x + y`
</td>
<td>
A function that expects a set with required attributes `x` and `y`, and binds the whole set to `args`
</td>
</tr>
<tr>
<td>
*Built-in functions*
</td>
<td>
</td>
</tr>
<tr>
<td>
`import ./foo.nix`
</td>
<td>
Load and return Nix expression in given file
</td>
</tr>
<tr>
<td>
`map (x: x + x) [ 1 2 3 ]`
</td>
<td>
Apply a function to every element of a list (evaluates to `[ 2 4 6 ]`)
</td>
</tr>
</table>

View file

@ -150,6 +150,20 @@
recognized as a path. `a.${foo}/b.${bar}` is a syntactically valid division recognized as a path. `a.${foo}/b.${bar}` is a syntactically valid division
operation. `./a.${foo}/b.${bar}` is a path. operation. `./a.${foo}/b.${bar}` is a path.
When a path appears in an antiquotation, and is thus coerced into a string,
the path is first copied into the Nix store and the resulting string is
the Nix store path. For instance `"${./foo.txt}" will cause `foo.txt` in
the current directory to be copied into the Nix store and result in the
string `"/nix/store/<HASH>-foo.txt"`.
Note that the Nix language assumes that all input files will remain
_unchanged_ during the course of the Nix expression evaluation.
If you for example antiquote a file path during a `nix repl` session, and
then later in the same session, after having changed the file contents,
evaluate the antiquotation with the file path again, then Nix will still
return the first store path. It will _not_ reread the file contents to
produce a different Nix store path.
- <a id="type-boolean" href="#type-boolean">Boolean</a> - <a id="type-boolean" href="#type-boolean">Boolean</a>
*Booleans* with values `true` and `false`. *Booleans* with values `true` and `false`.

View file

@ -58,7 +58,7 @@ readonly EXTRACTED_NIX_PATH="$(dirname "$0")"
readonly ROOT_HOME=~root readonly ROOT_HOME=~root
if [ -t 0 ]; then if [ -t 0 ] && [ -z "${NIX_INSTALLER_YES:-}" ]; then
readonly IS_HEADLESS='no' readonly IS_HEADLESS='no'
else else
readonly IS_HEADLESS='yes' readonly IS_HEADLESS='yes'

View file

@ -71,6 +71,8 @@ while [ $# -gt 0 ]; do
# # intentional tail space # # intentional tail space
# ACTIONS="${ACTIONS}uninstall " # ACTIONS="${ACTIONS}uninstall "
# ;; # ;;
--yes)
export NIX_INSTALLER_YES=1;;
--no-channel-add) --no-channel-add)
export NIX_INSTALLER_NO_CHANNEL_ADD=1;; export NIX_INSTALLER_NO_CHANNEL_ADD=1;;
--daemon-user-count) --daemon-user-count)
@ -90,7 +92,7 @@ while [ $# -gt 0 ]; do
shift;; shift;;
*) *)
{ {
echo "Nix Installer [--daemon|--no-daemon] [--daemon-user-count INT] [--no-channel-add] [--no-modify-profile] [--nix-extra-conf-file FILE]" echo "Nix Installer [--daemon|--no-daemon] [--daemon-user-count INT] [--yes] [--no-channel-add] [--no-modify-profile] [--nix-extra-conf-file FILE]"
echo "Choose installation method." echo "Choose installation method."
echo "" echo ""
@ -104,6 +106,8 @@ while [ $# -gt 0 ]; do
echo " trivial to uninstall." echo " trivial to uninstall."
echo " (default)" echo " (default)"
echo "" echo ""
echo " --yes: Run the script non-interactively, accepting all prompts."
echo ""
echo " --no-channel-add: Don't add any channels. nixpkgs-unstable is installed by default." echo " --no-channel-add: Don't add any channels. nixpkgs-unstable is installed by default."
echo "" echo ""
echo " --no-modify-profile: Don't modify the user profile to automatically load nix." echo " --no-modify-profile: Don't modify the user profile to automatically load nix."

View file

@ -28,7 +28,9 @@ if test -n "$HOME" && test -n "$USER"
# Only use MANPATH if it is already set. In general `man` will just simply # Only use MANPATH if it is already set. In general `man` will just simply
# pick up `.nix-profile/share/man` because is it close to `.nix-profile/bin` # pick up `.nix-profile/share/man` because is it close to `.nix-profile/bin`
# which is in the $PATH. For more info, run `manpath -d`. # which is in the $PATH. For more info, run `manpath -d`.
set --export --prepend --path MANPATH "$NIX_LINK/share/man" if set --query MANPATH
set --export --prepend --path MANPATH "$NIX_LINK/share/man"
end
fish_add_path --prepend --global "$NIX_LINK/bin" fish_add_path --prepend --global "$NIX_LINK/bin"
set --erase NIX_LINK set --erase NIX_LINK

View file

@ -186,12 +186,12 @@ static int main_build_remote(int argc, char * * argv)
// build the hint template. // build the hint template.
std::string errorText = std::string errorText =
"Failed to find a machine for remote build!\n" "Failed to find a machine for remote build!\n"
"derivation: %s\nrequired (system, features): (%s, %s)"; "derivation: %s\nrequired (system, features): (%s, [%s])";
errorText += "\n%s available machines:"; errorText += "\n%s available machines:";
errorText += "\n(systems, maxjobs, supportedFeatures, mandatoryFeatures)"; errorText += "\n(systems, maxjobs, supportedFeatures, mandatoryFeatures)";
for (unsigned int i = 0; i < machines.size(); ++i) for (unsigned int i = 0; i < machines.size(); ++i)
errorText += "\n(%s, %s, %s, %s)"; errorText += "\n([%s], %s, [%s], [%s])";
// add the template values. // add the template values.
std::string drvstr; std::string drvstr;

View file

@ -88,7 +88,8 @@ EvalCommand::EvalCommand()
{ {
addFlag({ addFlag({
.longName = "debugger", .longName = "debugger",
.description = "start an interactive environment if evaluation fails", .description = "Start an interactive environment if evaluation fails.",
.category = MixEvalArgs::category,
.handler = {&startReplOnEvalErrors, true}, .handler = {&startReplOnEvalErrors, true},
}); });
} }
@ -225,7 +226,7 @@ MixProfile::MixProfile()
{ {
addFlag({ addFlag({
.longName = "profile", .longName = "profile",
.description = "The profile to update.", .description = "The profile to operate on.",
.labels = {"path"}, .labels = {"path"},
.handler = {&profile}, .handler = {&profile},
.completer = completePath .completer = completePath

View file

@ -13,8 +13,6 @@ namespace nix {
MixEvalArgs::MixEvalArgs() MixEvalArgs::MixEvalArgs()
{ {
auto category = "Common evaluation options";
addFlag({ addFlag({
.longName = "arg", .longName = "arg",
.description = "Pass the value *expr* as the argument *name* to Nix functions.", .description = "Pass the value *expr* as the argument *name* to Nix functions.",

View file

@ -10,6 +10,8 @@ class Bindings;
struct MixEvalArgs : virtual Args struct MixEvalArgs : virtual Args
{ {
static constexpr auto category = "Common evaluation options";
MixEvalArgs(); MixEvalArgs();
Bindings * getAutoArgs(EvalState & state); Bindings * getAutoArgs(EvalState & state);

View file

@ -1050,7 +1050,7 @@ struct CmdRepl : InstallablesCommand
evalSettings.pureEval = false; evalSettings.pureEval = false;
} }
void prepare() void prepare() override
{ {
if (!settings.isExperimentalFeatureEnabled(Xp::ReplFlake) && !(file) && this->_installables.size() >= 1) { if (!settings.isExperimentalFeatureEnabled(Xp::ReplFlake) && !(file) && this->_installables.size() >= 1) {
warn("future versions of Nix will require using `--file` to load a file"); warn("future versions of Nix will require using `--file` to load a file");

View file

@ -904,7 +904,7 @@ void EvalState::throwEvalError(const char * s, const std::string & s2,
const std::string & s3) const std::string & s3)
{ {
debugThrowLastTrace(EvalError({ debugThrowLastTrace(EvalError({
.msg = hintfmt(s, s2), .msg = hintfmt(s, s2, s3),
.errPos = positions[noPos] .errPos = positions[noPos]
})); }));
} }
@ -913,7 +913,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri
const std::string & s3) const std::string & s3)
{ {
debugThrowLastTrace(EvalError({ debugThrowLastTrace(EvalError({
.msg = hintfmt(s, s2), .msg = hintfmt(s, s2, s3),
.errPos = positions[pos] .errPos = positions[pos]
})); }));
} }
@ -922,7 +922,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri
const std::string & s3, Env & env, Expr & expr) const std::string & s3, Env & env, Expr & expr)
{ {
debugThrow(EvalError({ debugThrow(EvalError({
.msg = hintfmt(s, s2), .msg = hintfmt(s, s2, s3),
.errPos = positions[pos] .errPos = positions[pos]
}), env, expr); }), env, expr);
} }

View file

@ -43,7 +43,7 @@ let
outputs = flake.outputs (inputs // { self = result; }); outputs = flake.outputs (inputs // { self = result; });
result = outputs // sourceInfo // { inherit inputs; inherit outputs; inherit sourceInfo; }; result = outputs // sourceInfo // { inherit inputs; inherit outputs; inherit sourceInfo; _type = "flake"; };
in in
if node.flake or true then if node.flake or true then
assert builtins.isFunction flake.outputs; assert builtins.isFunction flake.outputs;

View file

@ -3826,8 +3826,8 @@ static RegisterPrimOp primop_parseDrvName({
.args = {"s"}, .args = {"s"},
.doc = R"( .doc = R"(
Split the string *s* into a package name and version. The package Split the string *s* into a package name and version. The package
name is everything up to but not including the first dash followed name is everything up to but not including the first dash not followed
by a digit, and the version is everything following that dash. The by a letter, and the version is everything following that dash. The
result is returned in a set `{ name, version }`. Thus, result is returned in a set `{ name, version }`. Thus,
`builtins.parseDrvName "nix-0.12pre12876"` returns `{ name = `builtins.parseDrvName "nix-0.12pre12876"` returns `{ name =
"nix"; version = "0.12pre12876"; }`. "nix"; version = "0.12pre12876"; }`.

View file

@ -485,6 +485,10 @@ struct GitInputScheme : InputScheme
} }
input.attrs.insert_or_assign("ref", *head); input.attrs.insert_or_assign("ref", *head);
unlockedAttrs.insert_or_assign("ref", *head); unlockedAttrs.insert_or_assign("ref", *head);
} else {
if (!input.getRev()) {
unlockedAttrs.insert_or_assign("ref", input.getRef().value());
}
} }
if (auto res = getCache()->lookup(store, unlockedAttrs)) { if (auto res = getCache()->lookup(store, unlockedAttrs)) {

View file

@ -262,17 +262,20 @@ struct GitHubInputScheme : GitArchiveInputScheme
DownloadUrl getDownloadUrl(const Input & input) const override DownloadUrl getDownloadUrl(const Input & input) const override
{ {
// FIXME: use regular /archive URLs instead? api.github.com
// might have stricter rate limits.
auto host = maybeGetStrAttr(input.attrs, "host").value_or("github.com"); auto host = maybeGetStrAttr(input.attrs, "host").value_or("github.com");
auto url = fmt( Headers headers = makeHeadersWithAuthTokens(host);
host == "github.com" // If we have no auth headers then we default to the public archive
? "https://api.%s/repos/%s/%s/tarball/%s" // urls so we do not run into rate limits.
: "https://%s/api/v3/repos/%s/%s/tarball/%s", const auto urlFmt =
host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"), host != "github.com"
? "https://%s/api/v3/repos/%s/%s/tarball/%s"
: headers.empty()
? "https://%s/%s/%s/archive/%s.tar.gz"
: "https://api.%s/repos/%s/%s/tarball/%s";
const auto url = fmt(urlFmt, host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"),
input.getRev()->to_string(Base16, false)); input.getRev()->to_string(Base16, false));
Headers headers = makeHeadersWithAuthTokens(host);
return DownloadUrl { url, headers }; return DownloadUrl { url, headers };
} }

View file

@ -32,6 +32,7 @@ MixCommonArgs::MixCommonArgs(const std::string & programName)
addFlag({ addFlag({
.longName = "option", .longName = "option",
.description = "Set the Nix configuration setting *name* to *value* (overriding `nix.conf`).", .description = "Set the Nix configuration setting *name* to *value* (overriding `nix.conf`).",
.category = miscCategory,
.labels = {"name", "value"}, .labels = {"name", "value"},
.handler = {[](std::string name, std::string value) { .handler = {[](std::string name, std::string value) {
try { try {

View file

@ -6,6 +6,7 @@ namespace nix {
//static constexpr auto commonArgsCategory = "Miscellaneous common options"; //static constexpr auto commonArgsCategory = "Miscellaneous common options";
static constexpr auto loggingCategory = "Logging-related options"; static constexpr auto loggingCategory = "Logging-related options";
static constexpr auto miscCategory = "Miscellaneous global options";
class MixCommonArgs : public virtual Args class MixCommonArgs : public virtual Args
{ {

View file

@ -503,7 +503,7 @@ public:
return s[0]; return s[0];
} }
virtual void setPrintBuildLogs(bool printBuildLogs) void setPrintBuildLogs(bool printBuildLogs) override
{ {
this->printBuildLogs = printBuildLogs; this->printBuildLogs = printBuildLogs;
} }

View file

@ -33,6 +33,7 @@
namespace nix { namespace nix {
char * * savedArgv;
static bool gcWarning = true; static bool gcWarning = true;

View file

@ -113,5 +113,25 @@ struct PrintFreed
/* Install a SIGSEGV handler to detect stack overflows. */ /* Install a SIGSEGV handler to detect stack overflows. */
void detectStackOverflow(); void detectStackOverflow();
/* Pluggable behavior to run in case of a stack overflow.
Default value: defaultStackOverflowHandler.
This is called by the handler installed by detectStackOverflow().
This gives Nix library consumers a limit opportunity to report the error
condition. The handler should exit the process.
See defaultStackOverflowHandler() for a reference implementation.
NOTE: Use with diligence, because this runs in the signal handler, with very
limited stack space and a potentially a corrupted heap, all while the failed
thread is blocked indefinitely. All functions called must be reentrant. */
extern std::function<void(siginfo_t * info, void * ctx)> stackOverflowHandler;
/* The default, robust implementation of stackOverflowHandler.
Prints an error message directly to stderr using a syscall instead of the
logger. Exits the process immediately after. */
void defaultStackOverflowHandler(siginfo_t * info, void * ctx);
} }

View file

@ -1,4 +1,5 @@
#include "error.hh" #include "error.hh"
#include "shared.hh"
#include <cstring> #include <cstring>
#include <cstddef> #include <cstddef>
@ -29,9 +30,7 @@ static void sigsegvHandler(int signo, siginfo_t * info, void * ctx)
ptrdiff_t diff = (char *) info->si_addr - sp; ptrdiff_t diff = (char *) info->si_addr - sp;
if (diff < 0) diff = -diff; if (diff < 0) diff = -diff;
if (diff < 4096) { if (diff < 4096) {
char msg[] = "error: stack overflow (possible infinite recursion)\n"; nix::stackOverflowHandler(info, ctx);
[[gnu::unused]] auto res = write(2, msg, strlen(msg));
_exit(1); // maybe abort instead?
} }
} }
@ -67,5 +66,12 @@ void detectStackOverflow()
#endif #endif
} }
std::function<void(siginfo_t * info, void * ctx)> stackOverflowHandler(defaultStackOverflowHandler);
void defaultStackOverflowHandler(siginfo_t * info, void * ctx) {
char msg[] = "error: stack overflow (possible infinite recursion)\n";
[[gnu::unused]] auto res = write(2, msg, strlen(msg));
_exit(1); // maybe abort instead?
}
} }

View file

@ -331,6 +331,17 @@ bool BinaryCacheStore::isValidPathUncached(const StorePath & storePath)
return fileExists(narInfoFileFor(storePath)); return fileExists(narInfoFileFor(storePath));
} }
std::optional<StorePath> BinaryCacheStore::queryPathFromHashPart(const std::string & hashPart)
{
auto pseudoPath = StorePath(hashPart + "-" + MissingName);
try {
auto info = queryPathInfo(pseudoPath);
return info->path;
} catch (InvalidPath &) {
return std::nullopt;
}
}
void BinaryCacheStore::narFromPath(const StorePath & storePath, Sink & sink) void BinaryCacheStore::narFromPath(const StorePath & storePath, Sink & sink)
{ {
auto info = queryPathInfo(storePath).cast<const NarInfo>(); auto info = queryPathInfo(storePath).cast<const NarInfo>();

View file

@ -95,8 +95,7 @@ public:
void queryPathInfoUncached(const StorePath & path, void queryPathInfoUncached(const StorePath & path,
Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept override; Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept override;
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override;
{ unsupported("queryPathFromHashPart"); }
void addToStore(const ValidPathInfo & info, Source & narSource, void addToStore(const ValidPathInfo & info, Source & narSource,
RepairFlag repair, CheckSigsFlag checkSigs) override; RepairFlag repair, CheckSigsFlag checkSigs) override;

View file

@ -16,11 +16,11 @@ HookInstance::HookInstance()
buildHookArgs.pop_front(); buildHookArgs.pop_front();
Strings args; Strings args;
args.push_back(std::string(baseNameOf(buildHook)));
for (auto & arg : buildHookArgs) for (auto & arg : buildHookArgs)
args.push_back(arg); args.push_back(arg);
args.push_back(std::string(baseNameOf(settings.buildHook.get())));
args.push_back(std::to_string(verbosity)); args.push_back(std::to_string(verbosity));
/* Create a pipe to get the output of the child. */ /* Create a pipe to get the output of the child. */

View file

@ -1594,6 +1594,8 @@ void LocalDerivationGoal::runChild()
/* Warning: in the child we should absolutely not make any SQLite /* Warning: in the child we should absolutely not make any SQLite
calls! */ calls! */
bool sendException = true;
try { /* child */ try { /* child */
commonChildInit(builderOut); commonChildInit(builderOut);
@ -2050,6 +2052,8 @@ void LocalDerivationGoal::runChild()
/* Indicate that we managed to set up the build environment. */ /* Indicate that we managed to set up the build environment. */
writeFull(STDERR_FILENO, std::string("\2\n")); writeFull(STDERR_FILENO, std::string("\2\n"));
sendException = false;
/* Execute the program. This should not return. */ /* Execute the program. This should not return. */
if (drv->isBuiltin()) { if (drv->isBuiltin()) {
try { try {
@ -2103,10 +2107,13 @@ void LocalDerivationGoal::runChild()
throw SysError("executing '%1%'", drv->builder); throw SysError("executing '%1%'", drv->builder);
} catch (Error & e) { } catch (Error & e) {
writeFull(STDERR_FILENO, "\1\n"); if (sendException) {
FdSink sink(STDERR_FILENO); writeFull(STDERR_FILENO, "\1\n");
sink << e; FdSink sink(STDERR_FILENO);
sink.flush(); sink << e;
sink.flush();
} else
std::cerr << e.msg();
_exit(1); _exit(1);
} }
} }

View file

@ -154,13 +154,9 @@ StringSet Settings::getDefaultExtraPlatforms()
// machines. Note that we cant force processes from executing // machines. Note that we cant force processes from executing
// x86_64 in aarch64 environments or vice versa since they can // x86_64 in aarch64 environments or vice versa since they can
// always exec with their own binary preferences. // always exec with their own binary preferences.
if (pathExists("/Library/Apple/System/Library/LaunchDaemons/com.apple.oahd.plist") || if (std::string{SYSTEM} == "aarch64-darwin" &&
pathExists("/System/Library/LaunchDaemons/com.apple.oahd.plist")) { runProgram(RunOptions {.program = "arch", .args = {"-arch", "x86_64", "/usr/bin/true"}, .mergeStderrToStdout = true}).first == 0)
if (std::string{SYSTEM} == "x86_64-darwin") extraPlatforms.insert("x86_64-darwin");
extraPlatforms.insert("aarch64-darwin");
else if (std::string{SYSTEM} == "aarch64-darwin")
extraPlatforms.insert("x86_64-darwin");
}
#endif #endif
return extraPlatforms; return extraPlatforms;

View file

@ -67,7 +67,7 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string
if (fakeSSH) { if (fakeSSH) {
args = { "bash", "-c" }; args = { "bash", "-c" };
} else { } else {
args = { "ssh", host.c_str(), "-x", "-a" }; args = { "ssh", host.c_str(), "-x" };
addCommonSSHOpts(args); addCommonSSHOpts(args);
if (socketPath != "") if (socketPath != "")
args.insert(args.end(), {"-S", socketPath}); args.insert(args.end(), {"-S", socketPath});

View file

@ -1363,9 +1363,9 @@ std::shared_ptr<Store> openFromNonUri(const std::string & uri, const Store::Para
} catch (Error & e) { } catch (Error & e) {
return std::make_shared<LocalStore>(params); return std::make_shared<LocalStore>(params);
} }
warn("'/nix' does not exist, so Nix will use '%s' as a chroot store", chrootStore); warn("'%s' does not exist, so Nix will use '%s' as a chroot store", stateDir, chrootStore);
} else } else
debug("'/nix' does not exist, so Nix will use '%s' as a chroot store", chrootStore); debug("'%s' does not exist, so Nix will use '%s' as a chroot store", stateDir, chrootStore);
Store::Params params2; Store::Params params2;
params2["root"] = chrootStore; params2["root"] = chrootStore;
return std::make_shared<LocalStore>(params2); return std::make_shared<LocalStore>(params2);

View file

@ -77,9 +77,7 @@ TarArchive::~TarArchive()
static void extract_archive(TarArchive & archive, const Path & destDir) static void extract_archive(TarArchive & archive, const Path & destDir)
{ {
int flags = ARCHIVE_EXTRACT_FFLAGS int flags = ARCHIVE_EXTRACT_TIME
| ARCHIVE_EXTRACT_PERM
| ARCHIVE_EXTRACT_TIME
| ARCHIVE_EXTRACT_SECURE_SYMLINKS | ARCHIVE_EXTRACT_SECURE_SYMLINKS
| ARCHIVE_EXTRACT_SECURE_NODOTDOT; | ARCHIVE_EXTRACT_SECURE_NODOTDOT;
@ -98,6 +96,10 @@ static void extract_archive(TarArchive & archive, const Path & destDir)
archive_entry_copy_pathname(entry, archive_entry_copy_pathname(entry,
(destDir + "/" + name).c_str()); (destDir + "/" + name).c_str());
// sources can and do contain dirs with no rx bits
if (archive_entry_filetype(entry) == AE_IFDIR && (archive_entry_mode(entry) & 0500) != 0500)
archive_entry_set_mode(entry, archive_entry_mode(entry) | 0500);
// Patch hardlink path // Patch hardlink path
const char *original_hardlink = archive_entry_hardlink(entry); const char *original_hardlink = archive_entry_hardlink(entry);
if (original_hardlink) { if (original_hardlink) {

View file

@ -66,7 +66,9 @@ UnresolvedApp Installable::toApp(EvalState & state)
auto type = cursor->getAttr("type")->getString(); auto type = cursor->getAttr("type")->getString();
std::string expected = !attrPath.empty() && state.symbols[attrPath[0]] == "apps" ? "app" : "derivation"; std::string expected = !attrPath.empty() &&
(state.symbols[attrPath[0]] == "apps" || state.symbols[attrPath[0]] == "defaultApp")
? "app" : "derivation";
if (type != expected) if (type != expected)
throw Error("attribute '%s' should have type '%s'", cursor->getAttrPathStr(), expected); throw Error("attribute '%s' should have type '%s'", cursor->getAttrPathStr(), expected);

View file

@ -11,7 +11,7 @@ R""(
# Description # Description
This command runs the Nix daemon, which is a required component in This command runs the Nix daemon, which is a required component in
multi-user Nix installations. It performs build actions and other multi-user Nix installations. It runs build tasks and other
operations on the Nix store on behalf of non-root users. Usually you operations on the Nix store on behalf of non-root users. Usually you
don't run the daemon directly; instead it's managed by a service don't run the daemon directly; instead it's managed by a service
management framework such as `systemd`. management framework such as `systemd`.

View file

@ -53,7 +53,6 @@ static bool haveInternet()
} }
std::string programPath; std::string programPath;
char * * savedArgv;
struct HelpRequested { }; struct HelpRequested { };
@ -74,6 +73,7 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
addFlag({ addFlag({
.longName = "help", .longName = "help",
.description = "Show usage information.", .description = "Show usage information.",
.category = miscCategory,
.handler = {[&]() { throw HelpRequested(); }}, .handler = {[&]() { throw HelpRequested(); }},
}); });
@ -88,6 +88,7 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
addFlag({ addFlag({
.longName = "version", .longName = "version",
.description = "Show version information.", .description = "Show version information.",
.category = miscCategory,
.handler = {[&]() { showVersion = true; }}, .handler = {[&]() { showVersion = true; }},
}); });
@ -95,12 +96,14 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
.longName = "offline", .longName = "offline",
.aliases = {"no-net"}, // FIXME: remove .aliases = {"no-net"}, // FIXME: remove
.description = "Disable substituters and consider all previously downloaded files up-to-date.", .description = "Disable substituters and consider all previously downloaded files up-to-date.",
.category = miscCategory,
.handler = {[&]() { useNet = false; }}, .handler = {[&]() { useNet = false; }},
}); });
addFlag({ addFlag({
.longName = "refresh", .longName = "refresh",
.description = "Consider all previously downloaded files out-of-date.", .description = "Consider all previously downloaded files out-of-date.",
.category = miscCategory,
.handler = {[&]() { refresh = true; }}, .handler = {[&]() { refresh = true; }},
}); });
} }
@ -187,7 +190,7 @@ static void showHelp(std::vector<std::string> subcommand, MultiCommand & topleve
*vUtils); *vUtils);
auto attrs = state.buildBindings(16); auto attrs = state.buildBindings(16);
attrs.alloc("command").mkString(toplevel.toJSON().dump()); attrs.alloc("toplevel").mkString(toplevel.toJSON().dump());
auto vRes = state.allocValue(); auto vRes = state.allocValue();
state.callFunction(*vGenerateManpage, state.allocValue()->mkAttrs(attrs), *vRes, noPos); state.callFunction(*vGenerateManpage, state.allocValue()->mkAttrs(attrs), *vRes, noPos);
@ -266,7 +269,7 @@ void mainWrapped(int argc, char * * argv)
programPath = argv[0]; programPath = argv[0];
auto programName = std::string(baseNameOf(programPath)); auto programName = std::string(baseNameOf(programPath));
if (argc > 0 && std::string_view(argv[0]) == "__build-remote") { if (argc > 1 && std::string_view(argv[1]) == "__build-remote") {
programName = "build-remote"; programName = "build-remote";
argv++; argc--; argv++; argc--;
} }

View file

@ -0,0 +1,39 @@
#include "command.hh"
#include "store-api.hh"
using namespace nix;
struct CmdPathFromHashPart : StoreCommand
{
std::string hashPart;
CmdPathFromHashPart()
{
expectArgs({
.label = "hash-part",
.handler = {&hashPart},
});
}
std::string description() override
{
return "get a store path from its hash part";
}
std::string doc() override
{
return
#include "path-from-hash-part.md"
;
}
void run(ref<Store> store) override
{
if (auto storePath = store->queryPathFromHashPart(hashPart))
logger->cout(store->printStorePath(*storePath));
else
throw Error("there is no store path corresponding to '%s'", hashPart);
}
};
static auto rCmdPathFromHashPart = registerCommand2<CmdPathFromHashPart>({"store", "path-from-hash-part"});

View file

@ -0,0 +1,20 @@
R""(
# Examples
* Return the full store path with the given hash part:
```console
# nix store path-from-hash-part --store https://cache.nixos.org/ 0i2jd68mp5g6h2sa5k9c85rb80sn8hi9
/nix/store/0i2jd68mp5g6h2sa5k9c85rb80sn8hi9-hello-2.10
```
# Description
Given the hash part of a store path (that is, the 32 characters
following `/nix/store/`), return the full store path. This is
primarily useful in the implementation of binary caches, where a
request for a `.narinfo` file only supplies the hash part
(e.g. `https://cache.nixos.org/0i2jd68mp5g6h2sa5k9c85rb80sn8hi9.narinfo`).
)""

View file

@ -36,7 +36,7 @@ R""(
Loading Installable ''... Loading Installable ''...
Added 1 variables. Added 1 variables.
# nix repl --extra_experimental_features 'flakes repl-flake' nixpkgs # nix repl --extra-experimental-features 'flakes repl-flake' nixpkgs
Loading Installable 'flake:nixpkgs#'... Loading Installable 'flake:nixpkgs#'...
Added 5 variables. Added 5 variables.

View file

@ -24,12 +24,14 @@ touch $repo/.gitignore
git -C $repo add hello .gitignore git -C $repo add hello .gitignore
git -C $repo commit -m 'Bla1' git -C $repo commit -m 'Bla1'
rev1=$(git -C $repo rev-parse HEAD) rev1=$(git -C $repo rev-parse HEAD)
git -C $repo tag -a tag1 -m tag1
echo world > $repo/hello echo world > $repo/hello
git -C $repo commit -m 'Bla2' -a git -C $repo commit -m 'Bla2' -a
git -C $repo worktree add $TEST_ROOT/worktree git -C $repo worktree add $TEST_ROOT/worktree
echo hello >> $TEST_ROOT/worktree/hello echo hello >> $TEST_ROOT/worktree/hello
rev2=$(git -C $repo rev-parse HEAD) rev2=$(git -C $repo rev-parse HEAD)
git -C $repo tag -a tag2 -m tag2
# Fetch a worktree # Fetch a worktree
unset _NIX_FORCE_HTTP unset _NIX_FORCE_HTTP
@ -217,6 +219,16 @@ rev4_nix=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$
path9=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"HEAD\"; name = \"foo\"; }).outPath") path9=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"HEAD\"; name = \"foo\"; }).outPath")
[[ $path9 =~ -foo$ ]] [[ $path9 =~ -foo$ ]]
# Specifying a ref without a rev shouldn't pick a cached rev for a different ref
export _NIX_FORCE_HTTP=1
rev_tag1_nix=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"refs/tags/tag1\"; }).rev")
rev_tag1=$(git -C $repo rev-parse refs/tags/tag1)
[[ $rev_tag1_nix = $rev_tag1 ]]
rev_tag2_nix=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"refs/tags/tag2\"; }).rev")
rev_tag2=$(git -C $repo rev-parse refs/tags/tag2)
[[ $rev_tag2_nix = $rev_tag2 ]]
unset _NIX_FORCE_HTTP
# should fail if there is no repo # should fail if there is no repo
rm -rf $repo/.git rm -rf $repo/.git
(! nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").outPath") (! nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").outPath")

View file

@ -7,7 +7,7 @@ with import (nixpkgs + "/nixos/lib/testing-python.nix") {
let let
# Generate a fake root CA and a fake api.github.com / channels.nixos.org certificate. # Generate a fake root CA and a fake api.github.com / github.com / channels.nixos.org certificate.
cert = pkgs.runCommand "cert" { buildInputs = [ pkgs.openssl ]; } cert = pkgs.runCommand "cert" { buildInputs = [ pkgs.openssl ]; }
'' ''
mkdir -p $out mkdir -p $out
@ -18,7 +18,7 @@ let
openssl req -newkey rsa:2048 -nodes -keyout $out/server.key \ openssl req -newkey rsa:2048 -nodes -keyout $out/server.key \
-subj "/C=CN/ST=Denial/L=Springfield/O=Dis/CN=github.com" -out server.csr -subj "/C=CN/ST=Denial/L=Springfield/O=Dis/CN=github.com" -out server.csr
openssl x509 -req -extfile <(printf "subjectAltName=DNS:api.github.com,DNS:channels.nixos.org") \ openssl x509 -req -extfile <(printf "subjectAltName=DNS:api.github.com,DNS:github.com,DNS:channels.nixos.org") \
-days 36500 -in server.csr -CA $out/ca.crt -CAkey ca.key -CAcreateserial -out $out/server.crt -days 36500 -in server.csr -CA $out/ca.crt -CAkey ca.key -CAcreateserial -out $out/server.crt
''; '';
@ -37,6 +37,17 @@ let
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs" "repo": "nixpkgs"
} }
},
{
"from": {
"type": "indirect",
"id": "private-flake"
},
"to": {
"type": "github",
"owner": "fancy-enterprise",
"repo": "private-flake"
}
} }
], ],
"version": 2 "version": 2
@ -45,20 +56,40 @@ let
destination = "/flake-registry.json"; destination = "/flake-registry.json";
}; };
api = pkgs.runCommand "nixpkgs-flake" {} private-flake-rev = "9f1dd0df5b54a7dc75b618034482ed42ce34383d";
private-flake-api = pkgs.runCommand "private-flake" {}
'' ''
mkdir -p $out/tarball mkdir -p $out/{commits,tarball}
# Setup https://docs.github.com/en/rest/commits/commits#get-a-commit
echo '{"sha": "${private-flake-rev}"}' > $out/commits/HEAD
# Setup tarball download via API
dir=private-flake
mkdir $dir
echo '{ outputs = {...}: {}; }' > $dir/flake.nix
tar cfz $out/tarball/${private-flake-rev} $dir --hard-dereference
'';
nixpkgs-api = pkgs.runCommand "nixpkgs-flake" {}
''
mkdir -p $out/commits
# Setup https://docs.github.com/en/rest/commits/commits#get-a-commit
echo '{"sha": "${nixpkgs.rev}"}' > $out/commits/HEAD
'';
archive = pkgs.runCommand "nixpkgs-flake" {}
''
mkdir -p $out/archive
dir=NixOS-nixpkgs-${nixpkgs.shortRev} dir=NixOS-nixpkgs-${nixpkgs.shortRev}
cp -prd ${nixpkgs} $dir cp -prd ${nixpkgs} $dir
# Set the correct timestamp in the tarball. # Set the correct timestamp in the tarball.
find $dir -print0 | xargs -0 touch -t ${builtins.substring 0 12 nixpkgs.lastModifiedDate}.${builtins.substring 12 2 nixpkgs.lastModifiedDate} -- find $dir -print0 | xargs -0 touch -t ${builtins.substring 0 12 nixpkgs.lastModifiedDate}.${builtins.substring 12 2 nixpkgs.lastModifiedDate} --
tar cfz $out/tarball/${nixpkgs.rev} $dir --hard-dereference tar cfz $out/archive/${nixpkgs.rev}.tar.gz $dir --hard-dereference
mkdir -p $out/commits
echo '{"sha": "${nixpkgs.rev}"}' > $out/commits/HEAD
''; '';
in in
makeTest ( makeTest (
@ -93,7 +124,20 @@ makeTest (
sslServerCert = "${cert}/server.crt"; sslServerCert = "${cert}/server.crt";
servedDirs = servedDirs =
[ { urlPath = "/repos/NixOS/nixpkgs"; [ { urlPath = "/repos/NixOS/nixpkgs";
dir = api; dir = nixpkgs-api;
}
{ urlPath = "/repos/fancy-enterprise/private-flake";
dir = private-flake-api;
}
];
};
services.httpd.virtualHosts."github.com" =
{ forceSSL = true;
sslServerKey = "${cert}/server.key";
sslServerCert = "${cert}/server.crt";
servedDirs =
[ { urlPath = "/NixOS/nixpkgs";
dir = archive;
} }
]; ];
}; };
@ -107,9 +151,8 @@ makeTest (
virtualisation.memorySize = 4096; virtualisation.memorySize = 4096;
nix.binaryCaches = lib.mkForce [ ]; nix.binaryCaches = lib.mkForce [ ];
nix.extraOptions = "experimental-features = nix-command flakes"; nix.extraOptions = "experimental-features = nix-command flakes";
environment.systemPackages = [ pkgs.jq ];
networking.hosts.${(builtins.head nodes.github.config.networking.interfaces.eth1.ipv4.addresses).address} = networking.hosts.${(builtins.head nodes.github.config.networking.interfaces.eth1.ipv4.addresses).address} =
[ "channels.nixos.org" "api.github.com" ]; [ "channels.nixos.org" "api.github.com" "github.com" ];
security.pki.certificateFiles = [ "${cert}/ca.crt" ]; security.pki.certificateFiles = [ "${cert}/ca.crt" ];
}; };
}; };
@ -121,22 +164,39 @@ makeTest (
start_all() start_all()
def cat_log():
github.succeed("cat /var/log/httpd/*.log >&2")
github.wait_for_unit("httpd.service") github.wait_for_unit("httpd.service")
client.succeed("curl -v https://api.github.com/ >&2") client.succeed("curl -v https://github.com/ >&2")
client.succeed("nix registry list | grep nixpkgs") out = client.succeed("nix registry list")
print(out)
assert "github:NixOS/nixpkgs" in out, "nixpkgs flake not found"
assert "github:fancy-enterprise/private-flake" in out, "private flake not found"
cat_log()
rev = client.succeed("nix flake info nixpkgs --json | jq -r .revision") # If no github access token is provided, nix should use the public archive url...
assert rev.strip() == "${nixpkgs.rev}", "revision mismatch" out = client.succeed("nix flake metadata nixpkgs --json")
print(out)
info = json.loads(out)
assert info["revision"] == "${nixpkgs.rev}", f"revision mismatch: {info['revision']} != ${nixpkgs.rev}"
cat_log()
# ... otherwise it should use the API
out = client.succeed("nix flake metadata private-flake --json --access-tokens github.com=ghp_000000000000000000000000000000000000 --tarball-ttl 0")
print(out)
info = json.loads(out)
assert info["revision"] == "${private-flake-rev}", f"revision mismatch: {info['revision']} != ${private-flake-rev}"
cat_log()
client.succeed("nix registry pin nixpkgs") client.succeed("nix registry pin nixpkgs")
client.succeed("nix flake metadata nixpkgs --tarball-ttl 0 >&2")
client.succeed("nix flake info nixpkgs --tarball-ttl 0 >&2")
# Shut down the web server. The flake should be cached on the client. # Shut down the web server. The flake should be cached on the client.
github.succeed("systemctl stop httpd.service") github.succeed("systemctl stop httpd.service")
info = json.loads(client.succeed("nix flake info nixpkgs --json")) info = json.loads(client.succeed("nix flake metadata nixpkgs --json"))
date = time.strftime("%Y%m%d%H%M%S", time.gmtime(info['lastModified'])) date = time.strftime("%Y%m%d%H%M%S", time.gmtime(info['lastModified']))
assert date == "${nixpkgs.lastModifiedDate}", "time mismatch" assert date == "${nixpkgs.lastModifiedDate}", "time mismatch"

View file

@ -2,7 +2,7 @@ source common.sh
requireDaemonNewerThan "2.8pre20220311" requireDaemonNewerThan "2.8pre20220311"
enableFeatures "ca-derivations ca-references impure-derivations" enableFeatures "ca-derivations impure-derivations"
restartDaemon restartDaemon
set -o pipefail set -o pipefail

View file

@ -0,0 +1 @@
true

View file

@ -1 +0,0 @@
Bool(True)

View file

@ -4,6 +4,7 @@ let
name2 = "hello"; name2 = "hello";
name3 = "915resolution-0.5.2"; name3 = "915resolution-0.5.2";
name4 = "xf86-video-i810-1.7.4"; name4 = "xf86-video-i810-1.7.4";
name5 = "name-that-ends-with-dash--1.0";
eq = 0; eq = 0;
lt = builtins.sub 0 1; lt = builtins.sub 0 1;
@ -23,6 +24,8 @@ let
((builtins.parseDrvName name3).version == "0.5.2") ((builtins.parseDrvName name3).version == "0.5.2")
((builtins.parseDrvName name4).name == "xf86-video-i810") ((builtins.parseDrvName name4).name == "xf86-video-i810")
((builtins.parseDrvName name4).version == "1.7.4") ((builtins.parseDrvName name4).version == "1.7.4")
((builtins.parseDrvName name5).name == "name-that-ends-with-dash")
((builtins.parseDrvName name5).version == "-1.0")
(versionTest "1.0" "2.3" lt) (versionTest "1.0" "2.3" lt)
(versionTest "2.1" "2.3" lt) (versionTest "2.1" "2.3" lt)
(versionTest "2.3" "2.3" eq) (versionTest "2.3" "2.3" eq)

View file

@ -109,7 +109,8 @@ nix_tests = \
store-ping.sh \ store-ping.sh \
fetchClosure.sh \ fetchClosure.sh \
completions.sh \ completions.sh \
impure-derivations.sh impure-derivations.sh \
path-from-hash-part.sh
ifeq ($(HAVE_LIBCPUID), 1) ifeq ($(HAVE_LIBCPUID), 1)
nix_tests += compute-levels.sh nix_tests += compute-levels.sh

View file

@ -0,0 +1,10 @@
source common.sh
path=$(nix build --no-link --print-out-paths -f simple.nix)
hash_part=$(basename $path)
hash_part=${hash_part:0:32}
path2=$(nix store path-from-hash-part $hash_part)
[[ $path = $path2 ]]