Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71353962cf | ||
|
|
dc5399dedc | ||
|
|
19ad871b74 | ||
|
|
f76b2961e7 |
-22
@@ -16,25 +16,3 @@ 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
|
||||
# we don't compile out our asserts
|
||||
- -bugprone-assert-side-effect
|
||||
# all thrown exceptions must derive from std::exception
|
||||
- hicpp-exception-baseclass
|
||||
# capturing async lambdas are dangerous
|
||||
- cppcoreguidelines-avoid-capturing-lambda-coroutines
|
||||
# crimes must be appropriately declared as crimes
|
||||
- cppcoreguidelines-pro-type-cstyle-cast
|
||||
- lix-*
|
||||
# This can not yet be applied to Lix itself since we need to do source
|
||||
# reorganization so that lix/ include paths work.
|
||||
- -lix-fixincludes
|
||||
# This lint is included as an example, but the lib function it replaces is
|
||||
# already gone.
|
||||
- -lix-hasprefixsuffix
|
||||
|
||||
|
||||
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>
|
||||
Generated
-79
@@ -1,79 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "countme"
|
||||
version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
|
||||
|
||||
[[package]]
|
||||
name = "dissimilar"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d"
|
||||
|
||||
[[package]]
|
||||
name = "expect-test"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e0be0a561335815e06dab7c62e50353134c796e7a6155402a64bcff66b6a5e0"
|
||||
dependencies = [
|
||||
"dissimilar",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[package]]
|
||||
name = "lix-doc"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"expect-test",
|
||||
"rnix",
|
||||
"rowan",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "rnix"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb35cedbeb70e0ccabef2a31bcff0aebd114f19566086300b8f42c725fc2cb5f"
|
||||
dependencies = [
|
||||
"rowan",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rowan"
|
||||
version = "0.15.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a542b0253fa46e632d27a1dc5cf7b930de4df8659dc6e720b647fc72147ae3d"
|
||||
dependencies = [
|
||||
"countme",
|
||||
"hashbrown",
|
||||
"rustc-hash",
|
||||
"text-size",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "text-size"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233"
|
||||
@@ -1,6 +0,0 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["lix/lix-doc"]
|
||||
|
||||
[workspace.package]
|
||||
edition = "2021"
|
||||
@@ -17,16 +17,13 @@ For systems that **already have a Nix implementation installed**, such as NixOS
|
||||
|
||||
## Building And Developing
|
||||
|
||||
See our [Hacking guide](https://git.lix.systems/lix-project/lix/src/branch/main/doc/manual/src/contributing/hacking.md) in our manual for instruction on how to set up a development environment and build Lix from source.
|
||||
See our [Hacking guide](https://git.lix.systems/lix-project/lix/src/branch/main/doc/manual/src/contributing/hacking.md) in our manual for instruction on how to to set up a development environment and build Lix from source.
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- The Lix reference manual:
|
||||
- [Stable](https://docs.lix.systems/manual/lix/stable/)
|
||||
- [Nightly](https://docs.lix.systems/manual/lix/nightly/) (NOTE: [not automatically updated, yet](https://git.lix.systems/lix-project/lix/issues/742))
|
||||
- [Our wiki](https://wiki.lix.systems)
|
||||
- [Matrix - #space:lix.systems](https://matrix.to/#/#space:lix.systems)
|
||||
|
||||
## License
|
||||
|
||||
Lix is released under [LGPL-2.1-or-later](./COPYING).
|
||||
Lix is released under the [LGPL v2.1](./COPYING).
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
bench-*.json
|
||||
bench-*.md
|
||||
perf-*.json
|
||||
nixpkgs
|
||||
|
||||
-116
@@ -1,116 +0,0 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i python3 -p python3 -p hyperfine -p "if stdenv.isLinux then linuxPackages.perf else null"
|
||||
|
||||
import argparse
|
||||
import subprocess
|
||||
import os
|
||||
import json
|
||||
import tempfile
|
||||
import platform
|
||||
|
||||
flake_args = ["--extra-experimental-features","'nix-command flakes'"]
|
||||
# hyperfine has its own variable substitution, so we use that and pass build="{BUILD}" here.
|
||||
# perf doesn't have variable substitution, so we call these with build being the actual build directory.
|
||||
cases = {
|
||||
"search": lambda build: [f"{build}/bin/nix", *flake_args, "search", "--no-eval-cache", "github:nixos/nixpkgs/e1fa12d4f6c6fe19ccb59cac54b5b3f25e160870", "hello"],
|
||||
"rebuild": lambda build: [f"{build}/bin/nix", *flake_args, "eval", "--raw", "--impure", "--expr", "'with import <nixpkgs/nixos> {}; system'"],
|
||||
"rebuild_lh": lambda build: ["GC_INITIAL_HEAP_SIZE=10g", f"{build}/bin/nix", *flake_args, "eval", "--raw", "--impure", "--expr", "'with import <nixpkgs/nixos> {}; system'"],
|
||||
"parse": lambda build: [f"{build}/bin/nix", *flake_args, "eval", "-f", "bench/nixpkgs/pkgs/development/haskell-modules/hackage-packages.nix"],
|
||||
}
|
||||
|
||||
arg_parser = argparse.ArgumentParser()
|
||||
# FIXME(jade, gilice): it is a reasonable use case to want to run a benchmark run
|
||||
# on just one build. However, since we are using hyperfine in comparison
|
||||
# mode, we would have to combine the JSON ourselves to support that, which
|
||||
# would probably be better done by writing a benchmarking script in
|
||||
# not-bash.
|
||||
arg_parser.add_argument('builds', nargs='+', help="At least two build directories to compare, containing bin/nix")
|
||||
arg_parser.add_argument('--cases', type=str, help="A comma-separated list of cases you want to run. Defaults to running all")
|
||||
available_modes = [ "walltime" ] + [ "icount" ] if platform.system() == 'Linux' else [] # perf doesn't run on Darwin
|
||||
arg_parser.add_argument('--mode', choices=available_modes, default="walltime")
|
||||
args = arg_parser.parse_args()
|
||||
if len(args.builds) < 2:
|
||||
raise ValueError("need at least two build directories to compare")
|
||||
|
||||
benchmarks: list[str] = []
|
||||
if args.cases is None:
|
||||
benchmarks = list(cases.keys())
|
||||
else:
|
||||
for case in args.cases.split(","):
|
||||
if case not in cases: raise ValueError(f"no such case: {case}")
|
||||
benchmarks.append(case)
|
||||
|
||||
def bench_walltime(env):
|
||||
hyperfine_args = ["--parameter-list", "BUILD", ','.join(args.builds), "--warmup", "2", "--runs", "10"]
|
||||
for case in benchmarks:
|
||||
case_command = cases[case]("{BUILD}") # see the comment on cases
|
||||
subprocess.run([
|
||||
"taskset", "-c", "2,3",
|
||||
"chrt", "-f","50",
|
||||
"hyperfine", *hyperfine_args, "--export-json", f"bench/bench-{case}.json", "--export-markdown", f"bench/bench-{case}.md", "--", " ".join(case_command)
|
||||
], env=env, check=True)
|
||||
|
||||
print("Benchmarks summary\n---\n")
|
||||
for case in benchmarks:
|
||||
fd = open(f"bench/bench-{case}.json")
|
||||
result_json = json.load(fd)
|
||||
fd.close()
|
||||
for result in result_json["results"]:
|
||||
print(result["command"])
|
||||
print("-" * min(80,len(result["command"])))
|
||||
attr_rounded = lambda attr: f"{result[attr]:.3f}"
|
||||
print(" mean: ", attr_rounded("mean"), "±", attr_rounded("stddev"))
|
||||
print(" user:", attr_rounded("user"), "| system", attr_rounded("system"))
|
||||
print(" median: ", attr_rounded("median"))
|
||||
print(" range: ", attr_rounded("min") + "s.." + attr_rounded("max")+"s")
|
||||
print(" relative:", f"{result["mean"]/result_json["results"][0]["mean"]:.3f}")
|
||||
print("\n")
|
||||
|
||||
|
||||
def bench_icount(env):
|
||||
perf_results_for: dict[str, list[tuple[str, float]]] = {}
|
||||
for case in benchmarks:
|
||||
for build in args.builds:
|
||||
case_command = cases[case](build)
|
||||
# the perf stat -j output (incorrectly) localizes numbers, which will trip up the json parser.
|
||||
env["LC_ALL"]="C"
|
||||
commandline = [
|
||||
"perf", "stat", "-o", f"bench/perf-{case}.json", "-j", "sh", "-c", " ".join(case_command)
|
||||
]
|
||||
subprocess.run(commandline, env=env, check=True, stdout=subprocess.DEVNULL) # warmup run
|
||||
subprocess.run(commandline, env=env, check=True, stdout=subprocess.DEVNULL)
|
||||
perf_fd = open(f"bench/perf-{case}.json")
|
||||
perf_data = [json.loads(x) for x in perf_fd.readlines()]
|
||||
perf_fd.close()
|
||||
|
||||
instr = next(x for x in perf_data if x["event"] in ["instructions", "instructions:u"]) # an implementation of a find_first iterator
|
||||
if case not in perf_results_for: perf_results_for[case] = []
|
||||
perf_results_for[case].append((" ".join(case_command), float(instr["counter-value"])))
|
||||
|
||||
print("Benchmarks summary\n---\n")
|
||||
for (case, entries) in perf_results_for.items():
|
||||
for entry in entries:
|
||||
cmd,instr = entry
|
||||
print(cmd)
|
||||
print("-" * min(80,len(cmd)))
|
||||
print(" instructions: ", int(instr))
|
||||
print(" relative instructions:", int(instr)/perf_results_for[case][0][1])
|
||||
print("\n")
|
||||
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
subprocess.run([
|
||||
"nix", "build",
|
||||
"--extra-experimental-features", "nix-command flakes",
|
||||
"--impure", "--expr",'(builtins.getFlake "git+file:.").inputs.nixpkgs.outPath',
|
||||
"-o","bench/nixpkgs"
|
||||
], check=True)
|
||||
subenv = os.environ.copy()
|
||||
subenv["NIX_CONF_DIR"] = "/var/empty"
|
||||
subenv["NIX_REMOTE"] = tmp_dir
|
||||
subenv["NIX_PATH"] = "nixpkgs=bench/nixpkgs:nixos-config=bench/configuration.nix"
|
||||
|
||||
if args.mode == "walltime":
|
||||
bench_walltime(subenv)
|
||||
else:
|
||||
bench_icount(subenv)
|
||||
Executable
+62
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
shopt -s inherit_errexit
|
||||
|
||||
scriptdir=$(cd "$(dirname -- "$0")" ; pwd -P)
|
||||
cd "$scriptdir/.."
|
||||
|
||||
if [[ $# -lt 2 ]]; then
|
||||
# FIXME(jade): it is a reasonable use case to want to run a benchmark run
|
||||
# on just one build. However, since we are using hyperfine in comparison
|
||||
# mode, we would have to combine the JSON ourselves to support that, which
|
||||
# would probably be better done by writing a benchmarking script in
|
||||
# not-bash.
|
||||
echo "Fewer than two result dirs given, nothing to compare!" >&2
|
||||
echo "Pass some directories (with names indicating which alternative they are) with bin/nix in them" >&2
|
||||
echo "Usage: ./bench/bench.sh result-1 result-2 [result-3...]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
_exit=""
|
||||
trap "$_exit" EXIT
|
||||
|
||||
# XXX: yes this is very silly. flakes~!!
|
||||
nix build --impure --expr '(builtins.getFlake "git+file:.").inputs.nixpkgs.outPath' -o bench/nixpkgs
|
||||
|
||||
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="--extra-experimental-features 'nix-command flakes'"
|
||||
|
||||
hyperfineArgs=(
|
||||
--parameter-list BUILD "$(IFS=,; echo "${builds[*]}")"
|
||||
--warmup 2 --runs 10
|
||||
)
|
||||
|
||||
declare -A cases
|
||||
cases=(
|
||||
[search]="{BUILD}/bin/nix $flake_args search --no-eval-cache github:nixos/nixpkgs/e1fa12d4f6c6fe19ccb59cac54b5b3f25e160870 hello"
|
||||
[rebuild]="{BUILD}/bin/nix $flake_args eval --raw --impure --expr 'with import <nixpkgs/nixos> {}; system'"
|
||||
[rebuild-lh]="GC_INITIAL_HEAP_SIZE=10g {BUILD}/bin/nix eval $flake_args --raw --impure --expr 'with import <nixpkgs/nixos> {}; system'"
|
||||
[parse]="{BUILD}/bin/nix $flake_args eval -f bench/nixpkgs/pkgs/development/haskell-modules/hackage-packages.nix"
|
||||
)
|
||||
|
||||
benches=(
|
||||
rebuild
|
||||
rebuild-lh
|
||||
search
|
||||
parse
|
||||
)
|
||||
|
||||
for k in "${benches[@]}"; do
|
||||
taskset -c 2,3 \
|
||||
chrt -f 50 \
|
||||
hyperfine "${hyperfineArgs[@]}" --export-json="bench/bench-${k}.json" --export-markdown="bench/bench-${k}.md" "${cases[$k]}"
|
||||
done
|
||||
|
||||
echo "Benchmarks summary (from ./bench/summarize.jq bench/bench-*.json)"
|
||||
bench/summarize.jq bench/*.json
|
||||
+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
|
||||
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env -S jq -Mrf
|
||||
|
||||
def round3:
|
||||
. * 1000 | round | . / 1000
|
||||
;
|
||||
|
||||
def stats($first):
|
||||
[
|
||||
" mean: \(.mean | round3)s ± \(.stddev | round3)s",
|
||||
" user: \(.user | round3)s | system: \(.system | round3)s",
|
||||
" median: \(.median | round3)s",
|
||||
" range: \(.min | round3)s ... \(.max | round3)s",
|
||||
" relative: \(.mean / $first.mean | round3)"
|
||||
]
|
||||
| join("\n")
|
||||
;
|
||||
|
||||
def fmt($first):
|
||||
"\(.command)\n" + (. | stats($first))
|
||||
;
|
||||
|
||||
[.results | .[0] as $first | .[] | fmt($first)] | join("\n\n") | (. + "\n\n---\n")
|
||||
@@ -0,0 +1,54 @@
|
||||
diff --git a/pthread_stop_world.c b/pthread_stop_world.c
|
||||
index 2b45489..0e6d8ef 100644
|
||||
--- a/pthread_stop_world.c
|
||||
+++ b/pthread_stop_world.c
|
||||
@@ -776,6 +776,8 @@ STATIC void GC_restart_handler(int sig)
|
||||
/* world is stopped. Should not fail if it isn't. */
|
||||
GC_INNER void GC_push_all_stacks(void)
|
||||
{
|
||||
+ size_t stack_limit;
|
||||
+ pthread_attr_t pattr;
|
||||
GC_bool found_me = FALSE;
|
||||
size_t nthreads = 0;
|
||||
int i;
|
||||
@@ -868,6 +870,40 @@ GC_INNER void GC_push_all_stacks(void)
|
||||
hi = p->altstack + p->altstack_size;
|
||||
# endif
|
||||
/* FIXME: Need to scan the normal stack too, but how ? */
|
||||
+ } else {
|
||||
+ #ifdef HAVE_PTHREAD_ATTR_GET_NP
|
||||
+ if (pthread_attr_init(&pattr) != 0) {
|
||||
+ ABORT("GC_push_all_stacks: pthread_attr_init failed!");
|
||||
+ }
|
||||
+ if (pthread_attr_get_np(p->id, &pattr) != 0) {
|
||||
+ ABORT("GC_push_all_stacks: pthread_attr_get_np failed!");
|
||||
+ }
|
||||
+ #else
|
||||
+ if (pthread_getattr_np(p->id, &pattr)) {
|
||||
+ ABORT("GC_push_all_stacks: pthread_getattr_np failed!");
|
||||
+ }
|
||||
+ #endif
|
||||
+ if (pthread_attr_getstacksize(&pattr, &stack_limit)) {
|
||||
+ ABORT("GC_push_all_stacks: pthread_attr_getstacksize failed!");
|
||||
+ }
|
||||
+ if (pthread_attr_destroy(&pattr)) {
|
||||
+ ABORT("GC_push_all_stacks: pthread_attr_destroy failed!");
|
||||
+ }
|
||||
+ // When a thread goes into a coroutine, we lose its original sp until
|
||||
+ // control flow returns to the thread.
|
||||
+ // While in the coroutine, the sp points outside the thread stack,
|
||||
+ // so we can detect this and push the entire thread stack instead,
|
||||
+ // as an approximation.
|
||||
+ // We assume that the coroutine has similarly added its entire stack.
|
||||
+ // This could be made accurate by cooperating with the application
|
||||
+ // via new functions and/or callbacks.
|
||||
+ #ifndef STACK_GROWS_UP
|
||||
+ if (lo >= hi || lo < hi - stack_limit) { // sp outside stack
|
||||
+ lo = hi - stack_limit;
|
||||
+ }
|
||||
+ #else
|
||||
+ #error "STACK_GROWS_UP not supported in boost_coroutine2 (as of june 2021), so we don't support it in Nix."
|
||||
+ #endif
|
||||
}
|
||||
# ifdef STACKPTR_CORRECTOR_AVAILABLE
|
||||
if (GC_sp_corrector != 0)
|
||||
@@ -0,0 +1,90 @@
|
||||
#include "FixIncludes.hh"
|
||||
#include <clang-tidy/ClangTidyCheck.h>
|
||||
#include <clang/Basic/Diagnostic.h>
|
||||
#include <clang/Basic/SourceManager.h>
|
||||
#include <clang/Lex/PPCallbacks.h>
|
||||
#include <clang/Lex/Preprocessor.h>
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
#include <llvm/Support/Debug.h>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace nix::clang_tidy {
|
||||
|
||||
using namespace clang;
|
||||
using namespace clang::tidy;
|
||||
|
||||
class FixIncludesCallbacks : public PPCallbacks {
|
||||
public:
|
||||
ClangTidyCheck &Check;
|
||||
Preprocessor &PP;
|
||||
FixIncludesCallbacks(ClangTidyCheck &Check, Preprocessor &PP)
|
||||
: Check(Check), PP(PP) {}
|
||||
|
||||
private:
|
||||
bool Ignore = false;
|
||||
virtual void LexedFileChanged(FileID FID, LexedFileChangeReason Reason,
|
||||
SrcMgr::CharacteristicKind FileType,
|
||||
FileID PrevFID, SourceLocation Loc) override;
|
||||
|
||||
virtual void InclusionDirective(SourceLocation HashLoc,
|
||||
const Token &IncludeTok, StringRef FileName,
|
||||
bool IsAngled, CharSourceRange FilenameRange,
|
||||
OptionalFileEntryRef File,
|
||||
StringRef SearchPath, StringRef RelativePath,
|
||||
const Module *Imported,
|
||||
SrcMgr::CharacteristicKind FileType) override;
|
||||
};
|
||||
|
||||
void FixIncludesCallbacks::LexedFileChanged(FileID, LexedFileChangeReason,
|
||||
SrcMgr::CharacteristicKind FileType,
|
||||
FileID, SourceLocation) {
|
||||
Ignore = FileType != SrcMgr::C_User;
|
||||
}
|
||||
|
||||
void FixIncludesCallbacks::InclusionDirective(
|
||||
SourceLocation, const Token &, StringRef FileName, bool IsAngled,
|
||||
CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef,
|
||||
StringRef, const Module *, SrcMgr::CharacteristicKind) {
|
||||
if (Ignore)
|
||||
return;
|
||||
|
||||
// FIXME: this is kinda evil, but this is a one-time fixup
|
||||
const std::vector<std::string> SourceDirs = {"src/", "include/lix/"};
|
||||
|
||||
const auto Bracketize = [IsAngled](StringRef s) {
|
||||
return IsAngled ? ("<" + s + ">").str() : ("\"" + s + "\"").str();
|
||||
};
|
||||
|
||||
for (const auto &SourceDir : SourceDirs) {
|
||||
const bool IsAlreadyFixed = FileName.starts_with("lix/lib");
|
||||
if (File && File->getNameAsRequested().contains(SourceDir) &&
|
||||
!IsAlreadyFixed) {
|
||||
StringRef Name = File->getNameAsRequested();
|
||||
auto Idx = Name.find(SourceDir);
|
||||
assert(Idx != std::string::npos);
|
||||
std::string Suffix = Name.drop_front(Idx + SourceDir.length()).str();
|
||||
|
||||
if (!Suffix.starts_with("lib")) {
|
||||
llvm::dbgs() << "ignored: " << Suffix << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
Suffix = "lix/" + Suffix;
|
||||
|
||||
auto Diag = Check.diag(FilenameRange.getBegin(),
|
||||
"include needs to specify the source subdir");
|
||||
|
||||
Diag << FilenameRange
|
||||
<< FixItHint::CreateReplacement(FilenameRange, Bracketize(Suffix));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FixIncludesCheck::registerPPCallbacks(const SourceManager &,
|
||||
Preprocessor *PP, Preprocessor *) {
|
||||
PP->addPPCallbacks(std::make_unique<FixIncludesCallbacks>(*this, *PP));
|
||||
}
|
||||
|
||||
}; // namespace nix::clang_tidy
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include <clang-tidy/ClangTidyCheck.h>
|
||||
#include <clang/ASTMatchers/ASTMatchFinder.h>
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
|
||||
namespace nix::clang_tidy {
|
||||
|
||||
using namespace clang;
|
||||
using namespace clang::tidy;
|
||||
|
||||
class FixIncludesCheck : public ClangTidyCheck {
|
||||
public:
|
||||
FixIncludesCheck(StringRef Name, ClangTidyContext *Context)
|
||||
: ClangTidyCheck(Name, Context) {}
|
||||
|
||||
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override;
|
||||
};
|
||||
|
||||
};
|
||||
@@ -1,10 +1,7 @@
|
||||
#include <clang-tidy/ClangTidyModule.h>
|
||||
#include <clang-tidy/ClangTidyModuleRegistry.h>
|
||||
#include "DisallowedDecls.hh"
|
||||
#include "ForeignExceptions.hh"
|
||||
#include "FixIncludes.hh"
|
||||
#include "HasPrefixSuffix.hh"
|
||||
#include "CharPtrCast.hh"
|
||||
#include "NeverAsync.hh"
|
||||
|
||||
namespace nix::clang_tidy {
|
||||
using namespace clang;
|
||||
@@ -14,10 +11,7 @@ class NixClangTidyChecks : public ClangTidyModule {
|
||||
public:
|
||||
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
|
||||
CheckFactories.registerCheck<HasPrefixSuffixCheck>("lix-hasprefixsuffix");
|
||||
CheckFactories.registerCheck<CharPtrCastCheck>("lix-charptrcast");
|
||||
CheckFactories.registerCheck<NeverAsync>("lix-never-async");
|
||||
CheckFactories.registerCheck<DisallowedDeclsCheck>("lix-disallowed-decls");
|
||||
CheckFactories.registerCheck<ForeignExceptions>("lix-foreign-exceptions");
|
||||
CheckFactories.registerCheck<FixIncludesCheck>("lix-fixincludes");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,13 +10,13 @@ goal and is there as an example), `HasPrefixSuffixCheck`.
|
||||
One file:
|
||||
|
||||
```
|
||||
ninja -C build && clang-tidy --checks='-*,lix-*' --load=build/liblix-clang-tidy.so -p ../../build -header-filter '\.\./lix/.*\.h' --fix ../../lix/libcmd/installables.cc
|
||||
ninja -C build && clang-tidy --checks='-*,lix-*' --load=build/liblix-clang-tidy.so -p ../compile_commands.json -header-filter '\.\./src/.*\.h' --fix ../src/libcmd/installables.cc
|
||||
```
|
||||
|
||||
Several files, in parallel:
|
||||
|
||||
```
|
||||
ninja -C build && run-clang-tidy -checks='-*,lix-*' -load=build/liblix-clang-tidy.so -p ../../build -header-filter '\.\./lix/.*\.h' -fix ../../lix | tee -a clang-tidy-result
|
||||
ninja -C build && run-clang-tidy -checks='-*,lix-*' -load=build/liblix-clang-tidy.so -p .. -header-filter '\.\./src/.*\.h' -fix ../src | tee -a clang-tidy-result
|
||||
```
|
||||
|
||||
## Resources
|
||||
@@ -40,7 +40,7 @@ enable output dump
|
||||
match callExpr(callee(functionDecl(hasName("hasPrefix"))), optionally(hasArgument( 0, cxxConstructExpr(hasDeclaration(functionDecl(hasParameter(0, parmVarDecl(hasType(asString("const char *"))).bind("meow2"))))))))
|
||||
```
|
||||
|
||||
Then run, e.g. `clang-query --preload hasprefix.query -p compile_commands.json lix/libcmd/installables.cc`.
|
||||
Then run, e.g. `clang-query --preload hasprefix.query -p compile_commands.json src/libcmd/installables.cc`.
|
||||
|
||||
With this you can iterate a query before writing it in C++ and suffering from
|
||||
C++.
|
||||
@@ -0,0 +1,13 @@
|
||||
project('lix-clang-tidy', ['cpp', 'c'],
|
||||
version : '0.1',
|
||||
default_options : ['warning_level=3', 'cpp_std=c++20'])
|
||||
|
||||
llvm = dependency('Clang', version: '>= 14', modules: ['libclang'])
|
||||
sources = files(
|
||||
'HasPrefixSuffix.cc',
|
||||
'LixClangTidyChecks.cc',
|
||||
'FixIncludes.cc',
|
||||
)
|
||||
|
||||
shared_module('lix-clang-tidy', sources,
|
||||
dependencies: llvm)
|
||||
@@ -20,7 +20,7 @@ OUTPUT_DIRECTORY = @docdir@
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
# quick idea about the purpose of the project. Keep the description short.
|
||||
|
||||
PROJECT_BRIEF = "Lix: A modern, delicious implementation of the Nix package manager; unstable internal interfaces"
|
||||
PROJECT_BRIEF = "Nix, the purely functional package manager; unstable internal interfaces"
|
||||
|
||||
# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
|
||||
# The default value is: YES.
|
||||
@@ -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,
|
||||
|
||||
@@ -7,8 +7,9 @@ create-missing = false
|
||||
[output.html]
|
||||
additional-css = ["custom.css"]
|
||||
additional-js = ["redirects.js"]
|
||||
# Jumps directly into a new Gerrit CL editing the file in question.
|
||||
edit-url-template = "https://gerrit.lix.systems/admin/repos/edit/repo/lix/branch/main/file/doc/manual/{path}"
|
||||
# Using our GitHub mirror enables easier typo fixes since there is no easy way
|
||||
# to just submit a Gerrit CL by the web for trivial stuff.
|
||||
edit-url-template = "https://github.com/lix-project/lix/tree/main/doc/manual/{path}"
|
||||
git-repository-url = "https://git.lix.systems/lix-project/lix"
|
||||
# Folding by default would prevent things like "Ctrl+F for nix-env" from working
|
||||
# trivially, but the user should be able to fold if they want to.
|
||||
|
||||
@@ -12,10 +12,6 @@
|
||||
forgejo: rbt
|
||||
github: 9999years
|
||||
|
||||
9p4:
|
||||
display_name: Ersei Saggi
|
||||
github: 9p4
|
||||
|
||||
Artturin:
|
||||
github: Artturin
|
||||
|
||||
@@ -40,23 +36,10 @@ alois31:
|
||||
forgejo: alois31
|
||||
github: alois31
|
||||
|
||||
andrewhamon:
|
||||
display_name: Andrew Hamon
|
||||
github: andrewhamon
|
||||
|
||||
artemist:
|
||||
display_name: Artemis Tosini
|
||||
forgejo: artemist
|
||||
|
||||
bb010g:
|
||||
display_name: Dusk Banks
|
||||
forgejo: bb010g
|
||||
github: bb010g
|
||||
|
||||
blitz:
|
||||
display_name: Julian Stecklina
|
||||
github: blitz
|
||||
|
||||
cole-h:
|
||||
display_name: Cole Helbling
|
||||
github: cole-h
|
||||
@@ -66,10 +49,6 @@ delan:
|
||||
forgejo: delan
|
||||
github: delan
|
||||
|
||||
detroyejr:
|
||||
display_name: Jonathan De Troye
|
||||
github: detroyejr
|
||||
|
||||
edolstra:
|
||||
display_name: Eelco Dolstra
|
||||
github: edolstra
|
||||
@@ -78,14 +57,6 @@ ericson:
|
||||
display_name: John Ericson
|
||||
github: ericson2314
|
||||
|
||||
gilice:
|
||||
forgejo: gilice
|
||||
|
||||
goldstein:
|
||||
display_name: goldstein
|
||||
forgejo: goldstein
|
||||
github: GoldsteinE
|
||||
|
||||
horrors:
|
||||
display_name: eldritch horrors
|
||||
forgejo: pennae
|
||||
@@ -94,49 +65,14 @@ horrors:
|
||||
iFreilicht:
|
||||
github: iFreilicht
|
||||
|
||||
ian-h-chamberlain:
|
||||
forgejo: ian-h-chamberlain
|
||||
github: ian-h-chamberlain
|
||||
|
||||
isabelroses:
|
||||
forgejo: isabelroses
|
||||
github: isabelroses
|
||||
|
||||
jade:
|
||||
forgejo: jade
|
||||
github: lf-
|
||||
|
||||
just1602:
|
||||
forgejo: just1602
|
||||
|
||||
kfears:
|
||||
display_name: KFears
|
||||
forgejo: kfearsoff
|
||||
github: kfearsoff
|
||||
|
||||
kiara:
|
||||
github: KiaraGrouwstra
|
||||
|
||||
kjeremy:
|
||||
github: kjeremy
|
||||
|
||||
kloenk:
|
||||
display_name: Fiona Behrens
|
||||
forgejo: kloenk
|
||||
github: kloenk
|
||||
|
||||
lheckemann:
|
||||
forgejo: lheckemann
|
||||
github: lheckemann
|
||||
|
||||
lily:
|
||||
forgejo: lilyinstarlight
|
||||
github: lilyinstarlight
|
||||
|
||||
lilyball:
|
||||
forgejo: lilyball
|
||||
github: lilyball
|
||||
|
||||
lovesegfault:
|
||||
github: lovesegfault
|
||||
|
||||
@@ -155,32 +91,11 @@ midnightveil:
|
||||
ncfavier:
|
||||
github: ncfavier
|
||||
|
||||
p-e-meunier:
|
||||
display_name: Pierre-Etienne Meunier
|
||||
github: P-E-Meunier
|
||||
|
||||
pamplemousse:
|
||||
display_name: Xavier Maso
|
||||
github: pamplemousse
|
||||
|
||||
piegames:
|
||||
display_name: piegames
|
||||
forgejo: piegames
|
||||
github: piegamesde
|
||||
|
||||
poliorcetics:
|
||||
display_name: Poliorcetics
|
||||
github: poliorcetics
|
||||
|
||||
puck:
|
||||
display_name: puck
|
||||
forgejo: puck
|
||||
github: puckipedia
|
||||
|
||||
quantenzitrone:
|
||||
display_name: Zitrone
|
||||
forgejo: quantenzitrone
|
||||
|
||||
quantumjump:
|
||||
display_name: Quantum Jump
|
||||
github: QuantumBJump
|
||||
@@ -197,18 +112,6 @@ roberth:
|
||||
display_name: Robert Hensing
|
||||
github: roberth
|
||||
|
||||
seppel3210:
|
||||
github: Seppel3210
|
||||
|
||||
teofilc:
|
||||
forgejo: teofilc
|
||||
github: TeofilC
|
||||
|
||||
thubrecht:
|
||||
display_name: Tom Hubrecht
|
||||
forgejo: tom-hubrecht
|
||||
github: Tom-Hubrecht
|
||||
|
||||
thufschmitt:
|
||||
display_name: Théophane Hufschmitt
|
||||
github: thufschmitt
|
||||
@@ -221,23 +124,9 @@ valentin:
|
||||
display_name: Valentin Gagarin
|
||||
github: fricklerhandwerk
|
||||
|
||||
vigress8:
|
||||
display_name: Vigress
|
||||
forgejo: vigress8
|
||||
github: vigress8
|
||||
|
||||
winter:
|
||||
forgejo: winter
|
||||
github: winterqt
|
||||
|
||||
xanderio:
|
||||
github: xanderio
|
||||
|
||||
yorickvp:
|
||||
github: yorickvp
|
||||
|
||||
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
-11
@@ -1,7 +1,6 @@
|
||||
nix_env_for_docs = {
|
||||
'HOME': '/dummy',
|
||||
'NIX_CONF_DIR': '/dummy',
|
||||
'XDG_CONFIG_HOME': '/dummy',
|
||||
'NIX_SSL_CERT_FILE': '/dummy/no-ca-bundle.crt',
|
||||
'NIX_STATE_DIR': '/dummy',
|
||||
'NIX_CONFIG': 'cores = 0',
|
||||
@@ -16,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')
|
||||
|
||||
@@ -61,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,
|
||||
@@ -73,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',
|
||||
[
|
||||
|
||||
@@ -345,7 +345,7 @@ const redirects = {
|
||||
"linux": "uninstall.html#linux",
|
||||
"macos": "uninstall.html#macos",
|
||||
"uninstalling": "uninstall.html",
|
||||
},
|
||||
}
|
||||
"contributing/hacking.html": {
|
||||
"nix-with-flakes": "#building-nix-with-flakes",
|
||||
"classic-nix": "#building-nix",
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
---
|
||||
synopsis: "Trace which part of a `foo.bar.baz` expression errors"
|
||||
cls: 1505, 1506
|
||||
credits: Qyriad
|
||||
category: Improvements
|
||||
---
|
||||
|
||||
Previously, if an attribute path selection expression like `linux_4_9.meta.description` it wouldn't show you which one of those parts in the attribute path, or even that that line of code is what caused evaluation of the failing expression.
|
||||
The previous error looks like this:
|
||||
|
||||
```
|
||||
pkgs.linuxKernel.kernels.linux_4_9.meta.description
|
||||
|
||||
error:
|
||||
… while evaluating the attribute 'linuxKernel.kernels.linux_4_9.meta.description'
|
||||
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:5:
|
||||
277| } // lib.optionalAttrs config.allowAliases {
|
||||
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||
| ^
|
||||
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||
|
||||
… while calling the 'throw' builtin
|
||||
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:17:
|
||||
277| } // lib.optionalAttrs config.allowAliases {
|
||||
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||
| ^
|
||||
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||
|
||||
error: linux 4.9 was removed because it will reach its end of life within 22.11
|
||||
```
|
||||
|
||||
Now, the error will look like this:
|
||||
|
||||
```
|
||||
pkgs.linuxKernel.kernels.linux_4_9.meta.description
|
||||
|
||||
error:
|
||||
… while evaluating the attribute 'linuxKernel.kernels.linux_4_9.meta.description'
|
||||
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:5:
|
||||
277| } // lib.optionalAttrs config.allowAliases {
|
||||
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||
| ^
|
||||
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||
|
||||
… while evaluating 'pkgs.linuxKernel.kernels.linux_4_9' to select 'meta' on it
|
||||
at «string»:1:1:
|
||||
1| pkgs.linuxKernel.kernels.linux_4_9.meta.description
|
||||
| ^
|
||||
|
||||
… caused by explicit throw
|
||||
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:17:
|
||||
277| } // lib.optionalAttrs config.allowAliases {
|
||||
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||
| ^
|
||||
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||
|
||||
error: linux 4.9 was removed because it will reach its end of life within 22.11
|
||||
```
|
||||
|
||||
Not only does the line of code that referenced the failing attribute show up in the trace, it also tells you that it was specifically the `linux_4_9` part that failed.
|
||||
|
||||
This includes if the failing part is a top-level binding:
|
||||
|
||||
```
|
||||
let
|
||||
inherit (pkgs.linuxKernel.kernels) linux_4_9;
|
||||
in linux_4_9.meta.description
|
||||
error:
|
||||
… while evaluating 'linux_4_9' to select 'meta.description' on it
|
||||
at «string»:3:4:
|
||||
2| inherit (pkgs.linuxKernel.kernels) linux_4_9;
|
||||
3| in linux_4_9.meta.description
|
||||
| ^
|
||||
|
||||
… while evaluating the attribute 'linux_4_9'
|
||||
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:5:
|
||||
277| } // lib.optionalAttrs config.allowAliases {
|
||||
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||
| ^
|
||||
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||
|
||||
… caused by explicit throw
|
||||
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:17:
|
||||
277| } // lib.optionalAttrs config.allowAliases {
|
||||
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||
| ^
|
||||
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||
|
||||
error: linux 4.9 was removed because it will reach its end of life within 22.11
|
||||
```
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
synopsis: "Add a `build-dir` setting to set the backing directory for builds"
|
||||
cls: 1514
|
||||
credits: [roberth, tomberek]
|
||||
category: Improvements
|
||||
---
|
||||
|
||||
`build-dir` can now be set in the Nix configuration to choose the backing directory for the build sandbox.
|
||||
This can be useful on systems with `/tmp` on tmpfs, or simply to relocate large builds to another disk.
|
||||
|
||||
Also, `XDG_RUNTIME_DIR` is no longer considered when selecting the default temporary directory,
|
||||
as it's not intended to be used for large amounts of data.
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
synopsis: "Distinguish between explicit throws and errors that happened while evaluating a throw"
|
||||
cls: 1511
|
||||
credits: Qyriad
|
||||
category: Improvements
|
||||
---
|
||||
|
||||
Previously, errors caused by an expression like `throw "invalid argument"` were treated like an error that happened simply while some builtin function was being called:
|
||||
|
||||
```
|
||||
let
|
||||
throwMsg = p: throw "${p} isn't the right package";
|
||||
in throwMsg "linuz"
|
||||
|
||||
error:
|
||||
… while calling the 'throw' builtin
|
||||
at «string»:2:17:
|
||||
1| let
|
||||
2| throwMsg = p: throw "${p} isn't the right package";
|
||||
| ^
|
||||
3| in throwMsg "linuz"
|
||||
|
||||
error: linuz isn't the right package
|
||||
```
|
||||
|
||||
But the error didn't just happen "while" calling the `throw` builtin — it's a throw error!
|
||||
Now it looks like this:
|
||||
|
||||
```
|
||||
let
|
||||
throwMsg = p: throw "${p} isn't the right package";
|
||||
in throwMsg "linuz"
|
||||
|
||||
error:
|
||||
… caused by explicit throw
|
||||
at «string»:2:17:
|
||||
1| let
|
||||
2| throwMsg = p: throw "${p} isn't the right package";
|
||||
| ^
|
||||
3| in throwMsg "linuz"
|
||||
|
||||
error: linuz isn't the right package
|
||||
```
|
||||
|
||||
This also means that incorrect usage of `throw` or errors evaluating its arguments are easily distinguishable from explicit throws:
|
||||
|
||||
```
|
||||
let
|
||||
throwMsg = p: throw "${p} isn't the right package";
|
||||
in throwMsg { attrs = "error when coerced in string interpolation"; }
|
||||
|
||||
error:
|
||||
… while calling the 'throw' builtin
|
||||
at «string»:2:17:
|
||||
1| let
|
||||
2| throwMsg = p: throw "${p} isn't the right package";
|
||||
| ^
|
||||
3| in throwMsg { attrs = "error when coerced in string interpolation"; }
|
||||
|
||||
… while evaluating a path segment
|
||||
at «string»:2:24:
|
||||
1| let
|
||||
2| throwMsg = p: throw "${p} isn't the right package";
|
||||
| ^
|
||||
3| in throwMsg { attrs = "error when coerced in string interpolation"; }
|
||||
|
||||
error: cannot coerce a set to a string: { attrs = "error when coerced in string interpolation"; }
|
||||
```
|
||||
|
||||
Here, instead of an actual thrown error, a type error happens first (trying to coerce an attribute set to a string), but that type error happened *while* calling `throw`.
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
synopsis: Fix nix-collect-garbage --dry-run
|
||||
issues: [fj#432]
|
||||
cls: [1566]
|
||||
category: Fixes
|
||||
credits: [quantumjump]
|
||||
---
|
||||
|
||||
`nix-collect-garbage --dry-run` did not previously give any output - it simply
|
||||
exited without even checking to see what paths would be deleted.
|
||||
|
||||
```
|
||||
$ nix-collect-garbage --dry-run
|
||||
$
|
||||
```
|
||||
|
||||
We updated the behaviour of the flag such that instead it prints out how many
|
||||
paths it *would* delete, but doesn't actually delete them.
|
||||
|
||||
```
|
||||
$ nix-collect-garbage --dry-run
|
||||
finding garbage collector roots...
|
||||
determining live/dead paths...
|
||||
...
|
||||
<nix store paths>
|
||||
...
|
||||
2670 store paths deleted, 0.00MiB freed
|
||||
$
|
||||
```
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
synopsis: "Hash mismatch diagnostics for fixed-output derivations include the URL"
|
||||
cls: [1536]
|
||||
credits: [jade]
|
||||
category: Improvements
|
||||
---
|
||||
|
||||
Now, when building fixed-output derivations, Lix will guess the URL that was used in the derivation using the `url` or `urls` properties in the derivation environment.
|
||||
This is a layering violation but making these diagnostics tractable when there are multiple instances of the `AAAA` hash is too significant of an improvement to pass it up.
|
||||
|
||||
```
|
||||
error: hash mismatch in fixed-output derivation '/nix/store/sjfw324j4533lwnpmr5z4icpb85r63ai-x1.drv':
|
||||
likely URL: https://meow.puppy.forge/puppy.tar.gz
|
||||
specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
|
||||
got: sha256-a1Qvp3FOOkWpL9kFHgugU1ok5UtRPSu+NwCZKbbaEro=
|
||||
```
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
synopsis: Add log formats `multiline` and `multiline-with-logs`
|
||||
cls: [1369]
|
||||
credits: [kloenk]
|
||||
category: Improvements
|
||||
---
|
||||
|
||||
Added two new log formats (`multiline` and `multiline-with-logs`) that display
|
||||
current activities below each other for better visibility.
|
||||
|
||||
These formats attempt to use the maximum available lines
|
||||
(defaulting to 25 if unable to determine) and print up to that many lines.
|
||||
The status bar is displayed as the first line, with each subsequent
|
||||
activity on its own line.
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
synopsis: "`nix copy` is now several times faster at `querying info about /nix/store/...`"
|
||||
cls: [1462]
|
||||
issues: [fj#366]
|
||||
credits: [jade]
|
||||
category: Fixes
|
||||
---
|
||||
|
||||
We fixed a locking bug that serialized `querying info about /nix/store/...`
|
||||
onto just one thread such that it was eating `O(paths to copy * latency)` time
|
||||
while setting up to copy paths to s3 and other stores. It is now `nproc` times
|
||||
faster.
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
synopsis: "Lix no longer speaks the Nix remote-build worker protocol to clients or servers older than CppNix 2.3"
|
||||
cls: [1207, 1208, 1206, 1205, 1204, 1203, 1479]
|
||||
issues: [fj#325]
|
||||
credits: [jade]
|
||||
category: Breaking Changes
|
||||
---
|
||||
|
||||
CppNix 2.3 was released in 2019, and is the new oldest supported version. We
|
||||
will increase our support baseline in the future up to a final version of CppNix
|
||||
2.18 (which may happen soon given that it is the only still-packaged and thus
|
||||
still-tested >2.3 version), but this step already removes a significant amount
|
||||
of dead, untested, code paths.
|
||||
|
||||
Lix speaks the same version of the protocol as CppNix 2.18 and that fact will
|
||||
never change in the future; the Lix plans to replace the protocol for evolution
|
||||
will entail a complete incompatible replacement that will be supported in
|
||||
parallel with the old protocol. Lix will thus retain remote build compatibility
|
||||
with CppNix as long as CppNix maintains protocol compatibility with 2.18, and
|
||||
as long as Lix retains legacy protocol support (which will likely be a long
|
||||
time given that we plan to convert it to a frozen-in-time shim).
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
synopsis: "`nix registry add` now requires a shorthand flakeref on the 'from' side"
|
||||
cls: 1494
|
||||
credits: delan
|
||||
category: Improvements
|
||||
---
|
||||
|
||||
The 'from' argument must now be a shorthand flakeref like `nixpkgs` or `nixpkgs/nixos-20.03`, making it harder to accidentally swap the 'from' and 'to' arguments.
|
||||
|
||||
Registry entries that map from other flake URLs can still be specified in registry.json, the `nix.registry` option in NixOS, or the `--override-flake` option in the CLI, but they are not guaranteed to work correctly.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
synopsis: Allow automatic rejection of configuration options from flakes
|
||||
cls: [1541]
|
||||
credits: [alois31]
|
||||
category: Improvements
|
||||
---
|
||||
|
||||
Setting `accept-flake-config` to `false` now respects user choice by automatically rejecting configuration options set by flakes.
|
||||
The old behaviour of asking each time is still available (and default) by setting it to the special value `ask`.
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
synopsis: "`nix repl` now allows tab-completing the special repl :colon commands"
|
||||
cls: 1367
|
||||
credits: Qyriad
|
||||
category: Improvements
|
||||
---
|
||||
|
||||
The REPL (`nix repl`) supports pressing `<TAB>` to complete a partial expression, but now also supports completing the special :colon commands as well (`:b`, `:edit`, `:doc`, etc), if the line starts with a colon.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
synopsis: "Lix now supports building with UndefinedBehaviorSanitizer"
|
||||
cls: [1483]
|
||||
credits: [jade]
|
||||
category: Development
|
||||
---
|
||||
|
||||
You can now build Lix with the configuration option `-Db_sanitize=undefined` and it will both work and pass tests. AddressSanitizer support is also coming soon.
|
||||
|
||||
For a list of undefined behaviour fixed by sanitizer usage, see [the gerrit topic "undefined-behaviour"](https://gerrit.lix.systems/q/topic:%22undefined-behaviour%22).
|
||||
@@ -192,16 +192,12 @@
|
||||
- [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.93 (2025-05-09)](release-notes/rl-2.93.md)
|
||||
- [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)
|
||||
<!-- RELENG-AUTO-INSERTION-MARKER (see releng/release_notes.py) -->
|
||||
- [Lix 2.90 (FIXME date)](release-notes/rl-2.90.md)
|
||||
- [Nix 2.18 (2023-09-20)](release-notes/rl-2.18.md)
|
||||
- [Nix 2.17 (2023-07-24)](release-notes/rl-2.17.md)
|
||||
- [Nix 2.16 (2023-05-31)](release-notes/rl-2.16.md)
|
||||
|
||||
@@ -75,9 +75,7 @@ by spaces. Only the first element is required. To leave a field at its
|
||||
default, set it to `-`.
|
||||
|
||||
1. The URI of the remote store in the format
|
||||
`ssh://[username@]hostname[?port=<port>]`, e.g. `ssh://nix@mac` or `ssh://mac`.
|
||||
If the ssh server is not listening on port 22 (e.g. port 1337 in this case)
|
||||
the URI would be `ssh://nix@mac?port=1337`
|
||||
`ssh://[username@]hostname`, e.g. `ssh://nix@mac` or `ssh://mac`.
|
||||
For backward compatibility, `ssh://` may be omitted. The hostname
|
||||
may be an alias defined in your `~/.ssh/config`.
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@ The following [concept map] shows its main components (rectangles), the objects
|
||||
| |
|
||||
+----------|-------------------|--------------------------------+
|
||||
| Nix impl.| V |
|
||||
| (Lix) | +------------------------+ |
|
||||
| | | command line interface |------. |
|
||||
| | +------------------------+ | |
|
||||
| (Lix) | +-------------------------+ |
|
||||
| | | commmand line interface |------. |
|
||||
| | +-------------------------+ | |
|
||||
| | | | |
|
||||
| evaluated by calls manages |
|
||||
| | | | |
|
||||
|
||||
@@ -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,12 +0,0 @@
|
||||
<!--
|
||||
File-ish argument syntax summary.
|
||||
This file gets included into pages like nix-build.md and nix-instantiate.md, and each individual page that includes
|
||||
this also links to nix-build.md for the full explanation.
|
||||
-->
|
||||
- A normal filesystem path, like `/home/meow/nixfiles/default.nix`
|
||||
- Or a directory, like `/home/meow/nixfiles`, equivalent to above
|
||||
- A single lookup path, like `<nixpkgs>` or `<nixos>`
|
||||
- A URL to a tarball, like `https://github.com/NixOS/nixpkgs/archive/refs/heads/release-23.11.tar.gz`
|
||||
- A [flakeref](@docroot@/command-ref/new-cli/nix3-flake.md#flake-references), introduced by the prefix `flake:`, like `flake:git+https://git.lix.systems/lix-project/lix`
|
||||
- A *nixpkgs* channel tarball name, introduced by the prefix `channel:`, like `channel:nixos-unstable`.
|
||||
- This uses a hard-coded URL pattern and is *not* related to the subscribed channels managed by the [nix-channel](@docroot@/command-ref/nix-channel.md) command.
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
# Synopsis
|
||||
|
||||
`nix-build` [*fileish…*]
|
||||
`nix-build` [*paths…*]
|
||||
[`--arg` *name* *value*]
|
||||
[`--argstr` *name* *value*]
|
||||
[{`--attr` | `-A`} *attrPath*]
|
||||
@@ -20,55 +20,19 @@ For documentation on the latter, run `nix build --help` or see `man nix3-build`.
|
||||
# Description
|
||||
|
||||
The `nix-build` command builds the derivations described by the Nix
|
||||
expressions in each *fileish*. If the build succeeds, it places a symlink to
|
||||
expressions in *paths*. If the build succeeds, it places a symlink to
|
||||
the result in the current directory. The symlink is called `result`. If
|
||||
there are multiple Nix expressions, or the Nix expressions evaluate to
|
||||
multiple derivations, multiple sequentially numbered symlinks are
|
||||
created (`result`, `result-2`, and so on).
|
||||
|
||||
If no *fileish* is specified, then `nix-build` will use `default.nix` in
|
||||
If no *paths* are specified, then `nix-build` will use `default.nix` in
|
||||
the current directory, if it exists.
|
||||
|
||||
## Fileish Syntax
|
||||
|
||||
A given *fileish* may take one of a few different forms, the first being a simple filesystem path, e.g. `nix-build /tmp/some-file.nix`.
|
||||
Like the [import builtin](../language/builtins.md#builtins-import) specifying a directory is equivalent to specifying `default.nix` within that directory.
|
||||
It may also be a [search path](./env-common.md#env-NIX_PATH) (also known as a lookup path) like `<nixpkgs>`, which is convenient to use with `--attr`/`-A`:
|
||||
|
||||
```console
|
||||
$ nix-build '<nixpkgs>' -A firefox
|
||||
```
|
||||
|
||||
(Note the quotation marks around `<nixpkgs>`, which will be necessary in most Unix shells.)
|
||||
|
||||
If a *fileish* starts with `http://` or `https://`, it is interpreted as the URL of a tarball which will be fetched and unpacked.
|
||||
Lix will then `import` the unpacked directory, so these tarballs must include at least a single top-level directory with a file called `default.nix`
|
||||
For example, you could build from a specific version of Nixpkgs with something like:
|
||||
|
||||
```console
|
||||
$ nix-build "https://github.com/NixOS/nixpkgs/archive/refs/heads/release-23.11.tar.gz" -A firefox
|
||||
```
|
||||
|
||||
If a path starts with `flake:`, the rest of the argument is interpreted as a [flakeref](./new-cli/nix3-flake.md#flake-references) (see `nix flake --help` or `man nix3-flake`), which requires the "flakes" experimental feature to be enabled.
|
||||
Lix will fetch the flake, and then `import` its unpacked directory, so the flake must include a file called `default.nix`.
|
||||
For example, the flake analogues to the above `nix-build` commands are:
|
||||
|
||||
```console
|
||||
$ nix-build flake:nixpkgs -A firefox
|
||||
$ nix-build flake:github:NixOS/nixpkgs/release-23.11 -A firefox
|
||||
```
|
||||
|
||||
Finally, for legacy reasons, if a path starts with `channel:`, the rest of the argument is interpreted as the name of a *nixpkgs* channel tarball to fetch from `https://nixos.org/channels/$CHANNEL_NAME/nixexprs.tar.xz`.
|
||||
This is a **hard coded URL** pattern and is *not* related to the subscribed channels managed by the [nix-channel](./nix-channel.md) command.
|
||||
|
||||
> **Note**: any of the special syntaxes may always be disambiguated by prefixing the path.
|
||||
> For example: a file in the current directory literally called `<nixpkgs>` can be addressed as `./<nixpkgs>`, to escape the special interpretation.
|
||||
|
||||
In summary, a path argument may be one of:
|
||||
|
||||
{{#include ./fileish-summary.md}}
|
||||
|
||||
## Notes
|
||||
If an element of *paths* starts with `http://` or `https://`, it is
|
||||
interpreted as the URL of a tarball that will be downloaded and unpacked
|
||||
to a temporary location. The tarball must include a single top-level
|
||||
directory containing at least a file named `default.nix`.
|
||||
|
||||
`nix-build` is essentially a wrapper around
|
||||
[`nix-instantiate`](nix-instantiate.md) (to translate a high-level Nix
|
||||
|
||||
@@ -14,7 +14,7 @@ The moving parts of channels are:
|
||||
- The official channels listed at <https://nixos.org/channels>
|
||||
- The user-specific list of [subscribed channels](#subscribed-channels)
|
||||
- The [downloaded channel contents](#channels)
|
||||
- The [Nix expression search path](@docroot@/command-ref/conf-file.md#conf-nix-path), set with the [`-I` option](#opt-I) or the [`NIX_PATH` environment variable](#env-NIX_PATH)
|
||||
- The [Nix expression search path](@docroot@/command-ref/conf-file.md#conf-nix-path), set with the [`-I` option](#opt-i) or the [`NIX_PATH` environment variable](#env-NIX_PATH)
|
||||
|
||||
> **Note**
|
||||
>
|
||||
|
||||
@@ -36,7 +36,7 @@ Instead, it looks in a few locations, and acts on all profiles it finds there:
|
||||
>
|
||||
> Not stable; subject to change
|
||||
>
|
||||
> Do not rely on this functionality; it just exists for migration purposes and may change in the future.
|
||||
> Do not rely on this functionality; it just exists for migration purposes and is may change in the future.
|
||||
> These deprecated paths remain a private implementation detail of Lix.
|
||||
|
||||
<!-- FIXME(Qyriad): this is inconsistent with https://git.lix.systems/lix-project/lix/issues/215, needs updating when that happens -->
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
[`--option` *name* *value*]
|
||||
[`--arg` *name* *value*]
|
||||
[`--argstr` *name* *value*]
|
||||
[{`--file` | `-f`} *fileish*]
|
||||
[{`--file` | `-f`} *path*]
|
||||
[{`--profile` | `-p`} *path*]
|
||||
[`--system-filter` *system*]
|
||||
[`--dry-run`]
|
||||
|
||||
@@ -26,7 +26,7 @@ This operation deletes the specified generations of the current profile.
|
||||
>
|
||||
> Older *and newer* generations will be deleted by this operation.
|
||||
>
|
||||
> One might expect this to just delete older generations than the current one, but that is only true if the current generation is also the latest.
|
||||
> One might expect this to just delete older generations than the curent one, but that is only true if the current generation is also the latest.
|
||||
> Because one can roll back to a previous generation, it is possible to have generations newer than the current one.
|
||||
> They will also be deleted.
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
[`--from-profile` *path*]
|
||||
[`--preserve-installed` | `-P`]
|
||||
[`--remove-all` | `-r`]
|
||||
[`--priority` *priority*]
|
||||
|
||||
# Description
|
||||
|
||||
@@ -60,11 +59,6 @@ a number of possible ways:
|
||||
unambiguous way, which is necessary if there are multiple
|
||||
derivations with the same name.
|
||||
|
||||
- If `--priority` *priority* is given, the priority of the derivations being
|
||||
installed is set to *priority*. This can be used to override the priority of
|
||||
the derivations being installed. This is useful if *args* are store paths,
|
||||
which don't have any priority information.
|
||||
|
||||
- If *args* are [store derivations](@docroot@/glossary.md#gloss-store-derivation), then these are
|
||||
[realised](@docroot@/command-ref/nix-store/realise.md), and the resulting output paths
|
||||
are installed.
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
|
||||
The following options are allowed for all `nix-env` operations, but may not always have an effect.
|
||||
|
||||
- `--file` / `-f` *fileish*\
|
||||
- `--file` / `-f` *path*\
|
||||
Specifies the Nix expression (designated below as the *active Nix
|
||||
expression*) used by the `--install`, `--upgrade`, and `--query
|
||||
--available` operations to obtain derivations. The default is
|
||||
`~/.nix-defexpr`.
|
||||
|
||||
*fileish* is interpreted the same as with [nix-build](../nix-build.md#fileish-syntax).
|
||||
See that section for complete details (`nix-build --help`), but in summary, a path argument may be one of:
|
||||
|
||||
{{#include ../fileish-summary.md}}
|
||||
If the argument starts with `http://` or `https://`, it is
|
||||
interpreted as the URL of a tarball that will be downloaded and
|
||||
unpacked to a temporary location. The tarball must include a single
|
||||
top-level directory containing at least a file named `default.nix`.
|
||||
|
||||
- `--profile` / `-p` *path*\
|
||||
Specifies the profile to be used by those operations that operate on
|
||||
|
||||
@@ -22,7 +22,7 @@ left untouched; this is not an error. It is also not an error if an
|
||||
element of *args* matches no installed derivations.
|
||||
|
||||
For a description of how *args* is mapped to a set of store paths, see
|
||||
[`--install`](install.md). If *args* describes multiple
|
||||
[`--install`](#operation---install). If *args* describes multiple
|
||||
store paths with the same symbolic name, only the one with the highest
|
||||
version is installed.
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
[{`--attr`| `-A`} *attrPath*]
|
||||
[`--add-root` *path*]
|
||||
[`--expr` | `-E`]
|
||||
*fileish…*
|
||||
*files…*
|
||||
|
||||
`nix-instantiate` `--find-file` *files…*
|
||||
|
||||
@@ -25,11 +25,8 @@ of the resulting store derivations are printed on standard output.
|
||||
|
||||
[store derivation]: ../glossary.md#gloss-store-derivation
|
||||
|
||||
If *fileish* is the character `-`, then a Nix expression will be read from standard input.
|
||||
Otherwise, each *fileish* is interpreted the same as with [nix-build](./nix-build.md#fileish-syntax).
|
||||
See that section for complete details (`nix-build --help`), but in summary, a path argument may be one of:
|
||||
|
||||
{{#include ./fileish-summary.md}}
|
||||
If *files* is the character `-`, then a Nix expression will be read from
|
||||
standard input.
|
||||
|
||||
# Options
|
||||
|
||||
@@ -38,14 +35,7 @@ See that section for complete details (`nix-build --help`), but in summary, a pa
|
||||
|
||||
- `--parse`\
|
||||
Just parse the input files, and print their abstract syntax trees on
|
||||
standard output. The output format of the AST depends on the current
|
||||
internal representation and may change in the future.
|
||||
|
||||
Tooling can use the stderr and exit code of `--parse` to check any
|
||||
Nix code for correctness, but should not rely on stdout without careful
|
||||
versioning. Note that `--parse` also checks for unbound variables.
|
||||
In cases where this is undesired, `with {};` can be prepended
|
||||
to the program to transform all such parse errors into eval errors.
|
||||
standard output as a Nix expression.
|
||||
|
||||
- `--eval`\
|
||||
Just parse and evaluate the input files, and print the resulting
|
||||
|
||||
@@ -33,9 +33,10 @@ the environment of a derivation for development.
|
||||
If *path* is not given, `nix-shell` defaults to `shell.nix` if it
|
||||
exists, and `default.nix` otherwise.
|
||||
|
||||
If *path* is given it is interpreted like a [*fileish* argument to nix-build](./nix-build.md#fileish-syntax):
|
||||
|
||||
{{#include ./fileish-summary.md}}
|
||||
If *path* starts with `http://` or `https://`, it is interpreted as the
|
||||
URL of a tarball that will be downloaded and unpacked to a temporary
|
||||
location. The tarball must include a single top-level directory
|
||||
containing at least a file named `default.nix`.
|
||||
|
||||
If the derivation defines the variable `shellHook`, it will be run
|
||||
after `$stdenv/setup` has been sourced. Since this hook is not executed
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
# Synopsis
|
||||
|
||||
`nix-store` `--delete` [`--ignore-liveness`] [`--skip-live`] [`--delete-closure`] *paths…*
|
||||
`nix-store` `--delete` [`--ignore-liveness`] *paths…*
|
||||
|
||||
# Description
|
||||
|
||||
@@ -18,13 +18,6 @@ With the option `--ignore-liveness`, reachability from the roots is
|
||||
ignored. However, the path still won’t be deleted if there are other
|
||||
paths in the store that refer to it (i.e., depend on it).
|
||||
|
||||
This operation will raise an error if any of the paths are still live
|
||||
and `--ignore-liveness` is not passed. Passing `--skip-live` will
|
||||
prevent this from being considered an error.
|
||||
|
||||
The option `--delete-closure` will also attempt to delete any paths
|
||||
that are in the given path's dependency closure.
|
||||
|
||||
{{#include ./opt-common.md}}
|
||||
|
||||
{{#include ../opt-common.md}}
|
||||
|
||||
@@ -93,12 +93,9 @@ symlink.
|
||||
[deriver]: ../../glossary.md#gloss-deriver
|
||||
|
||||
- `--valid-derivers`\
|
||||
Prints the set of all [derivers](../../glossary.md#gloss-deriver) that can be
|
||||
used to build the store paths *paths*.
|
||||
This differs from `--deriver`, which prints the deriver that actually
|
||||
produced *paths*.
|
||||
No deriver may be returned if is not present in the store,
|
||||
eg, if *paths* were substituted from a binary cache.
|
||||
Prints a set of derivation files (`.drv`) which are supposed produce
|
||||
said paths when realized. Might print nothing, for example for source paths
|
||||
or paths subsituted from a binary cache.
|
||||
|
||||
- `--graph`\
|
||||
Prints the references graph of the store paths *paths* in the format
|
||||
|
||||
@@ -85,7 +85,7 @@ Most commands in Lix accept the following command-line options:
|
||||
|
||||
- `multiline-with-logs`
|
||||
|
||||
Display the raw logs, with a progress bar and activities each in a new line at the bottom.
|
||||
Displayes the raw logs, with a progress bar and activities each in a new line at the bottom.
|
||||
|
||||
|
||||
- <span id="opt-no-build-output">[`--no-build-output`](#opt-no-build-output)</span> / `-Q`
|
||||
|
||||
@@ -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}}
|
||||
|
||||
@@ -39,28 +39,17 @@ $ nix-shell -A native-clangStdenvPackages
|
||||
|
||||
### Building from the development shell
|
||||
|
||||
Run a clean build and test with `just clean build install test`.
|
||||
|
||||
You can also run the unit tests and integration tests separately:
|
||||
You can build and test Lix with just:
|
||||
|
||||
```bash
|
||||
$ just setup build test-unit
|
||||
$ just install test-integration
|
||||
$ just setup
|
||||
$ just build
|
||||
$ just test --suite=check
|
||||
$ just install
|
||||
$ just test --suite=installcheck
|
||||
```
|
||||
|
||||
Many targets have a `-custom` variant which pass extra arguments to `meson`.
|
||||
For example, to work on both Lix and nix-eval-jobs you can run:
|
||||
|
||||
```
|
||||
$ just setup-custom -Dnix-eval-jobs=enabled
|
||||
$ # or
|
||||
$ mesonFlags=-Dnix-eval-jobs=enabled just setup
|
||||
```
|
||||
|
||||
Note that only targets which don't accept extra arguments can be used when
|
||||
running multiple targets at once; `just setup build` is fine, but `just
|
||||
setup-custom build` is an error. The `test` target is usually the last one to
|
||||
run, so it always accepts extra arguments.
|
||||
(Check and installcheck may both be done after install, allowing you to omit the --suite argument entirely, but this is the order package.nix runs them in.)
|
||||
|
||||
You can also build Lix manually:
|
||||
|
||||
@@ -113,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:
|
||||
@@ -152,7 +141,6 @@ Lix can be built for various platforms, as specified in [`flake.nix`]:
|
||||
|
||||
- `x86_64-linux`
|
||||
- `x86_64-darwin`
|
||||
- `x86_64-freebsd`
|
||||
- `i686-linux`
|
||||
- `aarch64-linux`
|
||||
- `aarch64-darwin`
|
||||
@@ -187,7 +175,6 @@ These are specified in `crossSystems` in `flake.nix`; feel free to submit change
|
||||
|
||||
- `armv6l-linux`
|
||||
- `armv7l-linux`
|
||||
- `aarch64-linux`
|
||||
- `riscv64-linux`
|
||||
|
||||
For example, to cross-compile Lix for `armv6l-linux` from another Linux, use the following:
|
||||
@@ -229,7 +216,7 @@ Lix uses a string with the following format to identify the *system type* or *pl
|
||||
|
||||
It is set when Lix is compiled for the given system, and determined by [Meson's `host_machine.cpu_family()` and `host_machine.system()` values](https://mesonbuild.com/Reference-manual_builtin_host_machine.html).
|
||||
|
||||
For historic reasons and backward-compatibility, some CPU and OS identifiers are translated from the GNU Autotools naming convention in [`meson.build`](https://git.lix.systems/lix-project/lix/src/branch/main/meson.build) as follows:
|
||||
For historic reasons and backward-compatibility, some CPU and OS identifiers are translated from the GNU Autotools naming convention in [`meson.build`](https://git.lix.systems/lix-project/lix/blob/main/meson.build) as follows:
|
||||
|
||||
| `host_machine.cpu_family()` | Nix |
|
||||
|----------------------------|---------------------|
|
||||
@@ -256,13 +243,13 @@ To build with one of those environments, you can use
|
||||
$ nix build .#nix-ccacheStdenv
|
||||
```
|
||||
|
||||
for <a id="nix-with-flakes">flake-enabled Nix</a>, or
|
||||
for flake-enabled Nix, or
|
||||
|
||||
```console
|
||||
$ nix-build --attr nix-ccacheStdenv
|
||||
```
|
||||
|
||||
for <a id="classic-nix">classic Nix</a>.
|
||||
for classic Nix.
|
||||
|
||||
You can use any of the other supported environments in place of `nix-ccacheStdenv`.
|
||||
|
||||
@@ -411,76 +398,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 definition 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 builtin 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
|
||||
@@ -247,6 +247,7 @@ To ensure that characterization testing doesn't make it harder to intentionally
|
||||
|
||||
The integration tests are defined in the Nix flake under the `hydraJobs.tests` attribute.
|
||||
These tests include everything that needs to interact with external services or run Lix in a non-trivial distributed setup.
|
||||
Because these tests are expensive and require more than what the standard github-actions setup provides, they only run on the master branch (on <https://hydra.nixos.org/jobset/nix/master>).
|
||||
|
||||
You can run them manually with `nix build .#hydraJobs.tests.{testName}` or `nix-build -A hydraJobs.tests.{testName}`
|
||||
|
||||
@@ -345,7 +346,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 +362,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 +375,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`.
|
||||
@@ -427,7 +428,6 @@ I grepped `lix/` for `get[eE]nv\("` to find the mentions in Lix code.
|
||||
- `NIX_SHOW_STATS_PATH` - Writes those statistics into a file at the given path instead of stdout. Undocumented.
|
||||
- `NIX_SHOW_SYMBOLS` - Dumps the symbol table into the show-stats json output.
|
||||
- `TERM` - If `dumb` or unset, disables ANSI colour output.
|
||||
- `FORCE_COLOR`, `CLICOLOR_FORCE` - Enables ANSI colour output if `NO_COLOR`/`NOCOLOR` not set.
|
||||
- `NO_COLOR`, `NOCOLOR` - Disables ANSI colour output.
|
||||
- `_NIX_DEVELOPER_SHOW_UNKNOWN_LOCATIONS` - Highlights unknown locations in errors.
|
||||
- `NIX_PROFILE` - Selects which profile `nix-env` will operate on. Documented elsewhere.
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
|
||||
See [File System Object](@docroot@/architecture/file-system-object.md) for details.
|
||||
|
||||
[file system object]: #gloss-store-path
|
||||
[file system object]: #gloss-file-system-object
|
||||
|
||||
- [store object]{#gloss-store-object}
|
||||
|
||||
@@ -249,7 +249,7 @@
|
||||
links. NARs are generated and unpacked using `nix-store --dump`
|
||||
and `nix-store --restore`.
|
||||
|
||||
- [`∅`]{#gloss-empty-set}
|
||||
- [`∅`]{#gloss-emtpy-set}
|
||||
|
||||
The empty set symbol. In the context of profile history, this denotes a package is not present in a particular version of the profile.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -148,7 +148,7 @@ paths) are set.
|
||||
|
||||
For example, the following command gets all dependencies of the
|
||||
Pan newsreader, as described by [its
|
||||
Nix expression](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/pa/pan/package.nix):
|
||||
Nix expression](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/networking/newsreaders/pan/default.nix):
|
||||
|
||||
```console
|
||||
$ nix-shell '<nixpkgs>' --attr pan
|
||||
|
||||
@@ -261,7 +261,7 @@ Derivations can declare some infrequently used optional attributes.
|
||||
useful for very trivial derivations (such as `writeText` in Nixpkgs)
|
||||
that are cheaper to build than to substitute from a binary cache.
|
||||
|
||||
You may disable the effects of this attribute by enabling the
|
||||
You may disable the effects of this attibute by enabling the
|
||||
`always-allow-substitutes` configuration option in Lix.
|
||||
|
||||
> **Note**
|
||||
@@ -292,12 +292,6 @@ Derivations can declare some infrequently used optional attributes.
|
||||
(associative) arrays. For example, the attribute `hardening.format = true`
|
||||
ends up as the Bash associative array element `${hardening[format]}`.
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> If set to `true`, other advanced attributes such as [`allowedReferences`](#adv-attr-allowedReferences), [`allowedReferences`](#adv-attr-allowedReferences), [`allowedRequisites`](#adv-attr-allowedRequisites),
|
||||
[`disallowedReferences`](#adv-attr-disallowedReferences) and [`disallowedRequisites`](#adv-attr-disallowedRequisites), maxSize, and maxClosureSize.
|
||||
will have no effect.
|
||||
|
||||
- [`outputChecks`]{#adv-attr-outputChecks}\
|
||||
When using [structured attributes](#adv-attr-structuredAttrs), the `outputChecks`
|
||||
attribute allows defining checks per-output.
|
||||
@@ -332,6 +326,7 @@ Derivations can declare some infrequently used optional attributes.
|
||||
```
|
||||
|
||||
- [`unsafeDiscardReferences`]{#adv-attr-unsafeDiscardReferences}\
|
||||
|
||||
When using [structured attributes](#adv-attr-structuredAttrs), the
|
||||
attribute `unsafeDiscardReferences` is an attribute set with a boolean value for each output name.
|
||||
If set to `true`, it disables scanning the output for runtime dependencies.
|
||||
|
||||
@@ -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,6 @@
|
||||
| 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 |
|
||||
|
||||
[string]: ./values.md#type-string
|
||||
[path]: ./values.md#type-path
|
||||
@@ -61,10 +59,8 @@ The result is a [Boolean] value.
|
||||
|
||||
## Arithmetic
|
||||
|
||||
Numbers will retain their type unless mixed with other numeric types:
|
||||
Pure integer operations will always return integers, whereas any operation involving at least one floating point number returns a floating point number.
|
||||
|
||||
Integer overflow (of 64-bit signed integers) and division by zero are defined to throw an error.
|
||||
Numbers are type-compatible:
|
||||
Pure integer operations will always return integers, whereas any operation involving at least one floating point number return a floating point number.
|
||||
|
||||
See also [Comparison] and [Equality].
|
||||
|
||||
@@ -147,103 +143,21 @@ All comparison operators are implemented in terms of `<`, and the following equi
|
||||
| *a* `>` *b* | *b* `<` *a* |
|
||||
| *a* `>=` *b* | `! (` *a* `<` *b* `)` |
|
||||
|
||||
Note that the above behaviour violates IEEE 754 for floating point numbers with respect to NaN, for instance.
|
||||
This may be fixed in a future major language revision.
|
||||
|
||||
[Comparison]: #comparison-operators
|
||||
|
||||
## Equality
|
||||
|
||||
The following equality comparison rules are followed in order:
|
||||
|
||||
- Comparisons are first, sometimes, performed by identity (pointer value), and whether or not this occurs varies depending on the context in which the comparison is performed; for example, through `builtins.elem`, comparison of lists, or other cases.
|
||||
The exact instances in which this occurs, aside from direct list and attribute set comparisons as discussed below, are too dependent on implementation details to meaningfully document.
|
||||
|
||||
See [note on identity comparison](#identity-comparison) below.
|
||||
- Comparisons between a combination of integers and floating point numbers are first converted to floating point then compared as floating point.
|
||||
- Comparisons between values of differing types, besides the ones mentioned in the above rule, are unequal.
|
||||
- Strings are compared as their string values, disregarding string contexts.
|
||||
- Paths are compared as their absolute form (since they are stored as such).
|
||||
- [Functions][function] are always considered unequal, including with themselves.
|
||||
- The following are compared in the typical manner:
|
||||
- Integers
|
||||
- Floating point numbers have equality comparison per IEEE 754.
|
||||
|
||||
Note that this means that just like in most languages, floating point arithmetic results are not typically equality comparable, and should instead be compared by checking that the absolute difference is less than some error margin.
|
||||
- Booleans
|
||||
- Null
|
||||
- [Attribute sets][attribute set] are compared following these rules in order:
|
||||
- If both attribute sets have the same identity (via pointer equality), they are considered equal, regardless of whether the contents have reflexive equality (e.g. even if there are functions contained within).
|
||||
|
||||
See [note on identity comparison](#identity-comparison) below.
|
||||
- If both attribute sets have `type = "derivation"` and have an attribute `outPath` that is equal, they are considered equal.
|
||||
|
||||
This means that two results of `builtins.derivation`, regardless of other things added to their attributes via `//` afterwards (or `passthru` in nixpkgs), will compare equal if they passed the same arguments to `builtins.derivation`.
|
||||
- Otherwise, they are compared element-wise in an unspecified order.
|
||||
Although this order *may* be deterministic in some cases, this is not guaranteed, and correct code must not rely on this ordering behaviour.
|
||||
|
||||
The order determines which elements are evaluated first and thus, if there are throwing values in the attribute set, which of those get evaluated, if any, before the comparison returns an unequal result.
|
||||
- Lists are compared following these rules in order:
|
||||
- If both lists have the same identity (via pointer equality), they are considered equal, regardless of whether the contents have reflexive equality (e.g. even if there are functions contained within).
|
||||
|
||||
See [note on identity comparison](#identity-comparison) below.
|
||||
- Otherwise, they are compared element-wise in list order.
|
||||
- [Attribute sets][attribute set] and [list]s are compared recursively, and therefore are fully evaluated.
|
||||
- Comparison of [function]s always returns `false`.
|
||||
- Numbers are type-compatible, see [arithmetic] operators.
|
||||
- Floating point numbers only differ up to a limited precision.
|
||||
|
||||
[function]: ./constructs.md#functions
|
||||
|
||||
[Equality]: #equality
|
||||
|
||||
### Identity comparison
|
||||
|
||||
In the current revision of the Nix language, values are first compared by identity (pointer equality).
|
||||
This means that values that are not reflexively equal (that is, they do not satisfy `a == a`), such as functions, are nonetheless sometimes compared as equal with themselves if they are placed in attribute sets or lists, or are compared through other indirect means.
|
||||
|
||||
Whether identity comparison applies to a given usage of the language aside from direct list and attribute set comparison is strongly dependent on implementation details to the point it is not feasible to document the exact instances.
|
||||
|
||||
This is rather unfortunate behaviour which is regrettably load-bearing on nixpkgs (such as with the `type` attribute of NixOS options) and cannot be changed for the time being.
|
||||
It may be changed in a future major language revision.
|
||||
|
||||
Correct code must not rely on this behaviour.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
nix-repl> let f = x: 1; s = { func = f; }; in [ (f == f) (s == s) ]
|
||||
[ false true ]
|
||||
```
|
||||
|
||||
## Logical implication
|
||||
|
||||
Equivalent to `!`*b1* `||` *b2*.
|
||||
|
||||
[Logical implication]: #logical-implication
|
||||
|
||||
## \[Experimental\] Function piping
|
||||
|
||||
*This language feature is still experimental and may change at any time. Enable `--extra-experimental-features pipe-operator` to use it.*
|
||||
|
||||
Pipes are a dedicated operator for function application, but with reverse order and a lower binding strength.
|
||||
This allows you to chain function calls together in way that is more natural to read and requires less parentheses.
|
||||
|
||||
`a |> f b |> g` is equivalent to `g (f b a)`.
|
||||
`g <| f b <| a` is equivalent to `g (f b a)`.
|
||||
|
||||
Example code snippet:
|
||||
|
||||
```nix
|
||||
defaultPrefsFile = defaultPrefs
|
||||
|> lib.mapAttrsToList (
|
||||
key: value: ''
|
||||
// ${value.reason}
|
||||
pref("${key}", ${builtins.toJSON value.value});
|
||||
''
|
||||
)
|
||||
|> lib.concatStringsSep "\n"
|
||||
|> pkgs.writeText "nixos-default-prefs.js";
|
||||
```
|
||||
|
||||
Note how `mapAttrsToList` is called with two arguments (the lambda and `defaultPrefs`),
|
||||
but moving the last argument in front of the rest improves the reading flow.
|
||||
This is common for functions with long first argument, including all `map`-like functions.
|
||||
|
||||
[Function piping]: #experimental-function-piping
|
||||
|
||||
@@ -7,16 +7,13 @@
|
||||
*Strings* can be written in three ways.
|
||||
|
||||
The most common way is to enclose the string between double quotes,
|
||||
e.g., `"foo bar"`. Strings can span multiple lines. The backslash
|
||||
(`\`) can be used to escape characters: newlines, carriage returns
|
||||
and tabs may be written as `\n`, `\r` and `\t` respectively; any
|
||||
other characters can be preceded by a backslash to remove any
|
||||
special meaning they may have, like the special characters `"` and
|
||||
`\` and the character sequence `${`.
|
||||
e.g., `"foo bar"`. Strings can span multiple lines. The special
|
||||
characters `"` and `\` and the character sequence `${` must be
|
||||
escaped by prefixing them with a backslash (`\`). Newlines, carriage
|
||||
returns and tabs can be written as `\n`, `\r` and `\t`,
|
||||
respectively.
|
||||
|
||||
You can include the results of other expressions into a string by enclosing them in `${ }`, a feature known as [string interpolation].
|
||||
Due to a parser issue that has since come to be relied upon, the character sequence `$${` is interpreted literally and does not introduce an interpolation.
|
||||
To express a `$` character immediately followed by an interpolation, the former must be escaped.
|
||||
|
||||
[string interpolation]: ./string-interpolation.md
|
||||
|
||||
@@ -46,16 +43,16 @@
|
||||
Note that the whitespace and newline following the opening `''` is
|
||||
ignored if there is no non-whitespace text on the initial line.
|
||||
|
||||
Indented strings support [string interpolation].
|
||||
|
||||
Since `${` and `''` have special meaning in indented strings, you
|
||||
need a way to quote them. `$` can be escaped by prefixing it with
|
||||
`''` (that is, two single quotes), i.e., `''$`. `''` can be escaped
|
||||
by prefixing it with `'`, i.e., `'''`. Linefeed, carriage-return and tab
|
||||
by prefixing it with `'`, i.e., `'''`. `$` removes any special
|
||||
meaning from the following `$`. Linefeed, carriage-return and tab
|
||||
characters can be written as `''\n`, `''\r`, `''\t`, and `''\`
|
||||
escapes any other character.
|
||||
|
||||
Indented strings support [string interpolation] using `${ }` the same way regular strings do.
|
||||
`$${` is interpreted literally in indented strings as well, so the `$` character must be escaped if it is to be followed by an interpolation.
|
||||
|
||||
Indented strings are primarily useful in that they allow multi-line
|
||||
string literals to follow the indentation of the enclosing Nix
|
||||
expression, and that less escaping is typically necessary for
|
||||
@@ -77,14 +74,17 @@
|
||||
}
|
||||
```
|
||||
|
||||
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*
|
||||
(like `123.43` or `.27e13`).
|
||||
|
||||
Integers in the Nix language are 64-bit signed integers.
|
||||
Integer overflow is defined to throw an error.
|
||||
|
||||
See [arithmetic] and [comparison] operators for semantics.
|
||||
|
||||
[arithmetic]: ./operators.md#arithmetic
|
||||
@@ -164,7 +164,7 @@ Note that lists are only lazy in values, and they are strict in length.
|
||||
|
||||
An attribute set is a collection of name-value-pairs (called *attributes*) enclosed in curly brackets (`{ }`).
|
||||
|
||||
An attribute name can be an identifier or a [string](#type-string).
|
||||
An attribute name can be an identifier or a [string](#string).
|
||||
An identifier must start with a letter (`a-z`, `A-Z`) or underscore (`_`), and can otherwise contain letters (`a-z`, `A-Z`), numbers (`0-9`), underscores (`_`), apostrophes (`'`), or dashes (`-`).
|
||||
|
||||
> *name* = *identifier* | *string* \
|
||||
|
||||
@@ -126,7 +126,7 @@ $ nix-env --install --attr nixpkgs.subversion
|
||||
```
|
||||
|
||||
will install the package called `subversion` from `nixpkgs` channel (which is, of course, the
|
||||
[Subversion version management system](https://subversion.apache.org/)).
|
||||
[Subversion version management system](http://subversion.tigris.org/)).
|
||||
|
||||
> **Note**
|
||||
>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
- The `discard-references` feature has been stabilized.
|
||||
This means that the
|
||||
`unsafeDiscardReferences`
|
||||
[unsafeDiscardReferences](@docroot@/contributing/experimental-features.md#xp-feature-discard-references)
|
||||
attribute is no longer guarded by an experimental flag and can be used
|
||||
freely.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Lix 2.90 "Vanilla Ice Cream" (2024-07-10)
|
||||
# Lix 2.90 "Vanilla Ice Cream" (FIXME date)
|
||||
|
||||
|
||||
# Lix 2.90.0 (2024-07-10)
|
||||
# Lix 2.90.0 (FIXME date)
|
||||
|
||||
## Breaking Changes
|
||||
- Deprecate the online flake registries and vendor the default registry [fj#183](https://git.lix.systems/lix-project/lix/issues/183) [fj#110](https://git.lix.systems/lix-project/lix/issues/110) [fj#116](https://git.lix.systems/lix-project/lix/issues/116) [#8953](https://github.com/NixOS/nix/issues/8953) [#9087](https://github.com/NixOS/nix/issues/9087) [cl/1127](https://gerrit.lix.systems/c/lix/+/1127)
|
||||
|
||||
@@ -1,489 +0,0 @@
|
||||
# Lix 2.91 "Dragon's Breath" (2024-08-12)
|
||||
|
||||
|
||||
# Lix 2.91.0 (2024-08-12)
|
||||
|
||||
## Breaking Changes
|
||||
- Block io_uring in the Linux sandbox [cl/1611](https://gerrit.lix.systems/c/lix/+/1611)
|
||||
|
||||
The io\_uring API has the unfortunate property that it is not possible to selectively decide which operations should be allowed.
|
||||
This, together with the fact that new operations are routinely added, makes it a hazard to the proper function of the sandbox.
|
||||
|
||||
Therefore, any access to io\_uring has been made unavailable inside the sandbox.
|
||||
As such, attempts to execute any system calls forming part of this API will fail with the error `ENOSYS`, as if io\_uring support had not been configured into the kernel.
|
||||
|
||||
Many thanks to [alois31](https://git.lix.systems/alois31) for this.
|
||||
- The `build-hook` setting is now deprecated
|
||||
|
||||
Build hooks communicate with the daemon using a custom, internal, undocumented protocol that is entirely unversioned and cannot be changed.
|
||||
Since we intend to change it anyway we must unfortunately deprecate the current build hook infrastructure.
|
||||
We do not expect this to impact most users—we have not found any uses of `build-hook` in the wild—but if this does affect you, we'd like to hear from you!
|
||||
- Lix no longer speaks the Nix remote-build worker protocol to clients or servers older than CppNix 2.3 [fj#325](https://git.lix.systems/lix-project/lix/issues/325) [cl/1207](https://gerrit.lix.systems/c/lix/+/1207) [cl/1208](https://gerrit.lix.systems/c/lix/+/1208) [cl/1206](https://gerrit.lix.systems/c/lix/+/1206) [cl/1205](https://gerrit.lix.systems/c/lix/+/1205) [cl/1204](https://gerrit.lix.systems/c/lix/+/1204) [cl/1203](https://gerrit.lix.systems/c/lix/+/1203) [cl/1479](https://gerrit.lix.systems/c/lix/+/1479)
|
||||
|
||||
CppNix 2.3 was released in 2019, and is the new oldest supported version. We
|
||||
will increase our support baseline in the future up to a final version of CppNix
|
||||
2.18 (which may happen soon given that it is the only still-packaged and thus
|
||||
still-tested >2.3 version), but this step already removes a significant amount
|
||||
of dead, untested, code paths.
|
||||
|
||||
Lix speaks the same version of the protocol as CppNix 2.18 and that fact will
|
||||
never change in the future; the Lix plans to replace the protocol for evolution
|
||||
will entail a complete incompatible replacement that will be supported in
|
||||
parallel with the old protocol. Lix will thus retain remote build compatibility
|
||||
with CppNix as long as CppNix maintains protocol compatibility with 2.18, and
|
||||
as long as Lix retains legacy protocol support (which will likely be a long
|
||||
time given that we plan to convert it to a frozen-in-time shim).
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
|
||||
## Features
|
||||
- Pipe operator `|>` (experimental) [fj#438](https://git.lix.systems/lix-project/lix/issues/438) [cl/1654](https://gerrit.lix.systems/c/lix/+/1654)
|
||||
|
||||
Implementation of the pipe operator (`|>`) in the language as described in [RFC 148](https://github.com/NixOS/rfcs/pull/148).
|
||||
The feature is still marked experimental, enable `--extra-experimental-features pipe-operator` to use it.
|
||||
|
||||
Many thanks to [piegames](https://git.lix.systems/piegames) and [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
|
||||
## Improvements
|
||||
- Trace which part of a `foo.bar.baz` expression errors [cl/1505](https://gerrit.lix.systems/c/lix/+/1505) [cl/1506](https://gerrit.lix.systems/c/lix/+/1506)
|
||||
|
||||
Previously, if an attribute path selection expression like `linux_4_9.meta.description` it wouldn't show you which one of those parts in the attribute path, or even that that line of code is what caused evaluation of the failing expression.
|
||||
The previous error looks like this:
|
||||
|
||||
```
|
||||
pkgs.linuxKernel.kernels.linux_4_9.meta.description
|
||||
|
||||
error:
|
||||
… while evaluating the attribute 'linuxKernel.kernels.linux_4_9.meta.description'
|
||||
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:5:
|
||||
277| } // lib.optionalAttrs config.allowAliases {
|
||||
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||
| ^
|
||||
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||
|
||||
… while calling the 'throw' builtin
|
||||
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:17:
|
||||
277| } // lib.optionalAttrs config.allowAliases {
|
||||
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||
| ^
|
||||
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||
|
||||
error: linux 4.9 was removed because it will reach its end of life within 22.11
|
||||
```
|
||||
|
||||
Now, the error will look like this:
|
||||
|
||||
```
|
||||
pkgs.linuxKernel.kernels.linux_4_9.meta.description
|
||||
|
||||
error:
|
||||
… while evaluating the attribute 'linuxKernel.kernels.linux_4_9.meta.description'
|
||||
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:5:
|
||||
277| } // lib.optionalAttrs config.allowAliases {
|
||||
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||
| ^
|
||||
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||
|
||||
… while evaluating 'pkgs.linuxKernel.kernels.linux_4_9' to select 'meta' on it
|
||||
at «string»:1:1:
|
||||
1| pkgs.linuxKernel.kernels.linux_4_9.meta.description
|
||||
| ^
|
||||
|
||||
… caused by explicit throw
|
||||
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:17:
|
||||
277| } // lib.optionalAttrs config.allowAliases {
|
||||
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||
| ^
|
||||
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||
|
||||
error: linux 4.9 was removed because it will reach its end of life within 22.11
|
||||
```
|
||||
|
||||
Not only does the line of code that referenced the failing attribute show up in the trace, it also tells you that it was specifically the `linux_4_9` part that failed.
|
||||
|
||||
This includes if the failing part is a top-level binding:
|
||||
|
||||
```
|
||||
let
|
||||
inherit (pkgs.linuxKernel.kernels) linux_4_9;
|
||||
in linux_4_9.meta.description
|
||||
error:
|
||||
… while evaluating 'linux_4_9' to select 'meta.description' on it
|
||||
at «string»:3:4:
|
||||
2| inherit (pkgs.linuxKernel.kernels) linux_4_9;
|
||||
3| in linux_4_9.meta.description
|
||||
| ^
|
||||
|
||||
… while evaluating the attribute 'linux_4_9'
|
||||
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:5:
|
||||
277| } // lib.optionalAttrs config.allowAliases {
|
||||
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||
| ^
|
||||
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||
|
||||
… caused by explicit throw
|
||||
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:17:
|
||||
277| } // lib.optionalAttrs config.allowAliases {
|
||||
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||
| ^
|
||||
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||
|
||||
error: linux 4.9 was removed because it will reach its end of life within 22.11
|
||||
```
|
||||
|
||||
Many thanks to [Qyriad](https://git.lix.systems/Qyriad) for this.
|
||||
- Confusing 'invalid path' errors are now 'path does not exist' [cl/1161](https://gerrit.lix.systems/c/lix/+/1161) [cl/1160](https://gerrit.lix.systems/c/lix/+/1160) [cl/1159](https://gerrit.lix.systems/c/lix/+/1159)
|
||||
|
||||
Previously, if a path did not exist in a Nix store, it was referred to as the internal name "path is invalid".
|
||||
This is, however, very confusing, and there were numerous such errors that were exactly the same, making it hard to debug.
|
||||
These errors are now more specific and refer to the path not existing in the store.
|
||||
|
||||
Many thanks to [julia](https://git.lix.systems/midnightveil) for this.
|
||||
- Add a `build-dir` setting to set the backing directory for builds [gh#10303](https://github.com/NixOS/nix/pull/10303) [gh#10312](https://github.com/NixOS/nix/pull/10312) [gh#10883](https://github.com/NixOS/nix/pull/10883) [cl/1514](https://gerrit.lix.systems/c/lix/+/1514)
|
||||
|
||||
`build-dir` can now be set in the Nix configuration to choose the backing directory for the build sandbox.
|
||||
This can be useful on systems with `/tmp` on tmpfs, or simply to relocate large builds to another disk.
|
||||
|
||||
Also, `XDG_RUNTIME_DIR` is no longer considered when selecting the default temporary directory,
|
||||
as it's not intended to be used for large amounts of data.
|
||||
|
||||
Many thanks to [Robert Hensing](https://github.com/roberth) and [Tom Bereknyei](https://github.com/tomberek) for this.
|
||||
- Better usage of colour control environment variables [cl/1699](https://gerrit.lix.systems/c/lix/+/1699) [cl/1702](https://gerrit.lix.systems/c/lix/+/1702)
|
||||
|
||||
Lix now heeds `NO_COLOR`/`NOCOLOR` for more output types, such as that used in `nix search`, `nix flake metadata` and similar.
|
||||
|
||||
It also now supports `CLICOLOR_FORCE`/`FORCE_COLOR` to force colours regardless of whether there is a terminal on the other side.
|
||||
|
||||
It now follows rules compatible with those described on <https://bixense.com/clicolors/> with `CLICOLOR` defaulted to enabled.
|
||||
|
||||
That is to say, the following procedure is followed in order:
|
||||
- NO_COLOR or NOCOLOR set
|
||||
|
||||
Always disable colour
|
||||
- CLICOLOR_FORCE or FORCE_COLOR set
|
||||
|
||||
Enable colour
|
||||
- The output is a tty; TERM != "dumb"
|
||||
|
||||
Enable colour
|
||||
- Otherwise
|
||||
|
||||
Disable colour
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
- Distinguish between explicit throws and errors that happened while evaluating a throw [cl/1511](https://gerrit.lix.systems/c/lix/+/1511)
|
||||
|
||||
Previously, errors caused by an expression like `throw "invalid argument"` were treated like an error that happened simply while some builtin function was being called:
|
||||
|
||||
```
|
||||
let
|
||||
throwMsg = p: throw "${p} isn't the right package";
|
||||
in throwMsg "linuz"
|
||||
|
||||
error:
|
||||
… while calling the 'throw' builtin
|
||||
at «string»:2:17:
|
||||
1| let
|
||||
2| throwMsg = p: throw "${p} isn't the right package";
|
||||
| ^
|
||||
3| in throwMsg "linuz"
|
||||
|
||||
error: linuz isn't the right package
|
||||
```
|
||||
|
||||
But the error didn't just happen "while" calling the `throw` builtin — it's a throw error!
|
||||
Now it looks like this:
|
||||
|
||||
```
|
||||
let
|
||||
throwMsg = p: throw "${p} isn't the right package";
|
||||
in throwMsg "linuz"
|
||||
|
||||
error:
|
||||
… caused by explicit throw
|
||||
at «string»:2:17:
|
||||
1| let
|
||||
2| throwMsg = p: throw "${p} isn't the right package";
|
||||
| ^
|
||||
3| in throwMsg "linuz"
|
||||
|
||||
error: linuz isn't the right package
|
||||
```
|
||||
|
||||
This also means that incorrect usage of `throw` or errors evaluating its arguments are easily distinguishable from explicit throws:
|
||||
|
||||
```
|
||||
let
|
||||
throwMsg = p: throw "${p} isn't the right package";
|
||||
in throwMsg { attrs = "error when coerced in string interpolation"; }
|
||||
|
||||
error:
|
||||
… while calling the 'throw' builtin
|
||||
at «string»:2:17:
|
||||
1| let
|
||||
2| throwMsg = p: throw "${p} isn't the right package";
|
||||
| ^
|
||||
3| in throwMsg { attrs = "error when coerced in string interpolation"; }
|
||||
|
||||
… while evaluating a path segment
|
||||
at «string»:2:24:
|
||||
1| let
|
||||
2| throwMsg = p: throw "${p} isn't the right package";
|
||||
| ^
|
||||
3| in throwMsg { attrs = "error when coerced in string interpolation"; }
|
||||
|
||||
error: cannot coerce a set to a string: { attrs = "error when coerced in string interpolation"; }
|
||||
```
|
||||
|
||||
Here, instead of an actual thrown error, a type error happens first (trying to coerce an attribute set to a string), but that type error happened *while* calling `throw`.
|
||||
|
||||
Many thanks to [Qyriad](https://git.lix.systems/Qyriad) for this.
|
||||
- `nix flake metadata` prints modified date [cl/1700](https://gerrit.lix.systems/c/lix/+/1700)
|
||||
|
||||
Ever wonder "gee, when *did* I update nixpkgs"?
|
||||
Wonder no more, because `nix flake metadata` now simply tells you the times every locked flake input was updated:
|
||||
|
||||
```
|
||||
<...>
|
||||
Description: The purely functional package manager
|
||||
Path: /nix/store/c91yi8sxakc2ry7y4ac1smzwka4l5p78-source
|
||||
Revision: c52cff582043838bbe29768e7da232483d52b61d-dirty
|
||||
Last modified: 2024-07-31 22:15:54
|
||||
Inputs:
|
||||
├───flake-compat: github:edolstra/flake-compat/0f9255e01c2351cc7d116c072cb317785dd33b33
|
||||
│ Last modified: 2023-10-04 06:37:54
|
||||
├───nix2container: github:nlewo/nix2container/3853e5caf9ad24103b13aa6e0e8bcebb47649fe4
|
||||
│ Last modified: 2024-07-10 13:15:56
|
||||
├───nixpkgs: github:NixOS/nixpkgs/e21630230c77140bc6478a21cd71e8bb73706fce
|
||||
│ Last modified: 2024-07-25 11:26:27
|
||||
├───nixpkgs-regression: github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2
|
||||
│ Last modified: 2022-01-24 11:20:45
|
||||
└───pre-commit-hooks: github:cachix/git-hooks.nix/f451c19376071a90d8c58ab1a953c6e9840527fd
|
||||
Last modified: 2024-07-15 04:21:09
|
||||
```
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
- Hash mismatch diagnostics for fixed-output derivations include the URL [cl/1536](https://gerrit.lix.systems/c/lix/+/1536)
|
||||
|
||||
Now, when building fixed-output derivations, Lix will guess the URL that was used in the derivation using the `url` or `urls` properties in the derivation environment.
|
||||
This is a layering violation but making these diagnostics tractable when there are multiple instances of the `AAAA` hash is too significant of an improvement to pass it up.
|
||||
|
||||
```
|
||||
error: hash mismatch in fixed-output derivation '/nix/store/sjfw324j4533lwnpmr5z4icpb85r63ai-x1.drv':
|
||||
likely URL: https://meow.puppy.forge/puppy.tar.gz
|
||||
specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
|
||||
got: sha256-a1Qvp3FOOkWpL9kFHgugU1ok5UtRPSu+NwCZKbbaEro=
|
||||
```
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
- Add log formats `multiline` and `multiline-with-logs` [cl/1369](https://gerrit.lix.systems/c/lix/+/1369)
|
||||
|
||||
Added two new log formats (`multiline` and `multiline-with-logs`) that display
|
||||
current activities below each other for better visibility.
|
||||
|
||||
These formats attempt to use the maximum available lines
|
||||
(defaulting to 25 if unable to determine) and print up to that many lines.
|
||||
The status bar is displayed as the first line, with each subsequent
|
||||
activity on its own line.
|
||||
|
||||
Many thanks to [kloenk](https://git.lix.systems/kloenk) for this.
|
||||
- Lix will now show the package descriptions in when running `nix flake show`. [cl/1540](https://gerrit.lix.systems/c/lix/+/1540)
|
||||
|
||||
When running `nix flake show`, Lix will now show the package descriptions, if they exist.
|
||||
|
||||
Before:
|
||||
|
||||
```shell
|
||||
$ nix flake show
|
||||
path:/home/isabel/dev/lix-show?lastModified=1721736108&narHash=sha256-Zo8HP1ur7Q2b39hKUEG8EAh/opgq8xJ2jvwQ/htwO4Q%3D
|
||||
└───packages
|
||||
└───x86_64-linux
|
||||
├───aNoDescription: package 'simple'
|
||||
├───bOneLineDescription: package 'simple'
|
||||
├───cMultiLineDescription: package 'simple'
|
||||
├───dLongDescription: package 'simple'
|
||||
└───eEmptyDescription: package 'simple'
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```shell
|
||||
$ nix flake show
|
||||
path:/home/isabel/dev/lix-show?lastModified=1721736108&narHash=sha256-Zo8HP1ur7Q2b39hKUEG8EAh/opgq8xJ2jvwQ/htwO4Q%3D
|
||||
└───packages
|
||||
└───x86_64-linux
|
||||
├───aNoDescription: package 'simple'
|
||||
├───bOneLineDescription: package 'simple' - 'one line'
|
||||
├───cMultiLineDescription: package 'simple' - 'line one'
|
||||
├───dLongDescription: package 'simple' - 'abcdefghijklmnopqrstuvwxyz'
|
||||
└───eEmptyDescription: package 'simple'
|
||||
```
|
||||
|
||||
Many thanks to [kjeremy](https://github.com/kjeremy) and [isabelroses](https://git.lix.systems/isabelroses) for this.
|
||||
- Eliminate some pretty-printing surprises [#11100](https://github.com/NixOS/nix/pull/11100) [cl/1616](https://gerrit.lix.systems/c/lix/+/1616) [cl/1617](https://gerrit.lix.systems/c/lix/+/1617) [cl/1618](https://gerrit.lix.systems/c/lix/+/1618)
|
||||
|
||||
Some inconsistent and surprising behaviours have been eliminated from the pretty-printing used by the REPL and `nix eval`:
|
||||
* Lists and attribute sets that contain only a single item without nested structures are no longer sometimes inappropriately indented in the REPL, depending on internal state of the evaluator.
|
||||
* Empty attribute sets and derivations are no longer shown as `«repeated»`, since they are always cheap to print.
|
||||
This matches the existing behaviour of `nix-instantiate` on empty attribute sets.
|
||||
Empty lists were never printed as `«repeated»` already.
|
||||
* The REPL by default does not print nested attribute sets and lists, and indicates elided items with an ellipsis.
|
||||
Previously, the ellipsis was printed even when the structure was empty, so that such items do not in fact exist.
|
||||
Since this behaviour was confusing, it does not happen any more.
|
||||
|
||||
Before:
|
||||
```
|
||||
nix-repl> :p let x = 1 + 2; in [ [ x ] [ x ] ]
|
||||
[
|
||||
[
|
||||
3
|
||||
]
|
||||
[ 3 ]
|
||||
]
|
||||
|
||||
nix-repl> let inherit (import <nixpkgs> { }) hello; in [ hello hello ]
|
||||
[
|
||||
«derivation /nix/store/fqs92lzychkm6p37j7fnj4d65nq9fzla-hello-2.12.1.drv»
|
||||
«repeated»
|
||||
]
|
||||
|
||||
nix-repl> let x = {}; in [ x ]
|
||||
[
|
||||
{ ... }
|
||||
]
|
||||
```
|
||||
|
||||
After:
|
||||
```
|
||||
nix-repl> :p let x = 1 + 2; in [ [ x ] [ x ] ]
|
||||
[
|
||||
[ 3 ]
|
||||
[ 3 ]
|
||||
]
|
||||
|
||||
nix-repl> let inherit (import <nixpkgs> { }) hello; in [ hello hello ]
|
||||
[
|
||||
«derivation /nix/store/fqs92lzychkm6p37j7fnj4d65nq9fzla-hello-2.12.1.drv»
|
||||
«derivation /nix/store/fqs92lzychkm6p37j7fnj4d65nq9fzla-hello-2.12.1.drv»
|
||||
]
|
||||
|
||||
nix-repl> let x = {}; in [ x ]
|
||||
[
|
||||
{ }
|
||||
]
|
||||
```
|
||||
|
||||
Many thanks to [alois31](https://git.lix.systems/alois31) and [Robert Hensing](https://github.com/roberth) for this.
|
||||
- `nix registry add` now requires a shorthand flakeref on the 'from' side [cl/1494](https://gerrit.lix.systems/c/lix/+/1494)
|
||||
|
||||
The 'from' argument must now be a shorthand flakeref like `nixpkgs` or `nixpkgs/nixos-20.03`, making it harder to accidentally swap the 'from' and 'to' arguments.
|
||||
|
||||
Registry entries that map from other flake URLs can still be specified in registry.json, the `nix.registry` option in NixOS, or the `--override-flake` option in the CLI, but they are not guaranteed to work correctly.
|
||||
|
||||
Many thanks to [delan](https://git.lix.systems/delan) for this.
|
||||
- Allow automatic rejection of configuration options from flakes [cl/1541](https://gerrit.lix.systems/c/lix/+/1541)
|
||||
|
||||
Setting `accept-flake-config` to `false` now respects user choice by automatically rejecting configuration options set by flakes.
|
||||
The old behaviour of asking each time is still available (and default) by setting it to the special value `ask`.
|
||||
|
||||
Many thanks to [alois31](https://git.lix.systems/alois31) for this.
|
||||
- `nix repl` now allows tab-completing the special repl :colon commands [cl/1367](https://gerrit.lix.systems/c/lix/+/1367)
|
||||
|
||||
The REPL (`nix repl`) supports pressing `<TAB>` to complete a partial expression, but now also supports completing the special :colon commands as well (`:b`, `:edit`, `:doc`, etc), if the line starts with a colon.
|
||||
|
||||
Many thanks to [Qyriad](https://git.lix.systems/Qyriad) for this.
|
||||
- `:edit`ing a file in Nix store no longer reloads the repl [fj#341](https://git.lix.systems/lix-project/lix/issues/341) [cl/1620](https://gerrit.lix.systems/c/lix/+/1620)
|
||||
|
||||
Calling `:edit` from the repl now only reloads if the file being edited was outside of Nix store.
|
||||
That means that all the local variables are now preserved across `:edit`s of store paths.
|
||||
This is always safe because the store is read-only.
|
||||
|
||||
Many thanks to [goldstein](https://git.lix.systems/goldstein) for this.
|
||||
- `:log` in repl now works on derivation paths [fj#51](https://git.lix.systems/lix-project/lix/issues/51) [cl/1716](https://gerrit.lix.systems/c/lix/+/1716)
|
||||
|
||||
`:log` can now accept store derivation paths in addition to derivation expressions.
|
||||
|
||||
Many thanks to [goldstein](https://git.lix.systems/goldstein) for this.
|
||||
|
||||
## Fixes
|
||||
- Define integer overflow in the Nix language as an error [fj#423](https://git.lix.systems/lix-project/lix/issues/423) [cl/1594](https://gerrit.lix.systems/c/lix/+/1594) [cl/1595](https://gerrit.lix.systems/c/lix/+/1595) [cl/1597](https://gerrit.lix.systems/c/lix/+/1597) [cl/1609](https://gerrit.lix.systems/c/lix/+/1609)
|
||||
|
||||
Previously, integer overflow in the Nix language invoked C++ level signed overflow, which was undefined behaviour, but *probably* manifested as wrapping around on overflow.
|
||||
|
||||
Since prior to the public release of Lix, Lix had C++ signed overflow defined to crash the process and nobody noticed this having accidentally removed overflow from the Nix language for three months until it was caught by fiddling around.
|
||||
Given the significant body of actual Nix code that has been evaluated by Lix in that time, it does not appear that nixpkgs or much of importance depends on integer overflow, so it is safe to turn into an error.
|
||||
|
||||
Some other overflows were fixed:
|
||||
- `builtins.fromJSON` of values greater than the maximum representable value in a signed 64-bit integer will generate an error.
|
||||
- `nixConfig` in flakes will no longer accept negative values for configuration options.
|
||||
|
||||
Integer overflow now looks like the following:
|
||||
|
||||
```
|
||||
» nix eval --expr '9223372036854775807 + 1'
|
||||
error: integer overflow in adding 9223372036854775807 + 1
|
||||
```
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
- Fix nix-collect-garbage --dry-run [fj#432](https://git.lix.systems/lix-project/lix/issues/432) [cl/1566](https://gerrit.lix.systems/c/lix/+/1566)
|
||||
|
||||
`nix-collect-garbage --dry-run` did not previously give any output - it simply
|
||||
exited without even checking to see what paths would be deleted.
|
||||
|
||||
```
|
||||
$ nix-collect-garbage --dry-run
|
||||
$
|
||||
```
|
||||
|
||||
We updated the behaviour of the flag such that instead it prints out how many
|
||||
paths it *would* delete, but doesn't actually delete them.
|
||||
|
||||
```
|
||||
$ nix-collect-garbage --dry-run
|
||||
finding garbage collector roots...
|
||||
determining live/dead paths...
|
||||
...
|
||||
<nix store paths>
|
||||
...
|
||||
2670 store paths deleted, 0.00MiB freed
|
||||
$
|
||||
```
|
||||
|
||||
Many thanks to [Quantum Jump](https://github.com/QuantumBJump) for this.
|
||||
- Fix unexpectedly-successful GC failures on macOS [fj#446](https://git.lix.systems/lix-project/lix/issues/446) [cl/1723](https://gerrit.lix.systems/c/lix/+/1723)
|
||||
|
||||
Has the following happened to you on macOS? This failure has been successfully eliminated, thanks to our successful deployment of advanced successful-failure detection technology (it's just `if (failed && errno == 0)`. Patent pending<sup>not really</sup>):
|
||||
|
||||
```
|
||||
$ nix-store --gc --print-dead
|
||||
finding garbage collector roots...
|
||||
error: Listing pid 87261 file descriptors: Undefined error: 0
|
||||
```
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
- `nix copy` is now several times faster at `querying info about /nix/store/...` [fj#366](https://git.lix.systems/lix-project/lix/issues/366) [cl/1462](https://gerrit.lix.systems/c/lix/+/1462)
|
||||
|
||||
We fixed a locking bug that serialized `querying info about /nix/store/...`
|
||||
onto just one thread such that it was eating `O(paths to copy * latency)` time
|
||||
while setting up to copy paths to s3 and other stores. It is now `nproc` times
|
||||
faster.
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
|
||||
## Development
|
||||
- clang-tidy support [fj#147](https://git.lix.systems/lix-project/lix/issues/147) [cl/1697](https://gerrit.lix.systems/c/lix/+/1697)
|
||||
|
||||
`clang-tidy` can be used to lint Lix with a limited set of lints using `ninja -C build clang-tidy` and `ninja -C build clang-tidy-fix`.
|
||||
In practice, this fixes the built-in meson rule that was used the same as above being broken ever since precompiled headers were introduced.
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
- Lix now supports building with UndefinedBehaviorSanitizer [cl/1483](https://gerrit.lix.systems/c/lix/+/1483) [cl/1481](https://gerrit.lix.systems/c/lix/+/1481) [cl/1669](https://gerrit.lix.systems/c/lix/+/1669)
|
||||
|
||||
You can now build Lix with the configuration option `-Db_sanitize=undefined,address` and it will both work and pass tests with both AddressSanitizer and UndefinedBehaviorSanitizer enabled.
|
||||
To use ASan specifically, you have to set `-Dgc=disabled`, which an error message will tell you to do if necessary anyhow.
|
||||
|
||||
Furthermore, tests passing with Clang ASan+UBSan is checked on every change in CI.
|
||||
|
||||
For a list of undefined behaviour found by tooling usage, see [the gerrit topic "undefined-behaviour"](https://gerrit.lix.systems/q/topic:%22undefined-behaviour%22).
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
@@ -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 ]]; then 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.
|
||||
@@ -1,870 +0,0 @@
|
||||
# Lix 2.93 "Bici Bici" (2025-05-09)
|
||||
# Lix 2.93.3 (2025-07-22)
|
||||
## Improvements
|
||||
|
||||
- `--keep-failed` chowns the build directory to the user that request the build [cl/3678](https://gerrit.lix.systems/c/lix/+/3678)
|
||||
|
||||
Running a build with `--keep-failed` now chowns the temporary directory from the
|
||||
builder user and group to the user that request the build if the build came from
|
||||
a local user connected to the daemon. This makes inspecting failed derivations a
|
||||
lot easier. On Linux the build directory made visible to the user will not be in
|
||||
the same path as it was in the sandbox and continuing builds will usually break.
|
||||
|
||||
Many thanks to [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
|
||||
|
||||
|
||||
|
||||
# Lix 2.93.2 (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/3444](https://gerrit.lix.systems/c/lix/+/3444) [cl/3528](https://gerrit.lix.systems/c/lix/+/3528)
|
||||
|
||||
Following the initial mitigation of **CVE-2025-52992** in `cl/3444`, 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**.
|
||||
|
||||
The affected patches (`cl/3444`) have been rolled back for the time being.
|
||||
|
||||
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/3501](https://gerrit.lix.systems/c/lix/+/3501)
|
||||
|
||||
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.93.1 (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/3442](https://gerrit.lix.systems/c/lix/+/3442)
|
||||
|
||||
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/3444](https://gerrit.lix.systems/c/lix/+/3444)
|
||||
|
||||
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/3443](https://gerrit.lix.systems/c/lix/+/3443)
|
||||
|
||||
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.
|
||||
|
||||
- Remove reliance on Bash for remote stores via SSH [fj#830](https://git.lix.systems/lix-project/lix/issues/830) [fj#805](https://git.lix.systems/lix-project/lix/issues/805) [fj#304](https://git.lix.systems/lix-project/lix/issues/304) [cl/3159](https://gerrit.lix.systems/c/lix/+/3159)
|
||||
|
||||
The pre-flight `echo started` handshake -- added years ago to catch race conditions -- has been removed.
|
||||
|
||||
After removal of connection sharing in Lix 2.93, it required a Bash-compatible shell and a standard `echo`, so it failed on:
|
||||
|
||||
* builders protected by `ForceCommand` wrappers (e.g. `nix-remote-build`),
|
||||
* BusyBox / initrd images with no Bash,
|
||||
* hosts using non-POSIX shells such as Nushell.
|
||||
|
||||
The race the probe once addressed was tied to SSH connection-sharing -- since connection-sharing code has already been removed, the probe is now pointless.
|
||||
|
||||
Real connection or protocol errors are now left to SSH/Nix to report directly.
|
||||
|
||||
This is technically a breaking change if you had scripts that relied on the literal "started" which needs to be updated to rely on other signals, e.g., exit codes.
|
||||
|
||||
Many thanks to [Raito Bezarius](https://git.lix.systems/raito) for this.
|
||||
|
||||
|
||||
## Miscellany
|
||||
|
||||
- Deprecation of CA derivations, dynamic derivations, and impure derivations [fj#815](https://git.lix.systems/lix-project/lix/issues/815)
|
||||
|
||||
Content-addressed derivations are now deprecated and slated for removal in Lix 2.94.
|
||||
We're doing this because the CA derivation system has been a known cause of problems
|
||||
and inconsistencies, is unmaintained, habitually makes improving the store code very
|
||||
difficult (or blocks such improvements outright), and is beset by a number of design
|
||||
flaws that in our opinion cannot be fixed without a full reimplementation from zero.
|
||||
Dynamic derivations and impure derivations are built on the CA derivation framework,
|
||||
and owing to this they too are deprecated and slated for removal in another release.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Lix 2.93.0 (2025-05-09)
|
||||
## Breaking Changes
|
||||
|
||||
- more deprecated features
|
||||
|
||||
This release cycle features a new batch of deprecated (anti-)features.
|
||||
You can opt in into the old behavior with `--extra-deprecated-features` or any equivalent configuration option.
|
||||
|
||||
- `cr-line-endings`: Current handling of CR (`\r`) or CRLF (`\r\n`) line endings in Nix is inconsistent and broken, and will lead to unexpected evaluation results with certain strings. Given that fixing the semantics might silently alter the evaluation result of derivations, the only option at the moment is to disallow them altogether. More proper support for CRLF is planned to be added back again in the future. Until then, all files must use `\n` exclusively.
|
||||
- `nul-bytes`: Currently the Nix grammar allows NUL bytes (`\0`) in strings, and thus indirectly also in identifiers. Unfortunately, several core parts of the code base still work with NUL-terminated strings and cannot easily be migrated. Also note that it is still possible to introduce NUL bytes and thus problematic behavior via other means, those are tracked separately.
|
||||
|
||||
Many thanks to [piegames](https://git.lix.systems/piegames) and [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
|
||||
- Removal of the `recursive-nix` experimental feature [fj#767](https://git.lix.systems/lix-project/lix/issues/767) [cl/2872](https://gerrit.lix.systems/c/lix/+/2872)
|
||||
|
||||
The `recursive-nix` experimental feature and all associated code have been removed.
|
||||
|
||||
`recursive-nix` enabled running Nix operations (like evaluations and builds) *inside* a derivation builder. This worked by spawning a temporary Nix daemon socket within the build environment, allowing the derivation to emit outputs that appeared in the outer store. This was primarily used to prototype **dynamic derivations** (dyndrvs), where build plans are generated on-the-fly during a build.
|
||||
|
||||
However, this approach introduced critical issues:
|
||||
|
||||
- It entrenched the legacy Nix daemon protocol as part of the derivation ABI, which is a blocker for future stabilization.
|
||||
- It imposed tight coupling between sandbox setup code and knowledge of Nix internals, complicating refactoring and long-term maintenance.
|
||||
- It was never intended to be the final design for dynamic derivations. The original Nix implementation team, who are leading dyndrv development, have agreed it will be replaced (likely via `varlink` or similar) before any stabilization.
|
||||
- There is currently no known usage of `recursive-nix` on `lix` or elsewhere **in production**.
|
||||
|
||||
If you're using `recursive-nix` for something niche or experimental, we'd love to hear from you on the RFD issue.
|
||||
You can still run `nix` inside a builder manually if needed — including with isolated user namespaces and fake stores — but the special daemon-handshake machinery is gone.
|
||||
|
||||
This removal unblocks several important internal cleanups.
|
||||
|
||||
Many thanks to [Raito Bezarius](https://git.lix.systems/raito) for this.
|
||||
|
||||
- Flake inputs/`builtins.fetchTree` invocations with `type = "file"` now have consistent (but different from previous versions) resulting paths [fj#750](https://git.lix.systems/lix-project/lix/issues/750) [cl/2864](https://gerrit.lix.systems/c/lix/+/2864)
|
||||
|
||||
Previously `fetchTree { type = "file"; url = "...", narHash = "sha256-..."; }` could return a different result depending on whether someone has run `nix store add-path --name source ...` on a path with the same `narHash` as the flake input/`fetchTree` invocation (or if such a path exists in an accessible binary cache).
|
||||
|
||||
In the past `type = "file"` flake inputs were, in contrast to all other flake inputs, hashed in *flat* hash mode rather than *recursive* hash mode.
|
||||
The difference between the two is that *flat* mode hashes are just what you get from `sha256sum` of a single file, whereas *recursive* hashes are the SHA256 sum of a NAR (Nix ARchive, a deterministic tarball-like format) of a file tree.
|
||||
|
||||
Much of flakes assumes that everything is recursive-hashed including `nix flake archive`, substitution of flake inputs from binary caches, and more, which led to the substitution path code being taken if such a path is present, yielding a different store path non-deterministically.
|
||||
|
||||
To fix this non-deterministic evaluation bug, we needed to break derivation hash stability, so some Nix evaluations now produce different results than previous versions of Lix.
|
||||
Lix now has consistent behaviour with CppNix 2.24 with respect to `file` flake inputs: they are *always* recursively hashed.
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
|
||||
- Builders are always started in a fresh cgroup namespace [cl/1996](https://gerrit.lix.systems/c/lix/+/1996)
|
||||
|
||||
If you haven't enabled the experimental `cgroups` feature, Nix previously launched builder processes in new namespaces but did not create new cgroup namespaces. As a result, derivations could access and observe the parent cgroup namespace.
|
||||
|
||||
Although this update introduces a breaking change, it ensures that all derivations now start in a fresh cgroup namespace by default. This reduces potential impurities observable within the sandbox, improving the likelihood of reproducible builds across different environments.
|
||||
|
||||
Many thanks to [Raito Bezarius](https://git.lix.systems/raito) for this.
|
||||
|
||||
- `nix-instantiate --parse` outputs json [fj#487](https://git.lix.systems/lix-project/lix/issues/487) [nix#11124](https://github.com/NixOS/nix/issues/11124) [nix#4726](https://github.com/NixOS/nix/issues/4726) [nix#3077](https://github.com/NixOS/nix/issues/3077) [cl/2190](https://gerrit.lix.systems/c/lix/+/2190)
|
||||
|
||||
`nix-instantiate --parse` does not print out the AST in a Nix-like format anymore.
|
||||
Instead, it now prints a JSON representation of the internal expression tree.
|
||||
Tooling should not rely on the stdout of `nix-instantiate --parse`.
|
||||
|
||||
We've done our best to ensure that the new behavior is as compatible with the old one as possible.
|
||||
If you depend on the old behavior in ways that are not covered anymore or are otherwise negatively affected by this change,
|
||||
then please reach out so that we can find a sustainable solution together.
|
||||
|
||||
Many thanks to [piegames](https://git.lix.systems/piegames) and [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
|
||||
- Remove experimental repl-flake [gh#10103](https://github.com/NixOS/nix/issues/10103) [fj#557](https://git.lix.systems/lix-project/lix/issues/557) [gh#10299](https://github.com/NixOS/nix/pull/10299) [cl/2147](https://gerrit.lix.systems/c/lix/+/2147)
|
||||
|
||||
The `repl-flake` experimental feature flag has been removed, its functionality is now the default when `flakes` experimental feature is active. The `nix repl` command now works like the rest of the new CLI in that `nix repl {path}` now tries to load a flake at `{path}` (or fails if the `flakes` experimental feature isn't enabled).
|
||||
|
||||
Many thanks to [Jonathan De Troye](https://github.com/detroyejr) and [KFears](https://git.lix.systems/kfearsoff) for this.
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- `lix foo` now invokes `lix-foo` from PATH [cl/2119](https://gerrit.lix.systems/c/lix/+/2119)
|
||||
|
||||
Lix introduces the ability to extend the Nix command line by adding custom
|
||||
binaries to the `PATH`, similar to how Git integrates with other tools. This
|
||||
feature allows developers and end users to enhance their workflow by
|
||||
integrating additional functionalities directly into the Nix CLI.
|
||||
|
||||
#### Examples
|
||||
|
||||
For example, a user can create a custom deployment tool, `lix-deploy-tool`, and
|
||||
place it in their `PATH`. This allows them to execute `lix deploy-tool`
|
||||
directly from the command line, streamlining the process of deploying
|
||||
applications without needing to switch contexts or use separate commands.
|
||||
|
||||
#### Limitations
|
||||
|
||||
For now, autocompletion is supported to discover new custom commands, but the
|
||||
documentation will not render them. Argument autocompletion of the custom
|
||||
command is not supported either.
|
||||
|
||||
This is also locked behind a new experimental feature called
|
||||
`lix-custom-sub-commands` to enable developing all the required features.
|
||||
|
||||
Only the top-level `lix` command can be extended, this is an artificial
|
||||
limitation for the time being until we flesh out this feature.
|
||||
|
||||
#### Outline
|
||||
|
||||
In the future, this feature may pave the way for moving the Flake subcommand
|
||||
line to its own standalone binary, allowing for a more focused approach to
|
||||
managing Nix Flakes while letting the community explore alternatives to
|
||||
dependency management.
|
||||
|
||||
Many thanks to [Raito Bezarius](https://git.lix.systems/raito) for this.
|
||||
|
||||
- `nix-env --install` now accepts a `--priority` flag [cl/2607](https://gerrit.lix.systems/c/lix/+/2607)
|
||||
|
||||
`nix-env --install` now has an optional `--priority` flag.
|
||||
|
||||
Previously, it was only possible to specify a priority by adding a
|
||||
`meta.priority` attribute to a derivation. `meta` attributes only exist during
|
||||
eval, so that wouldn't work for installing a store path. It was also possible
|
||||
to change a priority after initial installation using `nix-env --set-flag`,
|
||||
however if there is already a conflict that needs to be resolved via priorities,
|
||||
this will not work.
|
||||
|
||||
Now, a priority can be set at install time using `--priority`, which allows for
|
||||
cleanly overriding the priority at install time.
|
||||
|
||||
#### Example
|
||||
|
||||
```console
|
||||
$ nix-build
|
||||
$ nix-env --install --priority 100 ./result
|
||||
```
|
||||
|
||||
Many thanks to [Andrew Hamon](https://github.com/andrewhamon) for this.
|
||||
|
||||
- Add support for eBPF USDT/dtrace probes inside Lix [fj#727](https://git.lix.systems/lix-project/lix/issues/727) [cl/2884](https://gerrit.lix.systems/c/lix/+/2884)
|
||||
|
||||
eBPF tracers like `bpftrace` and `dtrace` are a group of similar tools for debugging production systems.
|
||||
User-space statically defined tracing probes (USDT) allow for defining zero or near-zero disabled-probe-effect probes, thus allowing instrumentation of hot paths in production builds.
|
||||
Lix now has internal support for defining these probes and has shipped its first probe.
|
||||
|
||||
As of this writing it is available by default in the Linux build of Lix.
|
||||
|
||||
To try it out on Linux, you can use the following example command:
|
||||
|
||||
```
|
||||
$ sudo bpftrace -l 'usdt:/path/to/liblixstore.so:*:*'
|
||||
usdt:/path/to/liblixstore.so:lix_store:filetransfer__read
|
||||
|
||||
$ sudo bpftrace -e 'usdt:*:lix_store:filetransfer__read { printf("%s read %d\n", str(arg0), arg1); }'
|
||||
Attaching 1 probe...
|
||||
https://cache.nixos.org/wvpzaycmvs39h5bcsfrxkjsg48mj4h73.narinf.. read 8192
|
||||
https://cache.nixos.org/wvpzaycmvs39h5bcsfrxkjsg48mj4h73.narinf.. read 8192
|
||||
https://cache.nixos.org/nar/1qshsc30nlarzdig0v9b1aasdkwaxhnv0a0.. read 65536
|
||||
https://cache.nixos.org/nar/1qshsc30nlarzdig0v9b1aasdkwaxhnv0a0.. read 65536
|
||||
```
|
||||
|
||||
Note that bpftrace does not offer any way to list the arguments to USDT probes in a human readable form.
|
||||
To get the probe definitions, see the `*.d` files in the Lix source code, for example, `lix/libstore/trace-probes.d`.
|
||||
|
||||
For more resources on eBPF/bpftrace and dtrace, see:
|
||||
* The book "BPF Performance Tools" by Brendan Gregg, which discusses bpftrace at length.
|
||||
* <https://ebpf.io/get-started/>
|
||||
* [Illumos' dtrace book](https://illumos.org/books/dtrace/preface.html)
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
|
||||
|
||||
## Improvements
|
||||
|
||||
- Always print `post-build-hook` logs [fj#675](https://git.lix.systems/lix-project/lix/issues/675) [cl/2801](https://gerrit.lix.systems/c/lix/+/2801)
|
||||
|
||||
Logs of `post-build-hook` are now printed unconditionally.
|
||||
They used to be tied to whether print-build-logs is set, which made debugging them a nightmare when they fail, since the failure output would be eaten if build logs are disabled.
|
||||
Most usages of `post-build-hook` are pretty quiet especially compared to build logs, so it should not be that bothersome to not be able to turn off.
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
|
||||
- Crashes land in syslog now [cl/2640](https://gerrit.lix.systems/c/lix/+/2640)
|
||||
|
||||
When Lix crashes with unexpected exceptions and in some other conditions, it prints bug reporting instructions.
|
||||
Previously, these only landed in stderr and not in syslog.
|
||||
However, on larger Lix installations, it may be the case that Lix crashes in the client without the logs landing in the system logs, which impeded diagnosis.
|
||||
|
||||
Now, such crashes always land in syslog too.
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
|
||||
- Deletion of specific paths no longer fails fast [cl/2778](https://gerrit.lix.systems/c/lix/+/2778)
|
||||
|
||||
`nix-store --delete` and `nix store delete` now continue deleting
|
||||
paths even if some of the given paths are still live. An error is only
|
||||
thrown once deletion of all the given paths has been
|
||||
attempted. Previously, if some paths were deletable and others
|
||||
weren't, the deletable ones would be deleted iff they preceded the
|
||||
live ones in lexical sort order.
|
||||
|
||||
The error message for still-live paths no longer reports the paths
|
||||
that could not be deleted, because there could potentially be many of
|
||||
these.
|
||||
|
||||
Many thanks to [lheckemann](https://git.lix.systems/lheckemann) for this.
|
||||
|
||||
- `--skip-live` for path deletion [cl/2778](https://gerrit.lix.systems/c/lix/+/2778)
|
||||
|
||||
`nix-store --delete` and `nix store delete` now support a
|
||||
`--skip-live` option and a `--delete-closure` option.
|
||||
|
||||
This makes custom garbage-collection logic a lot easier to implement
|
||||
and experiment with:
|
||||
|
||||
- Paths known to be large can be thrown at `nix store delete` without
|
||||
having to manually filter out those that are still reachable from a
|
||||
root, e.g.
|
||||
`nix store delete /nix/store/*mbrola-voices*`
|
||||
|
||||
- The `--delete-closure` option allows extending this to paths that are
|
||||
not large themselves but do have a large closure size, e.g.
|
||||
`nix store delete /nix/store/*nixos-system-gamingpc*`.
|
||||
|
||||
- Other heuristics like atime-based deletion can be applied more
|
||||
easily, because `nix store delete` once again takes over the task of
|
||||
working out which paths can't be deleted.
|
||||
|
||||
Many thanks to [lheckemann](https://git.lix.systems/lheckemann) for this.
|
||||
|
||||
- Allow `nix store diff-closures` to output JSON [cl/2360](https://gerrit.lix.systems/c/lix/+/2360)
|
||||
|
||||
Add the `--json` option to the `nix store diff-closures` command to allow users to collect diff information into a machine readable format.
|
||||
|
||||
```bash
|
||||
$ build/lix/nix/nix store diff-closures --json /run/current-system /nix/store/n1prick95pihd4lkv58nn3pzg1yivcdb-neovim-0.10.4/bin/nvim | jq | head -n 23
|
||||
{
|
||||
"packages": {
|
||||
"02overridedns": {
|
||||
"sizeDelta": -688,
|
||||
"versionsAfter": [],
|
||||
"versionsBefore": [
|
||||
""
|
||||
]
|
||||
},
|
||||
"50-coredump.conf": {
|
||||
"sizeDelta": -1976,
|
||||
"versionsAfter": [],
|
||||
"versionsBefore": [
|
||||
""
|
||||
]
|
||||
},
|
||||
"Diff": {
|
||||
"sizeDelta": -514864,
|
||||
"versionsAfter": [],
|
||||
"versionsBefore": [
|
||||
"0.4.1"
|
||||
]
|
||||
},
|
||||
```
|
||||
|
||||
Many thanks to [Xavier Maso](https://github.com/pamplemousse) for this.
|
||||
|
||||
- Show all missing and unexpected arguments in erroneous function calls [cl/2477](https://gerrit.lix.systems/c/lix/+/2477)
|
||||
|
||||
When calling a function that expects an attribute set, lix will now show all
|
||||
missing and unexpected arguments.
|
||||
e.g. with `({ a, b, c } : a + b + c) { a = 1; d = 1; }` lix will now show the error:
|
||||
```
|
||||
[...]
|
||||
error: function 'anonymous lambda' called without required arguments 'b' and 'c' and with unexpected argument 'd'
|
||||
[...]
|
||||
```
|
||||
Previously lix would just show `b`.
|
||||
Furthermore lix will now only suggest arguments that aren't yet used.
|
||||
e.g. with `({ a?1, b?1, c?1 } : a + b + c) { a = 1; d = 1; e = 1; }` lix will now show the error:
|
||||
```
|
||||
[...]
|
||||
error: function 'anonymous lambda' called with unexpected arguments 'd' and 'e'
|
||||
at «string»:1:2:
|
||||
1| ({ a?1, b?1, c?1 } : a + b + c) { a = 1; d = 1; e = 1; }
|
||||
| ^
|
||||
Did you mean one of b or c?
|
||||
```
|
||||
Previously lix would also suggest `a`.
|
||||
Suggestions are unfortunately still currently just for the first missing argument.
|
||||
|
||||
Many thanks to [Zitrone](https://git.lix.systems/quantenzitrone) for this.
|
||||
|
||||
- REPL improvements [cl/2319](https://gerrit.lix.systems/c/lix/+/2319) [cl/2320](https://gerrit.lix.systems/c/lix/+/2320) [cl/2321](https://gerrit.lix.systems/c/lix/+/2321)
|
||||
|
||||
The REPL has seen various minor improvements:
|
||||
|
||||
- Variable declarations have been improved, making copy-pasting code from attrsets a lot easier:
|
||||
- Declarations can now optionally end with a semicolon
|
||||
- Multiple declarations can be done within one command, separated by semicolon
|
||||
- The `foo.bar = "baz";` syntax from attrsets is also supported, however without the attrset merging rules and with restrictions on dynamic attrs like in `let` bindings.
|
||||
- Variable names now use the proper Nix grammar rules, instead of a regex that only vaguely matched legal identifiers.
|
||||
- Better error messages overall
|
||||
- The `:env` command to print currently available variables now also works outside of debug mode
|
||||
- Adding variables to the REPL now prints a small message on success
|
||||
|
||||
Many thanks to [piegames](https://git.lix.systems/piegames) for this.
|
||||
|
||||
- Consistently use SRI hashes in hash mismatch errors [cl/2868](https://gerrit.lix.systems/c/lix/+/2868)
|
||||
|
||||
Previously there were a few weird cases (flake inputs, e.g., among others) where Lix would print the old Nix base-32 hash format (sha256:abcd...) rather than the newer [SRI base64 format](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) (sha256-AAAA...) that is used in most Lix hash mismatch errors.
|
||||
This made it annoying to compare them to hashes shown by most of the modern UI surface of Lix which uses SRI.
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
|
||||
- Allow specifying ports for remote ssh[-ng] stores [cl/2432](https://gerrit.lix.systems/c/lix/+/2432)
|
||||
|
||||
You can now specify which port should be used for a remote ssh store (e.g. for remote/distributed builds) through a uri parameter.
|
||||
E.g., when a remote builder `foo` is listening on port `1234` instead of the default, it can be specified like this `ssh://foo?port=1234`.
|
||||
|
||||
Many thanks to [seppel3210](https://github.com/Seppel3210) for this.
|
||||
|
||||
- Implicit `__toString` now have stack trace entries [cl/3055](https://gerrit.lix.systems/c/lix/+/3055)
|
||||
|
||||
Coercion of attribute sets to strings via their `__toString` attribute now produce stack
|
||||
frames pointing to the coercion site and the attribute definition. This makes locating a
|
||||
coercion function error easier as the fault location is now more likely to be presented.
|
||||
|
||||
Previously:
|
||||
```
|
||||
nix-repl> builtins.substring 1 1 "${{ __toString = self: throw ''bar''; }}"
|
||||
error:
|
||||
… while calling the 'substring' builtin
|
||||
at «string»:1:1:
|
||||
1| builtins.substring 1 1 "${{ __toString = self: throw ''bar''; }}"
|
||||
| ^
|
||||
|
||||
… caused by explicit throw
|
||||
at «string»:1:48:
|
||||
1| builtins.substring 1 1 "${{ __toString = self: throw ''bar''; }}"
|
||||
| ^
|
||||
|
||||
error: bar
|
||||
```
|
||||
|
||||
Now:
|
||||
```
|
||||
nix-repl> builtins.substring 1 1 "${{ __toString = self: throw ''bar''; }}"
|
||||
error:
|
||||
… while calling the 'substring' builtin
|
||||
at «string»:1:1:
|
||||
1| builtins.substring 1 1 "${{ __toString = self: throw ''bar''; }}"
|
||||
| ^
|
||||
|
||||
… while converting a set to string
|
||||
at «string»:1:25:
|
||||
1| builtins.substring 1 1 "${{ __toString = self: throw ''bar''; }}"
|
||||
| ^
|
||||
|
||||
… from call site
|
||||
at «string»:1:29:
|
||||
1| builtins.substring 1 1 "${{ __toString = self: throw ''bar''; }}"
|
||||
| ^
|
||||
|
||||
… while calling '__toString'
|
||||
at «string»:1:42:
|
||||
1| builtins.substring 1 1 "${{ __toString = self: throw ''bar''; }}"
|
||||
| ^
|
||||
|
||||
… caused by explicit throw
|
||||
at «string»:1:48:
|
||||
1| builtins.substring 1 1 "${{ __toString = self: throw ''bar''; }}"
|
||||
| ^
|
||||
|
||||
error: bar
|
||||
```
|
||||
|
||||
Many thanks to [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
|
||||
|
||||
## Fixes
|
||||
|
||||
- Avoid unnecessarily killing processes for the build user's UID [nix#9142](https://github.com/NixOS/nix/issues/9142) [fj#667](https://git.lix.systems/lix-project/lix/issues/667)
|
||||
|
||||
We no longer kill all processes under the build user's UID before and after
|
||||
builds on Linux with sandboxes enabled.
|
||||
|
||||
This avoids unrelated processes being killed. This might happen for instance,
|
||||
if the user is running Lix inside a container, wherein the build users use the same UIDs as the daemon's.
|
||||
|
||||
Many thanks to [teofilc](https://git.lix.systems/teofilc) for this.
|
||||
|
||||
- Forbid impure path accesses in pure evaluation mode again [cl/2708](https://gerrit.lix.systems/c/lix/+/2708)
|
||||
|
||||
Lix 2.92.0 mistakenly started allowing the access to ancestors of allowed paths in pure evaluation mode.
|
||||
This made it possible to bypass the purity restrictions, for example by copying arbitrary files to the store:
|
||||
```nix
|
||||
builtins.path {
|
||||
path = "/";
|
||||
filter = …;
|
||||
}
|
||||
```
|
||||
Restore the previous behaviour of prohibiting such impure accesses.
|
||||
|
||||
Many thanks to [alois31](https://git.lix.systems/alois31) for this.
|
||||
|
||||
- Ctrl-C works correctly on macOS again [fj#729](https://git.lix.systems/lix-project/lix/issues/729) [cl/3066](https://gerrit.lix.systems/c/lix/+/3066)
|
||||
|
||||
Due to a kernel bug in macOS's `poll(2)` implementation where it would forget about event subscriptions, our detection of closed connections in the Lix daemon didn't work and left around lingering daemon processes.
|
||||
We have rewritten that thread to use `kqueue(2)`, which is what the `poll(2)` implementation uses internally in the macOS kernel, so now Ctrl-C on clients will reliably terminate daemons once more.
|
||||
|
||||
This FD close monitoring has had the highest Apple bug ID references per line of code anywhere in the project, and hopefully not using poll anymore will stop us hitting bugs in poll.
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
|
||||
- Fetch peer PID for daemon connections on macOS [fj#640](https://git.lix.systems/lix-project/lix/issues/640) [cl/2453](https://gerrit.lix.systems/c/lix/+/2453)
|
||||
|
||||
`nix-daemon` will now fetch the peer PID for connections on macOS, to match behavior with Linux.
|
||||
Besides showing up in the log output line, If `nix-daemon` is given an argument (such as `--daemon`)
|
||||
that argument will be overwritten with the peer PID for the forked process that handles the connection,
|
||||
which can be used for debugging purposes.
|
||||
|
||||
Many thanks to [lilyball](https://git.lix.systems/lilyball) for this.
|
||||
|
||||
- Test group membership better on macOS [gh#5885](https://github.com/NixOS/nix/issues/5885) [cl/2566](https://gerrit.lix.systems/c/lix/+/2566)
|
||||
|
||||
`nix-daemon` will now test group membership better on macOS for `trusted-users` and `allowed-users`.
|
||||
It not only fetches the peer gid (which fixes `@staff`) but it also asks opendirectory for group
|
||||
membership checks instead of just using the group database, which means nested groups (like `@_developer`)
|
||||
and groups with synthesized membership (like `@localaccounts`) will work.
|
||||
|
||||
Many thanks to [lilyball](https://git.lix.systems/lilyball) for this.
|
||||
|
||||
- `nix store delete` no longer builds paths [cl/2782](https://gerrit.lix.systems/c/lix/+/2782)
|
||||
|
||||
`nix store delete` no longer realises the installables
|
||||
specified. Previously, `nix store delete nixpkgs#hello` would download
|
||||
hello only to immediately delete it again. Now, it exits with an error
|
||||
if given an installable that isn't in the store.
|
||||
|
||||
Many thanks to [lheckemann](https://git.lix.systems/lheckemann) for this.
|
||||
|
||||
- Fix nix-store --delete on paths with remaining referrers [cl/2783](https://gerrit.lix.systems/c/lix/+/2783)
|
||||
|
||||
Nix 2.5 introduced a regression whereby `nix-store --delete` and `nix
|
||||
store delete` started to fail when trying to delete a path that was
|
||||
still referenced by other paths, even if the referrers were not
|
||||
reachable from any GC roots. The old behaviour, where attempting to
|
||||
delete a store path would also delete its referrer closure, is now
|
||||
restored.
|
||||
|
||||
Many thanks to [lheckemann](https://git.lix.systems/lheckemann) for this.
|
||||
|
||||
- Add a straightforward way to detect if in a Nix3 Shell [nix#6677](https://github.com/NixOS/nix/issues/6677) [nix#3862](https://github.com/NixOS/nix/issues/3862) [cl/2090](https://gerrit.lix.systems/c/lix/+/2090)
|
||||
|
||||
Running `nix shell` or `nix develop` will now set `IN_NIX_SHELL` to
|
||||
either `pure` or `impure`, depending on whether `--ignore-environment`
|
||||
is passed. `nix develop` will always be an impure environment.
|
||||
|
||||
Many thanks to [Ersei Saggi](https://github.com/9p4) for this.
|
||||
|
||||
- Fix experimental and deprecated features showing as integers in `nix config show --json` [fj#738](https://git.lix.systems/lix-project/lix/issues/738) [cl/2882](https://gerrit.lix.systems/c/lix/+/2882)
|
||||
|
||||
Internal changes in 2.92 caused `nix config show --json` to show deprecated and experimental features not as the list of named features 2.91 and earlier produced, but as integers. This has been fixed.
|
||||
|
||||
Many thanks to [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
|
||||
- `builtins.fetchTree` is no longer visible in `builtins` when flakes are disabled [cl/2399](https://gerrit.lix.systems/c/lix/+/2399)
|
||||
|
||||
`builtins.fetchTree` is the foundation of flake inputs and flake lock files, but is not fully specified in behaviour, which leads to regressions, behaviour differences with CppNix, and other unfun times.
|
||||
It's gated behind the `flakes` experimental feature, but prior to now, would throw an uncatchable error at runtime when used without the `flakes` feature enabled.
|
||||
Now it's like other builtins which are experimental feature gated, where it is not visible without the relevant feature enabled.
|
||||
|
||||
This fixes a bug in using Eelco Dolstra's version of flake-compat on Lix (and a divergence with CppNix): https://github.com/edolstra/flake-compat/issues/66
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
|
||||
- fix usage of `builtins.filterSource` and `builtins.path` with the filter argument when using chroot stores [nix#11503](https://github.com/NixOS/nix/issues/11503)
|
||||
|
||||
The semantics of `builtins.filterSource` (and the `filter` argument for
|
||||
`builtins.path`) have been adjusted regarding how paths inside the Nix store
|
||||
are handled.
|
||||
|
||||
Previously, when evaluating whether a path should be included, the filtering
|
||||
function received the **physical path** if the source was inside the chroot store.
|
||||
|
||||
Now, it receives the **logical path** instead.
|
||||
|
||||
This ensures consistency in path handling and avoids potential
|
||||
misinterpretations of paths within the evaluator, which led to various fallouts
|
||||
mentioned in <https://github.com/NixOS/nixpkgs/pull/369694>.
|
||||
|
||||
Many thanks to [lily](https://git.lix.systems/lilyinstarlight), [alois31](https://git.lix.systems/alois31), and [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
|
||||
- Fix `--help` formatting [fj#622](https://git.lix.systems/lix-project/lix/issues/622) [cl/2776](https://gerrit.lix.systems/c/lix/+/2776)
|
||||
|
||||
The help printed when invoking `nix` or `nix-store` and subcommands with `--help` previously contained garbled terminal escapes. These have been removed.
|
||||
|
||||
Many thanks to [lheckemann](https://git.lix.systems/lheckemann) for this.
|
||||
|
||||
- Parsing failures in flake.lock no longer crash Lix [fj#559](https://git.lix.systems/lix-project/lix/issues/559) [cl/2401](https://gerrit.lix.systems/c/lix/+/2401)
|
||||
|
||||
Failure to parse `flake.lock` no longer hard-crashes Lix and instead produces a nice error message.
|
||||
|
||||
```
|
||||
error:
|
||||
… while updating the lock file of flake 'git+file:///Users/jade/lix/lix2'
|
||||
|
||||
… while parsing the lock file at /nix/store/mm5dqh8a729yazzj82cjffxl97n5c62s-source//flake.lock
|
||||
|
||||
error: [json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal;
|
||||
last read: '#'
|
||||
```
|
||||
|
||||
Many thanks to [gilice](https://git.lix.systems/gilice) for this.
|
||||
|
||||
- Flakes follow `--eval-system` where it makes sense [fj#673](https://git.lix.systems/lix-project/lix/issues/673) [fj#692](https://git.lix.systems/lix-project/lix/issues/692) [gh#11359](https://github.com/NixOS/nix/issues/11359) [cl/2657](https://gerrit.lix.systems/c/lix/+/2657)
|
||||
|
||||
Most flake commands now follow `--eval-system` when choosing attributes to build/evaluate/etc.
|
||||
|
||||
The exceptions are commands that actually run something on the local machine:
|
||||
- nix develop
|
||||
- nix run
|
||||
- nix upgrade-nix
|
||||
- nix fmt
|
||||
- nix bundle
|
||||
|
||||
This is not a principled approach to cross compilation or anything, flakes still impede rather than support cross compilation, but this unbreaks many remote build use cases.
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
|
||||
- Remove some gremlins from path garbage collection [fj#621](https://git.lix.systems/lix-project/lix/issues/621) [fj#524](https://git.lix.systems/lix-project/lix/issues/524) [cl/2465](https://gerrit.lix.systems/c/lix/+/2465) [cl/2387](https://gerrit.lix.systems/c/lix/+/2387)
|
||||
|
||||
Path garbage collection had some known unsoundness issues where it would delete things improperly and cause desynchronization between the filesystem state and the database state.
|
||||
Now Lix tolerates better if such a condition exists by not failing the entire GC if a path fails to delete.
|
||||
We also fixed a bug in our file locking implementation that is one possible root cause, but may not be every root cause.
|
||||
|
||||
Many thanks to [eldritch horrors](https://git.lix.systems/pennae) and [Raito Bezarius](https://git.lix.systems/raito) for this.
|
||||
|
||||
- Show illegal path references in fixed-outputs derivations [fj#530](https://git.lix.systems/lix-project/lix/issues/530) [cl/2726](https://gerrit.lix.systems/c/lix/+/2726)
|
||||
|
||||
The error created when referencing a store path in a Fixed-Output Derivation is now more verbose, listing the offending paths.
|
||||
This allows for better pinpointing where the issue might be.
|
||||
|
||||
An offender is the following derivation:
|
||||
|
||||
```nix
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "illegal-fod";
|
||||
|
||||
dontUnpack = true;
|
||||
dontBuild = true;
|
||||
|
||||
installPhase = ''
|
||||
cp -R ${pkgs.hello} $out
|
||||
'';
|
||||
|
||||
outputHashMode = "recursive";
|
||||
outputHashAlgo = "sha256";
|
||||
outputHash = pkgs.lib.fakeHash;
|
||||
}
|
||||
```
|
||||
|
||||
The previous error shown would have been:
|
||||
|
||||
```
|
||||
error: illegal path references in fixed-output derivation '/nix/store/rpq4m1y79s2nhs1hj7k47yiyykxykiqa-illegal-fod.drv'
|
||||
```
|
||||
|
||||
and is now:
|
||||
|
||||
```
|
||||
error: the fixed-output derivation '/nix/store/rpq4m1y79s2nhs1hj7k47yiyykxykiqa-illegal-fod.drv' must not reference store paths but 2 such references were found:
|
||||
/nix/store/1q8w6gl1ll0mwfkqc3c2yx005s6wwfrl-hello-2.12.1
|
||||
/nix/store/wn7v2vhyyyi6clcyn0s9ixvl7d4d87ic-glibc-2.40-36
|
||||
```
|
||||
|
||||
Many thanks to [Tom Hubrecht](https://git.lix.systems/tom-hubrecht) for this.
|
||||
|
||||
- Show error when item from NIX_PATH cannot be downloaded
|
||||
|
||||
For e.g. `nix-instantiate -I https://example.com/404`, you'd only get a warning if the download failed, such as
|
||||
|
||||
warning: Nix search path entry 'https://example.com/404' cannot be downloaded, ignoring
|
||||
|
||||
Now, the full error that caused the download failure is displayed with a note that the search
|
||||
path entry is ignored, e.g.
|
||||
|
||||
warning:
|
||||
… while downloading https://example.com/404 to satisfy NIX_PATH lookup, ignoring search path entry
|
||||
|
||||
warning: unable to download 'https://example.com/404': HTTP error 404 ()
|
||||
|
||||
response body: […]
|
||||
|
||||
Many thanks to [ma27](https://git.lix.systems/ma27) for this.
|
||||
|
||||
- Fix Lix crashing on invalid json [fj#642](https://git.lix.systems/lix-project/lix/issues/642) [fj#753](https://git.lix.systems/lix-project/lix/issues/753) [fj#759](https://git.lix.systems/lix-project/lix/issues/759) [fj#769](https://git.lix.systems/lix-project/lix/issues/769) [cl/2907](https://gerrit.lix.systems/c/lix/+/2907)
|
||||
|
||||
Lix no longer crashes when it receives invalid JSON. Instead it'll point to the syntax error and give some context about what happened, for example
|
||||
|
||||
```
|
||||
❯ nix derivation add <<<"""
|
||||
error:
|
||||
… while parsing a derivation from stdin
|
||||
|
||||
error: failed to parse JSON: [json.exception.parse_error.101] parse error at line 2, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal
|
||||
```
|
||||
|
||||
Many thanks to [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
|
||||
- Fix handling of `lastModified` in tarball inputs [cl/2792](https://gerrit.lix.systems/c/lix/+/2792)
|
||||
|
||||
Previous versions of Lix would fail with the following error, if a
|
||||
[tarball flake input](@docroot@/protocols/tarball-fetcher.md) redirect
|
||||
to a URL that contains a `lastModified` field:
|
||||
|
||||
```
|
||||
error: input attribute 'lastModified' is not an integer
|
||||
```
|
||||
|
||||
This is now fixed.
|
||||
|
||||
Many thanks to [xanderio](https://github.com/xanderio) and [Julian Stecklina](https://github.com/blitz) for this.
|
||||
|
||||
- Fix `--debugger --ignore-try` [cl/2440](https://gerrit.lix.systems/c/lix/+/2440)
|
||||
|
||||
When in debug mode (e.g. from using the `--debugger` flag), enabling [`ignore-try`](@docroot@/command-ref/conf-file.md#conf-ignore-try) once again properly disables debug REPLs within [`builtins.tryEval`](@docroot@/language/builtins.md#builtins-tryEval) calls. Previously, a debug REPL would be started as if `ignore-try` was disabled, but that REPL wouldn't actually be in debug mode, and upon exiting the REPL the evaluating process would segfault.
|
||||
|
||||
Many thanks to [Dusk Banks](https://git.lix.systems/bb010g) for this.
|
||||
|
||||
- Don't consider a path with a specified rev to be `locked` [cl/2064](https://gerrit.lix.systems/c/lix/+/2064)
|
||||
|
||||
Until now it was allowed to do e.g.
|
||||
|
||||
$ echo 'lalala' > testfile
|
||||
$ nix eval --expr '(builtins.fetchTree { path = "/home/ma27/testfile"; rev = "0000000000000000000000000000000000000000"; type = "path"; })'
|
||||
{ lastModified = 1723656303; lastModifiedDate = "20240814172503"; narHash = "sha256-hOMY06A0ohaaCLwnhpZIMoAqi/8kG2vk30NRiqi0dfc="; outPath = "/nix/store/lhfz259iipmv9ky995rml8018jvriynh-source"; rev = "0000000000000000000000000000000000000000"; shortRev = "0000000"; }
|
||||
$ cat /nix/store/lhfz259iipmv9ky995rml8018jvriynh-source
|
||||
lalala
|
||||
|
||||
because any kind of input with a `rev` specified is considered to be locked.
|
||||
|
||||
With this change, inputs of type `path`, `indirect` and `tarball` are no longer
|
||||
considered locked with a rev, but no hash specified.
|
||||
|
||||
This behavior was changed in
|
||||
[CppNix 2.21 as well](https://github.com/nixos/nix/commit/071dd2b3a4e6c0b2106f1b6f14ec26e153d97446) as well.
|
||||
|
||||
Many thanks to [ma27](https://git.lix.systems/ma27) for this.
|
||||
|
||||
- Fix macOS sandbox profile size errors [fj#752](https://git.lix.systems/lix-project/lix/issues/752) [fj#718](https://git.lix.systems/lix-project/lix/issues/718) [cl/2861](https://gerrit.lix.systems/c/lix/+/2861)
|
||||
|
||||
Fixed an issue on macOS where the sandbox profile could exceed size limits when building derivations with many dependencies. The profile is now split into multiple allowed sections to stay under the interpreter's limits.
|
||||
|
||||
This resolves errors like
|
||||
|
||||
```
|
||||
error: (failed with exit code 1, previous messages: sandbox initialization failed: data object length 65730 exceeds maximum (65535)|failed to configure sandbox)
|
||||
|
||||
error: unexpected EOF reading a line
|
||||
```
|
||||
|
||||
Many thanks to [Pierre-Etienne Meunier](https://github.com/P-E-Meunier) and [Poliorcetics](https://github.com/poliorcetics) for this.
|
||||
|
||||
- Fix interference of the multiline progress bar with output [cl/2774](https://gerrit.lix.systems/c/lix/+/2774)
|
||||
|
||||
In some situations, the progress indicator of the multiline progress bar would interfere with persistent output.
|
||||
This would result in progress bar headers being visible in place of the desired text, for example the outputs shown after a `:b` command in the repl.
|
||||
The underlying ordering issue has been fixed, so that the undesired interference does not happen any more.
|
||||
|
||||
Many thanks to [alois31](https://git.lix.systems/alois31) for this.
|
||||
|
||||
- Paralellise `nix store sign` using a thread pool [fj#399](https://git.lix.systems/lix-project/lix/issues/399) [cl/2606](https://gerrit.lix.systems/c/lix/+/2606)
|
||||
|
||||
`nix store sign` with a large collection of provided paths (such as when using with `--all`) has historically
|
||||
signed these paths serially. Taking extreme amounts of time when preforming operations such as fixing binary
|
||||
caches. This has been changed. Now these signatures are performed using a thread pool like `nix store copy-sigs`.
|
||||
|
||||
Many thanks to [Lunaphied](https://git.lix.systems/Lunaphied) for this.
|
||||
|
||||
- `post-build-hook` only receives settings that are set [fj#739](https://git.lix.systems/lix-project/lix/issues/739) [cl/2800](https://gerrit.lix.systems/c/lix/+/2800)
|
||||
|
||||
If one is using `post-build-hook` to upload paths to a cache, it used to be broken if CppNix was used inside the script, since CppNix would fail about unsupported configuration option values in some of Lix's defaults.
|
||||
This is because `post-build-hook` receives the settings of the nix daemon in the `NIX_CONFIG` environment variable.
|
||||
Now Lix only emits overridden settings to `post-build-hook` invocations, which fixes this issue in the majority of cases: where the configuration is not explicitly incompatible.
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) for this.
|
||||
|
||||
- Remove lix-initiated ssh connection sharing [fj#304](https://git.lix.systems/lix-project/lix/issues/304) [fj#644](https://git.lix.systems/lix-project/lix/issues/644) [cl/3005](https://gerrit.lix.systems/c/lix/+/3005)
|
||||
|
||||
Lix no longer explicitly requests ssh connection sharing (ControlMaster/ControlPath SSH
|
||||
options, see also ssh_config(5) man page) when connecting to remote stores. This may
|
||||
impact command latency when `NIX_REMOTE` is set to a `ssh://` or `ssh-ng://` url, or if
|
||||
`--store` is specified. Remote build connections did not use ssh connection sharing.
|
||||
|
||||
Connection sharing configuration is now inherited from user configuration at all times. It
|
||||
is now advisable to configure connection sharing for remote builders for improved latency.
|
||||
|
||||
Many thanks to [eldritch horrors](https://git.lix.systems/pennae) for this.
|
||||
|
||||
|
||||
## Development
|
||||
|
||||
- Add `nix_plugin_entry` entry point for plugins [fj#740](https://git.lix.systems/lix-project/lix/issues/740) [fj#359](https://git.lix.systems/lix-project/lix/issues/359) [gh#8699](https://github.com/NixOS/nix/pull/8699) [cl/2826](https://gerrit.lix.systems/c/lix/+/2826)
|
||||
|
||||
Plugins are an exceptionally rarely used feature in Lix, but they are important as a prototyping tool for code destined for Lix itself, and we want to keep supporting them as a low-maintenance-cost feature.
|
||||
As part of the overall move towards getting rid of static initializers for stability and predictability reasons, we added an explicit `nix_plugin_entry` function like CppNix has, which is called immediately after plugin load, if present.
|
||||
This makes control flow more explicit and allows for easily registering things that have had their static initializer registration classes removed.
|
||||
|
||||
Many thanks to [jade](https://git.lix.systems/jade) and [yorickvp](https://github.com/yorickvp) for this.
|
||||
|
||||
|
||||
## Miscellany
|
||||
|
||||
- Set default of `connect-timeout` to `5` [cl/2799](https://gerrit.lix.systems/c/lix/+/2799)
|
||||
|
||||
By default, the connection timeout to substituters is now 5s instead of 300s.
|
||||
That way, unavailable substituters are detected quicker.
|
||||
|
||||
Many thanks to [ma27](https://git.lix.systems/ma27) for this.
|
||||
@@ -1,21 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Preprocesses mdbook markdown, primarily for include directives.
|
||||
|
||||
The include directive format is as follows:
|
||||
{{#include foo/bar/baz.md}}
|
||||
|
||||
The content of includes will be indented as much as the directive itself.
|
||||
|
||||
Including a generated file (from building Lix; generally for the 'new' CLI):
|
||||
{{#include @generated@/foo/bar/baz.md}}
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
import json
|
||||
import os, os.path
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
name = 'substitute.py'
|
||||
|
||||
@@ -23,12 +11,6 @@ def log(*args, **kwargs):
|
||||
kwargs['file'] = sys.stderr
|
||||
return print(f'{name}:', *args, **kwargs)
|
||||
|
||||
def remove_prefix_if_present(s: str, prefix: str) -> str | None:
|
||||
if s.startswith(prefix):
|
||||
return s.removeprefix(prefix)
|
||||
else:
|
||||
return None
|
||||
|
||||
def do_include(content: str, relative_md_path: Path, source_root: Path, search_path: Path):
|
||||
assert not relative_md_path.is_absolute(), f'{relative_md_path=} from mdbook should be relative'
|
||||
|
||||
@@ -38,32 +20,16 @@ def do_include(content: str, relative_md_path: Path, source_root: Path, search_p
|
||||
|
||||
lines = []
|
||||
for l in content.splitlines(keepends=True):
|
||||
if remain := remove_prefix_if_present(l.strip(), "{{#include"):
|
||||
requested = remain[1:-2]
|
||||
# We indent bodies of indent directives by the indent of the
|
||||
# directive itself.
|
||||
num_leading_indent = len(l) - len(l.lstrip())
|
||||
|
||||
if subpath := remove_prefix_if_present(requested, "@generated@/"):
|
||||
included = search_path / Path(subpath)
|
||||
if l.strip().startswith("{{#include "):
|
||||
requested = l.strip()[11:][:-2]
|
||||
if requested.startswith("@generated@/"):
|
||||
included = search_path / Path(requested[12:])
|
||||
requested = included.relative_to(search_path)
|
||||
else:
|
||||
included = source_root / relative_md_path.parent / requested
|
||||
requested = included.resolve().relative_to(source_root)
|
||||
assert included.exists(), f"{requested} not found at {included}"
|
||||
|
||||
lines.append(
|
||||
textwrap.indent(
|
||||
do_include(
|
||||
included.read_text(),
|
||||
requested,
|
||||
source_root,
|
||||
search_path,
|
||||
),
|
||||
" " * num_leading_indent
|
||||
)
|
||||
+ "\n"
|
||||
)
|
||||
lines.append(do_include(included.read_text(), requested, source_root, search_path) + "\n")
|
||||
else:
|
||||
lines.append(l)
|
||||
return "".join(lines)
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
+9
-8
@@ -157,7 +157,7 @@ let
|
||||
|
||||
nixConfContents =
|
||||
(lib.concatStringsSep "\n" (
|
||||
lib.mapAttrsToList (
|
||||
lib.mapAttrsFlatten (
|
||||
n: v:
|
||||
let
|
||||
vStr = if builtins.isList v then lib.concatStringsSep " " v else v;
|
||||
@@ -193,11 +193,13 @@ let
|
||||
in
|
||||
''
|
||||
{
|
||||
${lib.concatStringsSep "\n" (
|
||||
builtins.map (output: ''
|
||||
${output} = { outPath = "${lib.getOutput output drv}"; };
|
||||
'') outputs
|
||||
)}
|
||||
${
|
||||
lib.concatStringsSep "\n" (
|
||||
builtins.map (output: ''
|
||||
${output} = { outPath = "${lib.getOutput output drv}"; };
|
||||
'') outputs
|
||||
)
|
||||
}
|
||||
outputs = [ ${lib.concatStringsSep " " (builtins.map (x: "\"${x}\"") outputs)} ];
|
||||
name = "${drv.name}";
|
||||
outPath = "${drv}";
|
||||
@@ -359,8 +361,7 @@ let
|
||||
"org.opencontainers.image.source" = "https://git.lix.systems/lix-project/lix";
|
||||
"org.opencontainers.image.vendor" = "Lix project";
|
||||
"org.opencontainers.image.version" = pkgs.nix.version;
|
||||
"org.opencontainers.image.description" =
|
||||
"Minimal Lix container image, with some batteries included.";
|
||||
"org.opencontainers.image.description" = "Minimal Lix container image, with some batteries included.";
|
||||
} // lib.optionalAttrs (lixRevision != null) { "org.opencontainers.image.revision" = lixRevision; };
|
||||
};
|
||||
|
||||
|
||||
Generated
+11
-70
@@ -16,30 +16,14 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"lowdown-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1633514407,
|
||||
"narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=",
|
||||
"owner": "kristapsdz",
|
||||
"repo": "lowdown",
|
||||
"rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "kristapsdz",
|
||||
"repo": "lowdown",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix2container": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1724996935,
|
||||
"narHash": "sha256-njRK9vvZ1JJsP8oV2OgkBrpJhgQezI03S7gzskCcHos=",
|
||||
"lastModified": 1712990762,
|
||||
"narHash": "sha256-hO9W3w7NcnYeX8u8cleHiSpK2YJo7ecarFTUlbybl7k=",
|
||||
"owner": "nlewo",
|
||||
"repo": "nix2container",
|
||||
"rev": "fa6bb0a1159f55d071ba99331355955ae30b3401",
|
||||
"rev": "20aad300c925639d5d6cbe30013c8357ce9f2a2e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -48,44 +32,18 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix_2_18": {
|
||||
"inputs": {
|
||||
"flake-compat": [
|
||||
"flake-compat"
|
||||
],
|
||||
"lowdown-src": "lowdown-src",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-regression": [
|
||||
"nixpkgs-regression"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1730375271,
|
||||
"narHash": "sha256-RrOFlDGmRXcVRV2p2HqHGqvzGNyWoD0Dado/BNlJ1SI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nix",
|
||||
"rev": "0f665ff6779454f2117dcc32e44380cda7f45523",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "2.18.9",
|
||||
"repo": "nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1705033721,
|
||||
"narHash": "sha256-K5eJHmL1/kev6WuqyqqbS1cdNnSidIZ3jeqJ7GbrYnQ=",
|
||||
"lastModified": 1718111384,
|
||||
"narHash": "sha256-7tSst0S5FOmcgvNtfy6cjZX5w8CabCVAfAeCkhY4OVg=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a1982c92d8980a0114372973cbdfe0a307f1bdea",
|
||||
"rev": "a508a44af0c1b1b57785c34d8b54783536273eeb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-23.05-small",
|
||||
"ref": "nixos-24.05-small",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
@@ -106,30 +64,14 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1749522908,
|
||||
"narHash": "sha256-eWANkhWXFL1MmaxzsZ9bhLCNT8OVs7CC+OXaSDGlA8A=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "e5cb99555c45a13dcc5f1317462238530b0066b7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-25.05-small",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pre-commit-hooks": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1733318908,
|
||||
"narHash": "sha256-SVQVsbafSM1dJ4fpgyBqLZ+Lft+jcQuMtEL3lQWx2Sk=",
|
||||
"lastModified": 1712055707,
|
||||
"narHash": "sha256-4XLvuSIDZJGS17xEwSrNuJLL7UjDYKGJSbK1WWX2AK8=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "6f4e2a2112050951a314d2733a994fbab94864c6",
|
||||
"rev": "e35aed5fda3cc79f88ed7f1795021e559582093a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -142,8 +84,7 @@
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"nix2container": "nix2container",
|
||||
"nix_2_18": "nix_2_18",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-regression": "nixpkgs-regression",
|
||||
"pre-commit-hooks": "pre-commit-hooks"
|
||||
}
|
||||
|
||||
@@ -1,20 +1,9 @@
|
||||
{
|
||||
description = "Lix: A modern, delicious implementation of the Nix package manager";
|
||||
description = "The purely functional package manager";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05-small";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05-small";
|
||||
nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2";
|
||||
|
||||
# Required because Nix 2.18 is not in Nixpkgs ≥ 25.05 anymore.
|
||||
nix_2_18 = {
|
||||
url = "github:NixOS/nix/2.18.9";
|
||||
# NOTE(Raito): this is not possible because patches on libseccomp does not apply anymore on this Nix.
|
||||
# Let's keep the latest known nixpkgs useable with Nix 2.18 for our tests.
|
||||
# inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.nixpkgs-regression.follows = "nixpkgs-regression";
|
||||
inputs.flake-compat.follows = "flake-compat";
|
||||
};
|
||||
|
||||
pre-commit-hooks = {
|
||||
url = "github:cachix/git-hooks.nix";
|
||||
flake = false;
|
||||
@@ -36,7 +25,6 @@
|
||||
nixpkgs-regression,
|
||||
pre-commit-hooks,
|
||||
nix2container,
|
||||
nix_2_18,
|
||||
flake-compat,
|
||||
}:
|
||||
|
||||
@@ -45,10 +33,9 @@
|
||||
|
||||
# This notice gets echoed as a dev shell hook, and can be turned off with
|
||||
# `touch .nocontribmsg`
|
||||
sgr = builtins.fromJSON ''"\u001b["'';
|
||||
sgr = ''['';
|
||||
freezePage = "https://wiki.lix.systems/books/lix-contributors/page/freezes-and-recommended-contributions";
|
||||
codebaseOverview = "https://wiki.lix.systems/books/lix-contributors/page/codebase-overview";
|
||||
gerritWiki = "https://wiki.lix.systems/books/lix-contributors/page/gerrit";
|
||||
contribNotice = builtins.toFile "lix-contrib-notice" ''
|
||||
Hey there!
|
||||
|
||||
@@ -66,18 +53,13 @@
|
||||
and we'd like to work together with all contributors as much as possible.
|
||||
Lix is a collaborative project :)
|
||||
|
||||
If you want to submit a patch and you never used gerrit before, please
|
||||
check our gerrit wiki section:
|
||||
${sgr}32m${gerritWiki}${sgr}0m
|
||||
|
||||
You can open an issue at https://git.lix.systems/lix-project/lix/issues
|
||||
or chat with us on Matrix: #space:lix.systems.
|
||||
|
||||
(Run `touch .nocontribmsg` to hide this message.)
|
||||
'';
|
||||
|
||||
versionJson = builtins.fromJSON (builtins.readFile ./version.json);
|
||||
officialRelease = versionJson.official_release;
|
||||
officialRelease = false;
|
||||
|
||||
# Set to true to build the release notes for the next release.
|
||||
buildUnreleasedNotes = true;
|
||||
@@ -108,17 +90,16 @@
|
||||
"armv6l-linux"
|
||||
"armv7l-linux"
|
||||
"riscv64-linux"
|
||||
"aarch64-linux"
|
||||
"x86_64-freebsd"
|
||||
# FIXME: still broken in 24.05: fails to build rustc(??) due to missing -lstdc++ dep
|
||||
# "x86_64-freebsd"
|
||||
# FIXME: broken dev shell due to python
|
||||
# "x86_64-netbsd"
|
||||
];
|
||||
|
||||
stdenvs = [
|
||||
# see assertion in package.nix why these two are disabled
|
||||
# "stdenv"
|
||||
# "gccStdenv"
|
||||
"gccStdenv"
|
||||
"clangStdenv"
|
||||
"stdenv"
|
||||
"libcxxStdenv"
|
||||
"ccacheStdenv"
|
||||
];
|
||||
@@ -138,11 +119,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 (
|
||||
@@ -154,8 +131,18 @@
|
||||
localSystem = {
|
||||
inherit system;
|
||||
};
|
||||
crossSystem = if crossSystem == null then null else { system = crossSystem; };
|
||||
overlays = [ (overlayFor (p: p.${stdenv})) ];
|
||||
crossSystem =
|
||||
if crossSystem == null then
|
||||
null
|
||||
else
|
||||
{
|
||||
system = crossSystem;
|
||||
}
|
||||
// lib.optionalAttrs (crossSystem == "x86_64-freebsd") { useLLVM = true; };
|
||||
overlays = [
|
||||
(overlayFor (p: p.${stdenv}))
|
||||
(final: prev: { nixfmt = final.callPackage ./nix-support/nixfmt.nix { }; })
|
||||
];
|
||||
};
|
||||
stdenvs = forAllStdenvs (make-pkgs null);
|
||||
native = stdenvs.stdenvPackages;
|
||||
@@ -163,7 +150,7 @@
|
||||
{
|
||||
inherit stdenvs native;
|
||||
static = native.pkgsStatic;
|
||||
cross = forAllCrossSystems (crossSystem: make-pkgs crossSystem "clangStdenv");
|
||||
cross = forAllCrossSystems (crossSystem: make-pkgs crossSystem "stdenv");
|
||||
}
|
||||
);
|
||||
|
||||
@@ -175,16 +162,10 @@
|
||||
{
|
||||
nixStable = prev.nix;
|
||||
|
||||
# Nix 2.18 has been removed from Nixpkgs ≥ 25.05, so we need to reintroduce it ourselves for our tests.
|
||||
nixVersions = prev.nixVersions // {
|
||||
nix_2_18 = nix_2_18.outputs.packages.${currentStdenv.hostPlatform.system}.default;
|
||||
};
|
||||
|
||||
# Forward from the previous stage as we don’t want it to pick the lowdown override
|
||||
nixUnstable = prev.nixUnstable;
|
||||
|
||||
check-headers = final.buildPackages.callPackage ./maintainers/check-headers.nix { };
|
||||
check-syscalls = final.buildPackages.callPackage ./maintainers/check-syscalls.nix { };
|
||||
|
||||
default-busybox-sandbox-shell = final.busybox.override {
|
||||
useMusl = true;
|
||||
@@ -216,22 +197,7 @@
|
||||
busybox-sandbox-shell = final.busybox-sandbox-shell or final.default-busybox-sandbox-shell;
|
||||
};
|
||||
|
||||
lix-clang-tidy = final.callPackage ./subprojects/lix-clang-tidy { };
|
||||
|
||||
nix-eval-jobs = final.callPackage ./subprojects/nix-eval-jobs {
|
||||
srcDir = ./subprojects/nix-eval-jobs;
|
||||
};
|
||||
|
||||
# HACK: We need nix-prefetch-git for fetchCargoVendor for Rust stuff,
|
||||
# so it can't use Lix, or we infrec:
|
||||
# lix -> Rust stuff -> fetchCargoVendor -> nix-prefetch-git -> nix (lix)
|
||||
# This will eventually become a problem upstream, but until then,
|
||||
# apply some duct tape and pray.
|
||||
nix-prefetch-git =
|
||||
if (lib.functionArgs prev.nix-prefetch-git.override) ? "nix" then
|
||||
prev.nix-prefetch-git.override { nix = prev.nix; }
|
||||
else
|
||||
prev.nix-prefetch-git;
|
||||
pegtl = final.nix.passthru.pegtl;
|
||||
|
||||
# Export the patched version of boehmgc that Lix uses into the overlay
|
||||
# for consumers of this flake.
|
||||
@@ -246,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.
|
||||
@@ -282,9 +248,6 @@
|
||||
# Perl bindings for various platforms.
|
||||
perlBindings = forAllSystems (system: nixpkgsFor.${system}.native.nix.passthru.perl-bindings);
|
||||
|
||||
# nix-eval-jobs can be built against this Lix.
|
||||
nix-eval-jobs = forAllSystems (system: nixpkgsFor.${system}.native.nix-eval-jobs);
|
||||
|
||||
# Binary tarball for various platforms, containing a Nix store
|
||||
# with the closure of 'nix' package.
|
||||
binaryTarball = forAllSystems (system: nixpkgsFor.${system}.native.nix.passthru.binaryTarball);
|
||||
@@ -301,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;
|
||||
};
|
||||
@@ -316,100 +277,39 @@
|
||||
});
|
||||
|
||||
# System tests.
|
||||
tests =
|
||||
import ./tests/nixos {
|
||||
inherit
|
||||
self
|
||||
lib
|
||||
nixpkgs
|
||||
nixpkgsFor
|
||||
;
|
||||
}
|
||||
// {
|
||||
nix-eval-jobs = forAllSystems (system: self.packages.${system}.nix-eval-jobs.tests.nix-eval-jobs);
|
||||
tests = import ./tests/nixos { inherit lib nixpkgs nixpkgsFor; } // {
|
||||
|
||||
# This is x86_64-linux only, just because we have significantly
|
||||
# cheaper x86_64-linux compute in CI.
|
||||
# It is clangStdenv because clang's sanitizers are nicer.
|
||||
asanBuild = self.packages.x86_64-linux.nix-clangStdenv.override {
|
||||
# Improve caching of non-code changes by not changing the
|
||||
# derivation name every single time, since this will never be seen
|
||||
# by users anyway.
|
||||
versionSuffix = "";
|
||||
sanitize = [
|
||||
"address"
|
||||
"undefined"
|
||||
];
|
||||
# it is very hard to make *every* CI build use this option such
|
||||
# that we don't wind up building Lix twice, so we do it here where
|
||||
# we are already doing so.
|
||||
werror = true;
|
||||
};
|
||||
# Make sure that nix-env still produces the exact same result
|
||||
# on a particular version of Nixpkgs.
|
||||
evalNixpkgs =
|
||||
with nixpkgsFor.x86_64-linux.native;
|
||||
runCommand "eval-nixos" { buildInputs = [ nix ]; } ''
|
||||
type -p nix-env
|
||||
# Note: we're filtering out nixos-install-tools because https://github.com/NixOS/nixpkgs/pull/153594#issuecomment-1020530593.
|
||||
time nix-env --store dummy:// -f ${nixpkgs-regression} -qaP --drv-path | sort | grep -v nixos-install-tools > packages
|
||||
[[ $(sha1sum < packages | cut -c1-40) = 402242fca90874112b34718b8199d844e8b03d12 ]]
|
||||
mkdir $out
|
||||
'';
|
||||
|
||||
# Although this might be nicer to do with pre-commit, that would
|
||||
# require adding 12MB of nodejs to the dev shell, whereas building it
|
||||
# in CI with Nix avoids that at a cost of slower feedback on rarely
|
||||
# touched files.
|
||||
jsSyntaxCheck =
|
||||
let
|
||||
nixpkgs = nixpkgsFor.x86_64-linux.native;
|
||||
inherit (nixpkgs) pkgs;
|
||||
docSources = lib.fileset.toSource {
|
||||
root = ./doc;
|
||||
fileset = lib.fileset.fileFilter (f: f.hasExt "js") ./doc;
|
||||
};
|
||||
in
|
||||
pkgs.runCommand "js-syntax-check" { } ''
|
||||
find ${docSources} -type f -print -exec ${pkgs.nodejs-slim}/bin/node --check '{}' ';'
|
||||
touch $out
|
||||
'';
|
||||
|
||||
# clang-tidy run against the Lix codebase using the Lix clang-tidy plugin
|
||||
clang-tidy =
|
||||
let
|
||||
nixpkgs = nixpkgsFor.x86_64-linux.native;
|
||||
inherit (nixpkgs) pkgs;
|
||||
in
|
||||
pkgs.callPackage ./package.nix {
|
||||
# Required since we don't support gcc stdenv
|
||||
stdenv = pkgs.clangStdenv;
|
||||
versionSuffix = "";
|
||||
lintInsteadOfBuild = true;
|
||||
};
|
||||
|
||||
# Make sure that nix-env still produces the exact same result
|
||||
# on a particular version of Nixpkgs.
|
||||
evalNixpkgs =
|
||||
with nixpkgsFor.x86_64-linux.native;
|
||||
runCommand "eval-nixos" { buildInputs = [ nix ]; } ''
|
||||
type -p nix-env
|
||||
# Note: we're filtering out nixos-install-tools because https://github.com/NixOS/nixpkgs/pull/153594#issuecomment-1020530593.
|
||||
time nix-env --store dummy:// -f ${nixpkgs-regression} -qaP --drv-path | sort | grep -v nixos-install-tools > packages
|
||||
[[ $(sha1sum < packages | cut -c1-40) = 402242fca90874112b34718b8199d844e8b03d12 ]]
|
||||
mkdir $out
|
||||
'';
|
||||
|
||||
nixpkgsLibTests = forAllSystems (
|
||||
system:
|
||||
let
|
||||
inherit (self.packages.${system}) nix;
|
||||
pkgs = nixpkgsFor.${system}.native;
|
||||
testWithNix = import (nixpkgs + "/lib/tests/test-with-nix.nix") { inherit pkgs lib nix; };
|
||||
in
|
||||
pkgs.symlinkJoin {
|
||||
name = "nixpkgs-lib-tests";
|
||||
paths =
|
||||
[ testWithNix ]
|
||||
# NOTE: nixpkgs 25.05 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.
|
||||
++ lib.optionals pkgs.stdenv.isLinux [
|
||||
((pkgs.callPackage "${nixpkgs}/ci/eval" { nixVersions.latest = nix; }).attrpathsSuperset {
|
||||
evalSystem = system;
|
||||
})
|
||||
];
|
||||
}
|
||||
);
|
||||
};
|
||||
nixpkgsLibTests = forAllSystems (
|
||||
system:
|
||||
let
|
||||
inherit (self.packages.${system}) nix;
|
||||
pkgs = nixpkgsFor.${system}.native;
|
||||
testWithNix = import (nixpkgs + "/lib/tests/test-with-nix.nix") { inherit pkgs lib nix; };
|
||||
in
|
||||
pkgs.symlinkJoin {
|
||||
name = "nixpkgs-lib-tests";
|
||||
paths =
|
||||
[ testWithNix ]
|
||||
# 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 [
|
||||
(import (nixpkgs + "/pkgs/test/release") { inherit pkgs lib nix; })
|
||||
];
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
pre-commit = forAvailableSystems (
|
||||
system:
|
||||
@@ -428,25 +328,6 @@
|
||||
pkgs = nixpkgsFor.x86_64-linux.native;
|
||||
};
|
||||
|
||||
releaseTests = lib.foldl lib.recursiveUpdate { } [
|
||||
(lib.genAttrs (linux64BitSystems ++ darwinSystems) (system: {
|
||||
nativeBuild = self.packages.${system}.nix;
|
||||
}))
|
||||
(lib.genAttrs (linux64BitSystems) (system: {
|
||||
staticBuild = self.packages.${system}.nix-static;
|
||||
}))
|
||||
{
|
||||
x86_64-linux = {
|
||||
# TODO add more cross/static release targets?
|
||||
crossBuild.aarch64-linux = self.packages.x86_64-linux.nix-aarch64-linux;
|
||||
|
||||
# TODO wire up a nixos installer test with that lix and
|
||||
# run it, once nixpkgs can actually do that (again). :/
|
||||
# # nix build .#nixosTests.installer.{btrfsSimple,luksroot,lvm,simple,switchToFlake}
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
# NOTE *do not* add fresh derivations to checks, always add them to
|
||||
# hydraJobs first (so CI will pick them up) and only link them here
|
||||
checks = forAvailableSystems (
|
||||
@@ -457,7 +338,6 @@
|
||||
|
||||
binaryTarball = self.hydraJobs.binaryTarball.${system};
|
||||
perlBindings = self.hydraJobs.perlBindings.${system};
|
||||
nix-eval-jobs = self.hydraJobs.nix-eval-jobs.${system};
|
||||
nixpkgsLibTests = self.hydraJobs.tests.nixpkgsLibTests.${system};
|
||||
rl-next = self.hydraJobs.rl-next.${system}.user;
|
||||
# Will be empty attr set on i686-linux, and filtered out by forAvailableSystems.
|
||||
@@ -474,8 +354,6 @@
|
||||
rec {
|
||||
inherit (nixpkgsFor.${system}.native) nix;
|
||||
default = nix;
|
||||
|
||||
inherit (nixpkgsFor.${system}.native) lix-clang-tidy nix-eval-jobs;
|
||||
}
|
||||
// (
|
||||
lib.optionalAttrs (builtins.elem system linux64BitSystems) {
|
||||
@@ -512,7 +390,7 @@
|
||||
pkgs: stdenv:
|
||||
let
|
||||
nix = pkgs.callPackage ./package.nix {
|
||||
inherit stdenv versionSuffix;
|
||||
inherit stdenv officialRelease versionSuffix;
|
||||
busybox-sandbox-shell = pkgs.busybox-sandbox-shell or pkgs.default-busybox-sandbox;
|
||||
internalApiDocs = false;
|
||||
};
|
||||
@@ -539,10 +417,10 @@
|
||||
let
|
||||
pkgs = nixpkgsFor.${system}.cross.${crossSystem};
|
||||
in
|
||||
makeShell pkgs pkgs.clangStdenv
|
||||
makeShell pkgs pkgs.stdenv
|
||||
))
|
||||
// {
|
||||
default = self.devShells.${system}.native-clangStdenvPackages;
|
||||
default = self.devShells.${system}.native-stdenvPackages;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,47 +8,20 @@ list:
|
||||
clean:
|
||||
rm -rf build
|
||||
|
||||
# Prepare meson for building with extra options
|
||||
setup-custom *OPTIONS:
|
||||
# Prepare meson for building
|
||||
setup *OPTIONS:
|
||||
meson setup build --prefix="$PWD/outputs/out" $mesonFlags {{ OPTIONS }}
|
||||
|
||||
# Prepare meson for building
|
||||
setup: (setup-custom)
|
||||
|
||||
# Build lix with extra options
|
||||
build-custom *OPTIONS:
|
||||
meson compile -C build {{ OPTIONS }}
|
||||
|
||||
# Build lix
|
||||
build: (build-custom)
|
||||
build *OPTIONS:
|
||||
meson compile -C build {{ OPTIONS }}
|
||||
|
||||
alias compile := build
|
||||
|
||||
# Install lix for local development with extra options
|
||||
install-custom *OPTIONS: (build-custom OPTIONS)
|
||||
# Install lix for local development
|
||||
install *OPTIONS: (build OPTIONS)
|
||||
meson install -C build
|
||||
|
||||
# Install lix for local development
|
||||
install: (install-custom)
|
||||
|
||||
# Run tests (usually requires `install`) with extra options
|
||||
# Run tests
|
||||
test *OPTIONS:
|
||||
meson test -C build --print-errorlogs {{ OPTIONS }}
|
||||
|
||||
# Run unit tests only
|
||||
test-unit *OPTIONS: (test "--suite" "check")
|
||||
|
||||
# Run integration tests only
|
||||
test-integration *OPTIONS: install (test "--suite" "installcheck")
|
||||
|
||||
alias clang-tidy := lint
|
||||
|
||||
# Lint with `clang-tidy`
|
||||
lint:
|
||||
ninja -C build clang-tidy
|
||||
|
||||
alias clang-tidy-fix := lint-fix
|
||||
|
||||
# Fix lints with `clang-tidy-fix`
|
||||
lint-fix:
|
||||
ninja -C build clang-tidy-fix
|
||||
|
||||
Generated
+161
@@ -0,0 +1,161 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# 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 = "cbitset"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29b6ad25ae296159fb0da12b970b2fe179b234584d7cd294c891e2bbb284466b"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dissimilar"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632"
|
||||
|
||||
[[package]]
|
||||
name = "expect-test"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30d9eafeadd538e68fb28016364c9732d78e420b9ff8853fa5e4058861e9f8d3"
|
||||
dependencies = [
|
||||
"dissimilar",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lix-doc"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"expect-test",
|
||||
"rnix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rnix"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a9b645f0edba447dbfc6473dd22999f46a1d00ab39e777a2713a1cf34a1597b"
|
||||
dependencies = [
|
||||
"cbitset",
|
||||
"rowan",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rowan"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ea7cadf87a9d8432e85cb4eb86bd2e765ace60c24ef86e79084dcae5d1c5a19"
|
||||
dependencies = [
|
||||
"rustc-hash",
|
||||
"smol_str",
|
||||
"text_unit",
|
||||
"thin-dst",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smol_str"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fad6c857cbab2627dcf01ec85a623ca4e7dcb5691cbaa3d7fb7653671f0d09c9"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "text_unit"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20431e104bfecc1a40872578dbc390e10290a0e9c35fffe3ce6f73c15a9dbfc2"
|
||||
|
||||
[[package]]
|
||||
name = "thin-dst"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db3c46be180f1af9673ebb27bc1235396f61ef6965b3fe0dbb2e624deb604f0e"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
description = "Nix function documentation tool, stripped down into a library"
|
||||
edition = "2021"
|
||||
edition = "2018"
|
||||
name = "lix-doc"
|
||||
version = "0.0.1"
|
||||
license = "BSD-2-Clause OR MIT"
|
||||
@@ -8,10 +8,11 @@ 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"
|
||||
rnix = "0.8.0"
|
||||
|
||||
[dev-dependencies]
|
||||
expect-test = "1.1.0"
|
||||
@@ -0,0 +1,338 @@
|
||||
// SPDX-FileCopyrightText: 2024 Jade Lovelace
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause OR MIT
|
||||
|
||||
//! library components of nix-doc
|
||||
pub mod pprint;
|
||||
|
||||
use crate::pprint::pprint_args;
|
||||
|
||||
use rnix::types::{Lambda, TypedNode};
|
||||
use rnix::SyntaxKind::*;
|
||||
use rnix::{NodeOrToken, SyntaxNode, TextUnit, WalkEvent};
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::fs;
|
||||
use std::iter;
|
||||
use std::os::raw::c_char;
|
||||
use std::panic;
|
||||
|
||||
use std::ptr;
|
||||
|
||||
use std::{fmt::Display, str};
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||
|
||||
const DOC_INDENT: usize = 3;
|
||||
|
||||
struct SearchResult {
|
||||
/// Name of the function
|
||||
identifier: String,
|
||||
|
||||
/// Dedented documentation comments
|
||||
doc: String,
|
||||
|
||||
/// Parameter block for the function
|
||||
param_block: String,
|
||||
}
|
||||
|
||||
fn find_pos(file: &str, line: usize, col: usize) -> usize {
|
||||
let mut lines = 1;
|
||||
let mut line_start = 0;
|
||||
let mut it = file.chars().enumerate().peekable();
|
||||
while let Some((count, ch)) = it.next() {
|
||||
if ch == '\n' || ch == '\r' {
|
||||
lines += 1;
|
||||
let addend = if ch == '\r' && it.peek().map(|x| x.1) == Some('\n') {
|
||||
it.next();
|
||||
1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
line_start = count + addend;
|
||||
}
|
||||
|
||||
let col_diff = ((count as i32) - (line_start as i32)).abs() as usize;
|
||||
if lines == line && col_diff == col {
|
||||
return count;
|
||||
}
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
impl SearchResult {
|
||||
fn format<P: Display>(&self, filename: P, line: usize) -> String {
|
||||
format!(
|
||||
"**Synopsis:** `{}` = {}\n\n{}\n\n# {}",
|
||||
self.identifier.as_str(),
|
||||
self.param_block,
|
||||
indented(&self.doc, DOC_INDENT),
|
||||
format!("{}:{}", filename, line).as_str(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Emits a string `s` indented by `indent` spaces
|
||||
fn indented(s: &str, indent: usize) -> String {
|
||||
let indent_s = iter::repeat(' ').take(indent).collect::<String>();
|
||||
s.split('\n')
|
||||
.map(|line| indent_s.clone() + line)
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
}
|
||||
|
||||
/// Cleans up a single line, erasing prefix single line comments but preserving indentation
|
||||
fn cleanup_single_line<'a>(s: &'a str) -> &'a str {
|
||||
let mut cmt_new_start = 0;
|
||||
let mut iter = s.char_indices().peekable();
|
||||
while let Some((idx, ch)) = iter.next() {
|
||||
// peek at the next character, with an explicit '\n' as "next character" at end of line
|
||||
let (_, next_ch) = iter.peek().unwrap_or(&(0, '\n'));
|
||||
|
||||
// if we find a character, save the byte position after it as our new string start
|
||||
if ch == '#' || (ch == '*' && next_ch.is_whitespace()) {
|
||||
cmt_new_start = idx + 1;
|
||||
break;
|
||||
}
|
||||
// if, instead, we are on a line with no starting comment characters, leave it alone as it
|
||||
// will be handled by dedent later
|
||||
if !ch.is_whitespace() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
&s[cmt_new_start..]
|
||||
}
|
||||
|
||||
/// Erases indents in comments. This is *almost* a normal dedent function, but it starts by looking
|
||||
/// at the second line if it can.
|
||||
fn dedent_comment(s: &str) -> String {
|
||||
let mut whitespaces = 0;
|
||||
let mut lines = s.lines();
|
||||
let first = lines.next();
|
||||
|
||||
// scan for whitespace
|
||||
for line in lines.chain(first) {
|
||||
let line_whitespace = line.chars().take_while(|ch| ch.is_whitespace()).count();
|
||||
|
||||
if line_whitespace != line.len() {
|
||||
// a non-whitespace line, perfect for taking whitespace off of
|
||||
whitespaces = line_whitespace;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// maybe the first considered line we found was indented further, so let's look for more lines
|
||||
// that might have a shorter indent. In the case of one line, do nothing.
|
||||
for line in s.lines().skip(1) {
|
||||
let line_whitespace = line.chars().take_while(|ch| ch.is_whitespace()).count();
|
||||
|
||||
if line_whitespace != line.len() {
|
||||
whitespaces = line_whitespace.min(whitespaces);
|
||||
}
|
||||
}
|
||||
|
||||
// delete up to `whitespaces` whitespace characters from each line and reconstitute the string
|
||||
let mut out = String::new();
|
||||
for line in s.lines() {
|
||||
let content_begin = line.find(|ch: char| !ch.is_whitespace()).unwrap_or(0);
|
||||
out.push_str(&line[content_begin.min(whitespaces)..]);
|
||||
out.push('\n');
|
||||
}
|
||||
|
||||
out.truncate(out.trim_end_matches('\n').len());
|
||||
out
|
||||
}
|
||||
|
||||
/// Deletes whitespace and leading comment characters
|
||||
///
|
||||
/// Oversight we are choosing to ignore: if you put # characters at the beginning of lines in a
|
||||
/// multiline comment, they will be deleted.
|
||||
fn cleanup_comments<S: AsRef<str>, I: DoubleEndedIterator<Item = S>>(comment: &mut I) -> String {
|
||||
dedent_comment(
|
||||
&comment
|
||||
.rev()
|
||||
.map(|small_comment| {
|
||||
small_comment
|
||||
.as_ref()
|
||||
// space before multiline start
|
||||
.trim_start()
|
||||
// multiline starts
|
||||
.trim_start_matches("/*")
|
||||
// trailing so we can grab multiline end
|
||||
.trim_end()
|
||||
// multiline ends
|
||||
.trim_end_matches("*/")
|
||||
// extra space that was in the multiline
|
||||
.trim()
|
||||
.split('\n')
|
||||
// erase single line comments and such
|
||||
.map(cleanup_single_line)
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n"),
|
||||
)
|
||||
}
|
||||
|
||||
/// Get the docs for a specific function
|
||||
pub fn get_function_docs(filename: &str, line: usize, col: usize) -> Option<String> {
|
||||
let content = fs::read(filename).ok()?;
|
||||
let decoded = str::from_utf8(&content).ok()?;
|
||||
let pos = find_pos(&decoded, line, col);
|
||||
let rowan_pos = TextUnit::from_usize(pos);
|
||||
let tree = rnix::parse(decoded);
|
||||
|
||||
let mut lambda = None;
|
||||
for node in tree.node().preorder() {
|
||||
match node {
|
||||
WalkEvent::Enter(n) => {
|
||||
if n.text_range().start() >= rowan_pos && n.kind() == NODE_LAMBDA {
|
||||
lambda = Lambda::cast(n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
WalkEvent::Leave(_) => (),
|
||||
}
|
||||
}
|
||||
let lambda = lambda?;
|
||||
let res = visit_lambda("func".to_string(), &lambda);
|
||||
Some(res.format(filename, line))
|
||||
}
|
||||
|
||||
fn visit_lambda(name: String, lambda: &Lambda) -> SearchResult {
|
||||
// grab the arguments
|
||||
let param_block = pprint_args(&lambda);
|
||||
|
||||
// find the doc comment
|
||||
let comment = find_comment(lambda.node().clone()).unwrap_or_else(|| "".to_string());
|
||||
|
||||
SearchResult {
|
||||
identifier: name,
|
||||
doc: comment,
|
||||
param_block,
|
||||
}
|
||||
}
|
||||
|
||||
fn find_comment(node: SyntaxNode) -> Option<String> {
|
||||
let mut node = NodeOrToken::Node(node);
|
||||
let mut comments = Vec::new();
|
||||
loop {
|
||||
loop {
|
||||
if let Some(new) = node.prev_sibling_or_token() {
|
||||
node = new;
|
||||
break;
|
||||
} else {
|
||||
node = NodeOrToken::Node(node.parent()?);
|
||||
}
|
||||
}
|
||||
|
||||
match node.kind() {
|
||||
TOKEN_COMMENT => match &node {
|
||||
NodeOrToken::Token(token) => comments.push(token.text().clone()),
|
||||
NodeOrToken::Node(_) => unreachable!(),
|
||||
},
|
||||
// This stuff is found as part of `the-fn = f: ...`
|
||||
// here: ^^^^^^^^
|
||||
NODE_KEY | TOKEN_ASSIGN => (),
|
||||
t if t.is_trivia() => (),
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
let doc = cleanup_comments(&mut comments.iter().map(|c| c.as_str()));
|
||||
Some(doc).filter(|it| !it.is_empty())
|
||||
}
|
||||
|
||||
/// Get the docs for a function in the given file path at the given file position and return it as
|
||||
/// a C string pointer
|
||||
#[no_mangle]
|
||||
pub extern "C" fn nd_get_function_docs(
|
||||
filename: *const c_char,
|
||||
line: usize,
|
||||
col: usize,
|
||||
) -> *const c_char {
|
||||
let fname = unsafe { CStr::from_ptr(filename) };
|
||||
fname
|
||||
.to_str()
|
||||
.ok()
|
||||
.and_then(|f| {
|
||||
panic::catch_unwind(|| get_function_docs(f, line, col))
|
||||
.map_err(|e| {
|
||||
eprintln!("panic!! {:#?}", e);
|
||||
e
|
||||
})
|
||||
.ok()
|
||||
})
|
||||
.flatten()
|
||||
.and_then(|s| CString::new(s).ok())
|
||||
.map(|s| s.into_raw() as *const c_char)
|
||||
.unwrap_or(ptr::null())
|
||||
}
|
||||
|
||||
/// Call this to free a string from nd_get_function_docs
|
||||
#[no_mangle]
|
||||
pub extern "C" fn nd_free_string(s: *const c_char) {
|
||||
unsafe {
|
||||
// cast note: this cast is turning something that was cast to const
|
||||
// back to mut
|
||||
drop(CString::from_raw(s as *mut c_char));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_bytepos() {
|
||||
let fakefile = "abc\ndef\nghi";
|
||||
assert_eq!(find_pos(fakefile, 2, 2), 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bytepos_cursed() {
|
||||
let fakefile = "abc\rdef\r\nghi";
|
||||
assert_eq!(find_pos(fakefile, 2, 2), 5);
|
||||
assert_eq!(find_pos(fakefile, 3, 2), 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_comment_stripping() {
|
||||
let ex1 = ["/* blah blah blah\n foooo baaar\n blah */"];
|
||||
assert_eq!(
|
||||
cleanup_comments(&mut ex1.iter()),
|
||||
"blah blah blah\n foooo baaar\nblah"
|
||||
);
|
||||
|
||||
let ex2 = ["# a1", "# a2", "# aa"];
|
||||
assert_eq!(cleanup_comments(&mut ex2.iter()), "aa\n a2\na1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dedent() {
|
||||
let ex1 = "a\n b\n c\n d";
|
||||
assert_eq!(dedent_comment(ex1), "a\nb\nc\n d");
|
||||
let ex2 = "a\nb\nc";
|
||||
assert_eq!(dedent_comment(ex2), ex2);
|
||||
let ex3 = " a\n b\n\n c";
|
||||
assert_eq!(dedent_comment(ex3), "a\nb\n\n c");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_line_comment_stripping() {
|
||||
let ex1 = " * a";
|
||||
let ex2 = " # a";
|
||||
let ex3 = " a";
|
||||
let ex4 = " *";
|
||||
assert_eq!(cleanup_single_line(ex1), " a");
|
||||
assert_eq!(cleanup_single_line(ex2), " a");
|
||||
assert_eq!(cleanup_single_line(ex3), ex3);
|
||||
assert_eq!(cleanup_single_line(ex4), "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_line_retains_bold_headings() {
|
||||
let ex1 = " **Foo**:";
|
||||
assert_eq!(cleanup_single_line(ex1), ex1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// SPDX-FileCopyrightText: 2024 Jade Lovelace
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause OR MIT
|
||||
|
||||
use rnix::types::{Lambda, TypedNode};
|
||||
use rnix::SyntaxKind::*;
|
||||
|
||||
/// Pretty-prints the arguments to a function
|
||||
pub fn pprint_args(lambda: &Lambda) -> String {
|
||||
// TODO: handle docs directly on NODE_IDENT args (uncommon case)
|
||||
let mut lambda = lambda.clone();
|
||||
let mut out = String::new();
|
||||
loop {
|
||||
let arg = lambda.arg().unwrap();
|
||||
match arg.kind() {
|
||||
NODE_IDENT => {
|
||||
out += &format!("*{}*", &arg.to_string());
|
||||
out.push_str(": ");
|
||||
let body = lambda.body().unwrap();
|
||||
if body.kind() == NODE_LAMBDA {
|
||||
lambda = Lambda::cast(body).unwrap();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
NODE_PATTERN => {
|
||||
out += &format!("*{}*", &arg.to_string());
|
||||
out.push_str(": ");
|
||||
break;
|
||||
}
|
||||
t => {
|
||||
unreachable!("unhandled arg type {:?}", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
out.push_str("...");
|
||||
out
|
||||
|
||||
//pprint_arg(lambda.arg());
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/// @file This is very bothersome code that has to be included in every
|
||||
/// executable to get the correct default ASan options. I am so sorry.
|
||||
|
||||
extern "C" [[gnu::retain]] const char *__asan_default_options()
|
||||
{
|
||||
// We leak a bunch of memory knowingly on purpose. It's not worthwhile to
|
||||
// diagnose that memory being leaked for now.
|
||||
//
|
||||
// Instruction bytes are useful for finding the actual code that
|
||||
// corresponds to an ASan report.
|
||||
//
|
||||
// TODO: setting log_path=asan.log or not: neither works, since you can't
|
||||
// write to the fs in certain places in the testsuite, but you also cannot
|
||||
// write arbitrarily to stderr in other places so the reports get eaten.
|
||||
// pain 🥖
|
||||
return "halt_on_error=1:abort_on_error=1:detect_leaks=0:print_summary=1:dump_instruction_bytes=1";
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user