Compare commits

...

3 commits

Author SHA1 Message Date
Rebecca Turner
cf89bfc499 Format Nix code with nixfmt
Change-Id: I61efeb666ff7481c05fcb247168290e86a250151
2024-03-29 17:23:08 -07:00
Rebecca Turner
e7316a8e99 Add treefmt pre-commit hook
This lets us use different formatters for different filetypes.

Change-Id: Ib52383dd5097c8919a65e299aca2b5a55412223c
2024-03-29 17:23:06 -07:00
Rebecca Turner
7b3ef56094 Add pre-commit checks
The big ones here are `trim-trailing-whitespace` and `end-of-file-fixer`
(which makes sure that every file ends with exactly one newline
character).

Change-Id: Idca73b640883188f068f9903e013cf0d82aa1123
2024-03-29 17:22:56 -07:00
131 changed files with 1725 additions and 1254 deletions

View file

@ -48,4 +48,3 @@ PointerAlignment: Middle
SortIncludes: Never SortIncludes: Never
SpaceAfterCStyleCast: true SpaceAfterCStyleCast: true
SpaceAfterTemplateKeyword: false SpaceAfterTemplateKeyword: false

View file

@ -17,4 +17,3 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- run: bash scripts/check-hydra-status.sh - run: bash scripts/check-hydra-status.sh

2
.gitignore vendored
View file

@ -159,3 +159,5 @@ result-*
buildtime.bin buildtime.bin
.envrc.local .envrc.local
# We generate this with a Nix shell hook
/.pre-commit-config.yaml

20
COPYING
View file

