Format Nix code with nixfmt

Change-Id: I61efeb666ff7481c05fcb247168290e86a250151
This commit is contained in:
Rebecca Turner 2024-03-27 12:34:10 -07:00
parent e7316a8e99
commit cf89bfc499
31 changed files with 1278 additions and 917 deletions

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

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

@ -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"
]; ];
}; };
} }

647
flake.nix
View file

@ -14,11 +14,20 @@
nixpkgs-stable.follows = "nixpkgs"; nixpkgs-stable.follows = "nixpkgs";
}; };
}; };
flake-compat = { url = "github:edolstra/flake-compat"; flake = false; }; flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
}; };
outputs = { self, nixpkgs, nixpkgs-regression, pre-commit-hooks, flake-compat }: outputs =
{
self,
nixpkgs,
nixpkgs-regression,
pre-commit-hooks,
flake-compat,
}:
let let
inherit (nixpkgs) lib; inherit (nixpkgs) lib;
inherit (lib) fileset; inherit (lib) fileset;
@ -30,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}";
} }
'' ''
@ -149,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
@ -207,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.
@ -268,199 +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 { pre-commit = builtins.mapAttrs (
src = self; system: pre-commit-lib:
hooks = { pre-commit-lib.run {
no-commit-to-branch = { src = self;
enable = true; hooks = {
settings.branch = ["main"]; 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 ];
};
}; };
check-case-conflicts.enable = true; }
check-executables-have-shebangs = { ) pre-commit-hooks.lib;
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 = [ ];
};
};
}) 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;
pre-commit = self.hydraJobs.pre-commit.${system};
} // (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;
pre-commit = self.hydraJobs.pre-commit.${pkgs.system} or {}; dockerImage =
in 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 prev:
++ lib.optional (pre-commit ? enabledPackages) pre-commit.enabledPackages {
++ lib.optionals (stdenv.cc.isClang) [ pkgs.llvmPackages.llvm pkgs.llvmPackages.clang-unwrapped.dev ]; # Required for clang-tidy checks
nativeBuildInputs = prev.nativeBuildInputs buildInputs =
++ lib.optional (stdenv.cc.isClang && !stdenv.buildPlatform.isDarwin) pkgs.buildPackages.bear prev.buildInputs
# Required for clang-tidy checks ++ lib.optional (pre-commit ? enabledPackages) pre-commit.enabledPackages
++ lib.optionals (stdenv.cc.isClang) [ pkgs.buildPackages.cmake pkgs.buildPackages.ninja pkgs.buildPackages.llvmPackages.llvm.dev ] # Unfortunately `git-hooks.nix` can't propagate `treefmt`
++ lib.optional # formatters into `enabledPackages` correctly.
(stdenv.cc.isClang && stdenv.hostPlatform == stdenv.buildPlatform) ++ [ pkgs.nixfmt ]
# for some reason that seems accidental and was changed in ++ lib.optionals (stdenv.cc.isClang) [
# NixOS 24.05-pre, clang-tools is pinned to LLVM 14 when pkgs.llvmPackages.llvm
# default LLVM is newer. pkgs.llvmPackages.clang-unwrapped.dev
(pkgs.buildPackages.clang-tools.override { inherit (pkgs.buildPackages) llvmPackages; }) ];
++ [ nativeBuildInputs =
# FIXME(Qyriad): remove once the migration to Meson is complete. prev.nativeBuildInputs
pkgs.buildPackages.meson ++ lib.optional (stdenv.cc.isClang && !stdenv.buildPlatform.isDarwin) pkgs.buildPackages.bear
pkgs.buildPackages.ninja # 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.optionalString (pre-commit ? shellHook) pre-commit.shellHook} ${lib.optionalString (pre-commit ? shellHook) pre-commit.shellHook}
''; '';
} // 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 // lib.optionalAttrs (stdenv.buildPlatform.isLinux && pkgs.glibcLocales != null) {
LOCALE_ARCHIVE = "${lib.getLib pkgs.glibcLocales}/lib/locale/locale-archive"; # 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} "$@"

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

@ -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.

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

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