Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a8c42c1bf | ||
|
|
1bb22839d3 | ||
|
|
008f44beff | ||
|
|
49c27760c1 | ||
|
|
9638c4cd92 | ||
|
|
92cc6193e0 | ||
|
|
d227ad324e | ||
|
|
2310539e66 | ||
|
|
3d446ea37e | ||
|
|
4ef56601b5 | ||
|
|
779e795732 | ||
|
|
151cb75236 | ||
|
|
17df7e0e35 | ||
|
|
f67a99bdd3 | ||
|
|
d33062fd47 | ||
|
|
a2189bcb2e | ||
|
|
91f526e739 | ||
|
|
9c2d05997d | ||
|
|
83bba3f12c | ||
|
|
de6629754d | ||
|
|
faa50e15c8 | ||
|
|
18a50a1734 | ||
|
|
d27c247715 | ||
|
|
bda2f174e4 | ||
|
|
36327a3b2d | ||
|
|
d61d1c16e5 | ||
|
|
0848a16cce | ||
|
|
0d5520594e | ||
|
|
2667fb70c1 | ||
|
|
eccb26dd44 | ||
|
|
dcdeefd9c2 | ||
|
|
4422a649e6 | ||
|
|
c89ceb1669 | ||
|
|
0f099ae619 | ||
|
|
ed51a172c6 | ||
|
|
ca2b514e20 |
@@ -16,8 +16,6 @@ Checks:
|
||||
- -bugprone-unchecked-optional-access
|
||||
# many warnings, seems like a questionable lint
|
||||
- -bugprone-branch-clone
|
||||
# extremely noisy before clang 19: https://github.com/llvm/llvm-project/issues/93959
|
||||
- -bugprone-multi-level-implicit-pointer-conversion
|
||||
# all thrown exceptions must derive from std::exception
|
||||
- hicpp-exception-baseclass
|
||||
# capturing async lambdas are dangerous
|
||||
@@ -35,4 +33,3 @@ Checks:
|
||||
|
||||
CheckOptions:
|
||||
bugprone-reserved-identifier.AllowedIdentifiers: '__asan_default_options'
|
||||
bugprone-unused-return-value.AllowCastToVoid: true
|
||||
|
||||
@@ -29,7 +29,3 @@ trim_trailing_whitespace = false
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
max_line_length = 0
|
||||
|
||||
[meson.build]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name: Missing or incorrect documentation
|
||||
about: Help us improve the reference manual
|
||||
title: ''
|
||||
labels: docs
|
||||
labels: documentation
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
@@ -19,10 +19,10 @@ assignees: ''
|
||||
|
||||
<!-- make sure this issue is not redundant or obsolete -->
|
||||
|
||||
- [ ] checked [latest Lix manual] or its [source code]
|
||||
- [ ] checked [latest Lix manual] \([source]\)
|
||||
- [ ] checked [documentation issues] and [recent documentation changes] for possible duplicates
|
||||
|
||||
[latest Lix manual]: https://docs.lix.systems/manual/lix/nightly
|
||||
[source code]: https://git.lix.systems/lix-project/lix/src/main/doc/manual/src
|
||||
[latest Nix manual]: https://docs.lix.systems/manual/lix/nightly
|
||||
[source]: https://git.lix.systems/lix-project/lix/src/main/doc/manual/src
|
||||
[documentation issues]: https://git.lix.systems/lix-project/lix/issues?labels=151&state=all
|
||||
[recent documentation changes]: https://gerrit.lix.systems/q/p:lix+path:%22%5Edoc/manual/.*%22
|
||||
|
||||
-10
@@ -9,10 +9,6 @@ GTAGS
|
||||
# ccls
|
||||
/.ccls-cache
|
||||
|
||||
# auto-generated compilation database
|
||||
compile_commands.json
|
||||
rust-project.json
|
||||
|
||||
result
|
||||
result-*
|
||||
|
||||
@@ -33,9 +29,3 @@ buildtime.bin
|
||||
/.pre-commit-config.yaml
|
||||
/.nocontribmsg
|
||||
/release
|
||||
|
||||
# Rust build files when using Cargo (not actually supported for building but it spews the files anyway)
|
||||
/target/
|
||||
|
||||
# Python compiled files from the code generators and test suite
|
||||
*.pyc
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
Fiona Behrens <me@kloenk.dev>
|
||||
Fiona Behrens <me@kloenk.dev> <me@kloenk.de>
|
||||
@@ -1,6 +0,0 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["lix/lix-doc"]
|
||||
|
||||
[workspace.package]
|
||||
edition = "2021"
|
||||
+3
-9
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p bash -p hyperfine
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
shopt -s inherit_errexit
|
||||
@@ -22,21 +21,16 @@ fi
|
||||
_exit=""
|
||||
trap "$_exit" EXIT
|
||||
|
||||
flake_args=("--extra-experimental-features" "nix-command flakes")
|
||||
|
||||
# XXX: yes this is very silly. flakes~!!
|
||||
nix build "${flake_args[@]}" --impure --expr '(builtins.getFlake "git+file:.").inputs.nixpkgs.outPath' -o bench/nixpkgs
|
||||
nix build --impure --expr '(builtins.getFlake "git+file:.").inputs.nixpkgs.outPath' -o bench/nixpkgs
|
||||
|
||||
# We must ignore the global config, or else NIX_PATH won't work reliably.
|
||||
# See https://github.com/NixOS/nix/issues/9574
|
||||
export NIX_CONF_DIR='/var/empty'
|
||||
export NIX_REMOTE="$(mktemp -d)"
|
||||
_exit='rm -rfv "$NIX_REMOTE"; $_exit'
|
||||
export NIX_PATH="nixpkgs=bench/nixpkgs:nixos-config=bench/configuration.nix"
|
||||
|
||||
builds=("$@")
|
||||
|
||||
flake_args="${flake_args[*]@Q}"
|
||||
flake_args="--extra-experimental-features 'nix-command flakes'"
|
||||
|
||||
hyperfineArgs=(
|
||||
--parameter-list BUILD "$(IFS=,; echo "${builds[*]}")"
|
||||
|
||||
+21
-10
@@ -32,8 +32,8 @@
|
||||
hardware = {
|
||||
enableRedistributableFirmware = true;
|
||||
cpu.intel.updateMicrocode = true;
|
||||
graphics.enable32Bit = true;
|
||||
graphics.extraPackages = with pkgs; [
|
||||
opengl.driSupport32Bit = true;
|
||||
opengl.extraPackages = with pkgs; [
|
||||
vaapiIntel
|
||||
intel-media-driver
|
||||
intel-compute-runtime
|
||||
@@ -93,17 +93,16 @@
|
||||
|
||||
i18n = {
|
||||
defaultLocale = "en_US.UTF-8";
|
||||
inputMethod.enable = true;
|
||||
inputMethod.type = "ibus";
|
||||
inputMethod.enabled = "ibus";
|
||||
};
|
||||
|
||||
services = {
|
||||
libinput.enable = true;
|
||||
xserver = {
|
||||
enable = true;
|
||||
xkb.layout = "us";
|
||||
xkb.variant = "altgr-intl";
|
||||
xkb.options = "ctrl:nocaps";
|
||||
layout = "us";
|
||||
xkbVariant = "altgr-intl";
|
||||
xkbOptions = "ctrl:nocaps";
|
||||
libinput.enable = true;
|
||||
wacom.enable = true;
|
||||
videoDrivers = [ "modesetting" ];
|
||||
modules = [ pkgs.xf86_input_wacom ];
|
||||
@@ -122,6 +121,17 @@
|
||||
'';
|
||||
};
|
||||
|
||||
sound.enable = true;
|
||||
hardware.pulseaudio = {
|
||||
enable = true;
|
||||
package = pkgs.pulseaudioFull;
|
||||
daemon.config = {
|
||||
lock-memory = "yes";
|
||||
realtime-scheduling = "yes";
|
||||
rlimit-rtprio = "-1";
|
||||
};
|
||||
};
|
||||
|
||||
programs = {
|
||||
light.enable = true;
|
||||
wireshark = {
|
||||
@@ -136,7 +146,7 @@
|
||||
fonts.packages = with pkgs; [
|
||||
font-awesome
|
||||
noto-fonts
|
||||
noto-fonts-cjk-sans
|
||||
noto-fonts-cjk
|
||||
noto-fonts-emoji
|
||||
noto-fonts-extra
|
||||
dejavu_fonts
|
||||
@@ -229,7 +239,7 @@
|
||||
file
|
||||
firefox
|
||||
fluidsynth
|
||||
adwaita-icon-theme
|
||||
gnome3.adwaita-icon-theme
|
||||
gnuplot
|
||||
graphviz
|
||||
helm
|
||||
@@ -242,6 +252,7 @@
|
||||
libqalculate
|
||||
libreoffice
|
||||
man-pages
|
||||
nheko
|
||||
nix-diff
|
||||
nix-index
|
||||
nix-output-monitor
|
||||
|
||||
@@ -33,7 +33,32 @@ GENERATE_LATEX = NO
|
||||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = @INPUT_PATHS@
|
||||
# FIXME Make this list more maintainable somehow. We could maybe generate this
|
||||
# in the Makefile, but we would need to change how `.in` files are preprocessed
|
||||
# so they can expand variables despite configure variables.
|
||||
|
||||
INPUT = \
|
||||
src/libcmd \
|
||||
src/libexpr \
|
||||
src/libexpr/flake \
|
||||
tests/unit/libexpr \
|
||||
tests/unit/libexpr/value \
|
||||
tests/unit/libexpr/test \
|
||||
tests/unit/libexpr/test/value \
|
||||
src/libexpr/value \
|
||||
src/libfetchers \
|
||||
src/libmain \
|
||||
src/libstore \
|
||||
src/libstore/build \
|
||||
src/libstore/builtins \
|
||||
tests/unit/libstore \
|
||||
tests/unit/libstore/test \
|
||||
src/libutil \
|
||||
tests/unit/libutil \
|
||||
tests/unit/libutil/test \
|
||||
src/nix \
|
||||
src/nix-env \
|
||||
src/nix-store
|
||||
|
||||
# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
|
||||
# in the source code. If set to NO, only conditional compilation will be
|
||||
@@ -72,15 +97,3 @@ EXPAND_AS_DEFINED = \
|
||||
DECLARE_WORKER_SERIALISER \
|
||||
DECLARE_SERVE_SERIALISER \
|
||||
LENGTH_PREFIXED_PROTO_HELPER
|
||||
|
||||
# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
|
||||
# Stripping is only done if one of the specified strings matches the left-hand
|
||||
# part of the path. The tag can be used to show relative paths in the file list.
|
||||
# If left blank the directory from which doxygen is run is used as the path to
|
||||
# strip.
|
||||
#
|
||||
# Note that you can specify absolute paths here, but also relative paths, which
|
||||
# will be relative from the directory where doxygen is started.
|
||||
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
|
||||
|
||||
STRIP_FROM_PATH = "@PROJECT_SOURCE_ROOT@"
|
||||
|
||||
@@ -1,35 +1,3 @@
|
||||
internal_api_sources = [
|
||||
'lix/libcmd',
|
||||
'lix/libexpr',
|
||||
'lix/libexpr/flake',
|
||||
'tests/unit/libexpr',
|
||||
'tests/unit/libexpr/value',
|
||||
'tests/unit/libexpr/test',
|
||||
'tests/unit/libexpr/test/value',
|
||||
'lix/libexpr/value',
|
||||
'lix/libfetchers',
|
||||
'lix/libmain',
|
||||
'lix/libstore',
|
||||
'lix/libstore/build',
|
||||
'lix/libstore/builtins',
|
||||
'tests/unit/libstore',
|
||||
'tests/unit/libstore/test',
|
||||
'lix/libutil',
|
||||
'tests/unit/libutil',
|
||||
'tests/unit/libutil/test',
|
||||
'lix/nix',
|
||||
'lix/nix-env',
|
||||
'lix/nix-store',
|
||||
]
|
||||
|
||||
# We feed Doxygen absolute paths so it can be invoked from any working directory.
|
||||
internal_api_sources_absolute = []
|
||||
foreach src : internal_api_sources
|
||||
internal_api_sources_absolute += '"' + (meson.project_source_root() / src) + '"'
|
||||
endforeach
|
||||
|
||||
internal_api_sources_oneline = ' \\\n '.join(internal_api_sources_absolute)
|
||||
|
||||
doxygen_cfg = configure_file(
|
||||
input : 'doxygen.cfg.in',
|
||||
output : 'doxygen.cfg',
|
||||
@@ -37,16 +5,22 @@ doxygen_cfg = configure_file(
|
||||
'PACKAGE_VERSION': meson.project_version(),
|
||||
'RAPIDCHECK_HEADERS': rapidcheck_meson.get_variable('includedir'),
|
||||
'docdir' : meson.current_build_dir(),
|
||||
'INPUT_PATHS' : internal_api_sources_oneline,
|
||||
'PROJECT_SOURCE_ROOT' : meson.project_source_root(),
|
||||
},
|
||||
)
|
||||
|
||||
internal_api_docs = custom_target(
|
||||
'internal-api-docs',
|
||||
command : [
|
||||
doxygen.full_path(),
|
||||
'@INPUT0@',
|
||||
bash,
|
||||
# Meson can you please just give us a `workdir` argument to custom targets...
|
||||
'-c',
|
||||
# We have to prefix the doxygen_cfg path with the project build root
|
||||
# because of the cd in front.
|
||||
'cd @0@ && @1@ @2@/@INPUT0@'.format(
|
||||
meson.project_source_root(),
|
||||
doxygen.full_path(),
|
||||
meson.project_build_root(),
|
||||
),
|
||||
],
|
||||
input : [
|
||||
doxygen_cfg,
|
||||
|
||||
@@ -70,10 +70,6 @@ horrors:
|
||||
iFreilicht:
|
||||
github: iFreilicht
|
||||
|
||||
ian-h-chamberlain:
|
||||
forgejo: ian-h-chamberlain
|
||||
github: ian-h-chamberlain
|
||||
|
||||
isabelroses:
|
||||
forgejo: isabelroses
|
||||
github: isabelroses
|
||||
@@ -82,28 +78,13 @@ jade:
|
||||
forgejo: jade
|
||||
github: lf-
|
||||
|
||||
just1602:
|
||||
forgejo: just1602
|
||||
|
||||
kiara:
|
||||
github: KiaraGrouwstra
|
||||
|
||||
kjeremy:
|
||||
github: kjeremy
|
||||
|
||||
kloenk:
|
||||
display_name: Fiona Behrens
|
||||
forgejo: kloenk
|
||||
github: kloenk
|
||||
|
||||
lheckemann:
|
||||
forgejo: lheckemann
|
||||
github: lheckemann
|
||||
|
||||
lilyball:
|
||||
forgejo: lilyball
|
||||
github: lilyball
|
||||
|
||||
lovesegfault:
|
||||
github: lovesegfault
|
||||
|
||||
@@ -160,17 +141,9 @@ valentin:
|
||||
display_name: Valentin Gagarin
|
||||
github: fricklerhandwerk
|
||||
|
||||
vigress8:
|
||||
display_name: Vigress
|
||||
forgejo: vigress8
|
||||
github: vigress8
|
||||
|
||||
winter:
|
||||
forgejo: winter
|
||||
github: winterqt
|
||||
|
||||
yshui:
|
||||
github: yshui
|
||||
|
||||
zimbatm:
|
||||
github: zimbatm
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
let
|
||||
inherit (builtins) concatStringsSep attrValues mapAttrs;
|
||||
inherit (import ./utils.nix) optionalString squash;
|
||||
in
|
||||
|
||||
builtinsInfo:
|
||||
let
|
||||
showBuiltin =
|
||||
name:
|
||||
{
|
||||
doc,
|
||||
type,
|
||||
impure-only,
|
||||
}:
|
||||
let
|
||||
type' = optionalString (type != null) " (${type})";
|
||||
|
||||
impureNotice = optionalString impure-only ''
|
||||
> **Note**
|
||||
>
|
||||
> Not available in [pure evaluation mode](@docroot@/command-ref/conf-file.md#conf-pure-eval).
|
||||
'';
|
||||
in
|
||||
squash ''
|
||||
<dt id="builtins-${name}">
|
||||
<a href="#builtins-${name}"><code>${name}</code></a>${type'}
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
${doc}
|
||||
|
||||
${impureNotice}
|
||||
|
||||
</dd>
|
||||
'';
|
||||
in
|
||||
concatStringsSep "\n" (attrValues (mapAttrs showBuiltin builtinsInfo))
|
||||
@@ -0,0 +1,35 @@
|
||||
let
|
||||
inherit (builtins) concatStringsSep attrValues mapAttrs;
|
||||
inherit (import ./utils.nix) optionalString squash;
|
||||
in
|
||||
|
||||
builtinsInfo:
|
||||
let
|
||||
showBuiltin =
|
||||
name:
|
||||
{
|
||||
doc,
|
||||
args,
|
||||
arity,
|
||||
experimental-feature,
|
||||
}:
|
||||
let
|
||||
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.
|
||||
'';
|
||||
in
|
||||
squash ''
|
||||
<dt id="builtins-${name}">
|
||||
<a href="#builtins-${name}"><code>${name} ${listArgs args}</code></a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
${doc}
|
||||
|
||||
${experimentalNotice}
|
||||
|
||||
</dd>
|
||||
'';
|
||||
listArgs = args: concatStringsSep " " (map (s: "<var>${s}</var>") args);
|
||||
in
|
||||
concatStringsSep "\n" (attrValues (mapAttrs showBuiltin builtinsInfo))
|
||||
+22
-130
@@ -1,134 +1,26 @@
|
||||
with builtins;
|
||||
|
||||
let
|
||||
splitLines = s: filter (x: !isList x) (split "\n" s);
|
||||
|
||||
concatStrings = concatStringsSep "";
|
||||
|
||||
replaceStringsRec =
|
||||
from: to: string:
|
||||
# recursively replace occurrences of `from` with `to` within `string`
|
||||
# example:
|
||||
# replaceStringRec "--" "-" "hello-----world"
|
||||
# => "hello-world"
|
||||
let
|
||||
replaced = replaceStrings [ from ] [ to ] string;
|
||||
in
|
||||
if replaced == string then string else replaceStringsRec from to replaced;
|
||||
|
||||
squash = replaceStringsRec "\n\n\n" "\n\n";
|
||||
|
||||
trim =
|
||||
string:
|
||||
# trim trailing spaces and squash non-leading spaces
|
||||
let
|
||||
trimLine =
|
||||
line:
|
||||
let
|
||||
# separate leading spaces from the rest
|
||||
parts = split "(^ *)" line;
|
||||
spaces = head (elemAt parts 1);
|
||||
rest = elemAt parts 2;
|
||||
# drop trailing spaces
|
||||
body = head (split " *$" rest);
|
||||
in
|
||||
spaces + replaceStringsRec " " " " body;
|
||||
in
|
||||
concatStringsSep "\n" (map trimLine (splitLines string));
|
||||
|
||||
# FIXME: O(n^2)
|
||||
unique = foldl' (acc: e: if elem e acc then acc else acc ++ [ e ]) [ ];
|
||||
|
||||
nameValuePair = name: value: { inherit name value; };
|
||||
|
||||
filterAttrs =
|
||||
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 "";
|
||||
|
||||
showSetting =
|
||||
{ inlineHTML }:
|
||||
name:
|
||||
{
|
||||
description,
|
||||
documentDefault,
|
||||
defaultValue,
|
||||
aliases,
|
||||
value,
|
||||
experimentalFeature,
|
||||
}:
|
||||
let
|
||||
result = squash ''
|
||||
- ${
|
||||
if inlineHTML then ''<span id="conf-${name}">[`${name}`](#conf-${name})</span>'' else ''`${name}`''
|
||||
}
|
||||
|
||||
${indent " " body}
|
||||
'';
|
||||
|
||||
experimentalFeatureNote = optionalString (experimentalFeature != null) ''
|
||||
> **Warning**
|
||||
> This setting is part of an
|
||||
> [experimental feature](@docroot@/contributing/experimental-features.md).
|
||||
|
||||
To change this setting, you need to make sure the corresponding experimental feature,
|
||||
[`${experimentalFeature}`](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature}),
|
||||
is enabled.
|
||||
For example, include the following in [`nix.conf`](#):
|
||||
|
||||
```
|
||||
extra-experimental-features = ${experimentalFeature}
|
||||
${name} = ...
|
||||
```
|
||||
'';
|
||||
|
||||
# separate body to cleanly handle indentation
|
||||
body = ''
|
||||
${description}
|
||||
|
||||
${experimentalFeatureNote}
|
||||
|
||||
**Default:** ${showDefault documentDefault defaultValue}
|
||||
|
||||
${showAliases aliases}
|
||||
'';
|
||||
|
||||
showDefault =
|
||||
documentDefault: defaultValue:
|
||||
if documentDefault then
|
||||
# a StringMap value type is specified as a string, but
|
||||
# this shows the value type. The empty stringmap is `null` in
|
||||
# JSON, but that converts to `{ }` here.
|
||||
if defaultValue == "" || defaultValue == [ ] || isAttrs defaultValue then
|
||||
"*empty*"
|
||||
else if isBool defaultValue then
|
||||
if defaultValue then "`true`" else "`false`"
|
||||
else
|
||||
"`${toString defaultValue}`"
|
||||
else
|
||||
"*machine-specific*";
|
||||
|
||||
showAliases =
|
||||
aliases:
|
||||
optionalString (aliases != [ ])
|
||||
"**Deprecated alias:** ${(concatStringsSep ", " (map (s: "`${s}`") aliases))}";
|
||||
in
|
||||
result;
|
||||
|
||||
indent =
|
||||
prefix: s: concatStringsSep "\n" (map (x: if x == "" then x else "${prefix}${x}") (splitLines s));
|
||||
|
||||
showSettings =
|
||||
args: settingsInfo: concatStrings (attrValues (mapAttrs (showSetting args) settingsInfo));
|
||||
inherit (builtins)
|
||||
attrNames
|
||||
attrValues
|
||||
fromJSON
|
||||
listToAttrs
|
||||
mapAttrs
|
||||
concatStringsSep
|
||||
concatMap
|
||||
length
|
||||
lessThan
|
||||
replaceStrings
|
||||
sort
|
||||
;
|
||||
inherit (import ./utils.nix)
|
||||
concatStrings
|
||||
optionalString
|
||||
filterAttrs
|
||||
trim
|
||||
squash
|
||||
unique
|
||||
showSettings
|
||||
;
|
||||
in
|
||||
|
||||
inlineHTML: commandDump:
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
with builtins;
|
||||
with import ./utils.nix;
|
||||
|
||||
let
|
||||
showExperimentalFeature = name: doc: ''
|
||||
- [`${name}`](@docroot@/contributing/experimental-features.md#xp-feature-${name})
|
||||
'';
|
||||
in
|
||||
xps: indent " " (concatStrings (attrValues (mapAttrs showExperimentalFeature xps)))
|
||||
@@ -0,0 +1,13 @@
|
||||
with builtins;
|
||||
with import ./utils.nix;
|
||||
|
||||
let
|
||||
showExperimentalFeature =
|
||||
name: doc:
|
||||
squash ''
|
||||
## [`${name}`]{#xp-feature-${name}}
|
||||
|
||||
${doc}
|
||||
'';
|
||||
in
|
||||
xps: (concatStringsSep "\n" (attrValues (mapAttrs showExperimentalFeature xps)))
|
||||
+55
-10
@@ -15,21 +15,67 @@ nix_eval_for_docs_common = nix_for_docs + [
|
||||
]
|
||||
nix_eval_for_docs = nix_eval_for_docs_common + '--raw'
|
||||
|
||||
conf_file_json = custom_target(
|
||||
command : nix_for_docs + [ 'show-config', '--json' ],
|
||||
capture : true,
|
||||
output : 'conf-file.json',
|
||||
env : nix_env_for_docs,
|
||||
)
|
||||
|
||||
nix_conf_file_md_body = custom_target(
|
||||
command : nix_eval_for_docs + [
|
||||
'--expr',
|
||||
'(import @INPUT0@).showSettings { inlineHTML = true; } (builtins.fromJSON (builtins.readFile @INPUT1@))',
|
||||
],
|
||||
capture : true,
|
||||
input : [
|
||||
'utils.nix',
|
||||
conf_file_json,
|
||||
],
|
||||
output : 'conf-file.md.body',
|
||||
env : nix_env_for_docs,
|
||||
)
|
||||
|
||||
nix_conf_file_md = custom_target(
|
||||
command : [ 'cat', '@INPUT@' ],
|
||||
capture : true,
|
||||
input : [
|
||||
'src/command-ref/conf-file.md',
|
||||
nix_conf_file_md_body,
|
||||
],
|
||||
output : 'conf-file.md',
|
||||
)
|
||||
|
||||
nix_exp_features_json = custom_target(
|
||||
command : [ nix, '__dump-xp-features' ],
|
||||
capture : true,
|
||||
output : 'xp-features.json',
|
||||
)
|
||||
|
||||
language_json = custom_target(
|
||||
command: [nix, '__dump-language'],
|
||||
output : 'language.json',
|
||||
capture : true,
|
||||
env : nix_env_for_docs,
|
||||
)
|
||||
|
||||
nix3_cli_json = custom_target(
|
||||
command : [ nix, '__dump-cli' ],
|
||||
capture : true,
|
||||
output : 'nix.json',
|
||||
env : nix_env_for_docs,
|
||||
# FIXME: put the actual lib targets in here? meson have introspection challenge 2024 though.
|
||||
build_always_stale : true,
|
||||
)
|
||||
|
||||
generate_manual_deps = files(
|
||||
'generate-deps.py',
|
||||
)
|
||||
|
||||
# Generates new-cli pages and conf-file.md.
|
||||
# Generates builtins.md and builtin-constants.md.
|
||||
subdir('src/language')
|
||||
# Generates new-cli pages, experimental-features-shortlist.md, and conf-file.md.
|
||||
subdir('src/command-ref')
|
||||
# Generates experimental-feature-descriptions.md.
|
||||
subdir('src/contributing')
|
||||
# Generates rl-next-generated.md.
|
||||
subdir('src/release-notes')
|
||||
|
||||
@@ -60,8 +106,6 @@ manual = custom_target(
|
||||
nix3_cli_files,
|
||||
experimental_features_shortlist_md,
|
||||
experimental_feature_descriptions_md,
|
||||
deprecated_features_shortlist_md,
|
||||
deprecated_feature_descriptions_md,
|
||||
conf_file_md,
|
||||
builtins_md,
|
||||
builtin_constants_md,
|
||||
@@ -72,19 +116,20 @@ manual = custom_target(
|
||||
'manual',
|
||||
'markdown',
|
||||
],
|
||||
install : true,
|
||||
install_dir : [
|
||||
datadir / 'doc/nix',
|
||||
false,
|
||||
],
|
||||
depfile : 'manual.d',
|
||||
env : {
|
||||
'RUST_LOG': 'info',
|
||||
'MDBOOK_SUBSTITUTE_SEARCH': meson.current_build_dir() / 'src',
|
||||
},
|
||||
)
|
||||
manual_html = manual[0]
|
||||
manual_md = manual[1]
|
||||
|
||||
install_subdir(
|
||||
manual_html.full_path(),
|
||||
install_dir : datadir / 'doc/nix',
|
||||
)
|
||||
|
||||
nix_nested_manpages = [
|
||||
[ 'nix-env',
|
||||
[
|
||||
|
||||
@@ -192,13 +192,11 @@
|
||||
- [Hacking](contributing/hacking.md)
|
||||
- [Testing](contributing/testing.md)
|
||||
- [Experimental Features](contributing/experimental-features.md)
|
||||
- [Deprecated Features](contributing/deprecated-features.md)
|
||||
- [CLI guideline](contributing/cli-guideline.md)
|
||||
- [C++ style guide](contributing/cxx.md)
|
||||
- [Release Notes](release-notes/release-notes.md)
|
||||
- [Upcoming release](release-notes/rl-next.md)
|
||||
<!-- RELENG-AUTO-INSERTION-MARKER (see releng/release_notes.py) -->
|
||||
- [Lix 2.92 (2025-01-18)](release-notes/rl-2.92.md)
|
||||
- [Lix 2.91 (2024-08-12)](release-notes/rl-2.91.md)
|
||||
- [Lix 2.90 (2024-07-10)](release-notes/rl-2.90.md)
|
||||
- [Nix 2.18 (2023-09-20)](release-notes/rl-2.18.md)
|
||||
|
||||
@@ -34,15 +34,9 @@ keep-outputs = true # Nice for developers
|
||||
keep-derivations = true # Idem
|
||||
```
|
||||
|
||||
Other files can be included with a line like `include <path>`.
|
||||
Other files can be included with a line like `include <path>`, where `<path>` is interpreted relative to the current configuration file.
|
||||
A missing file is an error unless `!include` is used instead.
|
||||
|
||||
Paths in `include`s and option values are interpreted relative to the current configuration file.
|
||||
In user configuration files, paths starting with `~/` are tilde expanded (by replacing the tilde by the value of `$HOME`).
|
||||
|
||||
Only user configuration files (like `$XDG_CONFIG_HOME/nix/nix.conf` or the files listed in `$NIX_USER_CONF_FILES`) can use tilde paths relative to your home directory.
|
||||
Configuration listed in the `$NIX_CONFIG` environment variable may not use relative paths.
|
||||
|
||||
A configuration setting usually overrides any previous value.
|
||||
However, for settings that take a list of items, you can prefix the name of the setting by `extra-` to *append* to the previous value.
|
||||
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
xp_features_json = custom_target(
|
||||
command : [nix, '__dump-xp-features'],
|
||||
capture : true,
|
||||
output : 'xp-features.json',
|
||||
)
|
||||
|
||||
experimental_features_shortlist_md = custom_target(
|
||||
command : nix_eval_for_docs + [
|
||||
'--expr',
|
||||
'import @INPUT0@ (builtins.fromJSON (builtins.readFile @INPUT1@))',
|
||||
],
|
||||
input : [
|
||||
'../../generate-xp-features-shortlist.nix',
|
||||
xp_features_json,
|
||||
],
|
||||
capture : true,
|
||||
output : 'experimental-features-shortlist.md',
|
||||
env : nix_env_for_docs,
|
||||
)
|
||||
|
||||
# Intermediate step for manpage generation.
|
||||
# This splorks the output of generate-manpage.nix as JSON,
|
||||
# which gets written as a directory tree below.
|
||||
@@ -31,23 +51,16 @@ nix3_cli_files = custom_target(
|
||||
|
||||
conf_file_md = custom_target(
|
||||
command : [
|
||||
python.full_path(),
|
||||
'@SOURCE_ROOT@/lix/code-generation/build_settings.py',
|
||||
'--kernel', host_machine.system(),
|
||||
'--docs', '@OUTPUT@',
|
||||
'--experimental-features', '@SOURCE_ROOT@/lix/libutil/experimental-features',
|
||||
'@INPUT@',
|
||||
nix_eval_for_docs,
|
||||
'--expr',
|
||||
'(import @INPUT0@).showSettings { inlineHTML = true; } (builtins.fromJSON (builtins.readFile @INPUT1@))',
|
||||
],
|
||||
capture : true,
|
||||
input : [
|
||||
libexpr_setting_definitions,
|
||||
libfetchers_setting_definitions,
|
||||
file_transfer_setting_definitions,
|
||||
libstore_setting_definitions,
|
||||
archive_setting_definitions,
|
||||
feature_setting_definitions,
|
||||
logging_setting_definitions,
|
||||
daemon_setting_definitions,
|
||||
develop_settings_definitions,
|
||||
'../../utils.nix',
|
||||
conf_file_json,
|
||||
experimental_features_shortlist_md,
|
||||
],
|
||||
output : 'conf-file.md',
|
||||
env : nix_env_for_docs,
|
||||
)
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
This section describes the notion of *deprecated features*, and how it fits into the big picture of the development of Lix.
|
||||
|
||||
# What are deprecated features?
|
||||
|
||||
Deprecated features are disabled by default, with the intent to eventually remove them.
|
||||
Users must explicitly enable them to keep using them, by toggling the associated [deprecated feature flags](@docroot@/command-ref/conf-file.md#conf-deprecated-features).
|
||||
This allows backwards compatibility and a graceful transition away from undesired features.
|
||||
|
||||
# Which features can be deprecated?
|
||||
|
||||
Undesired features should be soft-deprecated by yielding a warning when used for a significant amount of time before the can be deprecated.
|
||||
Legacy obsolete feature with little to no usage may go through this process faster.
|
||||
Deprecated features should have a migration path to a preferred alternative.
|
||||
|
||||
# Lifecycle of a deprecated feature
|
||||
|
||||
This description is not normative, but a feature removal may roughly happen like this:
|
||||
|
||||
1. Add a warning when the feature is being used.
|
||||
2. Disable the feature by default, putting it behind a deprecated feature flag.
|
||||
- If disabling the feature started out as an opt-in experimental feature, turn that experimental flag into a no-op or remove it entirely.
|
||||
For example, `--extra-experimental-features=no-url-literals` becomes `--extra-deprecated-features=url-literals`.
|
||||
3. Decide on a time frame for how long that feature will still be supported for backwards compatibility, and clearly communicate that in the error messages.
|
||||
- Sometimes, automatic migration to alternatives is possible, and such should be provided if possible
|
||||
- At least one NixOS release cycle should be the minimum
|
||||
4. Finally remove the feature entirely, only keeping the error message for those still using it.
|
||||
|
||||
# Relation to language versioning
|
||||
|
||||
Obviously, removing anything breaks backwards compatibility.
|
||||
In an ideal world, we'd have SemVer controls over the language and its features, cleanly allowing us to make breaking changes.
|
||||
See https://wiki.lix.systems/books/lix-contributors/page/language-versioning and [RFC 137](https://github.com/nixos/rfcs/pull/137) for efforts on that.
|
||||
However, we do not live in such an ideal world, and currently this goal is so far away, that "just disable it with some back-compat for a couple of years" is the most realistic solution, especially for comparatively minor changes.
|
||||
|
||||
# Currently available deprecated features
|
||||
|
||||
{{#include @generated@/../../../lix/libutil/deprecated-feature-descriptions.md}}
|
||||
@@ -99,4 +99,4 @@ This means that experimental features and RFCs are orthogonal mechanisms, and ca
|
||||
|
||||
# Currently available experimental features
|
||||
|
||||
{{#include @generated@/../../../lix/libutil/experimental-feature-descriptions.md}}
|
||||
{{#include @generated@/contributing/experimental-feature-descriptions.md}}
|
||||
|
||||
@@ -102,14 +102,14 @@ $ meson compile -C build nixexpr
|
||||
All targets may be addressed as their output, relative to the build directory, e.g.:
|
||||
|
||||
```bash
|
||||
$ meson compile -C build lix/libexpr/liblixexpr.so
|
||||
$ meson compile -C build src/libexpr/liblixexpr.so
|
||||
```
|
||||
|
||||
But Meson does not consider intermediate files like object files targets.
|
||||
To build a specific object file, use Ninja directly and specify the output file relative to the build directory:
|
||||
|
||||
```bash
|
||||
$ ninja -C build lix/libexpr/liblixexpr.so.p/nixexpr.cc.o
|
||||
$ ninja -C build src/libexpr/liblixexpr.so.p/nixexpr.cc.o
|
||||
```
|
||||
|
||||
To inspect the canonical source of truth on what the state of the buildsystem configuration is, use:
|
||||
@@ -137,7 +137,7 @@ You can also build Lix for one of the [supported platforms](#platforms).
|
||||
|
||||
Lix can be built for various platforms, as specified in [`flake.nix`]:
|
||||
|
||||
[`flake.nix`]: https://git.lix.systems/lix-project/lix/lix/branch/main/flake.nix
|
||||
[`flake.nix`]: https://git.lix.systems/lix-project/lix/src/branch/main/flake.nix
|
||||
|
||||
- `x86_64-linux`
|
||||
- `x86_64-darwin`
|
||||
@@ -399,76 +399,3 @@ The following properties are supported:
|
||||
|
||||
Releases have a precomputed `rl-MAJOR.MINOR.md`, and no `rl-next.md`.
|
||||
Set `buildUnreleasedNotes = true;` in `flake.nix` to build the release notes on the fly.
|
||||
|
||||
## Adding experimental or deprecated features, global settings, or builtins
|
||||
|
||||
Experimental and deprecated features, global settings, and builtins are generally referenced both in the code and in the documentation.
|
||||
To prevent duplication or divergence, they are defined in data files, and a script generates the necessary glue.
|
||||
The data file format is similar to the release notes: it consists of a YAML metadata header, followed by the documentation in Markdown format.
|
||||
|
||||
### Experimental or deprecated features
|
||||
|
||||
Experimental and deprecated features support the following metadata properties:
|
||||
* `name` (required): user-facing name of the feature, to be used in `nix.conf` options and on the command line.
|
||||
This should also be the stem of the file name (with extension `md`).
|
||||
* `internalName` (required): identifier used to refer to the feature inside the C++ code.
|
||||
|
||||
Experimental feature data files should live in `lix/libutil/experimental-features`, and deprecated features in `lix/libutil/deprecated-features`.
|
||||
They must be listed in the `experimental_feature_definitions` or `deprecated_feature_definitions` lists in `lix/libutil/meson.build` respectively to be considered by the build system.
|
||||
|
||||
### Global settings
|
||||
|
||||
Global settings support the following metadata properties:
|
||||
* `name` (required): user-facing name of the setting, to be used as key in `nix.conf` and in the `--option` command line argument.
|
||||
* `internalName` (required): identifier used to refer to the setting inside the C++ code.
|
||||
* `platforms` (optional): a list specifying the platforms on which this setting is available.
|
||||
If not specified, it is available on all platforms.
|
||||
Valid platform names are `darwin`, `linux`.
|
||||
* `type` (optional): C++ type of the setting value.
|
||||
This specifies the setting object type as `Setting<T>`; if more control is required, use `settingType` instead.
|
||||
* `settingType` (required if `type` is not specified): C++ type of the setting object.
|
||||
* `default` (optional): default value of the setting.
|
||||
`null`, truth values, integers, strings and lists are supported as long as the correct YAML type is used, `type` is not taken into account).
|
||||
Other types, machine-dependent values or non-standard representations must be handled using `defaultExpr` and `defaultText` instead.
|
||||
* `defaultExpr` (required if `default` is not specified): a string containing the C++ expression representing the default value.
|
||||
* `defaultText` (required if `default` is not specified): a string containing the Markdown expression representing the default value in the documentation.
|
||||
Literal values are conventionally surrounded by backticks, and a system-dependent value is signaled by `*machine-specific*`.
|
||||
* `aliases` (optional): a list of secondary user-facing names under which the setting is available.
|
||||
Defaults to empty if not specified.
|
||||
* `experimentalFeature` (optional): the user-facing name of the experimental feature which needs to be enabled to change the setting.
|
||||
If not specified, no experimental feature is required.
|
||||
* `deprecated` (optional): whether the setting is deprecated and shown as such in the documentation for `nix.conf`.
|
||||
Defaults to false if not specified.
|
||||
|
||||
Settings are not collected in a single place in the source tree, so an appropriate place needs to be found for the setting to live.
|
||||
Look for related setting definition files under second-level subdirectories of `lix` whose name includes `settings`.
|
||||
Then add the new file there, and don't forget to register it in the appropriate `meson.build` file.
|
||||
|
||||
### Builtin functions
|
||||
|
||||
The following metadata properties are supported for builtin functions:
|
||||
* `name` (required): the language-facing name (as a member of the `builtins` attribute set) of the function.
|
||||
* `implementation` (optional): a C++ expression specifying the implementation of the builtin.
|
||||
It must be a function of signature `void(EvalState &, PosIdx, Value * *, Value &)`.
|
||||
If not specified, defaults to `prim_${name}`.
|
||||
* `renameInGlobalScope` (optional): whether the definiton should be "hidden" in the global scope by prefixing its name with two underscores.
|
||||
If not specified, defaults to `true`.
|
||||
* `args` (required): list containing the names of the arguments, as shown in the documentation.
|
||||
All arguments must be listed here since the function arity is derived as the length of this list.
|
||||
* `experimental_feature` (optional): the user-facing name of the experimental feature which needs to be enabled for the bultin function to be available.
|
||||
If not specified, no experimental feature is required.
|
||||
|
||||
New builtin function definition files must be added to `lix/libexpr/builtins` and registered in the `builtin_definitions` list in `lix/libexpr/meson.build`.
|
||||
|
||||
### Builtin constants
|
||||
The following metadata properties are supported for builtin constants:
|
||||
* `name` (required): the language-facing name (as a member of the `builtins` attribute set) of the constant.
|
||||
* `type` (required): the Nix language type of the constant; the C++ type is automatically derived.
|
||||
* `constructorArgs` (optional): list of strings containing C++ expressions passed as arguments to the appropriate `Value` constructor.
|
||||
If the value computation is more complex, `implementation` can be used instead.
|
||||
* `implementation` (required if `constructorArgs` is not specified): string containing a C++ expressing computing the value of the constant.
|
||||
* `impure` (optional): whether the constant is considered impure.
|
||||
Impure constants are not available when pure evaluation mode is activated.
|
||||
Defaults to `false` when not specified.
|
||||
|
||||
New builtin constant definition files must be added to `lix/libexpr/builtin-constants` and registered in the `builtin_constant_definitions` list in `lix/libexpr/meson.build`.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# Intermediate step for experimental-feature-descriptions.md.
|
||||
# This splorks the output of generate-xp-features.nix as JSON,
|
||||
# which gets written as a directory tree below.
|
||||
experimental_feature_descriptions_md = custom_target(
|
||||
command : nix_eval_for_docs + [
|
||||
'--expr',
|
||||
'import @INPUT0@ (builtins.fromJSON (builtins.readFile @INPUT1@))',
|
||||
],
|
||||
input : [
|
||||
'../../generate-xp-features.nix',
|
||||
xp_features_json,
|
||||
],
|
||||
capture : true,
|
||||
output : 'experimental-feature-descriptions.md',
|
||||
)
|
||||
@@ -13,7 +13,7 @@ The unit tests are defined using the [googletest] and [rapidcheck] frameworks.
|
||||
>
|
||||
> ```
|
||||
> …
|
||||
> ├── lix
|
||||
> ├── src
|
||||
> │ ├── libexpr
|
||||
> │ │ ├── …
|
||||
> │ │ ├── value
|
||||
@@ -46,10 +46,10 @@ The unit tests are defined using the [googletest] and [rapidcheck] frameworks.
|
||||
> … … … … … …
|
||||
> ```
|
||||
|
||||
The unit tests for each Lix library (`liblixexpr`, `liblixstore`, etc..) live inside a directory `lix/${library_shortname}/tests` within the directory for the library (`lix/${library_shortname}`).
|
||||
The unit tests for each Lix library (`liblixexpr`, `liblixstore`, etc..) live inside a directory `src/${library_shortname}/tests` within the directory for the library (`src/${library_shortname}`).
|
||||
|
||||
The data is in `tests/unit/LIBNAME/data/LIBNAME`, with one subdir per library, with the same name as where the code goes.
|
||||
For example, `liblixstore` code is in `lix/libstore`, and its test data is in `tests/unit/libstore/data/libstore`.
|
||||
For example, `liblixstore` code is in `src/libstore`, and its test data is in `tests/unit/libstore/data/libstore`.
|
||||
The path to the unit test data directory is passed to the unit test executable with the environment variable `_NIX_TEST_UNIT_DATA`.
|
||||
|
||||
### Running tests
|
||||
@@ -345,7 +345,7 @@ rg '(?:[^A-Za-z]|^)(_[A-Z][^-\[ }/:");$(]+)' -r '$1' --no-filename --only-matchi
|
||||
rg '\$\{?([A-Z][^-\[ }/:");]+)' -r '$1' --no-filename --only-matching tests | sort -u > vars.txt
|
||||
```
|
||||
|
||||
I grepped `lix/` for `get[eE]nv\("` to find the mentions in Lix code.
|
||||
I grepped `src/` for `get[eE]nv\("` to find the mentions in Lix code.
|
||||
|
||||
### Used by Lix testing support code
|
||||
|
||||
@@ -361,8 +361,8 @@ I grepped `lix/` for `get[eE]nv\("` to find the mentions in Lix code.
|
||||
|
||||
- `_NIX_FORCE_HTTP` - Forces file URIs to be treated as remote ones.
|
||||
|
||||
Used by `lix/libfetchers/git.cc`, `lix/libstore/http-binary-cache-store.cc`,
|
||||
`lix/libstore/local-binary-cache-store.cc`. Seems to be for forcing Git
|
||||
Used by `src/libfetchers/git.cc`, `src/libstore/http-binary-cache-store.cc`,
|
||||
`src/libstore/local-binary-cache-store.cc`. Seems to be for forcing Git
|
||||
clones of `git+file://` URLs, making the HTTP binary
|
||||
cache store accept `file://` URLs (presumably passing them to curl?), and
|
||||
unknown reasons for the local binary cache.
|
||||
@@ -374,7 +374,7 @@ I grepped `lix/` for `get[eE]nv\("` to find the mentions in Lix code.
|
||||
`structuredAttrs` documentation.
|
||||
- `NIX_BIN_DIR`, `NIX_STORE_DIR` (or its inconsistently-used old alias `NIX_STORE`), `NIX_DATA_DIR`,
|
||||
`NIX_LOG_DIR`, `NIX_LOG_DIR`, `NIX_STATE_DIR`, `NIX_CONF_DIR` -
|
||||
Overrides compile-time configuration of various locations used by Lix. See `lix/libstore/globals.cc`.
|
||||
Overrides compile-time configuration of various locations used by Lix. See `src/libstore/globals.cc`.
|
||||
|
||||
**Expected value**: a directory
|
||||
- `NIX_DAEMON_SOCKET_PATH` (optional) - Overrides the daemon socket path from `$NIX_STATE_DIR/daemon-socket/socket`.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Installing a Binary Distribution
|
||||
|
||||
See <https://lix.systems/install/> for more details.
|
||||
See https://lix.systems/install/ for more details.
|
||||
|
||||
<!--
|
||||
|
||||
|
||||
@@ -36,10 +36,7 @@ All users of the Lix daemon may do the following to bring things into the Nix st
|
||||
- Input-addressed, so they are run in the sandbox with no network access, with the following exceptions:
|
||||
|
||||
- The (poorly named, since it is not *just* about chroot) property `__noChroot` is set on the derivation and `sandbox` is set to `relaxed`.
|
||||
- On macOS, the derivation property `__darwinAllowLocalNetworking` allows network access to localhost from input-addressed derivations regardless of the `sandbox` setting value.
|
||||
This property exists with such semantics because macOS has no network namespace equivalent to isolate individual processes' localhost networking.
|
||||
- On macOS, the derivation property `__sandboxProfile` accepts extra sandbox profile S-expressions, allowing derivations to bypass arbitrary parts of the sandbox without altogether disabling it.
|
||||
This is only permitted when `sandbox` is set to `relaxed`.
|
||||
- On macOS, the derivation property `__darwinAllowLocalNetworking` allows network access to localhost from input-addressed derivations regardless of the `sandbox` setting value. This property exists with such semantics because macOS has no network namespace equivalent to isolate individual processes' localhost networking.
|
||||
- Output-addressed, so they are run with network access but their result must match an expected hash.
|
||||
|
||||
Trusted users may set any setting, including `sandbox = false`, so the sandbox state can be different at runtime from what is described in `nix.conf` for builds invoked with such settings.
|
||||
|
||||
@@ -4,7 +4,7 @@ These constants are built into the Nix language evaluator:
|
||||
|
||||
<dl>
|
||||
|
||||
{{#include @generated@/../../../lix/libexpr/builtin-constants.md}}
|
||||
{{#include @generated@/language/builtin-constants.md}}
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
@@ -15,6 +15,6 @@ For convenience, some built-ins can be accessed directly:
|
||||
<dd><p><var>derivation</var> is described in
|
||||
<a href="derivations.md">its own section</a>.</p></dd>
|
||||
|
||||
{{#include @generated@/../../../lix/libexpr/builtins.md}}
|
||||
{{#include @generated@/language/builtins.md}}
|
||||
|
||||
</dl>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
builtins_md = custom_target(
|
||||
command : nix_eval_for_docs + [
|
||||
'--expr',
|
||||
'import @INPUT0@ (builtins.fromJSON (builtins.readFile @INPUT1@)).builtins',
|
||||
],
|
||||
capture : true,
|
||||
input : [
|
||||
'../../generate-builtins.nix',
|
||||
language_json,
|
||||
],
|
||||
output : 'builtins.md',
|
||||
env : nix_env_for_docs,
|
||||
)
|
||||
|
||||
builtin_constants_md = custom_target(
|
||||
command : nix_eval_for_docs + [
|
||||
'--expr',
|
||||
'import @INPUT0@ (builtins.fromJSON (builtins.readFile @INPUT1@)).constants',
|
||||
],
|
||||
capture : true,
|
||||
input : [
|
||||
'../../generate-builtin-constants.nix',
|
||||
language_json,
|
||||
],
|
||||
output : 'builtin-constants.md',
|
||||
env : nix_env_for_docs,
|
||||
)
|
||||
@@ -26,8 +26,8 @@
|
||||
| Logical conjunction (`AND`) | *bool* `&&` *bool* | left | 12 |
|
||||
| Logical disjunction (`OR`) | *bool* <code>\|\|</code> *bool* | left | 13 |
|
||||
| [Logical implication] | *bool* `->` *bool* | none | 14 |
|
||||
| \[Experimental\] [Function piping] | *expr* `\|>` *func* | left | 15 |
|
||||
| \[Experimental\] [Function piping] | *expr* `<\|` *func* | right | 16 |
|
||||
| \[Experimental\] [Function piping] | *expr* |> *func* | left | 15 |
|
||||
| \[Experimental\] [Function piping] | *expr* <| *func* | right | 16 |
|
||||
|
||||
[string]: ./values.md#type-string
|
||||
[path]: ./values.md#type-path
|
||||
|
||||
@@ -77,6 +77,12 @@
|
||||
}
|
||||
```
|
||||
|
||||
Finally, as a convenience, *URIs* as defined in appendix B of
|
||||
[RFC 2396](http://www.ietf.org/rfc/rfc2396.txt) can be written *as
|
||||
is*, without quotes. For instance, the string
|
||||
`"http://example.org/foo.tar.bz2"` can also be written as
|
||||
`http://example.org/foo.tar.bz2`.
|
||||
|
||||
- <a id="type-number" href="#type-number">Number</a>
|
||||
|
||||
Numbers, which can be *integers* (like `123`) or *floating point*
|
||||
|
||||
@@ -1,4 +1,114 @@
|
||||
# Lix 2.91 "Dragon's Breath" (2024-08-12)
|
||||
# Lix 2.91.3 (2025-06-30)
|
||||
|
||||
## Fixes
|
||||
- Revert CVE-2025-52992 failed mitigation [fj#883](https://git.lix.systems/lix-project/lix/issues/883) [fj#887](https://git.lix.systems/lix-project/lix/issues/887) [cl/3420](https://gerrit.lix.systems/c/lix/+/3420) [cl/3524](https://gerrit.lix.systems/c/lix/+/3524) [cl/3523](https://gerrit.lix.systems/c/lix/+/3523) [cl/3522](https://gerrit.lix.systems/c/lix/+/3522)
|
||||
|
||||
Following the initial mitigation of **CVE-2025-52992** in `cl/3420`, we
|
||||
received reports of **unexpected deletion of in-use store paths**.
|
||||
|
||||
Upon investigation, we found that the patch did **not correctly cancel all
|
||||
automatic deleters**, resulting in potentially critical path loss during normal
|
||||
operation.
|
||||
|
||||
Given the severity and time-sensitive nature of the situation ([see incident
|
||||
report](https://lix.systems/blog/2025-06-27-lix-critical-bug/)), we evaluated
|
||||
possible options to repair the behavior safely. However, we concluded that a
|
||||
rushed fix would either:
|
||||
|
||||
* **Overdelete**, i.e. breaking running systems, or,
|
||||
* **Underdelete**, effectively **reopening CVE-2025-52992** while leaving
|
||||
orphaned paths behind.
|
||||
|
||||
As **CVE-2025-52992 has no known exploit vector**, and correctness is critical
|
||||
in the Lix project, we have **fully reverted the previous mitigations**.
|
||||
|
||||
Moving forward, the Lix team will rework this code path in a **long-term,
|
||||
correctness-first fix** on the main branch. We will explore backporting it to
|
||||
stable channels once its safety is assured.
|
||||
|
||||
We are deeply sorry for the stability incident and the Lix team remain
|
||||
available for assisting you in recovering your systems.
|
||||
|
||||
Many thanks to [Raito Bezarius](https://git.lix.systems/raito) and [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
- Fallback to safe temp dir when build-dir is unwritable [fj#876](https://git.lix.systems/lix-project/lix/issues/876) [cl/3502](https://gerrit.lix.systems/c/lix/+/3502)
|
||||
|
||||
Non-daemon builds started failing with a permission error after introducing the `build-dir` option:
|
||||
|
||||
```
|
||||
$ nix build --store ~/scratch nixpkgs#hello --rebuild
|
||||
error: creating directory '/nix/var/nix/builds/nix-build-hello-2.12.2.drv-0': Permission denied
|
||||
```
|
||||
|
||||
This happens because:
|
||||
|
||||
1. These builds are not run via the daemon, which owns `/nix/var/nix/builds`.
|
||||
2. The user lacks permissions for that path.
|
||||
|
||||
We considered making `build-dir` a store-level option and defaulting it to `<chroot-root>/nix/var/nix/builds` for chroot stores, but opted instead for a fallback: if the default fails, Nix now creates a safe build directory under `/tmp`.
|
||||
|
||||
To avoid CVE-2025-52991, the fallback uses an extra path component between `/tmp` and the build dir.
|
||||
|
||||
**Note**: this fallback clutters `/tmp` with build directories that are not cleaned up. To prevent this, explicitly set `build-dir` to a path managed by Lix, even for local workloads.
|
||||
|
||||
Many thanks to [Raito Bezarius](https://git.lix.systems/raito) and [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
|
||||
|
||||
# Lix 2.91.2 (2025-06-23)
|
||||
|
||||
## Breaking Changes
|
||||
- Fixed output derivations can be run using `pasta` network isolation [fj#285](https://git.lix.systems/lix-project/lix/issues/285) [cl/3418](https://gerrit.lix.systems/c/lix/+/3418)
|
||||
|
||||
Fixed output derivations traditionally run in the host network namespace.
|
||||
On Linux this allows such derivations to communicate with other sandboxes
|
||||
or the host using the abstract Unix domains socket namespace; this hasn't
|
||||
been unproblematic in the past and has been used in two distinct exploits
|
||||
to break out of the sandbox. For this reason fixed output derivations can
|
||||
now run in a network namespace (provided by [`pasta`]), restricted to TCP
|
||||
and UDP communication with the rest of the world. When enabled this could
|
||||
be a breaking change and we classify it as such, even though we don't yet
|
||||
enable or require such isolation by default. We may enforce this in later
|
||||
releases of Lix once we have sufficient confidence that breakage is rare.
|
||||
|
||||
[`pasta`]: https://passt.top/
|
||||
|
||||
Many thanks to [eldritch horrors](https://git.lix.systems/pennae) and [puck](https://git.lix.systems/puck) for this.
|
||||
|
||||
## Fixes
|
||||
- Always clean up scratch paths after derivations failed to build [cl/3420](https://gerrit.lix.systems/c/lix/+/3420)
|
||||
|
||||
Previously, scratch paths created during builds were not always cleaned up if
|
||||
the derivation failed, potentially leaving behind unnecessary temporary files
|
||||
or directories in the Nix store.
|
||||
|
||||
This fix ensures that such paths are consistently removed after a failed build,
|
||||
improving Nix store hygiene, hardening Lix against mis-reuse of failed builds
|
||||
scratch paths.
|
||||
|
||||
Many thanks to [Raito Bezarius](https://git.lix.systems/raito) and [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
- `build-dir` no longer defaults to `temp-dir` [cl/3419](https://gerrit.lix.systems/c/lix/+/3419)
|
||||
|
||||
The directory in which temporary build directories are created no longer defaults
|
||||
to the value of the `temp-dir` setting to avoid builders making their directories
|
||||
world-accessible. This behavior has been used to escape the build sandbox and can
|
||||
cause build impurities even when not used maliciously. We now default to `builds`
|
||||
in `NIX_STATE_DIR` (which is `/nix/var/nix/builds` in the default configuration).
|
||||
|
||||
Many thanks to [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
|
||||
|
||||
# Lix 2.91.1 (2024-10-18)
|
||||
|
||||
## Fixes
|
||||
- `<nix/fetchurl.nix>` now uses TLS verification [#11585](https://github.com/NixOS/nix/pull/11585)
|
||||
|
||||
Previously `<nix/fetchurl.nix>` did not do TLS verification. This was because the Nix sandbox in the past did not have access to TLS certificates, and Nix checks the hash of the fetched file anyway. However, this can expose authentication data from `netrc` and URLs to man-in-the-middle attackers. In addition, Nix now in some cases (such as when using impure derivations) does *not* check the hash. Therefore we have now enabled TLS verification. This means that downloads by `<nix/fetchurl.nix>` will now fail if you're fetching from a HTTPS server that does not have a valid certificate.
|
||||
|
||||
`<nix/fetchurl.nix>` is also known as the builtin derivation builder `builtin:fetchurl`. It's not to be confused with the evaluation-time function `builtins.fetchurl`, which was not affected by this issue.
|
||||
|
||||
Many thanks to [Eelco Dolstra](https://github.com/edolstra) for this.
|
||||
|
||||
|
||||
|
||||
|
||||
# Lix 2.91.0 (2024-08-12)
|
||||
|
||||
@@ -1,428 +0,0 @@
|
||||
# Lix 2.92 "Bombe glacée" (2025-01-18)
|
||||
|
||||
|
||||
# Lix 2.92.0 (2025-01-18)
|
||||
|
||||
## Breaking Changes
|
||||
- Deprecated language features [fj#437](https://git.lix.systems/lix-project/lix/issues/437) [#861](https://github.com/NixOS/nix/issues/861) [cl/1785](https://gerrit.lix.systems/c/lix/+/1785) [cl/1736](https://gerrit.lix.systems/c/lix/+/1736) [cl/1735](https://gerrit.lix.systems/c/lix/+/1735) [cl/1744](https://gerrit.lix.systems/c/lix/+/1744) [cl/2206](https://gerrit.lix.systems/c/lix/+/2206)
|
||||
|
||||
A system for deprecation (and then the planned removal) of undesired language features has been put into place.
|
||||
It is controlled via feature flags much like experimental features, except that the deprecations are enabled default,
|
||||
and can be disabled via the flags for backwards compatibility (opt-out with `--extra-deprecated-features` or the Nix configuration file).
|
||||
|
||||
- `url-literals`: **URL literals** have long been obsolete and discouraged of use, and now they are officially deprecated.
|
||||
This means that all URLs must be properly put within quotes like all other strings.
|
||||
- `rec-set-overrides`: **__overrides** is an old arcane syntax which has not been in use for more than a decade.
|
||||
It is soft-deprecated with a warning only, with the plan to turn that into an error in a future release.
|
||||
- `ancient-let`: **The old `let` syntax** (`let { body = …; … }`) is soft-deprecated with a warning as well. Use the regular `let … in` instead.
|
||||
- `shadow-internal-symbols`: Arithmetic expressions like `5 - 3` internally expand to `__sub 5 3`, where `__sub` maps to a subtraction builtin. Shadowing such a symbols would affect the evaluation of such operations, but in a very inconsistent way, and is therefore deprecated now. **Affected symbols are:** `__sub`, `__mul`, `__div` and `__lessThan`. Note that these symbols may still be used as variable names as long as they do not shadow internal operations, so e.g. `let __sub = x: y: x + y; in __sub 3 5` remains valid code.
|
||||
- **Call to action:** If you have any use cases or workflows that depend on being able to override the `__nixPath` and `__findFile` symbols, please reach out to us. We want to eventually deprecate overriding these as well, and need input on how to design a better alternative.
|
||||
|
||||
Many thanks to [piegames](https://git.lix.systems/piegames) and [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
- transfers no longer allow arbitrary url schemas [cl/2106](https://gerrit.lix.systems/c/lix/+/2106)
|
||||
|
||||
Lix no longer allows transfers using arbitrary url schemas. Only `http://`, `https://`, `ftp://`, `ftps://`, and `file://` urls are supported going forward. This affects `builtins.fetchurl`, `<nix/fetchurl.nix>`, transfers to and from binary caches, and all other uses of the internal file transfer code. Flake inputs using multi-protocol schemas (e.g. `git+ssh`) are not affected as those use external utilities to transfer data.
|
||||
|
||||
The `s3://` scheme is not affected at all by this change and continues to work if S3 support is built into Lix.
|
||||
|
||||
Many thanks to [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
- Removing the `.` default argument passed to the `nix fmt` formatter [#11438](https://github.com/NixOS/nix/pull/11438) [cl/1902](https://gerrit.lix.systems/c/lix/+/1902)
|
||||
|
||||
The underlying formatter no longer receives the ". " default argument when `nix fmt` is called with no arguments.
|
||||
|
||||
This change was necessary as the formatter wasn't able to distinguish between
|
||||
a user wanting to format the current folder with `nix fmt .` or the generic
|
||||
`nix fmt`.
|
||||
|
||||
The default behaviour is now the responsibility of the formatter itself, and
|
||||
allows tools such as treefmt to format the whole tree instead of only the
|
||||
current directory and below.
|
||||
|
||||
This may cause issues with some formatters: nixfmt, nixpkgs-fmt and alejandra currently format stdin when no arguments are passed.
|
||||
|
||||
Here is a small wrapper example that will restore the previous behaviour for such a formatter:
|
||||
|
||||
```nix
|
||||
{
|
||||
outputs = { self, nixpkgs, systems }:
|
||||
let
|
||||
eachSystem = nixpkgs.lib.genAttrs (import systems) (system: nixpkgs.legacyPackages.${system});
|
||||
in
|
||||
{
|
||||
formatter = eachSystem (pkgs:
|
||||
pkgs.writeShellScriptBin "formatter" ''
|
||||
if [[ $# = 0 ]]; set -- .; fi
|
||||
exec "${pkgs.nixfmt-rfc-style}/bin/nixfmt "$@"
|
||||
'');
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Many thanks to [zimbatm](https://github.com/zimbatm) for this.
|
||||
|
||||
## Features
|
||||
- Relative and tilde paths in configuration [fj#482](https://git.lix.systems/lix-project/lix/issues/482) [cl/1851](https://gerrit.lix.systems/c/lix/+/1851) [cl/1863](https://gerrit.lix.systems/c/lix/+/1863) [cl/1864](https://gerrit.lix.systems/c/lix/+/1864)
|
||||
|
||||
[Configuration settings](@docroot@/command-ref/conf-file.md) can now refer to
|
||||
files with paths relative to the file they're written in or relative to your
|
||||
home directory (with `~/`).
|
||||
|
||||
This makes settings like
|
||||
[`repl-overlays`](@docroot@/command-ref/conf-file.md#conf-repl-overlays) and
|
||||
[`secret-key-files`](@docroot@/command-ref/conf-file.md#conf-repl-overlays)
|
||||
much easier to set, especially if you'd like to refer to files in an existing
|
||||
dotfiles repo cloned into your home directory.
|
||||
|
||||
If you put `repl-overlays = repl.nix` in your `~/.config/nix/nix.conf`, it'll
|
||||
load `~/.config/nix/repl.nix`. Similarly, you can set `repl-overlays =
|
||||
~/.dotfiles/repl.nix` to load a file relative to your home directory.
|
||||
|
||||
Configuration files can also
|
||||
[`include`](@docroot@/command-ref/conf-file.md#file-format) paths relative to
|
||||
your home directory.
|
||||
|
||||
Only user configuration files (like `$XDG_CONFIG_HOME/nix/nix.conf` or the
|
||||
files listed in `$NIX_USER_CONF_FILES`) can use tilde paths relative to your
|
||||
home directory. Configuration listed in the `$NIX_CONFIG` environment variable
|
||||
may not use relative paths.
|
||||
|
||||
Many thanks to [wiggles](https://git.lix.systems/rbt) for this.
|
||||
|
||||
## Improvements
|
||||
- Improved error messages for bad attr paths [cl/2277](https://gerrit.lix.systems/c/lix/+/2277) [cl/2280](https://gerrit.lix.systems/c/lix/+/2280)
|
||||
|
||||
Lix now includes much more detail when a bad attribute path is accessed at the command line:
|
||||
|
||||
```
|
||||
» nix eval -f '<nixpkgs>' lixVersions.lix_2_92
|
||||
error: attribute 'lix_2_92' in selection path 'lixVersions.lix_2_92' not found
|
||||
Did you mean one of lix_2_90 or lix_2_91?
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```
|
||||
» nix eval --impure -f '<nixpkgs>' lixVersions.lix_2_92
|
||||
error: attribute 'lix_2_92' in selection path 'lixVersions.lix_2_92' not found inside path 'lixVersions', whose contents are: { __unfix__ = «lambda @ /nix/store/hfz1qqd0z8amlgn8qwich1dvkmldik36-source/lib/fixed-points.nix:
|
||||
447:7»; buildLix = «thunk»; extend = «thunk»; latest = «thunk»; lix_2_90 = «thunk»; lix_2_91 = «thunk»; override = «thunk»; overrideDerivation = «thunk»; recurseForDerivations = true; stable = «thunk»; }
|
||||
Did you mean one of lix_2_90 or lix_2_91?
|
||||
```
|
||||
|
||||
This should avoid some unnecessary trips to the repl or to the debugger by giving some information about the value being selected on that was unexpected.
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
- Small error message improvements [cl/2185](https://gerrit.lix.systems/c/lix/+/2185) [cl/2187](https://gerrit.lix.systems/c/lix/+/2187)
|
||||
|
||||
When an attribute selection fails, the error message now correctly points to the attribute in the chain that failed instead of at the beginning of the entire chain.
|
||||
```diff
|
||||
error: attribute 'x' missing
|
||||
- at /pwd/lang/eval-fail-remove.nix:4:3:
|
||||
+ at /pwd/lang/eval-fail-remove.nix:4:29:
|
||||
3| in
|
||||
4| (removeAttrs attrs ["x"]).x
|
||||
- | ^
|
||||
+ | ^
|
||||
5|
|
||||
```
|
||||
|
||||
Failed asserts don't print the failed assertion expression anymore in the error message. That code was buggy and the information was redundant anyways, given that the error position already more accurately shows what exactly failed.
|
||||
|
||||
Many thanks to [piegames](https://git.lix.systems/piegames) for this.
|
||||
- Improvements to interactive flake config [cl/2066](https://gerrit.lix.systems/c/lix/+/2066)
|
||||
|
||||
If `accept-flake-config` is set to `ask` and a `flake.nix` defines `nixConfig`,
|
||||
Lix will ask on the CLI which of these settings should be used for the command.
|
||||
|
||||
Now, it's possible to answer with `N` (as opposed to `n` to only reject the setting
|
||||
that is asked for) to reject _all untrusted_ entries from the flake's `nixConf`
|
||||
section.
|
||||
|
||||
Many thanks to [ma27](https://git.lix.systems/ma27) for this.
|
||||
- `nix --version` now shows details about the installation by default [fj#620](https://git.lix.systems/lix-project/lix/issues/620) [cl/2365](https://gerrit.lix.systems/c/lix/+/2365)
|
||||
|
||||
This happened with `nix-env --version` by default, but due to [oddities around the nix3 CLI's verbosity](https://gerrit.lix.systems/c/lix/+/1370), it used to be `nix --verbose --version`.
|
||||
|
||||
No longer:
|
||||
|
||||
```
|
||||
$ nix --version
|
||||
nix (Lix, like Nix) 2.92.0-dev-pre20250117-0d14c2b
|
||||
System type: x86_64-linux
|
||||
Additional system types: i686-linux, x86_64-v1-linux, x86_64-v2-linux, x86_64-v3-linux
|
||||
Features: gc, signed-caches
|
||||
System configuration file: /etc/nix/nix.conf
|
||||
User configuration files: /home/jade/.config/nix/nix.conf:/etc/xdg/nix/nix.conf
|
||||
Store directory: /nix/store
|
||||
State directory: /nix/var/nix
|
||||
Data directory: /nix/store/rliimcnqkplrqdgm4z6yqclpr6c32wh6-lix-2.92.0-dev-pre20250117-0d14c2b/share
|
||||
```
|
||||
|
||||
Many thanks to [just1602](https://git.lix.systems/just1602) for this.
|
||||
- `nix repl` correctly tab-completes attribute names that require quotes [cl/1783](https://gerrit.lix.systems/c/lix/+/1783)
|
||||
|
||||
The REPL (`nix repl`) now includes quotes as part of attribute names while completing with `<TAB>`,
|
||||
if necessary. For example, attribute names like `"hello@example.com"` or `"hello world"` would
|
||||
be suggested without quotes, resulting in invalid syntax.
|
||||
|
||||
Many thanks to [ian-h-chamberlain](https://git.lix.systems/ian-h-chamberlain) for this.
|
||||
- Reproducibility check builds now report all differing outputs [cl/2069](https://gerrit.lix.systems/c/lix/+/2069)
|
||||
|
||||
`nix-build --check` allows rerunning the build of an already-built derivation to check that it produces the same output again.
|
||||
|
||||
If a multiple-output derivation with impure behaviour is built with `--check`, only the first output would be shown in the resulting error message (and kept for comparison):
|
||||
|
||||
```
|
||||
error: derivation '/nix/store/4spy3nz1661zm15gkybsy1h5f36aliwx-python3.11-test-1.0.0.drv' may not be deterministic: output '/nix/store/ccqcp01zg18wp9iadzmzimqzdi3ll08d-python3.11-test
|
||||
-1.0.0-dist' differs from '/nix/store/ccqcp01zg18wp9iadzmzimqzdi3ll08d-python3.11-test-1.0.0-dist.check'
|
||||
```
|
||||
|
||||
Now, all differing outputs are kept and reported:
|
||||
```
|
||||
error: derivation '4spy3nz1661zm15gkybsy1h5f36aliwx-python3.11-test-1.0.0.drv' may not be deterministic: outputs differ
|
||||
output differs: output '/nix/store/ccqcp01zg18wp9iadzmzimqzdi3ll08d-python3.11-test-1.0.0-dist' differs from '/nix/store/ccqcp01zg18wp9iadzmzimqzdi3ll08d-python3.11-test-1.0.0-dist.check'
|
||||
output differs: output '/nix/store/yl59v08356i841c560alb0zmk7q16klb-python3.11-test-1.0.0' differs from '/nix/store/yl59v08356i841c560alb0zmk7q16klb-python3.11-test-1.0.0.check'
|
||||
```
|
||||
|
||||
Many thanks to [lheckemann](https://git.lix.systems/lheckemann) for this.
|
||||
- Some Lix crashes now produce reporting instructions and a stack trace, then abort [cl/1854](https://gerrit.lix.systems/c/lix/+/1854)
|
||||
|
||||
Lix, being a C++ program, can crash in a few kinds of ways.
|
||||
It can obviously do a memory access violation, which will generate a core dump and thus be relatively debuggable.
|
||||
But, worse, it could throw an unhandled exception, and, in the past, we would just show the message but not where it comes from, in spite of this always being a bug, since we expect all such errors to be translated to a Lix specific error.
|
||||
Now the latter kind of bug should print reporting instructions, a rudimentary stack trace and (depending on system configuration) generate a core dump.
|
||||
|
||||
Sample output:
|
||||
|
||||
```
|
||||
Lix crashed. This is a bug. We would appreciate if you report it along with what caused it at https://git.lix.systems/lix-project/lix/issues with the following information included:
|
||||
|
||||
Exception: std::runtime_error: test exception
|
||||
Stack trace:
|
||||
0# nix::printStackTrace() in /home/jade/lix/lix3/build/lix/nix/../libutil/liblixutil.so
|
||||
1# 0x000073C9862331F2 in /home/jade/lix/lix3/build/lix/nix/../libmain/liblixmain.so
|
||||
2# 0x000073C985F2E21A in /nix/store/p44qan69linp3ii0xrviypsw2j4qdcp2-gcc-13.2.0-lib/lib/libstdc++.so.6
|
||||
3# 0x000073C985F2E285 in /nix/store/p44qan69linp3ii0xrviypsw2j4qdcp2-gcc-13.2.0-lib/lib/libstdc++.so.6
|
||||
4# nix::handleExceptions(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::function<void ()>) in /home/jade/lix/lix3/build/lix/nix/../libmain/liblixmain.so
|
||||
...
|
||||
```
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
- Add a `temp-dir` setting to set the temporary directory location [#7731](https://github.com/NixOS/nix/issues/7731) [#8995](https://github.com/NixOS/nix/issues/8995) [fj#112](https://git.lix.systems/lix-project/lix/issues/112) [fj#253](https://git.lix.systems/lix-project/lix/issues/253) [cl/2103](https://gerrit.lix.systems/c/lix/+/2103)
|
||||
|
||||
[`temp-dir`](@docroot@/command-ref/conf-file.md#conf-temp-dir) can now be set in the Nix
|
||||
configuration to change the temporary directory. This can be used to relocate all temporary files
|
||||
to another filesystem without affecting the `TMPDIR` env var inherited by interactive
|
||||
`nix-shell`/`nix shell` shells or `nix run` commands.
|
||||
|
||||
Also on macOS, the `TMPDIR` env var is no longer unset for interactive shells when pointing
|
||||
to a per-session `/var/folders/` directory.
|
||||
|
||||
Many thanks to [lilyball](https://git.lix.systems/lilyball) for this.
|
||||
|
||||
## Fixes
|
||||
- Build failures caused by `allowSubstitutes = false` while being the wrong system now produce a decent error [fj#484](https://git.lix.systems/lix-project/lix/issues/484) [cl/1841](https://gerrit.lix.systems/c/lix/+/1841)
|
||||
|
||||
Nix allows derivations to set `allowSubstitutes = false` in order to force them to be built locally without querying substituters for them.
|
||||
This is useful for derivations that are very fast to build (especially if they produce large output).
|
||||
However, this can shoot you in the foot if the derivation *has* to be substituted such as if the derivation is for another architecture, which is what `--always-allow-substitutes` is for.
|
||||
|
||||
Perhaps such derivations that are known to be impossible to build locally should ignore `allowSubstitutes` (irrespective of remote builders) in the future, but this at least reports the failure and solution directly.
|
||||
|
||||
```
|
||||
$ nix build -f fail.nix
|
||||
error: a 'unicornsandrainbows-linux' with features {} is required to build '/nix/store/...-meow.drv', but I am a 'x86_64-linux' with features {...}
|
||||
|
||||
Hint: the failing derivation has allowSubstitutes set to false, forcing it to be built rather than substituted.
|
||||
Passing --always-allow-substitutes to force substitution may resolve this failure if the path is available in a substituter.
|
||||
```
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
- `Alt+Left` and `Alt+Right` go back/forwards by words in `nix repl` [fj#501](https://git.lix.systems/lix-project/lix/issues/501) [cl/1883](https://gerrit.lix.systems/c/lix/+/1883)
|
||||
|
||||
`nix repl` now recognizes `Alt+Left` and `Alt+Right` for navigating by words
|
||||
when entering input in `nix repl` on more terminals/platforms.
|
||||
|
||||
Many thanks to [wiggles](https://git.lix.systems/rbt) for this.
|
||||
- Ctrl-C stops Nix commands much more reliably and responsively [#7245](https://github.com/NixOS/nix/issues/7245) [fj#393](https://git.lix.systems/lix-project/lix/issues/393) [#11618](https://github.com/NixOS/nix/pull/11618) [cl/2016](https://gerrit.lix.systems/c/lix/+/2016)
|
||||
|
||||
CTRL-C will now stop Nix commands much more reliably and responsively. While
|
||||
there are still some cases where a Nix command can be slow or unresponsive
|
||||
following a `SIGINT` (please report these as issues!), the vast majority of
|
||||
signals will now cause the Nix command to quit quickly and consistently.
|
||||
|
||||
Many thanks to [Robert Hensing](https://github.com/roberth) and [wiggles](https://git.lix.systems/rbt) for this.
|
||||
- restore backwards-compatibility of `builtins.fetchGit` with Nix 2.3 [#5291](https://github.com/NixOS/nix/issues/5291) [#5128](https://github.com/NixOS/nix/issues/5128)
|
||||
|
||||
Compatibility with `builtins.fetchGit` from Nix 2.3 has been restored as follows:
|
||||
|
||||
* Until now, each `ref` was prefixed with `refs/heads` unless it starts with `refs/` itself.
|
||||
|
||||
Now, this is not done if the `ref` looks like a commit hash.
|
||||
|
||||
* Specifying `builtins.fetchGit { ref = "a-tag"; /* … */ }` was broken because `refs/heads` was appended.
|
||||
|
||||
Now, the fetcher doesn't turn a ref into `refs/heads/ref`, but into `refs/*/ref`. That way,
|
||||
the value in `ref` can be either a tag or a branch.
|
||||
|
||||
* The ref resolution happens the same way as in git:
|
||||
|
||||
* If `refs/ref` exists, it's used.
|
||||
* If a tag `refs/tags/ref` exists, it's used.
|
||||
* If a branch `refs/heads/ref` exists, it's used.
|
||||
|
||||
Many thanks to [ma27](https://git.lix.systems/ma27) for this.
|
||||
- Flakes/restrict-eval no longer allow reading contents of impure paths
|
||||
|
||||
Flakes and `--restrict-eval` now correctly restrict access to paths as intended.
|
||||
In prior versions since at least 2.18, `nix eval --raw .#lol` for the following flake didn't throw an error and acted as if `--impure` was passed.
|
||||
|
||||
Thanks to the person who reported this for telling us about it.
|
||||
This was handled as a low-severity security bug, but is not a violation of the [documented security model](../installation/multi-user.md) as untrusted Nix code should be assumed to have the privileges of the user running the evaluator.
|
||||
To report a security bug, email a report to `security at lix dot systems`.
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs = {};
|
||||
outputs = {...}: {
|
||||
lol = builtins.readFile "${/etc/passwd}";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Many thanks to [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
- HTTP proxy environment variables are now respected for S3 binary cache stores [fj#433](https://git.lix.systems/lix-project/lix/issues/433) [cl/1788](https://gerrit.lix.systems/c/lix/+/1788)
|
||||
|
||||
Due to "legacy reasons" (according to the AWS C++ SDK docs), the AWS SDK ignores system proxy configuration by default.
|
||||
We turned it back on.
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
- Fix potential store corruption with auto-optimise-store [#7273](https://github.com/NixOS/nix/issues/7273) [cl/2100](https://gerrit.lix.systems/c/lix/+/2100)
|
||||
|
||||
Optimising store paths (and other operations involving temporary files) no longer use `random(3)`
|
||||
to generate filenames. On darwin systems this was observed to potentially cause store corruption
|
||||
when using [`auto-optimise-store`](@docroot@/command-ref/conf-file.md#conf-auto-optimise-store),
|
||||
though this corruption was possible on any system whose `random(3)` does not have locking around
|
||||
the global state.
|
||||
|
||||
Many thanks to [lilyball](https://git.lix.systems/lilyball) for this.
|
||||
- Change `nix-build -o ""` to behave like `--no-out-link` [cl/2103](https://gerrit.lix.systems/c/lix/+/2103)
|
||||
|
||||
[`nix-build`](@docroot@/command-ref/nix-build.md) now treats <code>[--out-link](@docroot@/command-ref/nix-build.md#opt-out-link) ''</code>
|
||||
the same as [`--no-out-link`](@docroot@/command-ref/nix-build.md#opt-no-out-link). This matches
|
||||
[`nix build`](@docroot@/command-ref/new-cli/nix3-build.md) behavior. Previously when building the default output it
|
||||
would have resulted in throwing an error saying the current working directory already exists, and when building any
|
||||
other output it would have resulted in a symlink starting with a hyphen such as `-doc`, which is a footgun for
|
||||
terminal commands.
|
||||
|
||||
Many thanks to [lilyball](https://git.lix.systems/lilyball) for this.
|
||||
- Ignore broken `/etc/ssl/certs/ca-certificates.crt` symlink [fj#560](https://git.lix.systems/lix-project/lix/issues/560) [cl/2144](https://gerrit.lix.systems/c/lix/+/2144)
|
||||
|
||||
[`ssl-cert-file`](@docroot@/command-ref/conf-file.md#conf-ssl-cert-file) now checks its default
|
||||
value for a broken symlink before using it. This fixes a problem on macOS where uninstalling
|
||||
nix-darwin may leave behind a broken symlink at `/etc/ssl/certs/ca-certificates.crt` that was
|
||||
stopping Lix from using the cert at `/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt`.
|
||||
|
||||
Many thanks to [lilyball](https://git.lix.systems/lilyball) for this.
|
||||
- `<nix/fetchurl.nix>` now uses TLS verification [#11585](https://github.com/NixOS/nix/pull/11585)
|
||||
|
||||
Previously `<nix/fetchurl.nix>` did not do TLS verification. This was because the Nix sandbox in the past did not have access to TLS certificates, and Nix checks the hash of the fetched file anyway. However, this can expose authentication data from `netrc` and URLs to man-in-the-middle attackers. In addition, Nix now in some cases (such as when using impure derivations) does *not* check the hash. Therefore we have now enabled TLS verification. This means that downloads by `<nix/fetchurl.nix>` will now fail if you're fetching from a HTTPS server that does not have a valid certificate.
|
||||
|
||||
`<nix/fetchurl.nix>` is also known as the builtin derivation builder `builtin:fetchurl`. It's not to be confused with the evaluation-time function `builtins.fetchurl`, which was not affected by this issue.
|
||||
|
||||
Many thanks to [Eelco Dolstra](https://github.com/edolstra) for this.
|
||||
|
||||
## Packaging
|
||||
- readline support removed [cl/1885](https://gerrit.lix.systems/c/lix/+/1885)
|
||||
|
||||
Support for building Lix with [`readline`][readline] instead of
|
||||
[`editline`][editline] has been removed. `readline` support hasn't worked for a
|
||||
long time (attempting to use it would lead to build errors) and would make Lix
|
||||
subject to the GPL if it did work. In the future, we're hoping to replace
|
||||
`editline` with [`rustyline`][rustyline] for improved ergonomics in the `nix
|
||||
repl`.
|
||||
|
||||
[readline]: https://en.wikipedia.org/wiki/GNU_Readline
|
||||
[editline]: https://github.com/troglobit/editline
|
||||
[rustyline]: https://github.com/kkawakam/rustyline
|
||||
|
||||
Many thanks to [wiggles](https://git.lix.systems/rbt) for this.
|
||||
|
||||
## Development
|
||||
- Includes are now qualified with library name everywhere [cl/2178](https://gerrit.lix.systems/c/lix/+/2178) [cl/2362](https://gerrit.lix.systems/c/lix/+/2362)
|
||||
|
||||
The Lix includes have all been rearranged to be of the form `"lix/libexpr/foo.hh"` instead of `"foo.hh"`.
|
||||
This was already supported externally for a migration period, but it is now being applied to all the internal usages within Lix itself.
|
||||
The goal of this change is to both clarify where a file is from and to avoid polluting global include paths with things like `config.h` that might conflict with other projects.
|
||||
|
||||
Lix 2.92 removes support for the old `"foo.hh"` include form either internally or externally (that is, via pkg-config for things linking to Lix).
|
||||
|
||||
For other details, see the release notes of Lix 2.90.0, under "Rename all the libraries" in Breaking Changes.
|
||||
|
||||
To fix an external project with sources in `src` which has a separate build directory (such that headers are in `../src` relative to where the compiler is running), use a checkout of Lix 2.91 to run the following:
|
||||
|
||||
```
|
||||
lix_root=$HOME/lix
|
||||
(cd $lix_root && nix develop -c 'meson setup build && ninja -C build subprojects/lix-clang-tidy/liblix-clang-tidy.so')
|
||||
run-clang-tidy -checks='-*,lix-fixincludes' -load=$lix_root/build/subprojects/lix-clang-tidy/liblix-clang-tidy.so -p build/ -header-filter '\.\./src/.*\.h' -fix src
|
||||
```
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
- The beginnings of a new pytest-based functional test suite [cl/2036](https://gerrit.lix.systems/c/lix/+/2036) [cl/2037](https://gerrit.lix.systems/c/lix/+/2037)
|
||||
|
||||
The existing integration/functional test suite is based on a large volume of shell scripts.
|
||||
This often makes it somewhat challenging to debug at the best of times.
|
||||
The goal of the pytest test suite is to make tests have more obvious dependencies on files and to make tests more concise and easier to write, as well as making new testing methods like snapshot testing easy.
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
- Dependency on monolithic coreutils removed [cl/2108](https://gerrit.lix.systems/c/lix/+/2108)
|
||||
|
||||
Previously, the build erroneously depended on a `coreutils` binary, which requires `coreutils` to be built with a specific configuration. This was only used in one test and was not required to be a single binary. This dependency is removed now.
|
||||
|
||||
Many thanks to [Vigress](https://git.lix.systems/vigress8) for this.
|
||||
- All Lix threads are named [cl/2210](https://gerrit.lix.systems/c/lix/+/2210)
|
||||
|
||||
Lix now sets thread names on all of its secondary threads, which will make debugger usage slightly nicer and easier.
|
||||
|
||||
```
|
||||
(gdb) info thr
|
||||
Id Target Id Frame
|
||||
* 1 LWP 3719283 "nix-daemon" 0x00007e558587da0f in accept ()
|
||||
from target:/nix/store/c10zhkbp6jmyh0xc5kd123ga8yy2p4hk-glibc-2.39-52/lib/libc.so.6
|
||||
2 LWP 3719284 "signal handler" 0x00007e55857b2bea in sigtimedwait ()
|
||||
from target:/nix/store/c10zhkbp6jmyh0xc5kd123ga8yy2p4hk-glibc-2.39-52/lib/libc.so.6
|
||||
```
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
- Set `X-GitHub-Api-Version` header [fj#255](https://git.lix.systems/lix-project/lix/issues/255) [cl/1925](https://gerrit.lix.systems/c/lix/+/1925)
|
||||
|
||||
Sets the `X-GitHub-Api-Version` header to `2022-11-28` for calls to the
|
||||
GitHub API.
|
||||
This follows the later version as per
|
||||
https://docs.github.com/en/rest/about-the-rest-api/api-versions?apiVersion=2022-11-28.
|
||||
|
||||
This affected the check on whether to use the API versus unauthenticated
|
||||
calls as well, given the headers would no longer be empty if the
|
||||
authentication token were missing.
|
||||
The workaround to this used here is to use a check similar to an existing
|
||||
check for the token.
|
||||
|
||||
In the current implementation, headers are (still) similarly sent to
|
||||
non-authenticated as well as GitHub on-prem calls.
|
||||
For what it's worth, manual curl calls with such a header seemed to
|
||||
break nor unauthenticated calls nor ones to the github.com API.
|
||||
|
||||
Many thanks to [kiara](https://github.com/KiaraGrouwstra) for this.
|
||||
|
||||
## Miscellany
|
||||
- Drop support for `xz` and `bzip2` Content-Encoding [cl/2134](https://gerrit.lix.systems/c/lix/+/2134)
|
||||
|
||||
Lix no longer supports the non-standard HTTP Content-Encoding values `xz` and `bzip2`.
|
||||
We do not expect this to cause any problems in practice since these encodings *aren't*
|
||||
standard, and any server delivering them anyway without being asked to is already well
|
||||
and truly set on the path of causing inexplicable client breakages.
|
||||
|
||||
Lix's ability to decompress files compressed with `xz` or `bzip2` is unaffected. We're
|
||||
only bringing Lix more in line with the HTTP standard; all post-transfer data handling
|
||||
remains as it was before.
|
||||
|
||||
Many thanks to [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
@@ -0,0 +1,139 @@
|
||||
with builtins;
|
||||
|
||||
rec {
|
||||
splitLines = s: filter (x: !isList x) (split "\n" s);
|
||||
|
||||
concatStrings = concatStringsSep "";
|
||||
|
||||
attrsToList =
|
||||
a:
|
||||
map (name: {
|
||||
inherit name;
|
||||
value = a.${name};
|
||||
}) (builtins.attrNames a);
|
||||
|
||||
replaceStringsRec =
|
||||
from: to: string:
|
||||
# recursively replace occurrences of `from` with `to` within `string`
|
||||
# example:
|
||||
# replaceStringRec "--" "-" "hello-----world"
|
||||
# => "hello-world"
|
||||
let
|
||||
replaced = replaceStrings [ from ] [ to ] string;
|
||||
in
|
||||
if replaced == string then string else replaceStringsRec from to replaced;
|
||||
|
||||
squash = replaceStringsRec "\n\n\n" "\n\n";
|
||||
|
||||
trim =
|
||||
string:
|
||||
# trim trailing spaces and squash non-leading spaces
|
||||
let
|
||||
trimLine =
|
||||
line:
|
||||
let
|
||||
# separate leading spaces from the rest
|
||||
parts = split "(^ *)" line;
|
||||
spaces = head (elemAt parts 1);
|
||||
rest = elemAt parts 2;
|
||||
# drop trailing spaces
|
||||
body = head (split " *$" rest);
|
||||
in
|
||||
spaces + replaceStringsRec " " " " body;
|
||||
in
|
||||
concatStringsSep "\n" (map trimLine (splitLines string));
|
||||
|
||||
# FIXME: O(n^2)
|
||||
unique = foldl' (acc: e: if elem e acc then acc else acc ++ [ e ]) [ ];
|
||||
|
||||
nameValuePair = name: value: { inherit name value; };
|
||||
|
||||
filterAttrs =
|
||||
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 "";
|
||||
|
||||
showSetting =
|
||||
{ inlineHTML }:
|
||||
name:
|
||||
{
|
||||
description,
|
||||
documentDefault,
|
||||
defaultValue,
|
||||
aliases,
|
||||
value,
|
||||
experimentalFeature,
|
||||
}:
|
||||
let
|
||||
result = squash ''
|
||||
- ${
|
||||
if inlineHTML then ''<span id="conf-${name}">[`${name}`](#conf-${name})</span>'' else ''`${name}`''
|
||||
}
|
||||
|
||||
${indent " " body}
|
||||
'';
|
||||
|
||||
experimentalFeatureNote = optionalString (experimentalFeature != null) ''
|
||||
> **Warning**
|
||||
> This setting is part of an
|
||||
> [experimental feature](@docroot@/contributing/experimental-features.md).
|
||||
|
||||
To change this setting, you need to make sure the corresponding experimental feature,
|
||||
[`${experimentalFeature}`](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature}),
|
||||
is enabled.
|
||||
For example, include the following in [`nix.conf`](#):
|
||||
|
||||
```
|
||||
extra-experimental-features = ${experimentalFeature}
|
||||
${name} = ...
|
||||
```
|
||||
'';
|
||||
|
||||
# separate body to cleanly handle indentation
|
||||
body = ''
|
||||
${description}
|
||||
|
||||
${experimentalFeatureNote}
|
||||
|
||||
**Default:** ${showDefault documentDefault defaultValue}
|
||||
|
||||
${showAliases aliases}
|
||||
'';
|
||||
|
||||
showDefault =
|
||||
documentDefault: defaultValue:
|
||||
if documentDefault then
|
||||
# a StringMap value type is specified as a string, but
|
||||
# this shows the value type. The empty stringmap is `null` in
|
||||
# JSON, but that converts to `{ }` here.
|
||||
if defaultValue == "" || defaultValue == [ ] || isAttrs defaultValue then
|
||||
"*empty*"
|
||||
else if isBool defaultValue then
|
||||
if defaultValue then "`true`" else "`false`"
|
||||
else
|
||||
"`${toString defaultValue}`"
|
||||
else
|
||||
"*machine-specific*";
|
||||
|
||||
showAliases =
|
||||
aliases:
|
||||
optionalString (aliases != [ ])
|
||||
"**Deprecated alias:** ${(concatStringsSep ", " (map (s: "`${s}`") aliases))}";
|
||||
in
|
||||
result;
|
||||
|
||||
indent =
|
||||
prefix: s: concatStringsSep "\n" (map (x: if x == "" then x else "${prefix}${x}") (splitLines s));
|
||||
|
||||
showSettings =
|
||||
args: settingsInfo: concatStrings (attrValues (mapAttrs (showSetting args) settingsInfo));
|
||||
}
|
||||
Generated
+10
-10
@@ -19,11 +19,11 @@
|
||||
"nix2container": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1724996935,
|
||||
"narHash": "sha256-njRK9vvZ1JJsP8oV2OgkBrpJhgQezI03S7gzskCcHos=",
|
||||
"lastModified": 1749158376,
|
||||
"narHash": "sha256-uirStFNxauh0lxzBowcp28X+Sq7JgsBIDnbwbAfZwf8=",
|
||||
"owner": "nlewo",
|
||||
"repo": "nix2container",
|
||||
"rev": "fa6bb0a1159f55d071ba99331355955ae30b3401",
|
||||
"rev": "0f8974c58755dba441df03598eefd1e1cd50e341",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -34,16 +34,16 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1733348545,
|
||||
"narHash": "sha256-b4JrUmqT0vFNx42aEN9LTWOHomkTKL/ayLopflVf81U=",
|
||||
"lastModified": 1735651292,
|
||||
"narHash": "sha256-YLbzcBtYo1/FEzFsB3AnM16qFc6fWPMIoOuSoDwvg9g=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "9ecb50d2fae8680be74c08bb0a995c5383747f89",
|
||||
"rev": "0da3c44a9460a26d2025ec3ed2ec60a895eb1114",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.11-small",
|
||||
"ref": "nixos-24.05-small",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
@@ -67,11 +67,11 @@
|
||||
"pre-commit-hooks": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1733318908,
|
||||
"narHash": "sha256-SVQVsbafSM1dJ4fpgyBqLZ+Lft+jcQuMtEL3lQWx2Sk=",
|
||||
"lastModified": 1721042469,
|
||||
"narHash": "sha256-6FPUl7HVtvRHCCBQne7Ylp4p+dpP3P/OYuzjztZ4s70=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "6f4e2a2112050951a314d2733a994fbab94864c6",
|
||||
"rev": "f451c19376071a90d8c58ab1a953c6e9840527fd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
description = "Lix: A modern, delicious implementation of the Nix package manager";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11-small";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05-small";
|
||||
nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2";
|
||||
pre-commit-hooks = {
|
||||
url = "github:cachix/git-hooks.nix";
|
||||
@@ -99,10 +99,9 @@
|
||||
];
|
||||
|
||||
stdenvs = [
|
||||
# see assertion in package.nix why these two are disabled
|
||||
# "stdenv"
|
||||
# "gccStdenv"
|
||||
"gccStdenv"
|
||||
"clangStdenv"
|
||||
"stdenv"
|
||||
"libcxxStdenv"
|
||||
"ccacheStdenv"
|
||||
];
|
||||
@@ -122,11 +121,7 @@
|
||||
name = "${stdenvName}Packages";
|
||||
value = f stdenvName;
|
||||
}) stdenvs
|
||||
)
|
||||
// {
|
||||
# TODO delete this and reënable gcc stdenvs once gcc compiles kj coros correctly
|
||||
stdenvPackages = f "clangStdenv";
|
||||
};
|
||||
);
|
||||
|
||||
# Memoize nixpkgs for different platforms for efficiency.
|
||||
nixpkgsFor = forAllSystems (
|
||||
@@ -138,7 +133,14 @@
|
||||
localSystem = {
|
||||
inherit system;
|
||||
};
|
||||
crossSystem = if crossSystem == null then null else { system = crossSystem; };
|
||||
crossSystem =
|
||||
if crossSystem == null then
|
||||
null
|
||||
else
|
||||
{
|
||||
system = crossSystem;
|
||||
}
|
||||
// lib.optionalAttrs (crossSystem == "x86_64-freebsd") { useLLVM = true; };
|
||||
overlays = [ (overlayFor (p: p.${stdenv})) ];
|
||||
};
|
||||
stdenvs = forAllStdenvs (make-pkgs null);
|
||||
@@ -147,7 +149,7 @@
|
||||
{
|
||||
inherit stdenvs native;
|
||||
static = native.pkgsStatic;
|
||||
cross = forAllCrossSystems (crossSystem: make-pkgs crossSystem "clangStdenv");
|
||||
cross = forAllCrossSystems (crossSystem: make-pkgs crossSystem "stdenv");
|
||||
}
|
||||
);
|
||||
|
||||
@@ -210,7 +212,7 @@
|
||||
|
||||
# A Nixpkgs overlay that overrides the 'nix' and
|
||||
# 'nix.perl-bindings' packages.
|
||||
overlays.default = overlayFor (p: p.clangStdenv);
|
||||
overlays.default = overlayFor (p: p.stdenv);
|
||||
|
||||
hydraJobs = {
|
||||
# Binary package for various platforms.
|
||||
@@ -262,8 +264,6 @@
|
||||
nix = pkgs.callPackage ./package.nix {
|
||||
inherit versionSuffix officialRelease buildUnreleasedNotes;
|
||||
inherit (pkgs) build-release-notes;
|
||||
# Required since we don't support gcc stdenv
|
||||
stdenv = pkgs.clangStdenv;
|
||||
internalApiDocs = true;
|
||||
busybox-sandbox-shell = pkgs.busybox-sandbox-shell;
|
||||
};
|
||||
@@ -321,8 +321,6 @@
|
||||
inherit (nixpkgs) pkgs;
|
||||
in
|
||||
pkgs.callPackage ./package.nix {
|
||||
# Required since we don't support gcc stdenv
|
||||
stdenv = pkgs.clangStdenv;
|
||||
versionSuffix = "";
|
||||
lintInsteadOfBuild = true;
|
||||
};
|
||||
@@ -350,10 +348,10 @@
|
||||
name = "nixpkgs-lib-tests";
|
||||
paths =
|
||||
[ testWithNix ]
|
||||
# NOTE: nixpkgs 24.11 is being ... *creative*, and requires this dance to override
|
||||
# the evaluator used for the test. it will break again in the future, don't worry.
|
||||
# FIXME: This is disabled on darwin due to a nixpkgs bug https://github.com/NixOS/nixpkgs/issues/319147
|
||||
# After that is fixed, it should be restored to use lib/tests/release.nix as before, rather than this reimplementation.
|
||||
++ lib.optionals pkgs.stdenv.isLinux [
|
||||
(pkgs.callPackage "${nixpkgs}/ci/eval" { nixVersions.nix_2_24 = nix; }).attrpathsSuperset
|
||||
(import (nixpkgs + "/pkgs/test/release") { inherit pkgs lib nix; })
|
||||
];
|
||||
}
|
||||
);
|
||||
@@ -486,7 +484,7 @@
|
||||
let
|
||||
pkgs = nixpkgsFor.${system}.cross.${crossSystem};
|
||||
in
|
||||
makeShell pkgs pkgs.clangStdenv
|
||||
makeShell pkgs pkgs.stdenv
|
||||
))
|
||||
// {
|
||||
default = self.devShells.${system}.native-clangStdenvPackages;
|
||||
|
||||
Generated
+22
-6
@@ -2,6 +2,12 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "countme"
|
||||
version = "3.0.1"
|
||||
@@ -10,15 +16,15 @@ checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
|
||||
|
||||
[[package]]
|
||||
name = "dissimilar"
|
||||
version = "1.0.9"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d"
|
||||
checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632"
|
||||
|
||||
[[package]]
|
||||
name = "expect-test"
|
||||
version = "1.5.0"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e0be0a561335815e06dab7c62e50353134c796e7a6155402a64bcff66b6a5e0"
|
||||
checksum = "30d9eafeadd538e68fb28016364c9732d78e420b9ff8853fa5e4058861e9f8d3"
|
||||
dependencies = [
|
||||
"dissimilar",
|
||||
"once_cell",
|
||||
@@ -39,6 +45,15 @@ dependencies = [
|
||||
"rowan",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
@@ -56,12 +71,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rowan"
|
||||
version = "0.15.16"
|
||||
version = "0.15.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a542b0253fa46e632d27a1dc5cf7b930de4df8659dc6e720b647fc72147ae3d"
|
||||
checksum = "32a58fa8a7ccff2aec4f39cc45bf5f985cec7125ab271cf681c279fd00192b49"
|
||||
dependencies = [
|
||||
"countme",
|
||||
"hashbrown",
|
||||
"memoffset",
|
||||
"rustc-hash",
|
||||
"text-size",
|
||||
]
|
||||
@@ -8,10 +8,13 @@ license = "BSD-2-Clause OR MIT"
|
||||
homepage = "https://github.com/lf-/nix-doc"
|
||||
repository = "https://github.com/lf-/nix-doc"
|
||||
|
||||
[lib]
|
||||
crate_type = ["staticlib"]
|
||||
|
||||
[dependencies]
|
||||
rnix = "0.11.0"
|
||||
# Necessary because rnix fails to export a critical trait (Rowan's AstNode).
|
||||
rowan = "0.15.16"
|
||||
rowan = "0.15.0"
|
||||
|
||||
[dev-dependencies]
|
||||
expect-test = "1.1.0"
|
||||
@@ -1,93 +0,0 @@
|
||||
from typing import List, NamedTuple
|
||||
|
||||
from common import cxx_literal, generate_file, load_data
|
||||
|
||||
KNOWN_KEYS = set([
|
||||
'name',
|
||||
'type',
|
||||
'constructorArgs',
|
||||
'implementation',
|
||||
'impure',
|
||||
'renameInGlobalScope',
|
||||
])
|
||||
|
||||
class BuiltinConstant(NamedTuple):
|
||||
name: str
|
||||
type: str
|
||||
implementation: str
|
||||
impure: bool
|
||||
rename_in_global_scope: bool
|
||||
documentation: str
|
||||
|
||||
def parse(datum):
|
||||
unknown_keys = set(datum.keys()) - KNOWN_KEYS
|
||||
if unknown_keys:
|
||||
raise Exception('unknown keys', unknown_keys)
|
||||
return BuiltinConstant(
|
||||
name = datum['name'],
|
||||
type = datum['type'],
|
||||
implementation = ('{' + ', '.join([f'NewValueAs::{datum["type"]}', *datum['constructorArgs']]) + '}') if 'constructorArgs' in datum else datum['implementation'],
|
||||
impure = datum.get('impure', False),
|
||||
rename_in_global_scope = datum.get('renameInGlobalScope', True),
|
||||
documentation = datum.content,
|
||||
)
|
||||
|
||||
VALUE_TYPES = {
|
||||
'attrs': 'nAttrs',
|
||||
'boolean': 'nBool',
|
||||
'integer': 'nInt',
|
||||
'list': 'nList',
|
||||
'null': 'nNull',
|
||||
'string': 'nString',
|
||||
}
|
||||
|
||||
HUMAN_TYPES = {
|
||||
'attrs': 'set',
|
||||
'boolean': 'Boolean',
|
||||
'integer': 'integer',
|
||||
'list': 'list',
|
||||
'null': 'null',
|
||||
'string': 'string',
|
||||
}
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument('--header', help='Path of the header to generate')
|
||||
ap.add_argument('--docs', help='Path of the documentation file to generate')
|
||||
ap.add_argument('defs', help='Builtin definition files', nargs='+')
|
||||
args = ap.parse_args()
|
||||
|
||||
builtin_constants = load_data(args.defs, BuiltinConstant.parse)
|
||||
|
||||
generate_file(args.header, builtin_constants, lambda constant:
|
||||
# `builtins` is magic and must come first
|
||||
'' if constant.name == 'builtins' else constant.name,
|
||||
lambda constant:
|
||||
f'''{'if (!evalSettings.pureEval) ' if constant.impure else ''}{{
|
||||
addConstant({cxx_literal(('__' if constant.rename_in_global_scope else '') + constant.name)}, {constant.implementation}, {{
|
||||
.type = {VALUE_TYPES[constant.type]},
|
||||
.doc = {cxx_literal(constant.documentation)},
|
||||
.impureOnly = {cxx_literal(constant.impure)},
|
||||
}});
|
||||
}}
|
||||
''')
|
||||
generate_file(args.docs, builtin_constants, lambda constant: constant.name, lambda constant:
|
||||
f'''<dt id="builtins-{constant.name}">
|
||||
<a href="#builtins-{constant.name}"><code>{constant.name}</code></a> ({HUMAN_TYPES[constant.type]})
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
{constant.documentation}
|
||||
|
||||
''' + ('''> **Note**
|
||||
>
|
||||
> Not available in [pure evaluation mode](@docroot@/command-ref/conf-file.md#conf-pure-eval).
|
||||
|
||||
''' if constant.impure else '') + '''</dd>
|
||||
|
||||
''')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,82 +0,0 @@
|
||||
from typing import List, NamedTuple, Optional
|
||||
|
||||
from build_experimental_features import ExperimentalFeature
|
||||
from common import cxx_literal, generate_file, load_data
|
||||
|
||||
KNOWN_KEYS = set([
|
||||
'name',
|
||||
'implementation',
|
||||
'renameInGlobalScope',
|
||||
'args',
|
||||
'experimentalFeature',
|
||||
])
|
||||
|
||||
class Builtin(NamedTuple):
|
||||
name: str
|
||||
implementation: str
|
||||
rename_in_global_scope: bool
|
||||
args: List[str]
|
||||
experimental_feature: Optional[str]
|
||||
documentation: str
|
||||
|
||||
def parse(datum):
|
||||
unknown_keys = set(datum.keys()) - KNOWN_KEYS
|
||||
if unknown_keys:
|
||||
raise Exception('unknown keys', unknown_keys)
|
||||
return Builtin(
|
||||
name = datum['name'],
|
||||
implementation = datum['implementation'] if 'implementation' in datum else f'prim_{datum["name"]}',
|
||||
rename_in_global_scope = datum.get('renameInGlobalScope', True),
|
||||
args = datum['args'],
|
||||
experimental_feature = datum.get('experimentalFeature', None),
|
||||
documentation = datum.content,
|
||||
)
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument('--header', help='Path of the header to generate')
|
||||
ap.add_argument('--docs', help='Path of the documentation file to generate')
|
||||
ap.add_argument('--experimental-features', help='Directory containing the experimental feature definitions')
|
||||
ap.add_argument('defs', help='Builtin definition files', nargs='+')
|
||||
args = ap.parse_args()
|
||||
|
||||
builtins = load_data(args.defs, Builtin.parse)
|
||||
|
||||
experimental_feature_names = set([builtin.experimental_feature for (_, builtin) in builtins])
|
||||
experimental_feature_names.discard(None)
|
||||
experimental_feature_files = [f'{args.experimental_features}/{name}.md' for name in experimental_feature_names]
|
||||
experimental_features = load_data(experimental_feature_files, ExperimentalFeature.parse)
|
||||
experimental_features = dict(map(lambda path_and_feature:
|
||||
(path_and_feature[1].name, f'Xp::{path_and_feature[1].internal_name}'), experimental_features))
|
||||
experimental_features[None] = 'std::nullopt'
|
||||
|
||||
generate_file(args.header, builtins, lambda builtin: builtin.name, lambda builtin:
|
||||
f'''{'' if builtin.experimental_feature is None else f'if (experimentalFeatureSettings.isEnabled({experimental_features[builtin.experimental_feature]})) '}{{
|
||||
addPrimOp({{
|
||||
.name = {cxx_literal(('__' if builtin.rename_in_global_scope else '') + builtin.name)},
|
||||
.args = {cxx_literal(builtin.args)},
|
||||
.arity = {len(builtin.args)},
|
||||
.doc = {cxx_literal(builtin.documentation)},
|
||||
.fun = {builtin.implementation},
|
||||
.experimentalFeature = {experimental_features[builtin.experimental_feature]},
|
||||
}});
|
||||
}}
|
||||
''')
|
||||
generate_file(args.docs, builtins, lambda builtin: builtin.name, lambda builtin:
|
||||
f'''<dt id="builtins-{builtin.name}">
|
||||
<a href="#builtins-{builtin.name}"><code>{builtin.name} {' '.join([f'<var>{arg}</var>' for arg in builtin.args])}</code></a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
{builtin.documentation}
|
||||
|
||||
''' + (f'''This function is only available if the [{builtin.experimental_feature}](@docroot@/contributing/experimental-features.md#xp-feature-{builtin.experimental_feature}) experimental feature is enabled.
|
||||
|
||||
''' if builtin.experimental_feature is not None else '') + '''</dd>
|
||||
|
||||
''')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,58 +0,0 @@
|
||||
from typing import NamedTuple
|
||||
|
||||
from common import cxx_literal, generate_file, load_data
|
||||
|
||||
KNOWN_KEYS = set([
|
||||
'name',
|
||||
'internalName',
|
||||
])
|
||||
|
||||
class ExperimentalFeature(NamedTuple):
|
||||
name: str
|
||||
internal_name: str
|
||||
description: str
|
||||
|
||||
def parse(datum):
|
||||
unknown_keys = set(datum.keys()) - KNOWN_KEYS
|
||||
if unknown_keys:
|
||||
raise ValueError('unknown keys', unknown_keys)
|
||||
return ExperimentalFeature(
|
||||
name = datum['name'],
|
||||
internal_name = datum['internalName'],
|
||||
description = datum.content,
|
||||
)
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument('--deprecated', action='store_true', help='Generate deprecated features')
|
||||
ap.add_argument('--header', help='Path of the declaration header to generate')
|
||||
ap.add_argument('--impl-header', help='Path of the implementation header to generate')
|
||||
ap.add_argument('--descriptions', help='Path of the description file to generate')
|
||||
ap.add_argument('--shortlist', help='Path of the shortlist file to generate')
|
||||
ap.add_argument('defs', help='Experimental feature definition files', nargs='+')
|
||||
args = ap.parse_args()
|
||||
|
||||
features = load_data(args.defs, ExperimentalFeature.parse)
|
||||
|
||||
generate_file(args.header, features, lambda feature: feature.name, lambda feature:
|
||||
f' {feature.internal_name},\n')
|
||||
generate_file(args.impl_header, features, lambda feature: feature.name, lambda feature:
|
||||
f''' {{
|
||||
.tag = {"Dep" if args.deprecated else "Xp"}::{feature.internal_name},
|
||||
.name = {cxx_literal(feature.name)},
|
||||
.description = {cxx_literal(feature.description)},
|
||||
}},
|
||||
''')
|
||||
generate_file(args.descriptions, features, lambda feature: feature.name, lambda feature:
|
||||
f'''## [`{feature.name}`]{{#{"dp" if args.deprecated else "xp"}-feature-{feature.name}}}
|
||||
|
||||
{feature.description}
|
||||
|
||||
''')
|
||||
generate_file(args.shortlist, features, lambda feature: feature.name, lambda feature:
|
||||
f' - [`{feature.name}`](@docroot@/contributing/{"deprecated" if args.deprecated else "experimental"}-features.md#{"dp" if args.deprecated else "xp"}-feature-{feature.name})\n')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,141 +0,0 @@
|
||||
from typing import List, NamedTuple, Optional
|
||||
|
||||
from build_experimental_features import ExperimentalFeature
|
||||
from common import cxx_literal, generate_file, load_data
|
||||
|
||||
KNOWN_KEYS = set([
|
||||
'name',
|
||||
'internalName',
|
||||
'platforms',
|
||||
'type',
|
||||
'settingType',
|
||||
'default',
|
||||
'defaultExpr',
|
||||
'defaultText',
|
||||
'aliases',
|
||||
'experimentalFeature',
|
||||
'deprecated',
|
||||
])
|
||||
|
||||
class Setting(NamedTuple):
|
||||
name: str
|
||||
internal_name: str
|
||||
description: str
|
||||
platforms: Optional[List[str]]
|
||||
setting_type: str
|
||||
default_expr: str
|
||||
default_text: str
|
||||
aliases: List[str]
|
||||
experimental_feature: Optional[str]
|
||||
deprecated: bool
|
||||
|
||||
def parse(datum):
|
||||
unknown_keys = set(datum.keys()) - KNOWN_KEYS
|
||||
if unknown_keys:
|
||||
raise ValueError('unknown keys', unknown_keys)
|
||||
default_text = f'`{nix_conf_literal(datum["default"])}`' if 'default' in datum else datum['defaultText']
|
||||
if default_text == '``':
|
||||
default_text = '*empty*'
|
||||
return Setting(
|
||||
name = datum['name'],
|
||||
internal_name = datum['internalName'],
|
||||
description = datum.content,
|
||||
platforms = datum.get('platforms', None),
|
||||
setting_type = f'Setting<{datum["type"]}>' if 'type' in datum else datum['settingType'],
|
||||
default_expr = cxx_literal(datum['default']) if 'default' in datum else datum['defaultExpr'],
|
||||
default_text = default_text,
|
||||
aliases = datum.get('aliases', []),
|
||||
experimental_feature = datum.get('experimentalFeature', None),
|
||||
deprecated = datum.get('deprecated', False),
|
||||
)
|
||||
|
||||
platform_names = {
|
||||
'darwin': 'Darwin',
|
||||
'linux': 'Linux',
|
||||
}
|
||||
|
||||
def nix_conf_literal(v):
|
||||
if v is None:
|
||||
return ''
|
||||
elif isinstance(v, bool) and v == False: # 0 == False
|
||||
return 'false'
|
||||
elif isinstance(v, bool) and v == True: # 1 == True
|
||||
return 'true'
|
||||
elif isinstance(v, int):
|
||||
return str(v)
|
||||
elif isinstance(v, str):
|
||||
return v
|
||||
elif isinstance(v, list):
|
||||
return ' '.join([nix_conf_literal(item) for item in v])
|
||||
else:
|
||||
raise NotImplementedError(f'Cannot represent {repr(v)} in nix.conf')
|
||||
|
||||
def indent(prefix, body):
|
||||
return ''.join(['\n' if line == '' else f'{prefix}{line}\n' for line in body.split('\n')])
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument('--kernel', help='Name of the kernel Lix will run on')
|
||||
ap.add_argument('--header', help='Path of the header to generate')
|
||||
ap.add_argument('--docs', help='Path of the documentation file to generate')
|
||||
ap.add_argument('--experimental-features', help='Directory containing the experimental feature definitions')
|
||||
ap.add_argument('defs', help='Setting definition files', nargs='+')
|
||||
args = ap.parse_args()
|
||||
|
||||
settings = load_data(args.defs, Setting.parse)
|
||||
|
||||
experimental_feature_names = set([setting.experimental_feature for (_, setting) in settings])
|
||||
experimental_feature_names.discard(None)
|
||||
experimental_feature_files = [f'{args.experimental_features}/{name}.md' for name in experimental_feature_names]
|
||||
experimental_features = load_data(experimental_feature_files, ExperimentalFeature.parse)
|
||||
experimental_features = dict(map(lambda path_and_feature:
|
||||
(path_and_feature[1].name, f'Xp::{path_and_feature[1].internal_name}'), experimental_features))
|
||||
experimental_features[None] = 'std::nullopt'
|
||||
|
||||
generate_file(args.header, settings, lambda setting: setting.name, lambda setting:
|
||||
f'''{setting.setting_type} {setting.internal_name} {{
|
||||
this,
|
||||
{setting.default_expr},
|
||||
{cxx_literal(setting.name)},
|
||||
{cxx_literal(setting.description)},
|
||||
{cxx_literal(setting.aliases)},
|
||||
true,
|
||||
{experimental_features[setting.experimental_feature]},
|
||||
{cxx_literal(setting.deprecated)}
|
||||
}};
|
||||
|
||||
''' if setting.platforms is None or args.kernel in setting.platforms else '')
|
||||
generate_file(args.docs, settings, lambda setting: setting.name, lambda setting:
|
||||
f'''- <span id="conf-{setting.name}">[`{setting.name}`](#conf-{setting.name})</span>
|
||||
|
||||
{indent(" ", setting.description)}
|
||||
''' + (f''' > **Note**
|
||||
> This setting is only available on {', '.join([platform_names[platform] for platform in setting.platforms])} systems.
|
||||
|
||||
''' if setting.platforms is not None else '') + (f''' > **Warning**
|
||||
> This setting is part of an
|
||||
> [experimental feature](@docroot@/contributing/experimental-features.md).
|
||||
|
||||
To change this setting, you need to make sure the corresponding experimental feature,
|
||||
[`{setting.experimental_feature}`](@docroot@/contributing/experimental-features.md#xp-feature-{setting.experimental_feature}),
|
||||
is enabled.
|
||||
For example, include the following in [`nix.conf`](#):
|
||||
|
||||
```
|
||||
extra-experimental-features = {setting.experimental_feature}
|
||||
{setting.name} = ...
|
||||
```
|
||||
|
||||
''' if setting.experimental_feature is not None else '') + (''' > **Warning**
|
||||
> This setting is deprecated and will be removed in a future version of Lix.
|
||||
|
||||
''' if setting.deprecated else '') + f''' **Default:** {setting.default_text}
|
||||
|
||||
''' + (f''' **Deprecated alias:** {', '.join([f'`{item}`' for item in setting.aliases])}
|
||||
|
||||
''' if setting.aliases != [] else ''))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,60 +0,0 @@
|
||||
import frontmatter
|
||||
import pathlib
|
||||
from collections import defaultdict
|
||||
|
||||
def cxx_escape_character(c):
|
||||
if ord(c) >= 0x20 and ord(c) < 0x7f and c != '"' and c != '?' and c != '\\':
|
||||
return c
|
||||
elif c == '\t':
|
||||
return r'\t'
|
||||
elif c == '\n':
|
||||
return r'\n'
|
||||
elif c == '\r':
|
||||
return r'\r'
|
||||
elif c == '"':
|
||||
return r'\"'
|
||||
elif c == '?':
|
||||
return r'\?'
|
||||
elif c == '\\':
|
||||
return r'\\'
|
||||
elif ord(c) <= 0xffff:
|
||||
return str.format(r'\u{:04x}', ord(c))
|
||||
else:
|
||||
return str.format(r'\U{:08x}', ord(c))
|
||||
|
||||
def cxx_literal(v):
|
||||
if v is None:
|
||||
return 'std::nullopt'
|
||||
elif isinstance(v, bool) and v == False: # 0 == False
|
||||
return 'false'
|
||||
elif isinstance(v, bool) and v == True: # 1 == True
|
||||
return 'true'
|
||||
elif isinstance(v, int):
|
||||
return str(v)
|
||||
elif isinstance(v, str):
|
||||
return ''.join(['"', *(cxx_escape_character(c) for c in v), '"'])
|
||||
elif isinstance(v, list):
|
||||
return f'{{{", ".join([cxx_literal(item) for item in v])}}}'
|
||||
else:
|
||||
raise NotImplementedError(f'cannot represent {repr(v)} in C++')
|
||||
|
||||
def load_data(defs, parse_function):
|
||||
data = []
|
||||
for path in defs:
|
||||
try:
|
||||
datum = frontmatter.load(path)
|
||||
data.append((path, parse_function(datum)))
|
||||
except Exception as e:
|
||||
e.add_note(f'in {path}')
|
||||
raise
|
||||
return data
|
||||
|
||||
def generate_file(path, data, sort_key_function, generate_function):
|
||||
if path is not None:
|
||||
with open(path, 'w') as out:
|
||||
for path, datum in sorted(data, key=lambda pathAndDatum: sort_key_function(pathAndDatum[1])):
|
||||
try:
|
||||
out.write(generate_function(datum))
|
||||
except Exception as e:
|
||||
e.add_note(f'in {path}')
|
||||
raise
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
/// @file
|
||||
|
||||
namespace nix {
|
||||
|
||||
void registerBuildRemote();
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
legacy_include_directories = include_directories('.')
|
||||
|
||||
legacy_sources = files(
|
||||
# `build-remote` is not really legacy (it powers all remote builds), but it's
|
||||
# not a `nix3` command.
|
||||
'build-remote.cc',
|
||||
'dotgraph.cc',
|
||||
'graphml.cc',
|
||||
'nix-build.cc',
|
||||
'nix-channel.cc',
|
||||
'nix-collect-garbage.cc',
|
||||
'nix-copy-closure.cc',
|
||||
'nix-env.cc',
|
||||
'nix-env.hh',
|
||||
'nix-instantiate.cc',
|
||||
'nix-store.cc',
|
||||
'user-env.cc',
|
||||
)
|
||||
|
||||
legacy_headers = files(
|
||||
'build-remote.hh',
|
||||
'nix-build.hh',
|
||||
'nix-channel.hh',
|
||||
'nix-collect-garbage.hh',
|
||||
'nix-copy-closure.hh',
|
||||
'nix-instantiate.hh',
|
||||
'nix-store.hh',
|
||||
)
|
||||
|
||||
legacy_generated_headers = [
|
||||
gen_header.process('buildenv.nix', preserve_path_from: meson.current_source_dir()),
|
||||
gen_header.process('unpack-channel.nix', preserve_path_from: meson.current_source_dir()),
|
||||
]
|
||||
|
||||
fs.copyfile('unpack-channel.nix')
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
/// @file
|
||||
|
||||
namespace nix {
|
||||
|
||||
void registerNixBuildAndNixShell();
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
/// @file
|
||||
|
||||
namespace nix {
|
||||
|
||||
void registerNixChannel();
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
/// @file
|
||||
|
||||
namespace nix {
|
||||
|
||||
void registerNixCollectGarbage();
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
/// @file
|
||||
|
||||
namespace nix {
|
||||
|
||||
void registerNixCopyClosure();
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
/// @file
|
||||
|
||||
namespace nix {
|
||||
|
||||
void registerNixEnv();
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
/// @file
|
||||
|
||||
namespace nix {
|
||||
|
||||
void registerNixInstantiate();
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
/// @file
|
||||
|
||||
namespace nix {
|
||||
|
||||
void registerNixStore();
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#include "lix/libcmd/legacy.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
LegacyCommands::Commands * LegacyCommands::commands = 0;
|
||||
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
#include "lix/libexpr/attr-path.hh"
|
||||
#include "lix/libexpr/eval-inline.hh"
|
||||
#include "print-options.hh"
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
||||
std::vector<std::string> parseAttrPath(std::string_view const s)
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
std::string cur;
|
||||
bool haveData = false;
|
||||
auto i = s.begin();
|
||||
while (i != s.end()) {
|
||||
if (*i == '.') {
|
||||
res.push_back(cur);
|
||||
haveData = false;
|
||||
cur.clear();
|
||||
} else if (*i == '"') {
|
||||
// If there is a quote there *will* be a named term even if it is empty.
|
||||
++i;
|
||||
haveData = true;
|
||||
|
||||
while (1) {
|
||||
if (i == s.end())
|
||||
throw ParseError("missing closing quote in selection path '%1%'", s);
|
||||
if (*i == '"') break;
|
||||
cur.push_back(*i++);
|
||||
}
|
||||
} else {
|
||||
cur.push_back(*i);
|
||||
haveData = true;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
if (haveData) res.push_back(cur);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
std::string unparseAttrPath(std::vector<std::string> const & attrPath)
|
||||
{
|
||||
// FIXME(jade): can probably be rewritten with ranges once libc++ has a
|
||||
// fully featured implementation
|
||||
// https://github.com/llvm/llvm-project/pull/65536
|
||||
auto ret = std::ostringstream{};
|
||||
bool first = true;
|
||||
|
||||
for (auto const & part : attrPath) {
|
||||
if (!first) {
|
||||
ret << ".";
|
||||
}
|
||||
first = false;
|
||||
|
||||
bool mustQuote = std::ranges::any_of(part, [](char c) -> bool {
|
||||
return c == '"' || c == '.' || c == ' ';
|
||||
});
|
||||
|
||||
if (mustQuote || part.empty()) {
|
||||
ret << '"' << part << '"';
|
||||
} else {
|
||||
ret << part;
|
||||
}
|
||||
}
|
||||
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
|
||||
std::pair<Value *, PosIdx> findAlongAttrPath(EvalState & state, const std::string & attrPath,
|
||||
Bindings & autoArgs, Value & vIn)
|
||||
{
|
||||
auto tokens = parseAttrPath(attrPath);
|
||||
|
||||
Value * v = &vIn;
|
||||
PosIdx pos = noPos;
|
||||
|
||||
for (auto [attrPathIdx, attr] : enumerate(tokens)) {
|
||||
|
||||
/* Is i an index (integer) or a normal attribute name? */
|
||||
auto attrIndex = string2Int<unsigned int>(attr);
|
||||
|
||||
/* Evaluate the expression. */
|
||||
Value * vNew = state.ctx.mem.allocValue();
|
||||
state.autoCallFunction(autoArgs, *v, *vNew);
|
||||
v = vNew;
|
||||
state.forceValue(*v, noPos);
|
||||
|
||||
/* It should evaluate to either a set or an expression,
|
||||
according to what is specified in the attrPath. */
|
||||
|
||||
if (!attrIndex) {
|
||||
if (attr.empty())
|
||||
throw Error("empty attribute name in selection path '%1%'", attrPath);
|
||||
|
||||
if (v->type() != nAttrs) {
|
||||
auto pathPart =
|
||||
std::vector<std::string>(tokens.begin(), tokens.begin() + attrPathIdx);
|
||||
state.ctx.errors
|
||||
.make<TypeError>(
|
||||
"the value being indexed in the selection path '%1%' at '%2%' should be a "
|
||||
"set but is %3%: %4%",
|
||||
attrPath,
|
||||
unparseAttrPath(pathPart),
|
||||
showType(*v),
|
||||
ValuePrinter(state, *v, errorPrintOptions)
|
||||
)
|
||||
.debugThrow();
|
||||
}
|
||||
|
||||
Bindings::iterator a = v->attrs->find(state.ctx.symbols.create(attr));
|
||||
if (a == v->attrs->end()) {
|
||||
std::set<std::string> attrNames;
|
||||
for (auto & attr : *v->attrs)
|
||||
attrNames.insert(state.ctx.symbols[attr.name]);
|
||||
|
||||
auto suggestions = Suggestions::bestMatches(attrNames, attr);
|
||||
auto pathPart =
|
||||
std::vector<std::string>(tokens.begin(), tokens.begin() + attrPathIdx);
|
||||
throw AttrPathNotFound(
|
||||
suggestions,
|
||||
"attribute '%1%' in selection path '%2%' not found inside path '%3%', whose "
|
||||
"contents are: %4%",
|
||||
attr,
|
||||
attrPath,
|
||||
unparseAttrPath(pathPart),
|
||||
ValuePrinter(state, *v, errorPrintOptions)
|
||||
);
|
||||
}
|
||||
v = &*a->value;
|
||||
pos = a->pos;
|
||||
} else {
|
||||
if (!v->isList()) {
|
||||
state.ctx.errors
|
||||
.make<TypeError>(
|
||||
"the expression selected by the selection path '%1%' should be a list but "
|
||||
"is %2%: %3%",
|
||||
attrPath,
|
||||
showType(*v),
|
||||
ValuePrinter(state, *v, errorPrintOptions)
|
||||
)
|
||||
.debugThrow();
|
||||
}
|
||||
if (*attrIndex >= v->listSize()) {
|
||||
throw AttrPathNotFound(
|
||||
"list index %1% in selection path '%2%' is out of range for list %3%",
|
||||
*attrIndex,
|
||||
attrPath,
|
||||
ValuePrinter(state, *v, errorPrintOptions)
|
||||
);
|
||||
}
|
||||
|
||||
v = v->listElems()[*attrIndex];
|
||||
pos = noPos;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {v, pos};
|
||||
}
|
||||
|
||||
|
||||
std::pair<SourcePath, uint32_t> findPackageFilename(EvalState & state, Value & v, std::string what)
|
||||
{
|
||||
Value * v2;
|
||||
try {
|
||||
auto dummyArgs = state.ctx.mem.allocBindings(0);
|
||||
v2 = findAlongAttrPath(state, "meta.position", *dummyArgs, v).first;
|
||||
} catch (Error &) {
|
||||
throw NoPositionInfo("package '%s' has no source location information", what);
|
||||
}
|
||||
|
||||
// FIXME: is it possible to extract the Pos object instead of doing this
|
||||
// toString + parsing?
|
||||
NixStringContext context;
|
||||
auto path = state.coerceToPath(noPos, *v2, context, "while evaluating the 'meta.position' attribute of a derivation");
|
||||
|
||||
auto fn = path.canonical().abs();
|
||||
|
||||
auto fail = [fn]() {
|
||||
throw ParseError("cannot parse 'meta.position' attribute '%s'", fn);
|
||||
};
|
||||
|
||||
try {
|
||||
auto colon = fn.rfind(':');
|
||||
if (colon == std::string::npos) fail();
|
||||
auto lineno = std::stoi(std::string(fn, colon + 1, std::string::npos));
|
||||
return {CanonPath(fn.substr(0, colon)), lineno};
|
||||
} catch (std::invalid_argument & e) {
|
||||
fail();
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "lix/libexpr/eval.hh"
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace nix {
|
||||
|
||||
MakeError(AttrPathNotFound, Error);
|
||||
MakeError(NoPositionInfo, Error);
|
||||
|
||||
std::pair<Value *, PosIdx> findAlongAttrPath(
|
||||
EvalState & state,
|
||||
const std::string & attrPath,
|
||||
Bindings & autoArgs,
|
||||
Value & vIn);
|
||||
|
||||
/**
|
||||
* Heuristic to find the filename and lineno or a nix value.
|
||||
*/
|
||||
std::pair<SourcePath, uint32_t> findPackageFilename(EvalState & state, Value & v, std::string what);
|
||||
|
||||
/**
|
||||
* Parses an attr path (as used in nix-build -A foo.bar.baz) into a list of tokens.
|
||||
*
|
||||
* Such an attr path is a dot-separated sequence of attribute names, which are possibly quoted.
|
||||
* No escaping is performed; attribute names containing double quotes are unrepresentable.
|
||||
*/
|
||||
std::vector<std::string> parseAttrPath(std::string_view const s);
|
||||
|
||||
/**
|
||||
* Converts an attr path from a list of strings into a string once more.
|
||||
* The result returned is an attr path and is *not necessarily valid nix syntax*.
|
||||
*/
|
||||
std::string unparseAttrPath(std::vector<std::string> const & attrPath);
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
#include "lix/libexpr/attr-set.hh"
|
||||
#include "lix/libexpr/eval.hh"
|
||||
#include "lix/libexpr/gc-alloc.hh"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace nix {
|
||||
|
||||
Bindings Bindings::EMPTY{0};
|
||||
|
||||
|
||||
/* Allocate a new array of attributes for an attribute set with a specific
|
||||
capacity. The space is implicitly reserved after the Bindings
|
||||
structure. */
|
||||
Bindings * EvalMemory::allocBindings(size_t capacity)
|
||||
{
|
||||
if (capacity == 0)
|
||||
return &Bindings::EMPTY;
|
||||
if (capacity > std::numeric_limits<Bindings::Size>::max())
|
||||
throw Error("attribute set of size %d is too big", capacity);
|
||||
stats.nrAttrsets++;
|
||||
stats.nrAttrsInAttrsets += capacity;
|
||||
return new (gcAllocBytes(sizeof(Bindings) + sizeof(Attr) * capacity)) Bindings((Bindings::Size) capacity);
|
||||
}
|
||||
|
||||
|
||||
Value & BindingsBuilder::alloc(Symbol name, PosIdx pos)
|
||||
{
|
||||
auto value = mem.allocValue();
|
||||
bindings->push_back(Attr(name, value, pos));
|
||||
return *value;
|
||||
}
|
||||
|
||||
|
||||
Value & BindingsBuilder::alloc(std::string_view name, PosIdx pos)
|
||||
{
|
||||
return alloc(symbols.create(name), pos);
|
||||
}
|
||||
|
||||
|
||||
void Bindings::sort()
|
||||
{
|
||||
if (size_) std::sort(begin(), end());
|
||||
}
|
||||
|
||||
|
||||
Value & Value::mkAttrs(BindingsBuilder & bindings)
|
||||
{
|
||||
mkAttrs(bindings.finish());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
name: builtins
|
||||
type: attrs
|
||||
constructorArgs: [mem.buildBindings(symbols, 128).finish()]
|
||||
renameInGlobalScope: false
|
||||
---
|
||||
Contains all the [built-in functions](@docroot@/language/builtins.md) and values.
|
||||
|
||||
Since built-in functions were added over time, [testing for attributes](./operators.md#has-attribute) in `builtins` can be used for graceful fallback on older Nix installations:
|
||||
|
||||
```nix
|
||||
# if hasContext is not available, we assume `s` has a context
|
||||
if builtins ? hasContext then builtins.hasContext s else true
|
||||
```
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
name: currentSystem
|
||||
type: string
|
||||
constructorArgs: [evalSettings.getCurrentSystem()]
|
||||
impure: true
|
||||
---
|
||||
The value of the
|
||||
[`eval-system`](@docroot@/command-ref/conf-file.md#conf-eval-system)
|
||||
or else
|
||||
[`system`](@docroot@/command-ref/conf-file.md#conf-system)
|
||||
configuration option.
|
||||
|
||||
It can be used to set the `system` attribute for [`builtins.derivation`](@docroot@/language/derivations.md) such that the resulting derivation can be built on the same system that evaluates the Nix expression:
|
||||
|
||||
```nix
|
||||
builtins.derivation {
|
||||
# ...
|
||||
system = builtins.currentSystem;
|
||||
}
|
||||
```
|
||||
|
||||
It can be overridden in order to create derivations for different system than the current one:
|
||||
|
||||
```console
|
||||
$ nix-instantiate --system "mips64-linux" --eval --expr 'builtins.currentSystem'
|
||||
"mips64-linux"
|
||||
```
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
name: currentTime
|
||||
type: integer
|
||||
constructorArgs: ['NixInt{time(0)}']
|
||||
impure: true
|
||||
---
|
||||
Return the [Unix time](https://en.wikipedia.org/wiki/Unix_time) at first evaluation.
|
||||
Repeated references to that name will re-use the initially obtained value.
|
||||
|
||||
Example:
|
||||
|
||||
```console
|
||||
$ nix repl
|
||||
Welcome to Nix 2.15.1 Type :? for help.
|
||||
|
||||
nix-repl> builtins.currentTime
|
||||
1683705525
|
||||
|
||||
nix-repl> builtins.currentTime
|
||||
1683705525
|
||||
```
|
||||
|
||||
The [store path](@docroot@/glossary.md#gloss-store-path) of a derivation depending on `currentTime` will differ for each evaluation, unless both evaluate `builtins.currentTime` in the same second.
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
name: 'false'
|
||||
type: boolean
|
||||
constructorArgs: ['false']
|
||||
renameInGlobalScope: false
|
||||
---
|
||||
Primitive value.
|
||||
|
||||
It can be returned by
|
||||
[comparison operators](@docroot@/language/operators.md#Comparison)
|
||||
and used in
|
||||
[conditional expressions](@docroot@/language/constructs.md#Conditionals).
|
||||
|
||||
The name `false` is not special, and can be shadowed:
|
||||
|
||||
```nix-repl
|
||||
nix-repl> let false = 1; in false
|
||||
1
|
||||
```
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
name: langVersion
|
||||
type: integer
|
||||
constructorArgs: ['NixInt{6}']
|
||||
---
|
||||
The legacy version of the Nix language. Always is `6` on Lix,
|
||||
matching Nix 2.18.
|
||||
|
||||
Code in the Nix language should use other means of feature detection
|
||||
like detecting the presence of builtins, rather than trying to find
|
||||
the version of the Nix implementation, as there may be other Nix
|
||||
implementations with different feature combinations.
|
||||
|
||||
If the feature you want to write compatibility code for cannot be
|
||||
detected by any means, please file a Lix bug.
|
||||
@@ -1,21 +0,0 @@
|
||||
---
|
||||
name: nixPath
|
||||
type: list
|
||||
implementation: prepareNixPath(searchPath)
|
||||
---
|
||||
The search path used to resolve angle bracket path lookups.
|
||||
|
||||
Angle bracket expressions can be
|
||||
[desugared](https://en.wikipedia.org/wiki/Syntactic_sugar)
|
||||
using this and
|
||||
[`builtins.findFile`](./builtins.html#builtins-findFile):
|
||||
|
||||
```nix
|
||||
<nixpkgs>
|
||||
```
|
||||
|
||||
is equivalent to:
|
||||
|
||||
```nix
|
||||
builtins.findFile builtins.nixPath "nixpkgs"
|
||||
```
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
name: nixVersion
|
||||
type: string
|
||||
constructorArgs: ['"2.18.3-lix"']
|
||||
---
|
||||
Legacy version of Nix. Always returns "2.18.3-lix" on Lix.
|
||||
|
||||
Code in the Nix language should use other means of feature detection
|
||||
like detecting the presence of builtins, rather than trying to find
|
||||
the version of the Nix implementation, as there may be other Nix
|
||||
implementations with different feature combinations.
|
||||
|
||||
If the feature you want to write compatibility code for cannot be
|
||||
detected by any means, please file a Lix bug.
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
name: 'null'
|
||||
type: 'null'
|
||||
constructorArgs: []
|
||||
renameInGlobalScope: false
|
||||
---
|
||||
Primitive value.
|
||||
|
||||
The name `null` is not special, and can be shadowed:
|
||||
|
||||
```nix-repl
|
||||
nix-repl> let null = 1; in null
|
||||
1
|
||||
```
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
name: storeDir
|
||||
type: string
|
||||
constructorArgs: [storeDir]
|
||||
---
|
||||
Logical file system location of the [Nix store](@docroot@/glossary.md#gloss-store) currently in use.
|
||||
|
||||
This value is determined by the `store` parameter in [Store URLs](@docroot@/command-ref/new-cli/nix3-help-stores.md):
|
||||
|
||||
```shell-session
|
||||
$ nix-instantiate --store 'dummy://?store=/blah' --eval --expr builtins.storeDir
|
||||
"/blah"
|
||||
```
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
name: 'true'
|
||||
type: boolean
|
||||
constructorArgs: ['true']
|
||||
renameInGlobalScope: false
|
||||
---
|
||||
Primitive value.
|
||||
|
||||
It can be returned by
|
||||
[comparison operators](@docroot@/language/operators.md#Comparison)
|
||||
and used in
|
||||
[conditional expressions](@docroot@/language/constructs.md#Conditionals).
|
||||
|
||||
The name `true` is not special, and can be shadowed:
|
||||
|
||||
```nix-repl
|
||||
nix-repl> let true = 1; in true
|
||||
1
|
||||
```
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
name: abort
|
||||
args: [s]
|
||||
renameInGlobalScope: false
|
||||
---
|
||||
Abort Nix expression evaluation and print the error message *s*.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
name: add
|
||||
args: [e1, e2]
|
||||
---
|
||||
Return the sum of the numbers *e1* and *e2*.
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
name: addDrvOutputDependencies
|
||||
args: [s]
|
||||
---
|
||||
Create a copy of the given string where a single constant string context element is turned into a "derivation deep" string context element.
|
||||
|
||||
The store path that is the constant string context element should point to a valid derivation, and end in `.drv`.
|
||||
|
||||
The original string context element must not be empty or have multiple elements, and it must not have any other type of element other than a constant or derivation deep element.
|
||||
The latter is supported so this function is idempotent.
|
||||
|
||||
This is the opposite of [`builtins.unsafeDiscardOutputDependency`](#builtins-unsafeDiscardOutputDependency).
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
name: all
|
||||
args: [pred, list]
|
||||
---
|
||||
Return `true` if the function *pred* returns `true` for all elements
|
||||
of *list*, and `false` otherwise.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
name: any
|
||||
args: [pred, list]
|
||||
---
|
||||
Return `true` if the function *pred* returns `true` for at least one
|
||||
element of *list*, and `false` otherwise.
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
name: attrNames
|
||||
args: [set]
|
||||
---
|
||||
Return the names of the attributes in the set *set* in an
|
||||
alphabetically sorted list. For instance, `builtins.attrNames { y
|
||||
= 1; x = "foo"; }` evaluates to `[ "x" "y" ]`.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
name: attrValues
|
||||
args: [set]
|
||||
---
|
||||
Return the values of the attributes in the set *set* in the order
|
||||
corresponding to the sorted attribute names.
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
name: baseNameOf
|
||||
args: [s]
|
||||
renameInGlobalScope: false
|
||||
---
|
||||
Return the *base name* of the string *s*, that is, everything
|
||||
following the final slash in the string. This is similar to the GNU
|
||||
`basename` command.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
name: bitAnd
|
||||
args: [e1, e2]
|
||||
---
|
||||
Return the bitwise AND of the integers *e1* and *e2*.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
name: bitOr
|
||||
args: [e1, e2]
|
||||
---
|
||||
Return the bitwise OR of the integers *e1* and *e2*.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
name: bitXor
|
||||
args: [e1, e2]
|
||||
---
|
||||
Return the bitwise XOR of the integers *e1* and *e2*.
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
name: break
|
||||
args: [v]
|
||||
renameInGlobalScope: false
|
||||
---
|
||||
In debug mode (enabled using `--debugger`), pause Nix expression evaluation and enter the REPL.
|
||||
Otherwise, return the argument `v`.
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
name: catAttrs
|
||||
args: [attr, list]
|
||||
---
|
||||
Collect each attribute named *attr* from a list of attribute
|
||||
sets. Attrsets that don't contain the named attribute are
|
||||
ignored. For example,
|
||||
|
||||
```nix
|
||||
builtins.catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}]
|
||||
```
|
||||
|
||||
evaluates to `[1 2]`.
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
name: ceil
|
||||
args: [double]
|
||||
---
|
||||
Converts an IEEE-754 double-precision floating-point number (*double*) to
|
||||
the next higher integer.
|
||||
|
||||
If the datatype is neither an integer nor a "float", an evaluation error will be
|
||||
thrown.
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
name: compareVersions
|
||||
args: [s1, s2]
|
||||
---
|
||||
Compare two strings representing versions and return `-1` if
|
||||
version *s1* is older than version *s2*, `0` if they are the same,
|
||||
and `1` if *s1* is newer than *s2*. The version comparison
|
||||
algorithm is the same as the one used by [`nix-env
|
||||
-u`](../command-ref/nix-env.md#operation---upgrade).
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
name: concatLists
|
||||
args: [lists]
|
||||
---
|
||||
Concatenate a list of lists into a single list.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
name: concatMap
|
||||
args: [f, list]
|
||||
---
|
||||
This function is equivalent to `builtins.concatLists (map f list)`
|
||||
but is more efficient.
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
name: concatStringsSep
|
||||
args: [separator, list]
|
||||
---
|
||||
Concatenate a list of strings with a separator between each
|
||||
element, e.g. `concatStringsSep "/" ["usr" "local" "bin"] ==
|
||||
"usr/local/bin"`.
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
name: deepSeq
|
||||
args: [e1, e2]
|
||||
---
|
||||
This is like `seq e1 e2`, except that *e1* is evaluated *deeply*:
|
||||
if it’s a list or set, its elements or attributes are also
|
||||
evaluated recursively.
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
name: dirOf
|
||||
args: [s]
|
||||
renameInGlobalScope: false
|
||||
---
|
||||
Return the directory part of the string *s*, that is, everything
|
||||
before the final slash in the string. This is similar to the GNU
|
||||
`dirname` command.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
name: div
|
||||
args: [e1, e2]
|
||||
---
|
||||
Return the quotient of the numbers *e1* and *e2*.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
name: elem
|
||||
args: [x, xs]
|
||||
---
|
||||
Return `true` if a value equal to *x* occurs in the list *xs*, and
|
||||
`false` otherwise.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
name: elemAt
|
||||
args: [xs, n]
|
||||
---
|
||||
Return element *n* from the list *xs*. Elements are counted starting
|
||||
from 0. A fatal error occurs if the index is out of bounds.
|
||||
@@ -1,72 +0,0 @@
|
||||
---
|
||||
name: fetchClosure
|
||||
args: [args]
|
||||
experimentalFeature: fetch-closure
|
||||
---
|
||||
Fetch a store path [closure](@docroot@/glossary.md#gloss-closure) from a binary cache, and return the store path as a string with context.
|
||||
|
||||
This function can be invoked in three ways, that we will discuss in order of preference.
|
||||
|
||||
**Fetch a content-addressed store path**
|
||||
|
||||
Example:
|
||||
|
||||
```nix
|
||||
builtins.fetchClosure {
|
||||
fromStore = "https://cache.nixos.org";
|
||||
fromPath = /nix/store/ldbhlwhh39wha58rm61bkiiwm6j7211j-git-2.33.1;
|
||||
}
|
||||
```
|
||||
|
||||
This is the simplest invocation, and it does not require the user of the expression to configure [`trusted-public-keys`](@docroot@/command-ref/conf-file.md#conf-trusted-public-keys) to ensure their authenticity.
|
||||
|
||||
If your store path is [input addressed](@docroot@/glossary.md#gloss-input-addressed-store-object) instead of content addressed, consider the other two invocations.
|
||||
|
||||
**Fetch any store path and rewrite it to a fully content-addressed store path**
|
||||
|
||||
Example:
|
||||
|
||||
```nix
|
||||
builtins.fetchClosure {
|
||||
fromStore = "https://cache.nixos.org";
|
||||
fromPath = /nix/store/r2jd6ygnmirm2g803mksqqjm4y39yi6i-git-2.33.1;
|
||||
toPath = /nix/store/ldbhlwhh39wha58rm61bkiiwm6j7211j-git-2.33.1;
|
||||
}
|
||||
```
|
||||
|
||||
This example fetches `/nix/store/r2jd...` from the specified binary cache,
|
||||
and rewrites it into the content-addressed store path
|
||||
`/nix/store/ldbh...`.
|
||||
|
||||
Like the previous example, no extra configuration or privileges are required.
|
||||
|
||||
To find out the correct value for `toPath` given a `fromPath`,
|
||||
use [`nix store make-content-addressed`](@docroot@/command-ref/new-cli/nix3-store-make-content-addressed.md):
|
||||
|
||||
```console
|
||||
# nix store make-content-addressed --from https://cache.nixos.org /nix/store/r2jd6ygnmirm2g803mksqqjm4y39yi6i-git-2.33.1
|
||||
rewrote '/nix/store/r2jd6ygnmirm2g803mksqqjm4y39yi6i-git-2.33.1' to '/nix/store/ldbhlwhh39wha58rm61bkiiwm6j7211j-git-2.33.1'
|
||||
```
|
||||
|
||||
Alternatively, set `toPath = ""` and find the correct `toPath` in the error message.
|
||||
|
||||
**Fetch an input-addressed store path as is**
|
||||
|
||||
Example:
|
||||
|
||||
```nix
|
||||
builtins.fetchClosure {
|
||||
fromStore = "https://cache.nixos.org";
|
||||
fromPath = /nix/store/r2jd6ygnmirm2g803mksqqjm4y39yi6i-git-2.33.1;
|
||||
inputAddressed = true;
|
||||
}
|
||||
```
|
||||
|
||||
It is possible to fetch an [input-addressed store path](@docroot@/glossary.md#gloss-input-addressed-store-object) and return it as is.
|
||||
However, this is the least preferred way of invoking `fetchClosure`, because it requires that the input-addressed paths are trusted by the Lix configuration.
|
||||
|
||||
**`builtins.storePath`**
|
||||
|
||||
`fetchClosure` is similar to [`builtins.storePath`](#builtins-storePath) in that it allows you to use a previously built store path in a Nix expression.
|
||||
However, `fetchClosure` is more reproducible because it specifies a binary cache from which the path can be fetched.
|
||||
Also, using content-addressed store paths does not require users to configure [`trusted-public-keys`](@docroot@/command-ref/conf-file.md#conf-trusted-public-keys) to ensure their authenticity.
|
||||
@@ -1,138 +0,0 @@
|
||||
---
|
||||
name: fetchGit
|
||||
args: [args]
|
||||
renameInGlobalScope: false
|
||||
---
|
||||
Fetch a path from git. *args* can be a URL, in which case the HEAD
|
||||
of the repo at that URL is fetched. Otherwise, it can be an
|
||||
attribute with the following attributes (all except `url` optional):
|
||||
|
||||
- `url`
|
||||
|
||||
The URL of the repo.
|
||||
|
||||
- `name` (default: *basename of the URL*)
|
||||
|
||||
The name of the directory the repo should be exported to in the store.
|
||||
|
||||
- `rev` (default: *the tip of `ref`*)
|
||||
|
||||
The [Git revision] to fetch.
|
||||
This is typically a commit hash.
|
||||
|
||||
[Git revision]: https://git-scm.com/docs/git-rev-parse#_specifying_revisions
|
||||
|
||||
- `ref` (default: `HEAD`)
|
||||
|
||||
The [Git reference] under which to look for the requested revision.
|
||||
This is often a branch or tag name.
|
||||
|
||||
[Git reference]: https://git-scm.com/book/en/v2/Git-Internals-Git-References
|
||||
|
||||
By default, the `ref` value is prefixed with `refs/heads/`.
|
||||
As of 2.3.0, Nix will not prefix `refs/heads/` if `ref` starts with `refs/` or
|
||||
if `ref` looks like a commit hash for backwards compatibility with CppNix 2.3.
|
||||
|
||||
- `submodules` (default: `false`)
|
||||
|
||||
A Boolean parameter that specifies whether submodules should be checked out.
|
||||
|
||||
- `shallow` (default: `false`)
|
||||
|
||||
A Boolean parameter that specifies whether fetching from a shallow remote repository is allowed.
|
||||
This still performs a full clone of what is available on the remote.
|
||||
|
||||
- `allRefs`
|
||||
|
||||
Whether to fetch all references of the repository.
|
||||
With this argument being true, it's possible to load a `rev` from *any* `ref`
|
||||
(by default only `rev`s from the specified `ref` are supported).
|
||||
|
||||
Here are some examples of how to use `fetchGit`.
|
||||
|
||||
- To fetch a private repository over SSH:
|
||||
|
||||
```nix
|
||||
builtins.fetchGit {
|
||||
url = "git@github.com:my-secret/repository.git";
|
||||
ref = "master";
|
||||
rev = "adab8b916a45068c044658c4158d81878f9ed1c3";
|
||||
}
|
||||
```
|
||||
|
||||
- To fetch an arbitrary reference:
|
||||
|
||||
```nix
|
||||
builtins.fetchGit {
|
||||
url = "https://github.com/NixOS/nix.git";
|
||||
ref = "refs/heads/0.5-release";
|
||||
}
|
||||
```
|
||||
|
||||
- If the revision you're looking for is in the default branch of
|
||||
the git repository you don't strictly need to specify the branch
|
||||
name in the `ref` attribute.
|
||||
|
||||
However, if the revision you're looking for is in a future
|
||||
branch for the non-default branch you will need to specify the
|
||||
the `ref` attribute as well.
|
||||
|
||||
```nix
|
||||
builtins.fetchGit {
|
||||
url = "https://github.com/nixos/nix.git";
|
||||
rev = "841fcbd04755c7a2865c51c1e2d3b045976b7452";
|
||||
ref = "1.11-maintenance";
|
||||
}
|
||||
```
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> It is nice to always specify the branch which a revision
|
||||
> belongs to. Without the branch being specified, the fetcher
|
||||
> might fail if the default branch changes. Additionally, it can
|
||||
> be confusing to try a commit from a non-default branch and see
|
||||
> the fetch fail. If the branch is specified the fault is much
|
||||
> more obvious.
|
||||
|
||||
- If the revision you're looking for is in the default branch of
|
||||
the git repository you may omit the `ref` attribute.
|
||||
|
||||
```nix
|
||||
builtins.fetchGit {
|
||||
url = "https://github.com/nixos/nix.git";
|
||||
rev = "841fcbd04755c7a2865c51c1e2d3b045976b7452";
|
||||
}
|
||||
```
|
||||
|
||||
- To fetch a specific tag:
|
||||
|
||||
```nix
|
||||
builtins.fetchGit {
|
||||
url = "https://github.com/nixos/nix.git";
|
||||
ref = "refs/tags/1.9";
|
||||
}
|
||||
```
|
||||
|
||||
- To fetch the latest version of a remote branch:
|
||||
|
||||
```nix
|
||||
builtins.fetchGit {
|
||||
url = "ssh://git@github.com/nixos/nix.git";
|
||||
ref = "master";
|
||||
}
|
||||
```
|
||||
|
||||
Nix will refetch the branch according to the [`tarball-ttl`](@docroot@/command-ref/conf-file.md#conf-tarball-ttl) setting.
|
||||
|
||||
This behavior is disabled in [pure evaluation mode](@docroot@/command-ref/conf-file.md#conf-pure-eval).
|
||||
|
||||
- To fetch the content of a checked-out work directory:
|
||||
|
||||
```nix
|
||||
builtins.fetchGit ./work-dir
|
||||
```
|
||||
|
||||
If the URL points to a local directory, and no `ref` or `rev` is
|
||||
given, `fetchGit` will use the current content of the checked-out
|
||||
files, even if they are not committed or added to Git's index. It will
|
||||
only consider files added to the Git repository, as listed by `git ls-files`.
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
name: fetchTarball
|
||||
args: [args]
|
||||
renameInGlobalScope: false
|
||||
---
|
||||
Download the specified URL, unpack it and return the path of the
|
||||
unpacked tree. The file must be a tape archive (`.tar`) compressed
|
||||
with `gzip`, `bzip2` or `xz`. The top-level path component of the
|
||||
files in the tarball is removed, so it is best if the tarball
|
||||
contains a single directory at top level. The typical use of the
|
||||
function is to obtain external Nix expression dependencies, such as
|
||||
a particular version of Nixpkgs, e.g.
|
||||
|
||||
```nix
|
||||
with import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz") {};
|
||||
|
||||
stdenv.mkDerivation { … }
|
||||
```
|
||||
|
||||
The fetched tarball is cached for a certain amount of time (1
|
||||
hour by default) in `~/.cache/nix/tarballs/`. You can change the
|
||||
cache timeout either on the command line with `--tarball-ttl`
|
||||
*number-of-seconds* or in the Nix configuration file by adding
|
||||
the line `tarball-ttl = ` *number-of-seconds*.
|
||||
|
||||
Note that when obtaining the hash with `nix-prefetch-url` the
|
||||
option `--unpack` is required.
|
||||
|
||||
This function can also verify the contents against a hash. In that
|
||||
case, the function takes a set instead of a URL. The set requires
|
||||
the attribute `url` and the attribute `sha256`, e.g.
|
||||
|
||||
```nix
|
||||
with import (fetchTarball {
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz";
|
||||
sha256 = "1jppksrfvbk5ypiqdz4cddxdl8z6zyzdb2srq8fcffr327ld5jj2";
|
||||
}) {};
|
||||
|
||||
stdenv.mkDerivation { … }
|
||||
```
|
||||
|
||||
Not available in [restricted evaluation mode](@docroot@/command-ref/conf-file.md#conf-restrict-eval).
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
name: fetchurl
|
||||
args: [url]
|
||||
---
|
||||
Download the specified URL and return the path of the downloaded file.
|
||||
|
||||
Not available in [restricted evaluation mode](@docroot@/command-ref/conf-file.md#conf-restrict-eval).
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
name: filter
|
||||
args: [f, list]
|
||||
---
|
||||
Return a list consisting of the elements of *list* for which the
|
||||
function *f* returns `true`.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user