@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be author's reputation will not be affected by problems that might be
introduced by others. introduced by others.
Finally, software patents pose a constant threat to the existence of Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a effectively restrict the users of a free program by obtaining a
@ -111,7 +111,7 @@ modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The "work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must former contains code derived from the library, whereas the latter must
be combined with the library in order to run. be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@ -158,7 +158,7 @@ Library.
You may charge a fee for the physical act of transferring a copy, You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a and you may at your option offer warranty protection in exchange for a
fee. fee.
2. You may modify your copy or copies of the Library or any portion 2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1 distribute such modifications or work under the terms of Section 1
@ -216,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in that version instead if you wish.) Do not make any other change in
these notices. these notices.
Once this change is made in a given copy, it is irreversible for Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy. subsequent copies and derivative works made from that copy.
@ -267,7 +267,7 @@ Library will still fall under Section 6.)
distribute the object code for the work under the terms of Section 6. distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6, Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself. whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or 6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work work containing portions of the Library, and distribute that work
@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you use both them and the Library together in an executable that you
distribute. distribute.
7. You may place library facilities that are a work based on the 7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined facilities not covered by this License, and distribute such a combined
@ -370,7 +370,7 @@ subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein. restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with You are not responsible for enforcing compliance by third parties with
this License. this License.
11. If, as a consequence of a court judgment or allegation of patent 11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues), infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or conditions are imposed on you (whether by court order, agreement or
@ -422,7 +422,7 @@ conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by license version number, you may choose any version ever published by
the Free Software Foundation. the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free 14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these, programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is write to the author to ask for permission. For software which is
@ -456,7 +456,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES. DAMAGES.
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest If you develop a new library, and you want it to be of the greatest
@ -500,5 +500,3 @@ necessary. Here is a sample; alter the names:
Ty Coon, President of Vice Ty Coon, President of Vice
That's all there is to it! That's all there is to it!

View file

@ -1,10 +1,9 @@
(import (import (
( let
let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in lock = builtins.fromJSON (builtins.readFile ./flake.lock);
fetchTarball { in
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; fetchTarball {
sha256 = lock.nodes.flake-compat.locked.narHash; url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
} sha256 = lock.nodes.flake-compat.locked.narHash;
) }
{ src = ./.; } ) { src = ./.; }).defaultNix
).defaultNix

0
doc/manual/anchors.jq Executable file → Normal file
View file

View file

@ -2,10 +2,15 @@ let
inherit (builtins) concatStringsSep attrValues mapAttrs; inherit (builtins) concatStringsSep attrValues mapAttrs;
inherit (import ./utils.nix) optionalString squash; inherit (import ./utils.nix) optionalString squash;
in in
builtinsInfo: builtinsInfo:
let let
showBuiltin = name: { doc, type, impure-only }: showBuiltin =
name:
{
doc,
type,
impure-only,
}:
let let
type' = optionalString (type != null) " (${type})"; type' = optionalString (type != null) " (${type})";

View file

@ -2,10 +2,16 @@ let
inherit (builtins) concatStringsSep attrValues mapAttrs; inherit (builtins) concatStringsSep attrValues mapAttrs;
inherit (import ./utils.nix) optionalString squash; inherit (import ./utils.nix) optionalString squash;
in in
builtinsInfo: builtinsInfo:
let let
showBuiltin = name: { doc, args, arity, experimental-feature }: showBuiltin =
name:
{
doc,
args,
arity,
experimental-feature,
}:
let let
experimentalNotice = optionalString (experimental-feature != null) '' experimentalNotice = optionalString (experimental-feature != null) ''
This function is only available if the [${experimental-feature}](@docroot@/contributing/experimental-features.md#xp-feature-${experimental-feature}) experimental feature is enabled. This function is only available if the [${experimental-feature}](@docroot@/contributing/experimental-features.md#xp-feature-${experimental-feature}) experimental feature is enabled.

View file

@ -1,19 +1,39 @@
let let
inherit (builtins) inherit (builtins)
attrNames attrValues fromJSON listToAttrs mapAttrs attrNames
concatStringsSep concatMap length lessThan replaceStrings sort; attrValues
inherit (import ./utils.nix) concatStrings optionalString filterAttrs trim squash unique showSettings; fromJSON
listToAttrs
mapAttrs
concatStringsSep
concatMap
length
lessThan
replaceStrings
sort
;
inherit (import ./utils.nix)
concatStrings
optionalString
filterAttrs
trim
squash
unique
showSettings
;
in in
inlineHTML: commandDump: inlineHTML: commandDump:
let let
commandInfo = fromJSON commandDump; commandInfo = fromJSON commandDump;
showCommand = { command, details, filename, toplevel }: showCommand =
{
command,
details,
filename,
toplevel,
}:
let let
result = '' result = ''
> **Warning** \ > **Warning** \
> This program is > This program is
@ -35,26 +55,27 @@ let
${maybeOptions} ${maybeOptions}
''; '';
showSynopsis = command: args: showSynopsis =
command: args:
let let
showArgument = arg: "*${arg.label}*" + optionalString (! arg ? arity) "..."; showArgument = arg: "*${arg.label}*" + optionalString (!arg ? arity) "...";
arguments = concatStringsSep " " (map showArgument args); arguments = concatStringsSep " " (map showArgument args);
in '' in
`${command}` [*option*...] ${arguments} ''
`${command}` [*option*...] ${arguments}
''; '';
maybeSubcommands = optionalString (details ? commands && details.commands != {}) maybeSubcommands = optionalString (details ? commands && details.commands != { }) ''
'' where *subcommand* is one of the following:
where *subcommand* is one of the following:
${subcommands} ${subcommands}
''; '';
subcommands = if length categories > 1 subcommands = if length categories > 1 then listCategories else listSubcommands details.commands;
then listCategories
else listSubcommands details.commands;
categories = sort (x: y: x.id < y.id) (unique (map (cmd: cmd.category) (attrValues details.commands))); categories = sort (x: y: x.id < y.id) (
unique (map (cmd: cmd.category) (attrValues details.commands))
);
listCategories = concatStrings (map showCategory categories); listCategories = concatStrings (map showCategory categories);
@ -71,11 +92,11 @@ let
''; '';
# TODO: move this confusing special case out of here when implementing #8496 # TODO: move this confusing special case out of here when implementing #8496
maybeStoreDocs = optionalString maybeStoreDocs = optionalString (details ? doc) (
(details ? doc) replaceStrings [ "@stores@" ] [ storeDocs ] details.doc
(replaceStrings ["@stores@"] [storeDocs] details.doc); );
maybeOptions = optionalString (details.flags != {}) '' maybeOptions = optionalString (details.flags != { }) ''
# Options # Options
${showOptions details.flags toplevel.flags} ${showOptions details.flags toplevel.flags}
@ -85,51 +106,70 @@ let
> See [`man nix.conf`](@docroot@/command-ref/conf-file.md#command-line-flags) for overriding configuration settings with command line flags. > See [`man nix.conf`](@docroot@/command-ref/conf-file.md#command-line-flags) for overriding configuration settings with command line flags.
''; '';
showOptions = options: commonOptions: showOptions =
options: commonOptions:
let let
allOptions = options // commonOptions; allOptions = options // commonOptions;
showCategory = cat: '' showCategory = cat: ''
${optionalString (cat != "") "**${cat}:**"} ${optionalString (cat != "") "**${cat}:**"}
${listOptions (filterAttrs (n: v: v.category == cat) allOptions)} ${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:
let let
result = trim '' result = trim ''
- ${item} - ${item}
${option.description} ${option.description}
''; '';
item = if inlineHTML item =
then ''<span id="opt-${name}">[`--${name}`](#opt-${name})</span> ${shortName} ${labels}'' if inlineHTML then
else "`--${name}` ${shortName} ${labels}"; ''<span id="opt-${name}">[`--${name}`](#opt-${name})</span> ${shortName} ${labels}''
shortName = optionalString else
(option ? shortName) "`--${name}` ${shortName} ${labels}";
("/ `-${option.shortName}`"); shortName = optionalString (option ? shortName) "/ `-${option.shortName}`";
labels = optionalString labels = optionalString (option ? labels) (concatStringsSep " " (map (s: "*${s}*") option.labels));
(option ? labels) in
(concatStringsSep " " (map (s: "*${s}*") option.labels)); result;
in result;
categories = sort lessThan (unique (map (cmd: cmd.category) (attrValues allOptions))); categories = sort lessThan (unique (map (cmd: cmd.category) (attrValues allOptions)));
in concatStrings (map showCategory categories); in
in squash result; concatStrings (map showCategory categories);
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, toplevel }: 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 toplevel; }; value = showCommand {
inherit
command
details
filename
toplevel
;
};
}; };
subcommand = subCmd: processCommand { subcommand =
command = command + " " + subCmd; subCmd:
details = details.commands.${subCmd}; processCommand {
filename = appendName filename subCmd; command = command + " " + subCmd;
inherit toplevel; details = details.commands.${subCmd};
}; filename = appendName filename subCmd;
in [ cmd ] ++ concatMap subcommand (attrNames details.commands or {}); inherit toplevel;
};
in
[ cmd ] ++ concatMap subcommand (attrNames details.commands or { });
manpages = processCommand { manpages = processCommand {
command = "nix"; command = "nix";
@ -138,14 +178,21 @@ let
toplevel = commandInfo.args; toplevel = commandInfo.args;
}; };
tableOfContents = let tableOfContents =
showEntry = page: let
" - [${page.command}](command-ref/new-cli/${page.name})"; showEntry = page: " - [${page.command}](command-ref/new-cli/${page.name})";
in concatStringsSep "\n" (map showEntry manpages) + "\n"; in
concatStringsSep "\n" (map showEntry manpages) + "\n";
storeDocs = storeDocs =
let let
showStore = name: { settings, doc, experimentalFeature }: showStore =
name:
{
settings,
doc,
experimentalFeature,
}:
let let
experimentalFeatureNote = optionalString (experimentalFeature != null) '' experimentalFeatureNote = optionalString (experimentalFeature != null) ''
> **Warning** > **Warning**
@ -161,7 +208,8 @@ let
extra-experimental-features = ${experimentalFeature} extra-experimental-features = ${experimentalFeature}
``` ```
''; '';
in '' in
''
## ${name} ## ${name}
${doc} ${doc}
@ -172,6 +220,7 @@ let
${showSettings { inherit inlineHTML; } settings} ${showSettings { inherit inlineHTML; } settings}
''; '';
in concatStrings (attrValues (mapAttrs showStore commandInfo.stores)); in
concatStrings (attrValues (mapAttrs showStore commandInfo.stores));
in (listToAttrs manpages) // { "SUMMARY.md" = tableOfContents; } in
(listToAttrs manpages) // { "SUMMARY.md" = tableOfContents; }

View file

@ -1,9 +1,8 @@
with builtins; with builtins;
with import ./utils.nix; with import ./utils.nix;
let let
showExperimentalFeature = name: doc: showExperimentalFeature = name: doc: ''
'' - [`${name}`](@docroot@/contributing/experimental-features.md#xp-feature-${name})
- [`${name}`](@docroot@/contributing/experimental-features.md#xp-feature-${name}) '';
''; in
in xps: indent " " (concatStrings (attrValues (mapAttrs showExperimentalFeature xps))) xps: indent " " (concatStrings (attrValues (mapAttrs showExperimentalFeature xps)))

View file

@ -1,11 +1,12 @@
with builtins; with builtins;
with import ./utils.nix; with import ./utils.nix;
let let
showExperimentalFeature = name: doc: showExperimentalFeature =
name: doc:
squash '' squash ''
## [`${name}`]{#xp-feature-${name}} ## [`${name}`]{#xp-feature-${name}}
${doc} ${doc}
''; '';
in xps: (concatStringsSep "\n" (attrValues (mapAttrs showExperimentalFeature xps))) in
xps: (concatStringsSep "\n" (attrValues (mapAttrs showExperimentalFeature xps)))

View file

@ -37,4 +37,3 @@ error:
error: uh oh! error: uh oh!
``` ```

View file

@ -27,4 +27,3 @@
/package-management/channels* /command-ref/nix-channel 301! /package-management/channels* /command-ref/nix-channel 301!
/package-management/s3-substituter* /command-ref/new-cli/nix3-help-stores#s3-binary-cache-store 301! /package-management/s3-substituter* /command-ref/new-cli/nix3-help-stores#s3-binary-cache-store 301!

View file

@ -112,4 +112,3 @@ Build inputs used as instructions to a build task are marked accordingly:
| | | |
+--------------------------------------------------------------------+ +--------------------------------------------------------------------+
``` ```

View file

@ -67,4 +67,3 @@ Configuration options can be set on the command line, overriding the values set
The `extra-` prefix is supported for settings that take a list of items (e.g. `--extra-trusted users alice` or `--option extra-trusted-users alice`). The `extra-` prefix is supported for settings that take a list of items (e.g. `--extra-trusted users alice` or `--option extra-trusted-users alice`).
# Available settings # Available settings

View file

@ -184,4 +184,3 @@ channel:
```console ```console
$ nix-env --file https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz --install --attr firefox $ nix-env --file https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz --install --attr firefox
``` ```

View file

@ -30,4 +30,3 @@ $ nix-env --list-generations
97 2004-02-06 16:22:45 97 2004-02-06 16:22:45
98 2004-02-06 16:24:33 (current) 98 2004-02-06 16:24:33 (current)
``` ```

View file

@ -212,4 +212,3 @@ To show all packages in the latest revision of the Nixpkgs repository:
```console ```console
$ nix-env --file https://github.com/NixOS/nixpkgs/archive/master.tar.gz --query --available $ nix-env --file https://github.com/NixOS/nixpkgs/archive/master.tar.gz --query --available
``` ```

View file

@ -79,4 +79,3 @@ To make files from `binutils` take precedence over files from `gcc`:
$ nix-env --set-flag priority 5 binutils $ nix-env --set-flag priority 5 binutils
$ nix-env --set-flag priority 10 gcc $ nix-env --set-flag priority 10 gcc
``` ```

View file

@ -27,4 +27,3 @@ contain just Firefox:
```console ```console
$ nix-env --profile /nix/var/nix/profiles/browser --set firefox $ nix-env --profile /nix/var/nix/profiles/browser --set firefox
``` ```

View file

@ -30,4 +30,3 @@ Switching will fail if the specified generation does not exist.
$ nix-env --switch-generation 42 $ nix-env --switch-generation 42
switching from generation 50 to 42 switching from generation 50 to 42
``` ```

View file

@ -138,4 +138,3 @@ This is illustrated by the following examples:
2.3a < 2.3c 2.3a < 2.3c
2.3pre1 < 2.3c 2.3pre1 < 2.3c
2.3pre1 < 2.3q 2.3pre1 < 2.3q

View file

@ -32,4 +32,3 @@ This operation has the following options:
$ nix-store --add-fixed sha256 ./hello-2.10.tar.gz $ nix-store --add-fixed sha256 ./hello-2.10.tar.gz
/nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz /nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz
``` ```

View file

@ -69,4 +69,3 @@ To delete at least 100 MiBs of unreachable paths:
```console ```console
$ nix-store --gc --max-freed $((100 * 1024 * 1024)) $ nix-store --gc --max-freed $((100 * 1024 * 1024))
``` ```

View file

@ -33,4 +33,3 @@ The following options are allowed for all `nix-store` operations, but may not al
If there are multiple results, then multiple symlinks will be If there are multiple results, then multiple symlinks will be
created by sequentially numbering symlinks beyond the first one created by sequentially numbering symlinks beyond the first one
(e.g., `foo`, `foo-2`, `foo-3`, and so on). (e.g., `foo`, `foo-2`, `foo-3`, and so on).

View file

@ -37,4 +37,3 @@ hashing files in `/nix/store/qhqx7l2f1kmwihc9bnxs7rc159hsxnf3-gcc-4.1.1'
541838819 bytes (516.74 MiB) freed by hard-linking 54143 files; 541838819 bytes (516.74 MiB) freed by hard-linking 54143 files;
there are 114486 files with equal contents out of 215894 files in total there are 114486 files with equal contents out of 215894 files in total
``` ```

View file

@ -28,4 +28,3 @@ export stdenv; stdenv='/nix/store/7c8asx3yfrg5dg1gzhzyq2236zfgibnn-stdenv'
export system; system='x86_64-linux' export system; system='x86_64-linux'
export _args; _args='-e /nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25c-default-builder.sh' export _args; _args='-e /nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25c-default-builder.sh'
``` ```

View file

@ -225,4 +225,3 @@ $ nix-store --query --roots $(which svn)
/nix/var/nix/profiles/default-82-link /nix/var/nix/profiles/default-82-link
/home/eelco/.local/state/nix/profiles/profile-97-link /home/eelco/.local/state/nix/profiles/profile-97-link
``` ```

View file

@ -35,4 +35,3 @@ ktorrent-2.2.1/
ktorrent-2.2.1/NEWS ktorrent-2.2.1/NEWS
... ...
``` ```

View file

@ -32,4 +32,3 @@ $ nix-store --repair-path /nix/store/dj7a81wsm1ijwwpkks3725661h3263p5-glibc-2.13
fetching path `/nix/store/d7a81wsm1ijwwpkks3725661h3263p5-glibc-2.13'... fetching path `/nix/store/d7a81wsm1ijwwpkks3725661h3263p5-glibc-2.13'...
``` ```

View file

@ -35,4 +35,3 @@ $ cat <<EOF >>/root/.ssh/authorized_keys
command="nice -n20 nix-store --serve --write" ssh-rsa AAAAB3NzaC1yc2EAAAA... command="nice -n20 nix-store --serve --write" ssh-rsa AAAAB3NzaC1yc2EAAAA...
EOF EOF
``` ```

View file

@ -26,4 +26,3 @@ To verify the integrity of the `svn` command and all its dependencies:
```console ```console
$ nix-store --verify-path $(nix-store --query --requisites $(which svn)) $ nix-store --verify-path $(nix-store --query --requisites $(which svn))
``` ```

View file

@ -289,4 +289,3 @@ search/replaced in it for each new build.
The installer now supports a `--tarball-url-prefix` flag which _may_ have The installer now supports a `--tarball-url-prefix` flag which _may_ have
solved this need? solved this need?
--> -->

View file

@ -145,4 +145,3 @@ which you may remove.
> complete. macOS (Catalina+) directly controls root directories and its > complete. macOS (Catalina+) directly controls root directories and its
> read-only root will prevent you from manually deleting the empty `/nix` > read-only root will prevent you from manually deleting the empty `/nix`
> mountpoint. > mountpoint.

View file

@ -161,4 +161,3 @@ All comparison operators are implemented in terms of `<`, and the following equi
Equivalent to `!`*b1* `||` *b2*. Equivalent to `!`*b1* `||` *b2*.
[Logical implication]: #logical-implication [Logical implication]: #logical-implication

View file

@ -1,14 +1,18 @@
with builtins; with builtins;
rec { rec {
splitLines = s: filter (x: !isList x) (split "\n" s); splitLines = s: filter (x: !isList x) (split "\n" s);
concatStrings = concatStringsSep ""; concatStrings = concatStringsSep "";
attrsToList = a: attrsToList =
map (name: { inherit name; value = a.${name}; }) (builtins.attrNames a); a:
map (name: {
inherit name;
value = a.${name};
}) (builtins.attrNames a);
replaceStringsRec = from: to: string: replaceStringsRec =
from: to: string:
# recursively replace occurrences of `from` with `to` within `string` # recursively replace occurrences of `from` with `to` within `string`
# example: # example:
# replaceStringRec "--" "-" "hello-----world" # replaceStringRec "--" "-" "hello-----world"
@ -16,14 +20,16 @@ rec {
let let
replaced = replaceStrings [ from ] [ to ] string; replaced = replaceStrings [ from ] [ to ] string;
in in
if replaced == string then string else replaceStringsRec from to replaced; if replaced == string then string else replaceStringsRec from to replaced;
squash = replaceStringsRec "\n\n\n" "\n\n"; squash = replaceStringsRec "\n\n\n" "\n\n";
trim = string: trim =
string:
# trim trailing spaces and squash non-leading spaces # trim trailing spaces and squash non-leading spaces
let let
trimLine = line: trimLine =
line:
let let
# separate leading spaces from the rest # separate leading spaces from the rest
parts = split "(^ *)" line; parts = split "(^ *)" line;
@ -31,76 +37,102 @@ rec {
rest = elemAt parts 2; rest = elemAt parts 2;
# drop trailing spaces # drop trailing spaces
body = head (split " *$" rest); body = head (split " *$" rest);
in spaces + replaceStringsRec " " " " body; in
in concatStringsSep "\n" (map trimLine (splitLines string)); spaces + replaceStringsRec " " " " body;
in
concatStringsSep "\n" (map trimLine (splitLines string));
# FIXME: O(n^2) # FIXME: O(n^2)
unique = foldl' (acc: e: if elem e acc then acc else acc ++ [ e ]) []; unique = foldl' (acc: e: if elem e acc then acc else acc ++ [ e ]) [ ];
nameValuePair = name: value: { inherit name value; }; nameValuePair = name: value: { inherit name value; };
filterAttrs = pred: set: filterAttrs =
listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set)); pred: set:
listToAttrs (
concatMap (
name:
let
v = set.${name};
in
if pred name v then [ (nameValuePair name v) ] else [ ]
) (attrNames set)
);
optionalString = cond: string: if cond then string else ""; optionalString = cond: string: if cond then string else "";
showSetting = { inlineHTML }: name: { description, documentDefault, defaultValue, aliases, value, experimentalFeature }: showSetting =
{ inlineHTML }:
name:
{
description,
documentDefault,
defaultValue,
aliases,
value,
experimentalFeature,
}:
let let
result = squash '' result = squash ''
- ${if inlineHTML - ${
then ''<span id="conf-${name}">[`${name}`](#conf-${name})</span>'' if inlineHTML then ''<span id="conf-${name}">[`${name}`](#conf-${name})</span>'' else ''`${name}`''
else ''`${name}`''} }
${indent " " body} ${indent " " body}
''; '';
experimentalFeatureNote = optionalString (experimentalFeature != null) '' experimentalFeatureNote = optionalString (experimentalFeature != null) ''
> **Warning** > **Warning**
> This setting is part of an > This setting is part of an
> [experimental feature](@docroot@/contributing/experimental-features.md). > [experimental feature](@docroot@/contributing/experimental-features.md).
To change this setting, you need to make sure the corresponding experimental feature, To change this setting, you need to make sure the corresponding experimental feature,
[`${experimentalFeature}`](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature}), [`${experimentalFeature}`](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature}),
is enabled. is enabled.
For example, include the following in [`nix.conf`](#): For example, include the following in [`nix.conf`](#):
``` ```
extra-experimental-features = ${experimentalFeature} extra-experimental-features = ${experimentalFeature}
${name} = ... ${name} = ...
``` ```
''; '';
# separate body to cleanly handle indentation # separate body to cleanly handle indentation
body = '' body = ''
${description} ${description}
${experimentalFeatureNote} ${experimentalFeatureNote}
**Default:** ${showDefault documentDefault defaultValue} **Default:** ${showDefault documentDefault defaultValue}
${showAliases aliases} ${showAliases aliases}
''; '';
showDefault = documentDefault: defaultValue: showDefault =
documentDefault: defaultValue:
if documentDefault then if documentDefault then
# a StringMap value type is specified as a string, but # 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 defaultValue == "" || defaultValue == [] || isAttrs defaultValue if defaultValue == "" || defaultValue == [ ] || isAttrs defaultValue then
then "*empty*" "*empty*"
else if isBool defaultValue then else if isBool defaultValue then
if defaultValue then "`true`" else "`false`" if defaultValue then "`true`" else "`false`"
else "`${toString defaultValue}`" else
else "*machine-specific*"; "`${toString defaultValue}`"
else
"*machine-specific*";
showAliases = aliases: showAliases =
optionalString (aliases != []) aliases:
"**Deprecated alias:** ${(concatStringsSep ", " (map (s: "`${s}`") aliases))}"; optionalString (aliases != [ ])
"**Deprecated alias:** ${(concatStringsSep ", " (map (s: "`${s}`") aliases))}";
in
result;
in result; indent =
prefix: s: concatStringsSep "\n" (map (x: if x == "" then x else "${prefix}${x}") (splitLines s));
indent = prefix: s: showSettings =
concatStringsSep "\n" (map (x: if x == "" then x else "${prefix}${x}") (splitLines s)); args: settingsInfo: concatStrings (attrValues (mapAttrs (showSetting args) settingsInfo));
showSettings = args: settingsInfo: concatStrings (attrValues (mapAttrs (showSetting args) settingsInfo));
} }

View file

@ -1,70 +1,70 @@
{ pkgs ? import <nixpkgs> { } {
, lib ? pkgs.lib pkgs ? import <nixpkgs> { },
, name ? "nix" lib ? pkgs.lib,
, tag ? "latest" name ? "nix",
, bundleNixpkgs ? true tag ? "latest",
, channelName ? "nixpkgs" bundleNixpkgs ? true,
, channelURL ? "https://nixos.org/channels/nixpkgs-unstable" channelName ? "nixpkgs",
, extraPkgs ? [] channelURL ? "https://nixos.org/channels/nixpkgs-unstable",
, maxLayers ? 100 extraPkgs ? [ ],
, nixConf ? {} maxLayers ? 100,
, flake-registry ? null nixConf ? { },
flake-registry ? null,
}: }:
let let
defaultPkgs = with pkgs; [ defaultPkgs =
nix with pkgs;
bashInteractive [
coreutils-full nix
gnutar bashInteractive
gzip coreutils-full
gnugrep gnutar
which gzip
curl gnugrep
less which
wget curl
man less
cacert.out wget
findutils man
iana-etc cacert.out
git findutils
openssh iana-etc
] ++ extraPkgs; git
openssh
]
++ extraPkgs;
users = { users =
{
root = {
uid = 0;
shell = "${pkgs.bashInteractive}/bin/bash";
home = "/root";
gid = 0;
groups = [ "root" ];
description = "System administrator";
};
root = { nobody = {
uid = 0; uid = 65534;
shell = "${pkgs.bashInteractive}/bin/bash"; shell = "${pkgs.shadow}/bin/nologin";
home = "/root"; home = "/var/empty";
gid = 0; gid = 65534;
groups = [ "root" ]; groups = [ "nobody" ];
description = "System administrator"; description = "Unprivileged account (don't use!)";
}; };
}
nobody = { // lib.listToAttrs (
uid = 65534; map (n: {
shell = "${pkgs.shadow}/bin/nologin"; name = "nixbld${toString n}";
home = "/var/empty"; value = {
gid = 65534; uid = 30000 + n;
groups = [ "nobody" ]; gid = 30000;
description = "Unprivileged account (don't use!)"; groups = [ "nixbld" ];
}; description = "Nix build user ${toString n}";
};
} // lib.listToAttrs ( }) (lib.lists.range 1 32)
map );
(
n: {
name = "nixbld${toString n}";
value = {
uid = 30000 + n;
gid = 30000;
groups = [ "nixbld" ];
description = "Nix build user ${toString n}";
};
}
)
(lib.lists.range 1 32)
);
groups = { groups = {
root.gid = 0; root.gid = 0;
@ -74,24 +74,20 @@ let
userToPasswd = ( userToPasswd = (
k: k:
{ uid {
, gid ? 65534 uid,
, home ? "/var/empty" gid ? 65534,
, description ? "" home ? "/var/empty",
, shell ? "/bin/false" description ? "",
, groups ? [ ] shell ? "/bin/false",
}: "${k}:x:${toString uid}:${toString gid}:${description}:${home}:${shell}" groups ? [ ],
); }:
passwdContents = ( "${k}:x:${toString uid}:${toString gid}:${description}:${home}:${shell}"
lib.concatStringsSep "\n"
(lib.attrValues (lib.mapAttrs userToPasswd users))
); );
passwdContents = (lib.concatStringsSep "\n" (lib.attrValues (lib.mapAttrs userToPasswd users)));
userToShadow = k: { ... }: "${k}:!:1::::::"; userToShadow = k: { ... }: "${k}:!:1::::::";
shadowContents = ( shadowContents = (lib.concatStringsSep "\n" (lib.attrValues (lib.mapAttrs userToShadow users)));
lib.concatStringsSep "\n"
(lib.attrValues (lib.mapAttrs userToShadow users))
);
# Map groups to members # Map groups to members
# { # {
@ -101,42 +97,28 @@ let
let let
# Create a flat list of user/group mappings # Create a flat list of user/group mappings
mappings = ( mappings = (
builtins.foldl' builtins.foldl' (
( acc: user:
acc: user: let
let groups = users.${user}.groups or [ ];
groups = users.${user}.groups or [ ]; in
in acc ++ map (group: { inherit user group; }) groups
acc ++ map ) [ ] (lib.attrNames users)
(group: {
inherit user group;
})
groups
)
[ ]
(lib.attrNames users)
); );
in in
( (builtins.foldl' (
builtins.foldl' acc: v: acc // { ${v.group} = acc.${v.group} or [ ] ++ [ v.user ]; }
( ) { } mappings)
acc: v: acc // {
${v.group} = acc.${v.group} or [ ] ++ [ v.user ];
}
)
{ }
mappings)
); );
groupToGroup = k: { gid }: groupToGroup =
k:
{ gid }:
let let
members = groupMemberMap.${k} or [ ]; members = groupMemberMap.${k} or [ ];
in in
"${k}:x:${toString gid}:${lib.concatStringsSep "," members}"; "${k}:x:${toString gid}:${lib.concatStringsSep "," members}";
groupContents = ( groupContents = (lib.concatStringsSep "\n" (lib.attrValues (lib.mapAttrs groupToGroup groups)));
lib.concatStringsSep "\n"
(lib.attrValues (lib.mapAttrs groupToGroup groups))
);
defaultNixConf = { defaultNixConf = {
sandbox = "false"; sandbox = "false";
@ -144,11 +126,17 @@ let
trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ]; trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
}; };
nixConfContents = (lib.concatStringsSep "\n" (lib.mapAttrsFlatten (n: v: nixConfContents =
let (lib.concatStringsSep "\n" (
vStr = if builtins.isList v then lib.concatStringsSep " " v else v; lib.mapAttrsFlatten (
in n: v:
"${n} = ${vStr}") (defaultNixConf // nixConf))) + "\n"; let
vStr = if builtins.isList v then lib.concatStringsSep " " v else v;
in
"${n} = ${vStr}"
) (defaultNixConf // nixConf)
))
+ "\n";
baseSystem = baseSystem =
let let
@ -167,21 +155,31 @@ let
manifest = pkgs.buildPackages.runCommand "manifest.nix" { } '' manifest = pkgs.buildPackages.runCommand "manifest.nix" { } ''
cat > $out <<EOF cat > $out <<EOF
[ [
${lib.concatStringsSep "\n" (builtins.map (drv: let ${lib.concatStringsSep "\n" (
outputs = drv.outputsToInstall or [ "out" ]; builtins.map (
in '' drv:
{ let
${lib.concatStringsSep "\n" (builtins.map (output: '' outputs = drv.outputsToInstall or [ "out" ];
${output} = { outPath = "${lib.getOutput output drv}"; }; in
'') outputs)} ''
outputs = [ ${lib.concatStringsSep " " (builtins.map (x: "\"${x}\"") outputs)} ]; {
name = "${drv.name}"; ${
outPath = "${drv}"; lib.concatStringsSep "\n" (
system = "${drv.system}"; builtins.map (output: ''
type = "derivation"; ${output} = { outPath = "${lib.getOutput output drv}"; };
meta = { }; '') outputs
} )
'') defaultPkgs)} }
outputs = [ ${lib.concatStringsSep " " (builtins.map (x: "\"${x}\"") outputs)} ];
name = "${drv.name}";
outPath = "${drv}";
system = "${drv.system}";
type = "derivation";
meta = { };
}
''
) defaultPkgs
)}
] ]
EOF EOF
''; '';
@ -190,16 +188,22 @@ let
cp -a ${rootEnv}/* $out/ cp -a ${rootEnv}/* $out/
ln -s ${manifest} $out/manifest.nix ln -s ${manifest} $out/manifest.nix
''; '';
flake-registry-path = if (flake-registry == null) then flake-registry-path =
null if (flake-registry == null) then
else if (builtins.readFileType (toString flake-registry)) == "directory" then null
"${flake-registry}/flake-registry.json" else if (builtins.readFileType (toString flake-registry)) == "directory" then
else "${flake-registry}/flake-registry.json"
flake-registry; else
flake-registry;
in in
pkgs.runCommand "base-system" pkgs.runCommand "base-system"
{ {
inherit passwdContents groupContents shadowContents nixConfContents; inherit
passwdContents
groupContents
shadowContents
nixConfContents
;
passAsFile = [ passAsFile = [
"passwdContents" "passwdContents"
"groupContents" "groupContents"
@ -208,66 +212,68 @@ let
]; ];
allowSubstitutes = false; allowSubstitutes = false;
preferLocalBuild = true; preferLocalBuild = true;
} ('' }
env (
set -x ''
mkdir -p $out/etc env
set -x
mkdir -p $out/etc
mkdir -p $out/etc/ssl/certs mkdir -p $out/etc/ssl/certs
ln -s /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt $out/etc/ssl/certs ln -s /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt $out/etc/ssl/certs
cat $passwdContentsPath > $out/etc/passwd cat $passwdContentsPath > $out/etc/passwd
echo "" >> $out/etc/passwd echo "" >> $out/etc/passwd
cat $groupContentsPath > $out/etc/group cat $groupContentsPath > $out/etc/group
echo "" >> $out/etc/group echo "" >> $out/etc/group
cat $shadowContentsPath > $out/etc/shadow cat $shadowContentsPath > $out/etc/shadow
echo "" >> $out/etc/shadow echo "" >> $out/etc/shadow
mkdir -p $out/usr mkdir -p $out/usr
ln -s /nix/var/nix/profiles/share $out/usr/ ln -s /nix/var/nix/profiles/share $out/usr/
mkdir -p $out/nix/var/nix/gcroots mkdir -p $out/nix/var/nix/gcroots
mkdir $out/tmp mkdir $out/tmp
mkdir -p $out/var/tmp mkdir -p $out/var/tmp
mkdir -p $out/etc/nix mkdir -p $out/etc/nix
cat $nixConfContentsPath > $out/etc/nix/nix.conf cat $nixConfContentsPath > $out/etc/nix/nix.conf
mkdir -p $out/root mkdir -p $out/root
mkdir -p $out/nix/var/nix/profiles/per-user/root mkdir -p $out/nix/var/nix/profiles/per-user/root
ln -s ${profile} $out/nix/var/nix/profiles/default-1-link ln -s ${profile} $out/nix/var/nix/profiles/default-1-link
ln -s $out/nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default ln -s $out/nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default
ln -s /nix/var/nix/profiles/default $out/root/.nix-profile ln -s /nix/var/nix/profiles/default $out/root/.nix-profile
ln -s ${channel} $out/nix/var/nix/profiles/per-user/root/channels-1-link ln -s ${channel} $out/nix/var/nix/profiles/per-user/root/channels-1-link
ln -s $out/nix/var/nix/profiles/per-user/root/channels-1-link $out/nix/var/nix/profiles/per-user/root/channels ln -s $out/nix/var/nix/profiles/per-user/root/channels-1-link $out/nix/var/nix/profiles/per-user/root/channels
mkdir -p $out/root/.nix-defexpr mkdir -p $out/root/.nix-defexpr
ln -s $out/nix/var/nix/profiles/per-user/root/channels $out/root/.nix-defexpr/channels ln -s $out/nix/var/nix/profiles/per-user/root/channels $out/root/.nix-defexpr/channels
echo "${channelURL} ${channelName}" > $out/root/.nix-channels echo "${channelURL} ${channelName}" > $out/root/.nix-channels
mkdir -p $out/bin $out/usr/bin mkdir -p $out/bin $out/usr/bin
ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env
ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh
'' + (lib.optionalString (flake-registry-path != null) ''
nixCacheDir="/root/.cache/nix"
mkdir -p $out$nixCacheDir
globalFlakeRegistryPath="$nixCacheDir/flake-registry.json"
ln -s ${flake-registry-path} $out$globalFlakeRegistryPath
mkdir -p $out/nix/var/nix/gcroots/auto
rootName=$(${pkgs.nix}/bin/nix --extra-experimental-features nix-command hash file --type sha1 --base32 <(echo -n $globalFlakeRegistryPath))
ln -s $globalFlakeRegistryPath $out/nix/var/nix/gcroots/auto/$rootName
''));
''
+ (lib.optionalString (flake-registry-path != null) ''
nixCacheDir="/root/.cache/nix"
mkdir -p $out$nixCacheDir
globalFlakeRegistryPath="$nixCacheDir/flake-registry.json"
ln -s ${flake-registry-path} $out$globalFlakeRegistryPath
mkdir -p $out/nix/var/nix/gcroots/auto
rootName=$(${pkgs.nix}/bin/nix --extra-experimental-features nix-command hash file --type sha1 --base32 <(echo -n $globalFlakeRegistryPath))
ln -s $globalFlakeRegistryPath $out/nix/var/nix/gcroots/auto/$rootName
'')
);
in in
pkgs.dockerTools.buildLayeredImageWithNixDb { pkgs.dockerTools.buildLayeredImageWithNixDb {
inherit name tag maxLayers; inherit name tag maxLayers;
contents = [ baseSystem ]; contents = [ baseSystem ];
@ -285,20 +291,23 @@ pkgs.dockerTools.buildLayeredImageWithNixDb {
Cmd = [ "/root/.nix-profile/bin/bash" ]; Cmd = [ "/root/.nix-profile/bin/bash" ];
Env = [ Env = [
"USER=root" "USER=root"
"PATH=${lib.concatStringsSep ":" [ "PATH=${
"/root/.nix-profile/bin" lib.concatStringsSep ":" [
"/nix/var/nix/profiles/default/bin" "/root/.nix-profile/bin"
"/nix/var/nix/profiles/default/sbin" "/nix/var/nix/profiles/default/bin"
]}" "/nix/var/nix/profiles/default/sbin"
"MANPATH=${lib.concatStringsSep ":" [ ]
"/root/.nix-profile/share/man" }"
"/nix/var/nix/profiles/default/share/man" "MANPATH=${
]}" lib.concatStringsSep ":" [
"/root/.nix-profile/share/man"
"/nix/var/nix/profiles/default/share/man"
]
}"
"SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" "SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
"GIT_SSL_CAINFO=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" "GIT_SSL_CAINFO=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
"NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" "NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
"NIX_PATH=/nix/var/nix/profiles/per-user/root/channels:/root/.nix-defexpr/channels" "NIX_PATH=/nix/var/nix/profiles/per-user/root/channels:/root/.nix-defexpr/channels"
]; ];
}; };
} }

View file

@ -3,11 +3,11 @@
"flake-compat": { "flake-compat": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1673956053, "lastModified": 1696426674,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra", "owner": "edolstra",
"repo": "flake-compat", "repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -16,13 +16,52 @@
"type": "github" "type": "github"
} }
}, },
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"pre-commit-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1709884566, "lastModified": 1711481231,
"narHash": "sha256-NSYJg2sfdO/XS3L8XN/59Zhzn0dqWm7XtVnKI2mHq3w=", "narHash": "sha256-J/fW3Xhm3WsJPNd8ksZmfMnol5aOG2qEMDPbOnNNdTQ=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "2be119add7b37dc535da2dd4cba68e2cf8d1517e", "rev": "9d6ddb13cee3cc1192e4430277708c732685f38a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -48,11 +87,56 @@
"type": "github" "type": "github"
} }
}, },
"pre-commit-hooks": {
"inputs": {
"flake-compat": [
"flake-compat"
],
"flake-utils": "flake-utils",
"gitignore": "gitignore",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-stable": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1711562502,
"narHash": "sha256-SLo1yf/lfozph818VME9Y56uhaZWY0juZcj/qJZPPrs=",
"owner": "9999years",
"repo": "git-hooks.nix",
"rev": "d2f6f9376c38fb0c48526720793a17f10cd3ac10",
"type": "github"
},
"original": {
"owner": "9999years",
"ref": "add-default-pre-commit-hooks",
"repo": "git-hooks.nix",
"type": "github"
}
},
"root": { "root": {
"inputs": { "inputs": {
"flake-compat": "flake-compat", "flake-compat": "flake-compat",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"nixpkgs-regression": "nixpkgs-regression" "nixpkgs-regression": "nixpkgs-regression",
"pre-commit-hooks": "pre-commit-hooks"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
} }
} }
}, },

616
flake.nix
View file

@ -1,12 +1,33 @@
{ {
description = "The purely functional package manager"; description = "The purely functional package manager";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11-small"; inputs = {
inputs.nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11-small";
inputs.flake-compat = { url = "github:edolstra/flake-compat"; flake = false; }; nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2";
pre-commit-hooks = {
outputs = { self, nixpkgs, nixpkgs-regression, flake-compat }: # Can go back to `cachix/git-hooks.nix` when this is merged:
# https://github.com/cachix/git-hooks.nix/pull/401
url = "github:9999years/git-hooks.nix/add-default-pre-commit-hooks";
inputs = {
flake-compat.follows = "flake-compat";
nixpkgs.follows = "nixpkgs";
nixpkgs-stable.follows = "nixpkgs";
};
};
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
};
outputs =
{
self,
nixpkgs,
nixpkgs-regression,
pre-commit-hooks,
flake-compat,
}:
let let
inherit (nixpkgs) lib; inherit (nixpkgs) lib;
inherit (lib) fileset; inherit (lib) fileset;
@ -18,105 +39,137 @@
version = lib.fileContents ./.version + versionSuffix; version = lib.fileContents ./.version + versionSuffix;
versionSuffix = versionSuffix =
if officialRelease if officialRelease then
then "" ""
else "pre${builtins.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")}_${self.shortRev or "dirty"}"; else
"pre${
builtins.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")
}_${self.shortRev or "dirty"}";
linux32BitSystems = [ "i686-linux" ]; linux32BitSystems = [ "i686-linux" ];
linux64BitSystems = [ "x86_64-linux" "aarch64-linux" ]; linux64BitSystems = [
"x86_64-linux"
"aarch64-linux"
];
linuxSystems = linux32BitSystems ++ linux64BitSystems; linuxSystems = linux32BitSystems ++ linux64BitSystems;
darwinSystems = [ "x86_64-darwin" "aarch64-darwin" ]; darwinSystems = [
"x86_64-darwin"
"aarch64-darwin"
];
systems = linuxSystems ++ darwinSystems; systems = linuxSystems ++ darwinSystems;
crossSystems = [ crossSystems = [
"armv6l-linux" "armv7l-linux" "armv6l-linux"
"x86_64-freebsd13" "x86_64-netbsd" "armv7l-linux"
"x86_64-freebsd13"
"x86_64-netbsd"
]; ];
stdenvs = [ "gccStdenv" "clangStdenv" "stdenv" "libcxxStdenv" "ccacheStdenv" ]; stdenvs = [
"gccStdenv"
"clangStdenv"
"stdenv"
"libcxxStdenv"
"ccacheStdenv"
];
forAllSystems = lib.genAttrs systems; forAllSystems = lib.genAttrs systems;
forAllCrossSystems = lib.genAttrs crossSystems; forAllCrossSystems = lib.genAttrs crossSystems;
forAllStdenvs = f: forAllStdenvs =
lib.listToAttrs f:
(map lib.listToAttrs (
(stdenvName: { map (stdenvName: {
name = "${stdenvName}Packages"; name = "${stdenvName}Packages";
value = f stdenvName; value = f stdenvName;
}) }) stdenvs
stdenvs); );
# Memoize nixpkgs for different platforms for efficiency. # Memoize nixpkgs for different platforms for efficiency.
nixpkgsFor = forAllSystems nixpkgsFor = forAllSystems (
(system: let system:
make-pkgs = crossSystem: stdenv: import nixpkgs { let
localSystem = { make-pkgs =
inherit system; crossSystem: stdenv:
}; import nixpkgs {
crossSystem = if crossSystem == null then null else { localSystem = {
system = crossSystem; inherit system;
} // lib.optionalAttrs (crossSystem == "x86_64-freebsd13") { };
useLLVM = true; crossSystem =
}; if crossSystem == null then
overlays = [ null
(overlayFor (p: p.${stdenv})) else
]; {
system = crossSystem;
}
// lib.optionalAttrs (crossSystem == "x86_64-freebsd13") { useLLVM = true; };
overlays = [
(overlayFor (p: p.${stdenv}))
(final: prev: { nixfmt = final.callPackage ./nix-support/nixfmt.nix { }; })
];
config.permittedInsecurePackages = [ "nix-2.13.6" ]; config.permittedInsecurePackages = [ "nix-2.13.6" ];
}; };
stdenvs = forAllStdenvs (make-pkgs null); stdenvs = forAllStdenvs (make-pkgs null);
native = stdenvs.stdenvPackages; native = stdenvs.stdenvPackages;
in { in
{
inherit stdenvs native; inherit stdenvs native;
static = native.pkgsStatic; static = native.pkgsStatic;
cross = forAllCrossSystems (crossSystem: make-pkgs crossSystem "stdenv"); cross = forAllCrossSystems (crossSystem: make-pkgs crossSystem "stdenv");
}); }
);
testNixVersions = pkgs: client: daemon: let testNixVersions =
nix = pkgs.callPackage ./package.nix { pkgs: client: daemon:
pname = let
"nix-tests" nix = pkgs.callPackage ./package.nix {
+ lib.optionalString pname =
(lib.versionAtLeast daemon.version "2.4pre20211005" && "nix-tests"
lib.versionAtLeast client.version "2.4pre20211005") + lib.optionalString (
"-${client.version}-against-${daemon.version}"; lib.versionAtLeast daemon.version "2.4pre20211005"
&& lib.versionAtLeast client.version "2.4pre20211005"
) "-${client.version}-against-${daemon.version}";
inherit fileset; inherit fileset;
}; };
in nix.overrideAttrs (prevAttrs: { in
NIX_DAEMON_PACKAGE = daemon; nix.overrideAttrs (prevAttrs: {
NIX_CLIENT_PACKAGE = client; NIX_DAEMON_PACKAGE = daemon;
NIX_CLIENT_PACKAGE = client;
dontBuild = true; dontBuild = true;
doInstallCheck = true; doInstallCheck = true;
configureFlags = prevAttrs.configureFlags ++ [ configureFlags = prevAttrs.configureFlags ++ [
# We don't need the actual build here. # We don't need the actual build here.
"--disable-build" "--disable-build"
]; ];
installPhase = '' installPhase = ''
mkdir -p $out mkdir -p $out
''; '';
installCheckPhase = lib.optionalString pkgs.stdenv.hostPlatform.isDarwin '' installCheckPhase =
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES lib.optionalString pkgs.stdenv.hostPlatform.isDarwin ''
'' + '' export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
mkdir -p src/nix-channel ''
make installcheck -j$NIX_BUILD_CORES -l$NIX_BUILD_CORES + ''
''; mkdir -p src/nix-channel
}); make installcheck -j$NIX_BUILD_CORES -l$NIX_BUILD_CORES
'';
});
binaryTarball = nix: pkgs: binaryTarball =
nix: pkgs:
let let
inherit (pkgs) buildPackages; inherit (pkgs) buildPackages;
installerClosureInfo = buildPackages.closureInfo { rootPaths = [ nix ]; }; installerClosureInfo = buildPackages.closureInfo { rootPaths = [ nix ]; };
in in
buildPackages.runCommand "nix-binary-tarball-${version}" buildPackages.runCommand "nix-binary-tarball-${version}"
{ #nativeBuildInputs = lib.optional (system != "aarch64-linux") shellcheck; {
#nativeBuildInputs = lib.optional (system != "aarch64-linux") shellcheck;
meta.description = "Distribution-independent Nix bootstrap binaries for ${pkgs.system}"; meta.description = "Distribution-independent Nix bootstrap binaries for ${pkgs.system}";
} }
'' ''
@ -137,25 +190,26 @@
$(cat ${installerClosureInfo}/store-paths) $(cat ${installerClosureInfo}/store-paths)
''; '';
overlayFor = getStdenv: final: prev: overlayFor =
getStdenv: final: prev:
let let
currentStdenv = getStdenv final; currentStdenv = getStdenv final;
comDeps = with final; commonDeps { comDeps =
inherit pkgs; with final;
inherit (currentStdenv.hostPlatform) isStatic; commonDeps {
}; inherit pkgs;
in { inherit (currentStdenv.hostPlatform) isStatic;
};
in
{
nixStable = prev.nix; nixStable = prev.nix;
# Forward from the previous stage as we dont want it to pick the lowdown override # Forward from the previous stage as we dont want it to pick the lowdown override
nixUnstable = prev.nixUnstable; nixUnstable = prev.nixUnstable;
build-release-notes = build-release-notes = final.buildPackages.callPackage ./maintainers/build-release-notes.nix { };
final.buildPackages.callPackage ./maintainers/build-release-notes.nix { };
clangbuildanalyzer = final.buildPackages.callPackage ./misc/clangbuildanalyzer.nix { }; clangbuildanalyzer = final.buildPackages.callPackage ./misc/clangbuildanalyzer.nix { };
boehmgc-nix = (final.boehmgc.override { boehmgc-nix = (final.boehmgc.override { enableLargeConfig = true; }).overrideAttrs (o: {
enableLargeConfig = true;
}).overrideAttrs (o: {
patches = (o.patches or [ ]) ++ [ patches = (o.patches or [ ]) ++ [
./boehmgc-coroutine-sp-fallback.diff ./boehmgc-coroutine-sp-fallback.diff
@ -195,57 +249,65 @@
busybox-sandbox-shell = final.busybox-sandbox-shell or final.default-busybox-sandbox-shell; busybox-sandbox-shell = final.busybox-sandbox-shell or final.default-busybox-sandbox-shell;
}; };
}; };
in
in { {
# A Nixpkgs overlay that overrides the 'nix' and # A Nixpkgs overlay that overrides the 'nix' and
# 'nix.perl-bindings' packages. # 'nix.perl-bindings' packages.
overlays.default = overlayFor (p: p.stdenv); overlays.default = overlayFor (p: p.stdenv);
hydraJobs = { hydraJobs = {
# Binary package for various platforms. # Binary package for various platforms.
build = forAllSystems (system: self.packages.${system}.nix); build = forAllSystems (system: self.packages.${system}.nix);
# FIXME(Qyriad): remove this when the migration to Meson has been completed. # FIXME(Qyriad): remove this when the migration to Meson has been completed.
# NOTE: mesonBuildClang depends on mesonBuild depends on build to avoid OOMs # NOTE: mesonBuildClang depends on mesonBuild depends on build to avoid OOMs
# on aarch64 builders caused by too many parallel compiler/linker processes. # on aarch64 builders caused by too many parallel compiler/linker processes.
mesonBuild = forAllSystems (system: mesonBuild = forAllSystems (
(self.packages.${system}.nix.override { system:
buildWithMeson = true; (self.packages.${system}.nix.override { buildWithMeson = true; }).overrideAttrs (prev: {
}).overrideAttrs (prev: {
buildInputs = prev.buildInputs ++ [ self.packages.${system}.nix ]; buildInputs = prev.buildInputs ++ [ self.packages.${system}.nix ];
}));
mesonBuildClang = forAllSystems (system:
(nixpkgsFor.${system}.stdenvs.clangStdenvPackages.nix.override {
buildWithMeson = true;
}).overrideAttrs (prev: {
buildInputs = prev.buildInputs ++ [ self.hydraJobs.mesonBuild.${system} ];
}) })
); );
mesonBuildClang = forAllSystems (
system:
(nixpkgsFor.${system}.stdenvs.clangStdenvPackages.nix.override { buildWithMeson = true; })
.overrideAttrs
(prev: {
buildInputs = prev.buildInputs ++ [ self.hydraJobs.mesonBuild.${system} ];
})
);
# Perl bindings for various platforms. # Perl bindings for various platforms.
perlBindings = forAllSystems (system: nixpkgsFor.${system}.native.nix.perl-bindings); perlBindings = forAllSystems (system: nixpkgsFor.${system}.native.nix.perl-bindings);
# Binary tarball for various platforms, containing a Nix store # Binary tarball for various platforms, containing a Nix store
# with the closure of 'nix' package. # with the closure of 'nix' package.
binaryTarball = forAllSystems (system: binaryTarball nixpkgsFor.${system}.native.nix nixpkgsFor.${system}.native); binaryTarball = forAllSystems (
system: binaryTarball nixpkgsFor.${system}.native.nix nixpkgsFor.${system}.native
);
# docker image with Nix inside # docker image with Nix inside
dockerImage = lib.genAttrs linux64BitSystems (system: self.packages.${system}.dockerImage); dockerImage = lib.genAttrs linux64BitSystems (system: self.packages.${system}.dockerImage);
# API docs for Nix's unstable internal C++ interfaces. # API docs for Nix's unstable internal C++ interfaces.
internal-api-docs = let internal-api-docs =
nixpkgs = nixpkgsFor.x86_64-linux.native; let
inherit (nixpkgs) pkgs; nixpkgs = nixpkgsFor.x86_64-linux.native;
inherit (nixpkgs) pkgs;
nix = pkgs.callPackage ./package.nix { nix = pkgs.callPackage ./package.nix {
inherit versionSuffix fileset officialRelease buildUnreleasedNotes; inherit
inherit (pkgs) build-release-notes; versionSuffix
internalApiDocs = true; fileset
boehmgc = pkgs.boehmgc-nix; officialRelease
busybox-sandbox-shell = pkgs.busybox-sandbox-shell; buildUnreleasedNotes
}; ;
in inherit (pkgs) build-release-notes;
internalApiDocs = true;
boehmgc = pkgs.boehmgc-nix;
busybox-sandbox-shell = pkgs.busybox-sandbox-shell;
};
in
nix.overrideAttrs (prev: { nix.overrideAttrs (prev: {
# This Hydra job is just for the internal API docs. # This Hydra job is just for the internal API docs.
# We don't need the build artifacts here. # We don't need the build artifacts here.
@ -256,146 +318,248 @@
# System tests. # System tests.
tests = import ./tests/nixos { inherit lib nixpkgs nixpkgsFor; } // { tests = import ./tests/nixos { inherit lib nixpkgs nixpkgsFor; } // {
# Make sure that nix-env still produces the exact same result # Make sure that nix-env still produces the exact same result
# on a particular version of Nixpkgs. # on a particular version of Nixpkgs.
evalNixpkgs = evalNixpkgs =
with nixpkgsFor.x86_64-linux.native; with nixpkgsFor.x86_64-linux.native;
runCommand "eval-nixos" { buildInputs = [ nix ]; } runCommand "eval-nixos" { buildInputs = [ nix ]; } ''
'' type -p nix-env
type -p nix-env # Note: we're filtering out nixos-install-tools because https://github.com/NixOS/nixpkgs/pull/153594#issuecomment-1020530593.
# Note: we're filtering out nixos-install-tools because https://github.com/NixOS/nixpkgs/pull/153594#issuecomment-1020530593. time nix-env --store dummy:// -f ${nixpkgs-regression} -qaP --drv-path | sort | grep -v nixos-install-tools > packages
time nix-env --store dummy:// -f ${nixpkgs-regression} -qaP --drv-path | sort | grep -v nixos-install-tools > packages [[ $(sha1sum < packages | cut -c1-40) = 402242fca90874112b34718b8199d844e8b03d12 ]]
[[ $(sha1sum < packages | cut -c1-40) = 402242fca90874112b34718b8199d844e8b03d12 ]] mkdir $out
mkdir $out '';
'';
nixpkgsLibTests = nixpkgsLibTests = forAllSystems (
forAllSystems (system: system:
import (nixpkgs + "/lib/tests/release.nix") import (nixpkgs + "/lib/tests/release.nix") {
{ pkgs = nixpkgsFor.${system}.native; pkgs = nixpkgsFor.${system}.native;
nixVersions = [ self.packages.${system}.nix ]; nixVersions = [ self.packages.${system}.nix ];
} }
); );
}; };
pre-commit = builtins.mapAttrs (
system: pre-commit-lib:
pre-commit-lib.run {
src = self;
hooks = {
no-commit-to-branch = {
enable = true;
settings.branch = [ "main" ];
};
check-case-conflicts.enable = true;
check-executables-have-shebangs = {
enable = true;
stages = [ "commit" ];
};
check-shebang-scripts-are-executable = {
enable = true;
stages = [ "commit" ];
};
check-symlinks = {
enable = true;
excludes = [ "^tests/functional/lang/symlink-resolution/broken$" ];
};
check-merge-conflicts.enable = true;
end-of-file-fixer = {
enable = true;
excludes = [
"\\.drv$"
"^tests/functional/lang/"
];
};
mixed-line-endings = {
enable = true;
excludes = [ "^tests/functional/lang/" ];
};
# TODO: Once the test suite is nicer, clean up and start
# enforcing trailing whitespace on tests that don't explicitly
# check for it.
trim-trailing-whitespace = {
enable = true;
stages = [ "commit" ];
excludes = [ "^tests/functional/lang/" ];
};
treefmt = {
enable = true;
settings.formatters =
let
pkgs = nixpkgsFor.${system}.native;
in
[ pkgs.nixfmt ];
};
};
}
) pre-commit-hooks.lib;
}; };
checks = forAllSystems (system: let checks = forAllSystems (
rl-next-check = name: dir: system:
let pkgs = nixpkgsFor.${system}.native; let
in pkgs.buildPackages.runCommand "test-${name}-release-notes" { } '' rl-next-check =
LANG=C.UTF-8 ${lib.getExe pkgs.build-release-notes} ${dir} >$out name: dir:
''; let
in { pkgs = nixpkgsFor.${system}.native;
# FIXME(Qyriad): remove this when the migration to Meson has been completed. in
mesonBuild = self.hydraJobs.mesonBuild.${system}; pkgs.buildPackages.runCommand "test-${name}-release-notes" { } ''
mesonBuildClang = self.hydraJobs.mesonBuildClang.${system}; LANG=C.UTF-8 ${lib.getExe pkgs.build-release-notes} ${dir} >$out
binaryTarball = self.hydraJobs.binaryTarball.${system};
perlBindings = self.hydraJobs.perlBindings.${system};
nixpkgsLibTests = self.hydraJobs.tests.nixpkgsLibTests.${system};
rl-next = rl-next-check "rl-next" ./doc/manual/rl-next;
rl-next-dev = rl-next-check "rl-next-dev" ./doc/manual/rl-next-dev;
} // (lib.optionalAttrs (builtins.elem system linux64BitSystems)) {
dockerImage = self.hydraJobs.dockerImage.${system};
});
packages = forAllSystems (system: rec {
inherit (nixpkgsFor.${system}.native) nix;
default = nix;
} // (lib.optionalAttrs (builtins.elem system linux64BitSystems) {
nix-static = nixpkgsFor.${system}.static.nix;
dockerImage =
let
pkgs = nixpkgsFor.${system}.native;
image = import ./docker.nix { inherit pkgs; tag = version; };
in
pkgs.runCommand
"docker-image-tarball-${version}"
{ meta.description = "Docker image with Nix for ${system}"; }
''
mkdir -p $out/nix-support
image=$out/image.tar.gz
ln -s ${image} $image
echo "file binary-dist $image" >> $out/nix-support/hydra-build-products
''; '';
} // builtins.listToAttrs (map in
(crossSystem: { {
name = "nix-${crossSystem}"; # FIXME(Qyriad): remove this when the migration to Meson has been completed.
value = nixpkgsFor.${system}.cross.${crossSystem}.nix; mesonBuild = self.hydraJobs.mesonBuild.${system};
}) mesonBuildClang = self.hydraJobs.mesonBuildClang.${system};
crossSystems) binaryTarball = self.hydraJobs.binaryTarball.${system};
// builtins.listToAttrs (map perlBindings = self.hydraJobs.perlBindings.${system};
(stdenvName: { nixpkgsLibTests = self.hydraJobs.tests.nixpkgsLibTests.${system};
name = "nix-${stdenvName}"; rl-next = rl-next-check "rl-next" ./doc/manual/rl-next;
value = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".nix; rl-next-dev = rl-next-check "rl-next-dev" ./doc/manual/rl-next-dev;
}) pre-commit = self.hydraJobs.pre-commit.${system};
stdenvs))); }
// (lib.optionalAttrs (builtins.elem system linux64BitSystems)) {
dockerImage = self.hydraJobs.dockerImage.${system};
}
);
devShells = let packages = forAllSystems (
makeShell = pkgs: stdenv: system:
let rec {
nix = pkgs.callPackage ./package.nix { inherit (nixpkgsFor.${system}.native) nix;
inherit stdenv versionSuffix fileset; default = nix;
boehmgc = pkgs.boehmgc-nix; }
busybox-sandbox-shell = pkgs.busybox-sandbox-shell or pkgs.default-busybox-sandbox; // (
forDevShell = true; lib.optionalAttrs (builtins.elem system linux64BitSystems) {
}; nix-static = nixpkgsFor.${system}.static.nix;
in dockerImage =
let
pkgs = nixpkgsFor.${system}.native;
image = import ./docker.nix {
inherit pkgs;
tag = version;
};
in
pkgs.runCommand "docker-image-tarball-${version}"
{ meta.description = "Docker image with Nix for ${system}"; }
''
mkdir -p $out/nix-support
image=$out/image.tar.gz
ln -s ${image} $image
echo "file binary-dist $image" >> $out/nix-support/hydra-build-products
'';
}
// builtins.listToAttrs (
map (crossSystem: {
name = "nix-${crossSystem}";
value = nixpkgsFor.${system}.cross.${crossSystem}.nix;
}) crossSystems
)
// builtins.listToAttrs (
map (stdenvName: {
name = "nix-${stdenvName}";
value = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".nix;
}) stdenvs
)
)
);
devShells =
let
makeShell =
pkgs: stdenv:
let
nix = pkgs.callPackage ./package.nix {
inherit stdenv versionSuffix fileset;
boehmgc = pkgs.boehmgc-nix;
busybox-sandbox-shell = pkgs.busybox-sandbox-shell or pkgs.default-busybox-sandbox;
forDevShell = true;
};
pre-commit = self.hydraJobs.pre-commit.${pkgs.system} or { };
in
(nix.override { (nix.override {
buildUnreleasedNotes = true; buildUnreleasedNotes = true;
officialRelease = false; officialRelease = false;
}).overrideAttrs (prev: { }).overrideAttrs
# Required for clang-tidy checks (
buildInputs = prev.buildInputs ++ lib.optionals (stdenv.cc.isClang) [ pkgs.llvmPackages.llvm pkgs.llvmPackages.clang-unwrapped.dev ]; prev:
nativeBuildInputs = prev.nativeBuildInputs {
++ lib.optional (stdenv.cc.isClang && !stdenv.buildPlatform.isDarwin) pkgs.buildPackages.bear # Required for clang-tidy checks
# Required for clang-tidy checks buildInputs =
++ lib.optionals (stdenv.cc.isClang) [ pkgs.buildPackages.cmake pkgs.buildPackages.ninja pkgs.buildPackages.llvmPackages.llvm.dev ] prev.buildInputs
++ lib.optional ++ lib.optional (pre-commit ? enabledPackages) pre-commit.enabledPackages
(stdenv.cc.isClang && stdenv.hostPlatform == stdenv.buildPlatform) # Unfortunately `git-hooks.nix` can't propagate `treefmt`
# for some reason that seems accidental and was changed in # formatters into `enabledPackages` correctly.
# NixOS 24.05-pre, clang-tools is pinned to LLVM 14 when ++ [ pkgs.nixfmt ]
# default LLVM is newer. ++ lib.optionals (stdenv.cc.isClang) [
(pkgs.buildPackages.clang-tools.override { inherit (pkgs.buildPackages) llvmPackages; }) pkgs.llvmPackages.llvm
++ [ pkgs.llvmPackages.clang-unwrapped.dev
# FIXME(Qyriad): remove once the migration to Meson is complete. ];
pkgs.buildPackages.meson nativeBuildInputs =
pkgs.buildPackages.ninja prev.nativeBuildInputs
++ lib.optional (stdenv.cc.isClang && !stdenv.buildPlatform.isDarwin) pkgs.buildPackages.bear
# Required for clang-tidy checks
++ lib.optionals (stdenv.cc.isClang) [
pkgs.buildPackages.cmake
pkgs.buildPackages.ninja
pkgs.buildPackages.llvmPackages.llvm.dev
]
++
lib.optional (stdenv.cc.isClang && stdenv.hostPlatform == stdenv.buildPlatform)
# for some reason that seems accidental and was changed in
# NixOS 24.05-pre, clang-tools is pinned to LLVM 14 when
# default LLVM is newer.
(pkgs.buildPackages.clang-tools.override { inherit (pkgs.buildPackages) llvmPackages; })
++ [
# FIXME(Qyriad): remove once the migration to Meson is complete.
pkgs.buildPackages.meson
pkgs.buildPackages.ninja
pkgs.buildPackages.clangbuildanalyzer pkgs.buildPackages.clangbuildanalyzer
]; ];
src = null; src = null;
installFlags = "sysconfdir=$(out)/etc"; installFlags = "sysconfdir=$(out)/etc";
strictDeps = false; strictDeps = false;
shellHook = '' shellHook = ''
PATH=$prefix/bin:$PATH PATH=$prefix/bin:$PATH
unset PYTHONPATH unset PYTHONPATH
export MANPATH=$out/share/man:$MANPATH export MANPATH=$out/share/man:$MANPATH
# Make bash completion work. # Make bash completion work.
XDG_DATA_DIRS+=:$out/share XDG_DATA_DIRS+=:$out/share
'';
} // lib.optionalAttrs (stdenv.buildPlatform.isLinux && pkgs.glibcLocales != null) { ${lib.optionalString (pre-commit ? shellHook) pre-commit.shellHook}
# Required to make non-NixOS Linux not complain about missing locale files during configure in a dev shell '';
LOCALE_ARCHIVE = "${lib.getLib pkgs.glibcLocales}/lib/locale/locale-archive"; }
}); // lib.optionalAttrs (stdenv.buildPlatform.isLinux && pkgs.glibcLocales != null) {
# Required to make non-NixOS Linux not complain about missing locale files during configure in a dev shell
LOCALE_ARCHIVE = "${lib.getLib pkgs.glibcLocales}/lib/locale/locale-archive";
}
);
in in
forAllSystems (system: forAllSystems (
system:
let let
makeShells = prefix: pkgs: makeShells =
lib.mapAttrs' prefix: pkgs:
(k: v: lib.nameValuePair "${prefix}-${k}" v) lib.mapAttrs' (k: v: lib.nameValuePair "${prefix}-${k}" v) (
(forAllStdenvs (stdenvName: makeShell pkgs pkgs.${stdenvName})); forAllStdenvs (stdenvName: makeShell pkgs pkgs.${stdenvName})
);
in in
(makeShells "native" nixpkgsFor.${system}.native) // (makeShells "native" nixpkgsFor.${system}.native)
(makeShells "static" nixpkgsFor.${system}.static) // // (makeShells "static" nixpkgsFor.${system}.static)
(forAllCrossSystems (crossSystem: let pkgs = nixpkgsFor.${system}.cross.${crossSystem}; in makeShell pkgs pkgs.stdenv)) // // (forAllCrossSystems (
{ crossSystem:
default = self.devShells.${system}.native-stdenvPackages; let
} pkgs = nixpkgsFor.${system}.cross.${crossSystem};
in
makeShell pkgs pkgs.stdenv
))
// {
default = self.devShells.${system}.native-stdenvPackages;
}
); );
}; };
} }

View file

@ -1,5 +1,8 @@
{ lib, python3, writeShellScriptBin }: {
lib,
python3,
writeShellScriptBin,
}:
writeShellScriptBin "build-release-notes" '' writeShellScriptBin "build-release-notes" ''
exec ${lib.getExe (python3.withPackages (p: [ p.python-frontmatter ]))} \ exec ${lib.getExe (python3.withPackages (p: [ p.python-frontmatter ]))} \
${./build-release-notes.py} "$@" ${./build-release-notes.py} "$@"

0
maintainers/build-release-notes.py Executable file → Normal file
View file

View file

@ -193,4 +193,3 @@ release:
## Recovering from mistakes ## Recovering from mistakes
`upload-release.pl` should be idempotent. For instance a wrong `IS_LATEST` value can be fixed that way, by running the script on the actual latest release. `upload-release.pl` should be idempotent. For instance a wrong `IS_LATEST` value can be fixed that way, by running the script on the actual latest release.

View file

@ -84,4 +84,3 @@ except Exception as e:
print(f'{name}: INTERNAL ERROR running test ({sys.argv}): {e}', file=sys.stderr) print(f'{name}: INTERNAL ERROR running test ({sys.argv}): {e}', file=sys.stderr)
print(f'this is a bug in {name}') print(f'this is a bug in {name}')
sys.exit(99) sys.exit(99)

View file

@ -1,6 +1,11 @@
# Upstreaming here, can be deleted once it's upstreamed: # Upstreaming here, can be deleted once it's upstreamed:
# https://github.com/NixOS/nixpkgs/pull/297102 # https://github.com/NixOS/nixpkgs/pull/297102
{ stdenv, lib, cmake, fetchFromGitHub }: {
stdenv,
lib,
cmake,
fetchFromGitHub,
}:
stdenv.mkDerivation (finalAttrs: { stdenv.mkDerivation (finalAttrs: {
pname = "clangbuildanalyzer"; pname = "clangbuildanalyzer";
version = "1.5.0"; version = "1.5.0";
@ -12,9 +17,7 @@ stdenv.mkDerivation (finalAttrs: {
sha256 = "sha256-kmgdk634zM0W0OoRoP/RzepArSipa5bNqdVgdZO9gxo="; sha256 = "sha256-kmgdk634zM0W0OoRoP/RzepArSipa5bNqdVgdZO9gxo=";
}; };
nativeBuildInputs = [ nativeBuildInputs = [ cmake ];
cmake
];
meta = { meta = {
description = "Tool for analyzing Clang's -ftrace-time files"; description = "Tool for analyzing Clang's -ftrace-time files";

79
nix-support/nixfmt.nix Normal file
View file

@ -0,0 +1,79 @@
# Copy of `nixfmt-rfc-style` vendored from `nixpkgs` master:
# https://github.com/NixOS/nixpkgs/blob/ab6071eb54cc9b66dda436111d4f569e4e56cbf4/pkgs/by-name/ni/nixfmt-rfc-style/package.nix
{
haskell,
haskellPackages,
lib,
fetchpatch,
}:
let
inherit (haskell.lib.compose) overrideCabal justStaticExecutables;
overrides = {
version = "unstable-2024-03-01";
patches = [
(fetchpatch {
url = "https://github.com/serokell/nixfmt/commit/ca9c8975ed671112fdfce94f2e9e2ad3de480c9a.patch";
hash = "sha256-UOSAYahSKBsqPMVcQJ3H26Eg2xpPAsNOjYMI6g+WTYU=";
})
];
};
raw-pkg = haskellPackages.callPackage (
{
mkDerivation,
base,
cmdargs,
directory,
fetchzip,
filepath,
lib,
megaparsec,
mtl,
parser-combinators,
safe-exceptions,
scientific,
text,
transformers,
unix,
}:
mkDerivation {
pname = "nixfmt";
version = "0.5.0";
src = fetchzip {
url = "https://github.com/piegamesde/nixfmt/archive/2b5ee820690bae64cb4003e46917ae43541e3e0b.tar.gz";
sha256 = "1i1jbc1q4gd7fpilwy6s3a583yl5l8d8rlmipygj61mpclg9ihqg";
};
isLibrary = true;
isExecutable = true;
libraryHaskellDepends = [
base
megaparsec
mtl
parser-combinators
scientific
text
transformers
];
executableHaskellDepends = [
base
cmdargs
directory
filepath
safe-exceptions
text
unix
];
jailbreak = true;
homepage = "https://github.com/serokell/nixfmt";
description = "An opinionated formatter for Nix";
license = lib.licenses.mpl20;
mainProgram = "nixfmt";
}
) { };
in
lib.pipe raw-pkg [
(overrideCabal overrides)
justStaticExecutables
]

View file

@ -40,9 +40,11 @@
util-linuxMinimal ? utillinuxMinimal, util-linuxMinimal ? utillinuxMinimal,
utillinuxMinimal ? null, utillinuxMinimal ? null,
xz, xz,
busybox-sandbox-shell, busybox-sandbox-shell,
# Customization options
# =====================
pname ? "nix", pname ? "nix",
versionSuffix ? "", versionSuffix ? "",
officialRelease ? true, officialRelease ? true,
@ -61,19 +63,21 @@
__forDefaults ? { __forDefaults ? {
canRunInstalled = stdenv.buildPlatform.canExecute stdenv.hostPlatform; canRunInstalled = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
}, },
}: let }:
let
inherit (__forDefaults) canRunInstalled; inherit (__forDefaults) canRunInstalled;
version = lib.fileContents ./.version + versionSuffix; version = lib.fileContents ./.version + versionSuffix;
aws-sdk-cpp-nix = aws-sdk-cpp.override { aws-sdk-cpp-nix = aws-sdk-cpp.override {
apis = [ "s3" "transfer" ]; apis = [
"s3"
"transfer"
];
customMemoryManagement = false; customMemoryManagement = false;
}; };
testConfigureFlags = [ testConfigureFlags = [ "RAPIDCHECK_HEADERS=${lib.getDev rapidcheck}/extras/gtest/include" ];
"RAPIDCHECK_HEADERS=${lib.getDev rapidcheck}/extras/gtest/include"
];
# The internal API docs need these for the build, but if we're not building # The internal API docs need these for the build, but if we're not building
# Nix itself, then these don't need to be propagated. # Nix itself, then these don't need to be propagated.
@ -95,48 +99,60 @@
./README.md ./README.md
]; ];
topLevelBuildFiles = fileset.unions ([ topLevelBuildFiles = fileset.unions (
./local.mk [
./Makefile ./local.mk
./Makefile.config.in ./Makefile
./mk ./Makefile.config.in
] ++ lib.optionals buildWithMeson [ ./mk
./meson.build ]
./meson.options ++ lib.optionals buildWithMeson [
./meson ./meson.build
./scripts/meson.build ./meson.options
]); ./meson
./scripts/meson.build
]
);
functionalTestFiles = fileset.unions [ functionalTestFiles = fileset.unions [
./tests/functional ./tests/functional
./tests/unit ./tests/unit
(fileset.fileFilter (f: lib.strings.hasPrefix "nix-profile" f.name) ./scripts) (fileset.fileFilter (f: lib.strings.hasPrefix "nix-profile" f.name) ./scripts)
]; ];
in
in stdenv.mkDerivation (finalAttrs: { stdenv.mkDerivation (finalAttrs: {
inherit pname version; inherit pname version;
src = fileset.toSource { src = fileset.toSource {
root = ./.; root = ./.;
fileset = fileset.intersection baseFiles (fileset.unions ([ fileset = fileset.intersection baseFiles (
configureFiles fileset.unions (
topLevelBuildFiles [
functionalTestFiles configureFiles
] ++ lib.optionals (!finalAttrs.dontBuild || internalApiDocs) [ topLevelBuildFiles
./boehmgc-coroutine-sp-fallback.diff functionalTestFiles
./doc ]
./misc ++ lib.optionals (!finalAttrs.dontBuild || internalApiDocs) [
./precompiled-headers.h ./boehmgc-coroutine-sp-fallback.diff
./src ./doc
./COPYING ./misc
./scripts/local.mk ./precompiled-headers.h
])); ./src
./COPYING
./scripts/local.mk
]
)
);
}; };
VERSION_SUFFIX = versionSuffix; VERSION_SUFFIX = versionSuffix;
outputs = [ "out" ] outputs =
++ lib.optionals (!finalAttrs.dontBuild) [ "dev" "doc" ]; [ "out" ]
++ lib.optionals (!finalAttrs.dontBuild) [
"dev"
"doc"
];
dontBuild = false; dontBuild = false;
@ -148,51 +164,59 @@ in stdenv.mkDerivation (finalAttrs: {
# We only include CMake so that Meson can locate toml11, which only ships CMake dependency metadata. # We only include CMake so that Meson can locate toml11, which only ships CMake dependency metadata.
dontUseCmakeConfigure = true; dontUseCmakeConfigure = true;
nativeBuildInputs = [ nativeBuildInputs =
bison [
flex bison
] ++ [ flex
(lib.getBin lowdown) ]
mdbook ++ [
mdbook-linkcheck (lib.getBin lowdown)
autoconf-archive mdbook
] ++ lib.optional (!buildWithMeson) autoreconfHook ++ [ mdbook-linkcheck
pkg-config autoconf-archive
]
++ lib.optional (!buildWithMeson) autoreconfHook
++ [
pkg-config
# Tests # Tests
git git
mercurial mercurial
jq jq
lsof lsof
] ++ lib.optional stdenv.hostPlatform.isLinux util-linuxMinimal ]
++ lib.optional stdenv.hostPlatform.isLinux util-linuxMinimal
++ lib.optional (!officialRelease && buildUnreleasedNotes) build-release-notes ++ lib.optional (!officialRelease && buildUnreleasedNotes) build-release-notes
++ lib.optional internalApiDocs doxygen ++ lib.optional internalApiDocs doxygen
++ lib.optionals buildWithMeson [ ++ lib.optionals buildWithMeson [
meson meson
ninja ninja
cmake cmake
]; ];
buildInputs = [ buildInputs =
curl [
bzip2 curl
xz bzip2
brotli xz
editline brotli
openssl editline
sqlite openssl
libarchive sqlite
boost libarchive
lowdown boost
libsodium lowdown
toml11 libsodium
] toml11
++ lib.optionals stdenv.hostPlatform.isLinux [ libseccomp busybox-sandbox-shell ] ]
++ lib.optionals stdenv.hostPlatform.isLinux [
libseccomp
busybox-sandbox-shell
]
++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid ++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid
# There have been issues building these dependencies # There have been issues building these dependencies
++ lib.optional (stdenv.hostPlatform == stdenv.buildPlatform) aws-sdk-cpp-nix ++ lib.optional (stdenv.hostPlatform == stdenv.buildPlatform) aws-sdk-cpp-nix
++ lib.optionals (finalAttrs.dontBuild) maybePropagatedInputs ++ lib.optionals (finalAttrs.dontBuild) maybePropagatedInputs;
;
checkInputs = [ checkInputs = [
gtest gtest
@ -201,9 +225,7 @@ in stdenv.mkDerivation (finalAttrs: {
propagatedBuildInputs = lib.optionals (!finalAttrs.dontBuild) maybePropagatedInputs; propagatedBuildInputs = lib.optionals (!finalAttrs.dontBuild) maybePropagatedInputs;
disallowedReferences = [ disallowedReferences = [ boost ];
boost
];
# Needed for Meson to find Boost. # Needed for Meson to find Boost.
# https://github.com/NixOS/nixpkgs/issues/86131. # https://github.com/NixOS/nixpkgs/issues/86131.
@ -212,45 +234,49 @@ in stdenv.mkDerivation (finalAttrs: {
BOOST_LIBRARYDIR = "${lib.getLib boost}/lib"; BOOST_LIBRARYDIR = "${lib.getLib boost}/lib";
}; };
preConfigure = lib.optionalString (!finalAttrs.dontBuild && !stdenv.hostPlatform.isStatic) '' preConfigure =
# Copy libboost_context so we don't get all of Boost in our closure. lib.optionalString (!finalAttrs.dontBuild && !stdenv.hostPlatform.isStatic) ''
# https://github.com/NixOS/nixpkgs/issues/45462 # Copy libboost_context so we don't get all of Boost in our closure.
mkdir -p $out/lib # https://github.com/NixOS/nixpkgs/issues/45462
cp -pd ${boost}/lib/{libboost_context*,libboost_thread*,libboost_system*} $out/lib mkdir -p $out/lib
rm -f $out/lib/*.a cp -pd ${boost}/lib/{libboost_context*,libboost_thread*,libboost_system*} $out/lib
'' + lib.optionalString (!finalAttrs.dontBuild && stdenv.hostPlatform.isLinux) '' rm -f $out/lib/*.a
chmod u+w $out/lib/*.so.* ''
patchelf --set-rpath $out/lib:${stdenv.cc.cc.lib}/lib $out/lib/libboost_thread.so.* + lib.optionalString (!finalAttrs.dontBuild && stdenv.hostPlatform.isLinux) ''
'' + lib.optionalString (!finalAttrs.dontBuild && stdenv.hostPlatform.isDarwin) '' chmod u+w $out/lib/*.so.*
for LIB in $out/lib/*.dylib; do patchelf --set-rpath $out/lib:${stdenv.cc.cc.lib}/lib $out/lib/libboost_thread.so.*
chmod u+w $LIB ''
install_name_tool -id $LIB $LIB + lib.optionalString (!finalAttrs.dontBuild && stdenv.hostPlatform.isDarwin) ''
install_name_tool -delete_rpath ${boost}/lib/ $LIB || true for LIB in $out/lib/*.dylib; do
done chmod u+w $LIB
install_name_tool -change ${boost}/lib/libboost_system.dylib $out/lib/libboost_system.dylib $out/lib/libboost_thread.dylib install_name_tool -id $LIB $LIB
'' + '' install_name_tool -delete_rpath ${boost}/lib/ $LIB || true
# Workaround https://github.com/NixOS/nixpkgs/issues/294890. done
if [[ -n "''${doCheck:-}" ]]; then install_name_tool -change ${boost}/lib/libboost_system.dylib $out/lib/libboost_system.dylib $out/lib/libboost_thread.dylib
appendToVar configureFlags "--enable-tests" ''
else + ''
appendToVar configureFlags "--disable-tests" # Workaround https://github.com/NixOS/nixpkgs/issues/294890.
fi if [[ -n "''${doCheck:-}" ]]; then
''; appendToVar configureFlags "--enable-tests"
else
appendToVar configureFlags "--disable-tests"
fi
'';
configureFlags = lib.optionals stdenv.isLinux [ configureFlags =
"--with-boost=${boost}/lib" lib.optionals stdenv.isLinux [
"--with-sandbox-shell=${busybox-sandbox-shell}/bin/busybox" "--with-boost=${boost}/lib"
] ++ lib.optionals (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) [ "--with-sandbox-shell=${busybox-sandbox-shell}/bin/busybox"
"LDFLAGS=-fuse-ld=gold" ]
] ++ lib.optionals (
stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")
) [ "LDFLAGS=-fuse-ld=gold" ]
++ lib.optional stdenv.hostPlatform.isStatic "--enable-embedded-sandbox-shell" ++ lib.optional stdenv.hostPlatform.isStatic "--enable-embedded-sandbox-shell"
++ lib.optionals (finalAttrs.doCheck || internalApiDocs) testConfigureFlags ++ lib.optionals (finalAttrs.doCheck || internalApiDocs) testConfigureFlags
++ lib.optional (!canRunInstalled) "--disable-doc-gen" ++ lib.optional (!canRunInstalled) "--disable-doc-gen"
++ [ (lib.enableFeature internalApiDocs "internal-api-docs") ] ++ [ (lib.enableFeature internalApiDocs "internal-api-docs") ]
++ lib.optional (!forDevShell) "--sysconfdir=/etc" ++ lib.optional (!forDevShell) "--sysconfdir=/etc"
++ [ ++ [ "TOML11_HEADERS=${lib.getDev toml11}/include" ];
"TOML11_HEADERS=${lib.getDev toml11}/include"
];
mesonBuildType = lib.optional (buildWithMeson || forDevShell) "debugoptimized"; mesonBuildType = lib.optional (buildWithMeson || forDevShell) "debugoptimized";
@ -262,37 +288,37 @@ in stdenv.mkDerivation (finalAttrs: {
doCheck = true; doCheck = true;
mesonCheckFlags = lib.optionals (buildWithMeson || forDevShell) [ mesonCheckFlags = lib.optionals (buildWithMeson || forDevShell) [ "--suite=check" ];
"--suite=check"
];
installFlags = "sysconfdir=$(out)/etc"; installFlags = "sysconfdir=$(out)/etc";
postInstall = lib.optionalString (!finalAttrs.dontBuild) '' postInstall =
mkdir -p $doc/nix-support lib.optionalString (!finalAttrs.dontBuild) ''
echo "doc manual $doc/share/doc/nix/manual" >> $doc/nix-support/hydra-build-products mkdir -p $doc/nix-support
'' + lib.optionalString stdenv.hostPlatform.isStatic '' echo "doc manual $doc/share/doc/nix/manual" >> $doc/nix-support/hydra-build-products
mkdir -p $out/nix-support ''
echo "file binary-dist $out/bin/nix" >> $out/nix-support/hydra-build-products + lib.optionalString stdenv.hostPlatform.isStatic ''
'' + lib.optionalString stdenv.isDarwin '' mkdir -p $out/nix-support
for lib in libnixutil.dylib libnixexpr.dylib; do echo "file binary-dist $out/bin/nix" >> $out/nix-support/hydra-build-products
install_name_tool \ ''
-change "${lib.getLib boost}/lib/libboost_context.dylib" \ + lib.optionalString stdenv.isDarwin ''
"$out/lib/libboost_context.dylib" \ for lib in libnixutil.dylib libnixexpr.dylib; do
"$out/lib/$lib" install_name_tool \
done -change "${lib.getLib boost}/lib/libboost_context.dylib" \
'' + lib.optionalString internalApiDocs '' "$out/lib/libboost_context.dylib" \
mkdir -p $out/nix-support "$out/lib/$lib"
echo "doc internal-api-docs $out/share/doc/nix/internal-api/html" >> "$out/nix-support/hydra-build-products" done
''; ''
+ lib.optionalString internalApiDocs ''
mkdir -p $out/nix-support
echo "doc internal-api-docs $out/share/doc/nix/internal-api/html" >> "$out/nix-support/hydra-build-products"
'';
doInstallCheck = finalAttrs.doCheck; doInstallCheck = finalAttrs.doCheck;
installCheckFlags = "sysconfdir=$(out)/etc"; installCheckFlags = "sysconfdir=$(out)/etc";
installCheckTarget = "installcheck"; # work around buggy detection in stdenv installCheckTarget = "installcheck"; # work around buggy detection in stdenv
mesonInstallCheckFlags = [ mesonInstallCheckFlags = [ "--suite=installcheck" ];
"--suite=installcheck"
];
preInstallCheck = lib.optionalString stdenv.hostPlatform.isDarwin '' preInstallCheck = lib.optionalString stdenv.hostPlatform.isDarwin ''
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
@ -310,12 +336,9 @@ in stdenv.mkDerivation (finalAttrs: {
strictDeps = true; strictDeps = true;
# strictoverflow is disabled because we trap on signed overflow instead # strictoverflow is disabled because we trap on signed overflow instead
hardeningDisable = [ "strictoverflow" ] hardeningDisable = [ "strictoverflow" ] ++ lib.optional stdenv.hostPlatform.isStatic "pie";
++ lib.optional stdenv.hostPlatform.isStatic "pie";
meta.platforms = lib.platforms.unix; meta.platforms = lib.platforms.unix;
passthru.perl-bindings = pkgs.callPackage ./perl { passthru.perl-bindings = pkgs.callPackage ./perl { inherit fileset stdenv; };
inherit fileset stdenv;
};
}) })

View file

@ -1,51 +1,64 @@
{ lib, fileset {
, stdenv lib,
, perl, perlPackages fileset,
, autoconf-archive, autoreconfHook, pkg-config stdenv,
, nix, curl, bzip2, xz, boost, libsodium, darwin perl,
perlPackages,
autoconf-archive,
autoreconfHook,
pkg-config,
nix,
curl,
bzip2,
xz,
boost,
libsodium,
darwin,
}: }:
perl.pkgs.toPerlModule (
stdenv.mkDerivation {
name = "nix-perl-${nix.version}";
perl.pkgs.toPerlModule (stdenv.mkDerivation { src = fileset.toSource {
name = "nix-perl-${nix.version}"; root = ../.;
fileset = fileset.unions [
../.version
../m4
../mk
./MANIFEST
./Makefile
./Makefile.config.in
./configure.ac
./lib
./local.mk
];
};
src = fileset.toSource { nativeBuildInputs = [
root = ../.; autoconf-archive
fileset = fileset.unions [
../.version
../m4
../mk
./MANIFEST
./Makefile
./Makefile.config.in
./configure.ac
./lib
./local.mk
];
};
nativeBuildInputs =
[ autoconf-archive
autoreconfHook autoreconfHook
pkg-config pkg-config
]; ];
buildInputs = buildInputs =
[ nix [
curl nix
bzip2 curl
xz bzip2
perl xz
boost perl
] boost
++ lib.optional (stdenv.isLinux || stdenv.isDarwin) libsodium ]
++ lib.optional stdenv.isDarwin darwin.apple_sdk.frameworks.Security; ++ lib.optional (stdenv.isLinux || stdenv.isDarwin) libsodium
++ lib.optional stdenv.isDarwin darwin.apple_sdk.frameworks.Security;
configureFlags = [ configureFlags = [
"--with-dbi=${perlPackages.DBI}/${perl.libPrefix}" "--with-dbi=${perlPackages.DBI}/${perl.libPrefix}"
"--with-dbd-sqlite=${perlPackages.DBDSQLite}/${perl.libPrefix}" "--with-dbd-sqlite=${perlPackages.DBDSQLite}/${perl.libPrefix}"
]; ];
enableParallelBuilding = true; enableParallelBuilding = true;
postUnpack = "sourceRoot=$sourceRoot/perl"; postUnpack = "sourceRoot=$sourceRoot/perl";
}) }
)

View file

@ -1,43 +1,72 @@
{ system ? "" # obsolete {
, url system ? "", # obsolete
, hash ? "" # an SRI hash url,
hash ? "", # an SRI hash
# Legacy hash specification # Legacy hash specification
, md5 ? "", sha1 ? "", sha256 ? "", sha512 ? "" md5 ? "",
, outputHash ? sha1 ? "",
if hash != "" then hash else if sha512 != "" then sha512 else if sha1 != "" then sha1 else if md5 != "" then md5 else sha256 sha256 ? "",
, outputHashAlgo ? sha512 ? "",
if hash != "" then "" else if sha512 != "" then "sha512" else if sha1 != "" then "sha1" else if md5 != "" then "md5" else "sha256" outputHash ?
if hash != "" then
, executable ? false hash
, unpack ? false else if sha512 != "" then
, name ? baseNameOf (toString url) sha512
, impure ? false else if sha1 != "" then
sha1
else if md5 != "" then
md5
else
sha256,
outputHashAlgo ?
if hash != "" then
""
else if sha512 != "" then
"sha512"
else if sha1 != "" then
"sha1"
else if md5 != "" then
"md5"
else
"sha256",
executable ? false,
unpack ? false,
name ? baseNameOf (toString url),
impure ? false,
}: }:
derivation (
{
builder = "builtin:fetchurl";
derivation ({ # New-style output content requirements.
builder = "builtin:fetchurl"; outputHashMode = if unpack || executable then "recursive" else "flat";
# New-style output content requirements. inherit
outputHashMode = if unpack || executable then "recursive" else "flat"; name
url
executable
unpack
;
inherit name url executable unpack; system = "builtin";
system = "builtin"; # No need to double the amount of network traffic
preferLocalBuild = true;
# No need to double the amount of network traffic impureEnvVars = [
preferLocalBuild = true; # We borrow these environment variables from the caller to allow
# easy proxy configuration. This is impure, but a fixed-output
# derivation like fetchurl is allowed to do so since its result is
# by definition pure.
"http_proxy"
"https_proxy"
"ftp_proxy"
"all_proxy"
"no_proxy"
];
impureEnvVars = [ # To make "nix-prefetch-url" work.
# We borrow these environment variables from the caller to allow urls = [ url ];
# easy proxy configuration. This is impure, but a fixed-output }
# derivation like fetchurl is allowed to do so since its result is // (if impure then { __impure = true; } else { inherit outputHashAlgo outputHash; })
# by definition pure. )
"http_proxy" "https_proxy" "ftp_proxy" "all_proxy" "no_proxy"
];
# To make "nix-prefetch-url" work.
urls = [ url ];
} // (if impure
then { __impure = true; }
else { inherit outputHashAlgo outputHash; }))

View file

@ -1,72 +1,69 @@
lockFileStr: rootSrc: rootSubdir: lockFileStr: rootSrc: rootSubdir:
let let
lockFile = builtins.fromJSON lockFileStr; lockFile = builtins.fromJSON lockFileStr;
allNodes = allNodes = builtins.mapAttrs (
builtins.mapAttrs key: node:
(key: node: let
let sourceInfo =
if key == lockFile.root then
rootSrc
else
fetchTree (node.info or { } // removeAttrs node.locked [ "dir" ]);
sourceInfo = subdir = if key == lockFile.root then rootSubdir else node.locked.dir or "";
if key == lockFile.root
then rootSrc
else fetchTree (node.info or {} // removeAttrs node.locked ["dir"]);
subdir = if key == lockFile.root then rootSubdir else node.locked.dir or ""; outPath = sourceInfo + ((if subdir == "" then "" else "/") + subdir);
outPath = sourceInfo + ((if subdir == "" then "" else "/") + subdir); flake = import (outPath + "/flake.nix");
flake = import (outPath + "/flake.nix"); inputs = builtins.mapAttrs (inputName: inputSpec: allNodes.${resolveInput inputSpec}) (
node.inputs or { }
);
inputs = builtins.mapAttrs # Resolve a input spec into a node name. An input spec is
(inputName: inputSpec: allNodes.${resolveInput inputSpec}) # either a node name, or a 'follows' path from the root
(node.inputs or {}); # node.
resolveInput =
inputSpec: if builtins.isList inputSpec then getInputByPath lockFile.root inputSpec else inputSpec;
# Resolve a input spec into a node name. An input spec is # Follow an input path (e.g. ["dwarffs" "nixpkgs"]) from the
# either a node name, or a 'follows' path from the root # root node, returning the final node.
# node. getInputByPath =
resolveInput = inputSpec: nodeName: path:
if builtins.isList inputSpec if path == [ ] then
then getInputByPath lockFile.root inputSpec nodeName
else inputSpec; else
getInputByPath
# Since this could be a 'follows' input, call resolveInput.
(resolveInput lockFile.nodes.${nodeName}.inputs.${builtins.head path})
(builtins.tail path);
# Follow an input path (e.g. ["dwarffs" "nixpkgs"]) from the outputs = flake.outputs (inputs // { self = result; });
# root node, returning the final node.
getInputByPath = nodeName: path:
if path == []
then nodeName
else
getInputByPath
# Since this could be a 'follows' input, call resolveInput.
(resolveInput lockFile.nodes.${nodeName}.inputs.${builtins.head path})
(builtins.tail path);
outputs = flake.outputs (inputs // { self = result; }); result =
outputs
# We add the sourceInfo attribute for its metadata, as they are
# relevant metadata for the flake. However, the outPath of the
# sourceInfo does not necessarily match the outPath of the flake,
# as the flake may be in a subdirectory of a source.
# This is shadowed in the next //
// sourceInfo
// {
# This shadows the sourceInfo.outPath
inherit outPath;
result = inherit inputs;
outputs inherit outputs;
# We add the sourceInfo attribute for its metadata, as they are inherit sourceInfo;
# relevant metadata for the flake. However, the outPath of the _type = "flake";
# sourceInfo does not necessarily match the outPath of the flake, };
# as the flake may be in a subdirectory of a source. in
# This is shadowed in the next // if node.flake or true then
// sourceInfo assert builtins.isFunction flake.outputs;
// { result
# This shadows the sourceInfo.outPath else
inherit outPath; sourceInfo
) lockFile.nodes;
inherit inputs; inherit outputs; inherit sourceInfo; _type = "flake"; in
}; allNodes.${lockFile.root}
in
if node.flake or true then
assert builtins.isFunction flake.outputs;
result
else
sourceInfo
)
lockFile.nodes;
in allNodes.${lockFile.root}

View file

@ -1,21 +1,24 @@
attrs @ { drvPath, outputs, name, ... }: attrs@{
drvPath,
outputs,
name,
...
}:
let let
commonAttrs = (builtins.listToAttrs outputsList) // {
all = map (x: x.value) outputsList;
inherit drvPath name;
type = "derivation";
};
commonAttrs = (builtins.listToAttrs outputsList) // outputToAttrListElement = outputName: {
{ all = map (x: x.value) outputsList; name = outputName;
inherit drvPath name; value = commonAttrs // {
type = "derivation"; outPath = builtins.getAttr outputName attrs;
}; inherit outputName;
outputToAttrListElement = outputName:
{ name = outputName;
value = commonAttrs // {
outPath = builtins.getAttr outputName attrs;
inherit outputName;
};
}; };
};
outputsList = map outputToAttrListElement outputs; outputsList = map outputToAttrListElement outputs;
in
in (builtins.head outputsList).value (builtins.head outputsList).value

View file

@ -1,27 +1,32 @@
/* This is the implementation of the derivation builtin function. /*
It's actually a wrapper around the derivationStrict primop. */ This is the implementation of the derivation builtin function.
It's actually a wrapper around the derivationStrict primop.
drvAttrs @ { outputs ? [ "out" ], ... }: */
drvAttrs@{
outputs ? [ "out" ],
...
}:
let let
strict = derivationStrict drvAttrs; strict = derivationStrict drvAttrs;
commonAttrs = drvAttrs // (builtins.listToAttrs outputsList) // commonAttrs =
{ all = map (x: x.value) outputsList; drvAttrs
// (builtins.listToAttrs outputsList)
// {
all = map (x: x.value) outputsList;
inherit drvAttrs; inherit drvAttrs;
}; };
outputToAttrListElement = outputName: outputToAttrListElement = outputName: {
{ name = outputName; name = outputName;
value = commonAttrs // { value = commonAttrs // {
outPath = builtins.getAttr outputName strict; outPath = builtins.getAttr outputName strict;
drvPath = strict.drvPath; drvPath = strict.drvPath;
type = "derivation"; type = "derivation";
inherit outputName; inherit outputName;
};
}; };
};
outputsList = map outputToAttrListElement outputs; outputsList = map outputToAttrListElement outputs;
in
in (builtins.head outputsList).value (builtins.head outputsList).value

View file

@ -8,5 +8,3 @@ namespace nix {
void setPersonality(std::string_view system); void setPersonality(std::string_view system);
} }

View file

@ -152,5 +152,3 @@ void ThreadPool::doWork(bool mainThread)
} }
} }

View file

@ -1,5 +1,8 @@
{ name, channelName, src }: {
name,
channelName,
src,
}:
derivation { derivation {
builder = "builtin:unpack-channel"; builder = "builtin:unpack-channel";

View file

@ -1,5 +1,4 @@
{ derivations, manifest }: { derivations, manifest }:
derivation { derivation {
name = "user-environment"; name = "user-environment";
system = "builtin"; system = "builtin";
@ -8,13 +7,15 @@ derivation {
inherit manifest; inherit manifest;
# !!! grmbl, need structured data for passing this in a clean way. # !!! grmbl, need structured data for passing this in a clean way.
derivations = derivations = map (
map (d: d:
[ (d.meta.active or "true") [
(d.meta.priority or 5) (d.meta.active or "true")
(builtins.length d.outputs) (d.meta.priority or 5)
] ++ map (output: builtins.getAttr output d) d.outputs) (builtins.length d.outputs)
derivations; ]
++ map (output: builtins.getAttr output d) d.outputs
) derivations;
# Building user environments remotely just causes huge amounts of # Building user environments remotely just causes huge amounts of
# network traffic, so don't do that. # network traffic, so don't do that.

0
tests/functional/ca/build-cache.sh Normal file → Executable file
View file

View file

@ -3,4 +3,3 @@ source common.sh
export NIX_TESTS_CA_BY_DEFAULT=1 export NIX_TESTS_CA_BY_DEFAULT=1
cd .. && source build-dry.sh cd .. && source build-dry.sh

0
tests/functional/ca/build.sh Normal file → Executable file
View file

0
tests/functional/ca/eval-store.sh Normal file → Executable file
View file

View file

@ -3,4 +3,3 @@ source common.sh
export NIX_TESTS_CA_BY_DEFAULT=1 export NIX_TESTS_CA_BY_DEFAULT=1
cd .. && source import-derivation.sh cd .. && source import-derivation.sh

View file

@ -5,4 +5,3 @@ source common.sh
CONTENT_ADDRESSED=true CONTENT_ADDRESSED=true
cd .. cd ..
source ./nix-shell.sh source ./nix-shell.sh

View file

@ -32,4 +32,3 @@ rec {
''; '';
}; };
} }

View file

@ -7,5 +7,3 @@ requireDaemonNewerThan "2.4pre20210626"
export NIX_TESTS_CA_BY_DEFAULT=1 export NIX_TESTS_CA_BY_DEFAULT=1
cd .. cd ..
source ./post-hook.sh source ./post-hook.sh

0
tests/functional/ca/substitute.sh Normal file → Executable file
View file

0
tests/functional/dyn-drv/build-built-drv.sh Normal file → Executable file
View file

0
tests/functional/dyn-drv/dep-built-drv.sh Normal file → Executable file
View file

0
tests/functional/dyn-drv/eval-outputOf.sh Normal file → Executable file
View file

0
tests/functional/dyn-drv/text-hashed-output.sh Normal file → Executable file
View file

View file

@ -147,4 +147,3 @@ expectStderr 1 nix eval -v --raw --expr "
inputAddressed = true; inputAddressed = true;
} }
" | grepQuiet 'error.*The store object referred to by.*fromPath.* at .* is not input-addressed, but .*inputAddressed.* is set to .*true.*' " | grepQuiet 'error.*The store object referred to by.*fromPath.* at .* is not input-addressed, but .*inputAddressed.* is set to .*true.*'

View file

@ -47,4 +47,3 @@ nix flake update b --flake $flakeA
# Test list-inputs with circular dependencies # Test list-inputs with circular dependencies
nix flake metadata $flakeA nix flake metadata $flakeA

View file

@ -26,4 +26,3 @@ nix run --no-write-lock-file .#pkgAsPkg
! nix run --no-write-lock-file .#appAsPkg || fail "elements of 'apps' should be of type 'app'" ! nix run --no-write-lock-file .#appAsPkg || fail "elements of 'apps' should be of type 'app'"
clearStore clearStore

View file

@ -1 +1,3 @@
#!/usr/bin/env bash
echo Formatting: "${@}" echo Formatting: "${@}"

View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh source common.sh
set +x set +x

View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
# Don't start the daemon # Don't start the daemon
source common/vars-and-functions.sh source common/vars-and-functions.sh

View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh source common.sh
set -o pipefail set -o pipefail

View file

@ -1,5 +1,5 @@
error: undefined variable 'invalid' error: undefined variable 'invalid'
at /pwd/lang/eval-fail-eol-1.nix:2:1: at «stdin»:2:1:
1| # foo 1| # foo
2| invalid 2| invalid
| ^ | ^

View file

@ -1,5 +1,5 @@
error: undefined variable 'invalid' error: undefined variable 'invalid'
at /pwd/lang/eval-fail-eol-2.nix:2:1: at «stdin»:2:1:
1| # foo 1| # foo
2| invalid 2| invalid
| ^ | ^

View file

@ -1,5 +1,5 @@
error: undefined variable 'invalid' error: undefined variable 'invalid'
at /pwd/lang/eval-fail-eol-3.nix:2:1: at «stdin»:2:1:
1| # foo 1| # foo
2| invalid 2| invalid
| ^ | ^

View file

@ -1,5 +1,5 @@
error: path has a trailing slash error: path has a trailing slash
at /pwd/lang/eval-fail-path-slash.nix:6:12: at «stdin»:6:12:
5| # and https://nixos.org/nix-dev/2016-June/020829.html 5| # and https://nixos.org/nix-dev/2016-June/020829.html
6| /nix/store/ 6| /nix/store/
| ^ | ^

View file

@ -1,5 +1,5 @@
error: undefined variable 'x' error: undefined variable 'x'
at /pwd/lang/eval-fail-set.nix:1:3: at «stdin»:1:3:
1| 8.x 1| 8.x
| ^ | ^
2| 2|

View file

@ -27,4 +27,3 @@ mkDerivation (
normal = { }; normal = { };
}.${mode} }.${mode}
) )

View file

@ -63,4 +63,3 @@ grepQuiet 'item.*attrPath="foo".*name="dependencies-top"' $TEST_ROOT/meta.xml
# Do an install. # Do an install.
nix-env -i dependencies-top nix-env -i dependencies-top
[ -e $TEST_HOME/.nix-profile/foobar ] [ -e $TEST_HOME/.nix-profile/foobar ]

View file

@ -14,4 +14,3 @@ Commentary "the blank below should be chomped"
Command "command three" Command "command three"
Commentary "" Commentary ""
Output "meow output" Output "meow output"
Output ""

View file

@ -14,4 +14,3 @@ the blank below should be chomped
nix-repl> command three nix-repl> command three
meow output meow output

0
tests/functional/shell.shebang.rb Normal file → Executable file
View file

View file

@ -51,4 +51,3 @@ namespace nix {
} }
} }

View file

@ -30,4 +30,3 @@ namespace nix {
ASSERT_EQ(res->reference, "refs/head/main"); ASSERT_EQ(res->reference, "refs/head/main");
} }
} }

View file

@ -43,4 +43,3 @@ INSTANTIATE_TEST_CASE_P(
); );
} }

4
treefmt.toml Normal file
View file

@ -0,0 +1,4 @@
[formatter.nix]
command = "nixfmt"
includes = ["*.nix"]
excludes = ["tests/**"]