aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/manual/change-authors.yml111
-rw-r--r--doc/manual/rl-next/addDrvOutputDependencies.md14
-rw-r--r--doc/manual/rl-next/always-allow-substitutes.md13
-rw-r--r--doc/manual/rl-next/cve-fod-fix.md21
-rw-r--r--doc/manual/rl-next/gc-roots-darwin.md8
-rw-r--r--doc/manual/rl-next/macos-stack-size.md9
-rw-r--r--doc/manual/rl-next/more-logs.md9
-rw-r--r--doc/manual/rl-next/nix-eval-derivations.md9
-rw-r--r--doc/manual/rl-next/nix-store-prefetch-unpack.md18
-rw-r--r--doc/manual/rl-next/print-in-repl.md55
-rw-r--r--doc/manual/rl-next/print-value-in-installable-flake-error.md20
-rw-r--r--doc/manual/rl-next/repl-fix-history.md9
-rw-r--r--doc/manual/rl-next/repl-interrupt.md2
-rw-r--r--doc/manual/rl-next/shebang-single-quotes.md13
-rw-r--r--doc/manual/rl-next/ssh-ng-phase-reporting.md8
-rw-r--r--doc/manual/rl-next/ssh-ng-substitute.md9
-rw-r--r--doc/manual/rl-next/warn-ignored-client-settings.md9
-rw-r--r--doc/manual/src/language/derivations.md2
-rw-r--r--maintainers/README.md146
-rw-r--r--maintainers/backporting.md12
-rw-r--r--maintainers/release-process.md196
-rwxr-xr-xmaintainers/upload-release.pl256
-rw-r--r--misc/pre-commit.nix12
-rw-r--r--src/libcmd/installable-flake.cc9
-rw-r--r--src/libcmd/repl-interacter.cc33
-rw-r--r--src/libcmd/repl-interacter.hh5
-rw-r--r--src/libcmd/repl.cc11
-rw-r--r--src/libexpr/primops/context.cc6
-rw-r--r--src/libfetchers/cache.cc11
-rw-r--r--src/libstore/build/derivation-goal.cc11
-rw-r--r--src/libstore/build/local-derivation-goal.cc20
-rw-r--r--src/libutil/archive.cc9
-rw-r--r--src/libutil/archive.hh2
-rw-r--r--src/libutil/error.hh2
-rw-r--r--src/libutil/util.cc8
-rw-r--r--src/libutil/util.hh7
36 files changed, 407 insertions, 688 deletions
diff --git a/doc/manual/change-authors.yml b/doc/manual/change-authors.yml
index 8c07d7e90..98a135397 100644
--- a/doc/manual/change-authors.yml
+++ b/doc/manual/change-authors.yml
@@ -3,66 +3,109 @@
#
# It's used for crediting people accurately in release notes. The release notes
# script will link to forgejo, then to GitHub if forgejo is not present.
+9999years:
+ display_name: wiggles
+ forgejo: rbt
+ github: 9999years
+
+Artturin:
+ github: Artturin
+
+DavHau:
+ github: DavHau
+
+Kha:
+ github: Kha
+
+Lunaphied:
+ forgejo: Lunaphied
+ github: Lunaphied
+
+Qyriad:
+ forgejo: Qyriad
+ github: Qyriad
+
+SharzyL:
+ github: SharzyL
+
+alois31:
+ forgejo: alois31
+ github: alois31
+
+artemist:
+ display_name: Artemis Tosini
+ forgejo: artemist
+
+edolstra:
+ display_name: Eelco Dolstra
+ github: edolstra
+
+ericson:
+ display_name: John Ericson
+ github: ericson2314
+
horrors:
display_name: eldritch horrors
forgejo: pennae
github: pennae
-Qyriad:
- forgejo: Qyriad
- github: Qyriad
+iFreilicht:
+ github: iFreilicht
jade:
forgejo: jade
github: lf-
-iFreilicht:
- github: iFreilicht
+lovesegfault:
+ github: lovesegfault
ma27:
forgejo: ma27
github: ma27
-Lunaphied:
- forgejo: Lunaphied
- github: Lunaphied
-
-9999years:
- display_name: wiggles
- github: 9999years
- forgejo: rbt
-
matthewbauer:
github: matthewbauer
+midnightveil:
+ display_name: julia
+ forgejo: midnightveil
+ github: midnightveil
+
+ncfavier:
+ github: ncfavier
+
+puck:
+ display_name: puck
+ forgejo: puck
+ github: puckipedia
+
+r-vdp:
+ github: r-vdp
+
raito:
display_name: Raito Bezarius
- github: RaitoBezarius
forgejo: raito
+ github: RaitoBezarius
-winter:
- github: winterqt
- forgejo: winter
-
-Kha:
- github: Kha
-
-Artturin:
- github: Artturin
+roberth:
+ display_name: Robert Hensing
+ github: roberth
thufschmitt:
display_name: Théophane Hufschmitt
github: thufschmitt
-edolstra:
- display_name: Eelco Dolstra
- github: edolstra
+tomberek:
+ display_name: Tom Bereknyei
+ github: tomberek
-roberth:
- display_name: Robert Hensing
- github: roberth
+valentin:
+ display_name: Valentin Gagarin
+ github: fricklerhandwerk
-midnightveil:
- display_name: julia
- forgejo: midnightveil
- github: midnightveil
+winter:
+ forgejo: winter
+ github: winterqt
+
+yshui:
+ github: yshui
diff --git a/doc/manual/rl-next/addDrvOutputDependencies.md b/doc/manual/rl-next/addDrvOutputDependencies.md
new file mode 100644
index 000000000..0442383ec
--- /dev/null
+++ b/doc/manual/rl-next/addDrvOutputDependencies.md
@@ -0,0 +1,14 @@
+---
+synopsis: "Add a builtin `addDrvOutputDependencies`"
+prs: 9216
+issues: 7910
+credits: [ericson, horrors]
+category: Features
+---
+
+This builtin allows taking a `drvPath`-like string and turning it into a string
+with context such that, when it lands in a derivation, it will create
+dependencies on *all the outputs* in its closure (!). Although `drvPath` does this
+today, this builtin starts forming a path to migrate to making `drvPath` have a
+more normal and less surprising string context behaviour (see linked issue and
+PR for more details).
diff --git a/doc/manual/rl-next/always-allow-substitutes.md b/doc/manual/rl-next/always-allow-substitutes.md
new file mode 100644
index 000000000..60b588fd7
--- /dev/null
+++ b/doc/manual/rl-next/always-allow-substitutes.md
@@ -0,0 +1,13 @@
+---
+synopsis: "Add an option `always-allow-substitutes` to ignore `allowSubstitutes` in derivations"
+prs: 8047
+credits: [lovesegfault, horrors]
+category: Improvements
+---
+
+You can set this setting to force a system to always allow substituting even
+trivial derivations like `pkgs.writeText`. This is useful for
+[`nix-fast-build --skip-cached`][skip-cached] and similar to be able to also
+ignore trivial derivations.
+
+[skip-cached]: https://github.com/Mic92/nix-fast-build?tab=readme-ov-file#avoiding-redundant-package-downloads
diff --git a/doc/manual/rl-next/cve-fod-fix.md b/doc/manual/rl-next/cve-fod-fix.md
new file mode 100644
index 000000000..4499f639b
--- /dev/null
+++ b/doc/manual/rl-next/cve-fod-fix.md
@@ -0,0 +1,21 @@
+---
+synopsis: "Fix CVE-2024-27297 (GHSA-2ffj-w4mj-pg37)"
+cls: 266
+credits: [puck, jade, thufschmitt, tomberek, valentin]
+category: Fixes
+---
+
+Since Lix fixed-output derivations run in the host network namespace (which we
+wish to change in the future, see
+[lix#285](https://git.lix.systems/lix-project/lix/issues/285)), they may open
+abstract-namespace Unix sockets to each other and to programs on the host. Lix
+contained a now-fixed time-of-check/time-of-use vulnerability where one
+derivation could send writable handles to files in their final location in the
+store to another over an abstract-namespace Unix socket, exit, then the other
+derivation could wait for Lix to hash the paths and overwrite them.
+
+The impact of this vulnerability is that two malicious fixed-output derivations
+could create a poisoned path for the sources to Bash or similarly important
+software containing a backdoor, leading to local privilege execution.
+
+CppNix advisory: https://github.com/NixOS/nix/security/advisories/GHSA-2ffj-w4mj-pg37
diff --git a/doc/manual/rl-next/gc-roots-darwin.md b/doc/manual/rl-next/gc-roots-darwin.md
new file mode 100644
index 000000000..e8e90a397
--- /dev/null
+++ b/doc/manual/rl-next/gc-roots-darwin.md
@@ -0,0 +1,8 @@
+---
+synopsis: Find GC roots using libproc on Darwin
+cls: 723
+credits: artemist
+category: Improvements
+---
+
+Previously, the garbage collector found runtime roots on Darwin by shelling out to `lsof -n -w -F n` then parsing the result. The version of `lsof` packaged in Nixpkgs is very slow on Darwin, so Lix now uses `libproc` directly to speed up GC root discovery, in some tests taking 250ms now instead of 40s.
diff --git a/doc/manual/rl-next/macos-stack-size.md b/doc/manual/rl-next/macos-stack-size.md
new file mode 100644
index 000000000..efbba1577
--- /dev/null
+++ b/doc/manual/rl-next/macos-stack-size.md
@@ -0,0 +1,9 @@
+---
+synopsis: Increase default stack size on macOS
+prs: 9860
+credits: 9999years
+category: Improvements
+---
+
+Increase the default stack size on macOS to the same value as on Linux, subject to system restrictions to maximum stack size.
+This should reduce the number of stack overflow crashes on macOS when evaluating Nix code with deep call stacks.
diff --git a/doc/manual/rl-next/more-logs.md b/doc/manual/rl-next/more-logs.md
new file mode 100644
index 000000000..e239da5ad
--- /dev/null
+++ b/doc/manual/rl-next/more-logs.md
@@ -0,0 +1,9 @@
+---
+synopsis: Show more log context for failed builds
+prs: 9670
+credits: DavHau
+category: Improvements
+---
+
+Show 25 lines of log tail instead of 10 for failed builds.
+This increases the chances of having useful information in the shown logs.
diff --git a/doc/manual/rl-next/nix-eval-derivations.md b/doc/manual/rl-next/nix-eval-derivations.md
new file mode 100644
index 000000000..ae1952283
--- /dev/null
+++ b/doc/manual/rl-next/nix-eval-derivations.md
@@ -0,0 +1,9 @@
+---
+synopsis: Print derivation paths in `nix eval`
+cls: 446
+credits: 9999years
+category: Improvements
+---
+
+`nix eval` previously printed derivations as attribute sets, so commands that print derivations (e.g. `nix eval nixpkgs#bash`) would infinitely loop and segfault.
+It now prints the `.drv` path the derivation generates instead.
diff --git a/doc/manual/rl-next/nix-store-prefetch-unpack.md b/doc/manual/rl-next/nix-store-prefetch-unpack.md
new file mode 100644
index 000000000..5627c2c75
--- /dev/null
+++ b/doc/manual/rl-next/nix-store-prefetch-unpack.md
@@ -0,0 +1,18 @@
+---
+synopsis: "Add an option `--unpack` to unpack archives in `nix store prefetch-file`"
+prs: 9805
+cls: 224
+credits: [yshui, horrors]
+category: Improvements
+---
+
+It is now possible to fetch an archive then NAR-hash it (as in, hash it in the
+same manner as `builtins.fetchTarball` or fixed-output derivations with
+recursive hash type) in one command.
+
+Example:
+
+```
+~ » nix store prefetch-file --name source --unpack https://git.lix.systems/lix-project/lix/archive/2.90-beta.1.tar.gz
+Downloaded 'https://git.lix.systems/lix-project/lix/archive/2.90-beta.1.tar.gz' to '/nix/store/yvfqnq52ryjc3janw02ziv7kr6gd0cs1-source' (hash 'sha256-REWlo2RYHfJkxnmZTEJu3Cd/2VM+wjjpPy7Xi4BdDTQ=').
+```
diff --git a/doc/manual/rl-next/print-in-repl.md b/doc/manual/rl-next/print-in-repl.md
new file mode 100644
index 000000000..e0ac8e17f
--- /dev/null
+++ b/doc/manual/rl-next/print-in-repl.md
@@ -0,0 +1,55 @@
+---
+synopsis: "REPL printing improvements"
+prs: [9931, 10208]
+cls: [375, 492]
+credits: [9999years, horrors]
+category: Improvements
+---
+
+The REPL printer has been improved to do the following:
+- If a string is passed to `:print`, it is printed literally to the screen
+- Structures will be printed as multiple lines when necessary
+
+Before:
+
+```
+nix-repl> { attrs = { a = { b = { c = { }; }; }; }; list = [ 1 ]; list' = [ 1 2 3 ]; }
+{ attrs = { ... }; list = [ ... ]; list' = [ ... ]; }
+
+nix-repl> :p { attrs = { a = { b = { c = { }; }; }; }; list = [ 1 ]; list' = [ 1 2 3 ]; }
+{ attrs = { a = { b = { c = { }; }; }; }; list = [ 1 ]; list' = [ 1 2 3 ]; }
+
+nix-repl> :p "meow"
+"meow"
+```
+
+After:
+
+```
+nix-repl> { attrs = { a = { b = { c = { }; }; }; }; list = [ 1 ]; list' = [ 1 2 3 ]; }
+{
+ attrs = { ... };
+ list = [ ... ];
+ list' = [ ... ];
+}
+
+nix-repl> :p { attrs = { a = { b = { c = { }; }; }; }; list = [ 1 ]; list' = [ 1 2 3 ]; }
+{
+ attrs = {
+ a = {
+ b = {
+ c = { };
+ };
+ };
+ };
+ list = [ 1 ];
+ list' = [
+ 1
+ 2
+ 3
+ ];
+}
+
+nix-repl> :p "meow"
+meow
+```
diff --git a/doc/manual/rl-next/print-value-in-installable-flake-error.md b/doc/manual/rl-next/print-value-in-installable-flake-error.md
new file mode 100644
index 000000000..ae23b4dda
--- /dev/null
+++ b/doc/manual/rl-next/print-value-in-installable-flake-error.md
@@ -0,0 +1,20 @@
+---
+synopsis: New-cli flake commands that expect derivations now print the failing value and its type
+credits: Qyriad
+category: Improvements
+cls: 1177
+---
+
+In errors like `flake output attribute 'legacyPackages.x86_64-linux.lib' is not a derivation or path`, the message now includes the failing value and type.
+
+Before:
+
+```
+ error: flake output attribute 'nixosConfigurations.yuki.config' is not a derivation or path
+````
+
+After:
+
+```
+ error: expected flake output attribute 'nixosConfigurations.yuki.config' to be a derivation or path but found a set: { appstream = «thunk»; assertions = «thunk»; boot = { bcache = «thunk»; binfmt = «thunk»; binfmtMiscRegistrations = «thunk»; blacklistedKernelModules = «thunk»; bootMount = «thunk»; bootspec = «thunk»; cleanTmpDir = «thunk»; consoleLogLevel = «thunk»; «43 attributes elided» }; «48 attributes elided» }
+```
diff --git a/doc/manual/rl-next/repl-fix-history.md b/doc/manual/rl-next/repl-fix-history.md
new file mode 100644
index 000000000..1517f68e7
--- /dev/null
+++ b/doc/manual/rl-next/repl-fix-history.md
@@ -0,0 +1,9 @@
+---
+synopsis: "`nix repl` history is saved more reliably"
+cls: 1164
+credits: puck
+---
+
+`nix repl` now saves its history file after each line, rather than at the end
+of the session; ensuring that it will remember what you typed even after it
+crashes.
diff --git a/doc/manual/rl-next/repl-interrupt.md b/doc/manual/rl-next/repl-interrupt.md
index 61a8ab71e..da0bc698e 100644
--- a/doc/manual/rl-next/repl-interrupt.md
+++ b/doc/manual/rl-next/repl-interrupt.md
@@ -1,6 +1,8 @@
---
synopsis: Interrupting builds in the REPL works more than once
cls: 1097
+category: Fixes
+credits: alois31
---
Builds in the REPL can be interrupted by pressing Ctrl+C.
diff --git a/doc/manual/rl-next/shebang-single-quotes.md b/doc/manual/rl-next/shebang-single-quotes.md
new file mode 100644
index 000000000..f60caad84
--- /dev/null
+++ b/doc/manual/rl-next/shebang-single-quotes.md
@@ -0,0 +1,13 @@
+---
+synopsis: Allow single quotes in nix-shell shebangs
+prs: 8470
+credits: [ncfavier, horrors]
+category: Improvements
+---
+
+Example:
+
+```bash
+#! /usr/bin/env nix-shell
+#! nix-shell -i bash --packages 'terraform.withPlugins (plugins: [ plugins.openstack ])'
+```
diff --git a/doc/manual/rl-next/ssh-ng-phase-reporting.md b/doc/manual/rl-next/ssh-ng-phase-reporting.md
new file mode 100644
index 000000000..02f357410
--- /dev/null
+++ b/doc/manual/rl-next/ssh-ng-phase-reporting.md
@@ -0,0 +1,8 @@
+---
+synopsis: Include phase reporting in log file for ssh-ng builds
+prs: 9280
+credits: r-vdp
+category: Fixes
+---
+
+Store phase information of remote builds run via `ssh-ng` remotes in the local log file, matching logging behavior of local builds.
diff --git a/doc/manual/rl-next/ssh-ng-substitute.md b/doc/manual/rl-next/ssh-ng-substitute.md
new file mode 100644
index 000000000..20f79c106
--- /dev/null
+++ b/doc/manual/rl-next/ssh-ng-substitute.md
@@ -0,0 +1,9 @@
+---
+synopsis: Fix `ssh-ng://` remotes not respecting `--substitute-on-destination`
+prs: 9600
+credits: SharzyL
+category: Fixes
+---
+
+`nix copy ssh-ng://` now respects `--substitute-on-destination`, as does `nix-copy-closure` and other commands that operate on remote `ssh-ng` stores.
+Previously this was always set by `builders-use-substitutes` setting.
diff --git a/doc/manual/rl-next/warn-ignored-client-settings.md b/doc/manual/rl-next/warn-ignored-client-settings.md
new file mode 100644
index 000000000..88edd27fb
--- /dev/null
+++ b/doc/manual/rl-next/warn-ignored-client-settings.md
@@ -0,0 +1,9 @@
+---
+synopsis: Warn about ignored client settings
+cls: 1026
+credits: jade
+category: Improvements
+---
+
+Emit a warning for every client-provided setting the daemon ignores because the requesting client is not run by a trusted user.
+Previously this was only a debug message.
diff --git a/doc/manual/src/language/derivations.md b/doc/manual/src/language/derivations.md
index c10e8149d..28e686889 100644
--- a/doc/manual/src/language/derivations.md
+++ b/doc/manual/src/language/derivations.md
@@ -125,7 +125,7 @@ The builder is executed as follows:
directory (typically, `/nix/store`).
- `NIX_ATTRS_JSON_FILE` & `NIX_ATTRS_SH_FILE` if `__structuredAttrs`
- is set to `true` for the dervation. A detailed explanation of this
+ is set to `true` for the derivation. A detailed explanation of this
behavior can be found in the
[section about structured attrs](./advanced-attributes.md#adv-attr-structuredAttrs).
diff --git a/maintainers/README.md b/maintainers/README.md
deleted file mode 100644
index 0d520cb0c..000000000
--- a/maintainers/README.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# Nix maintainers team
-
-## Motivation
-
-The team's main responsibility is to set a direction for the development of Nix and ensure that the code is in good shape.
-
-We aim to achieve this by improving the contributor experience and attracting more maintainers – that is, by helping other people contributing to Nix and eventually taking responsibility – in order to scale the development process to match users' needs.
-
-### Objectives
-
-- It is obvious what is worthwhile to work on.
-- It is easy to find the right place in the code to make a change.
-- It is clear what is expected of a pull request.
-- It is predictable how to get a change merged and released.
-
-### Tasks
-
-- Establish, communicate, and maintain a technical roadmap
-- Improve documentation targeted at contributors
- - Record architecture and design decisions
- - Elaborate contribution guides and abide to them
- - Define and assert quality criteria for contributions
-- Maintain the issue tracker and triage pull requests
-- Help contributors succeed with pull requests that address roadmap milestones
-- Manage the release lifecycle
-- Regularly publish reports on work done
-- Engage with third parties in the interest of the project
-- Ensure the required maintainer capacity for all of the above
-
-## Members
-
-- Eelco Dolstra (@edolstra) – Team lead
-- Théophane Hufschmitt (@thufschmitt)
-- Valentin Gagarin (@fricklerhandwerk)
-- Thomas Bereknyei (@tomberek)
-- Robert Hensing (@roberth)
-- John Ericson (@Ericson2314)
-
-## Meeting protocol
-
-The team meets twice a week:
-
-- Discussion meeting: [Fridays 13:00-14:00 CET](https://calendar.google.com/calendar/event?eid=MHNtOGVuNWtrZXNpZHR2bW1sM3QyN2ZjaGNfMjAyMjExMjVUMTIwMDAwWiBiOW81MmZvYnFqYWs4b3E4bGZraGczdDBxZ0Bn)
-
- 1. Triage issues and pull requests from the [No Status](#no-status) column (30 min)
- 2. Discuss issues and pull requests from the [To discuss](#to-discuss) column (30 min)
-
-- Work meeting: [Mondays 13:00-15:00 CET](https://calendar.google.com/calendar/event?eid=NTM1MG1wNGJnOGpmOTZhYms3bTB1bnY5cWxfMjAyMjExMjFUMTIwMDAwWiBiOW81MmZvYnFqYWs4b3E4bGZraGczdDBxZ0Bn)
-
- 1. Code review on pull requests from [In review](#in-review).
- 2. Other chores and tasks.
-
-Meeting notes are collected on a [collaborative scratchpad](https://pad.lassul.us/Cv7FpYx-Ri-4VjUykQOLAw), and published on Discourse under the [Nix category](https://discourse.nixos.org/c/dev/nix/50).
-
-## Project board protocol
-
-The team uses a [GitHub project board](https://github.com/orgs/NixOS/projects/19/views/1) for tracking its work.
-
-Items on the board progress through the following states:
-
-### No Status
-
-During the discussion meeting, the team triages new items.
-To be considered, issues and pull requests must have a high-level description to provide the whole team with the necessary context at a glance.
-
-On every meeting, at least one item from each of the following categories is inspected:
-
-1. [critical](https://github.com/NixOS/nix/labels/critical)
-2. [security](https://github.com/NixOS/nix/labels/security)
-3. [regression](https://github.com/NixOS/nix/labels/regression)
-4. [bug](https://github.com/NixOS/nix/issues?q=is%3Aopen+label%3Abug+sort%3Areactions-%2B1-desc)
-5. [tests of existing functionality](https://github.com/NixOS/nix/issues?q=is%3Aopen+label%3Atests+-label%3Afeature+sort%3Areactions-%2B1-desc)
-
-- [oldest pull requests](https://github.com/NixOS/nix/pulls?q=is%3Apr+is%3Aopen+sort%3Acreated-asc)
-- [most popular pull requests](https://github.com/NixOS/nix/pulls?q=is%3Apr+is%3Aopen+sort%3Areactions-%2B1-desc)
-- [oldest issues](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Acreated-asc)
-- [most popular issues](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc)
-
-Team members can also add pull requests or issues they would like the whole team to consider.
-To ensure process quality and reliability, all non-trivial pull requests must be triaged before merging.
-
-If there is disagreement on the general idea behind an issue or pull request, it is moved to [To discuss](#to-discuss).
-Otherwise, the issue or pull request in questions get the label [`idea approved`](https://github.com/NixOS/nix/labels/idea%20approved).
-For issues this means that an implementation is welcome and will be prioritised for review.
-For pull requests this means that:
-- Unfinished work is encouraged to be continued.
-- A reviewer is assigned to take responsibility for getting the pull request merged.
- The item is moved to the [Assigned](#assigned) column.
-- If needed, the team can decide to do a collarorative review.
- Then the item is moved to the [In review](#in-review) column, and review session is scheduled.
-
-What constitutes a trivial pull request is up to maintainers' judgement.
-
-### To discuss
-
-Pull requests and issues that are deemed important and controversial are discussed by the team during discussion meetings.
-
-This may be where the merit of the change itself or the implementation strategy is contested by a team member.
-
-As a general guideline, the order of items is determined as follows:
-
-- Prioritise pull requests over issues
-
- Contributors who took the time to implement concrete change proposals should not wait indefinitely.
-
-- Prioritise fixing bugs and testing over documentation, improvements or new features
-
- The team values stability and accessibility higher than raw functionality.
-
-- Interleave issues and PRs
-
- This way issues without attempts at a solution get a chance to get addressed.
-
-### In review
-
-Pull requests in this column are reviewed together during work meetings.
-This is both for spreading implementation knowledge and for establishing common values in code reviews.
-
-When the overall direction is agreed upon, even when further changes are required, the pull request is assigned to one team member.
-If significant changes are requested or reviewers cannot come to a conclusion in reasonable time, the pull request is [marked as draft](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request#converting-a-pull-request-to-a-draft).
-
-### Assigned
-
-One team member is assigned to each of these pull requests.
-They will communicate with the authors, and make the final approval once all remaining issues are addressed.
-
-If more substantive issues arise, the assignee can move the pull request back to [To discuss](#to-discuss) or [In review](#in-review) to involve the team again.
-
-### Flowchart
-
-The process is illustrated in the following diagram:
-
-```mermaid
-flowchart TD
- discuss[To discuss]
-
- review[To review]
-
- New --> |Disagreement on idea| discuss
- New & discuss --> |Consensus on idea| review
-
- review --> |Consensus on implementation| Assigned
-
- Assigned --> |Implementation issues arise| review
- Assigned --> |Remaining issues fixed| Merged
-```
diff --git a/maintainers/backporting.md b/maintainers/backporting.md
deleted file mode 100644
index 2424050c8..000000000
--- a/maintainers/backporting.md
+++ /dev/null
@@ -1,12 +0,0 @@
-
-# Backporting
-
-To [automatically backport a pull request](https://github.com/NixOS/nix/blob/master/.github/workflows/backport.yml) to a release branch once it's merged, assign it a label of the form [`backport <branch>`](https://github.com/NixOS/nix/labels?q=backport).
-
-Since [GitHub Actions workflows will not trigger other workflows](https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow), checks on the automatic backport need to be triggered by another actor.
-This is achieved by closing and reopening the backport pull request.
-
-This specifically affects the [`installer_test`] check.
-Note that it only runs after the other tests, so it may take a while to appear.
-
-[`installer_test`]: https://github.com/NixOS/nix/blob/895dfc656a21f6252ddf48df0d1f215effa04ecb/.github/workflows/ci.yml#L70-L91
diff --git a/maintainers/release-process.md b/maintainers/release-process.md
deleted file mode 100644
index f2b60d8e7..000000000
--- a/maintainers/release-process.md
+++ /dev/null
@@ -1,196 +0,0 @@
-# Nix release process
-
-## Release artifacts
-
-The release process is intended to create the following for each
-release:
-
-* A Git tag
-
-* Binary tarballs in https://releases.nixos.org/?prefix=nix/
-
-* Docker images
-
-* Closures in https://cache.nixos.org
-
-* (Optionally) Updated `fallback-paths.nix` in Nixpkgs
-
-* An updated manual on https://nixos.org/manual/nix/stable/
-
-## Creating a new release from the `master` branch
-
-* Make sure that the [Hydra `master` jobset](https://hydra.nixos.org/jobset/nix/master) succeeds.
-
-* In a checkout of the Nix repo, make sure you're on `master` and run
- `git pull`.
-
-* Compile the release notes by running
-
- ```console
- $ git checkout -b release-notes
- $ VERSION=X.YY ./maintainers/release-notes
- ```
-
- where `X.YY` is *without* the patch level, e.g. `2.12` rather than ~~`2.12.0`~~.
-
- A commit is created.
-
-* Proof-read / edit / rearrange the release notes if needed. Breaking changes
- and highlights should go to the top.
-
-* Push.
-
- ```console
- $ git push --set-upstream $REMOTE release-notes
- ```
-
-* Create a PR for `release-notes`.
-
-* Wait for the PR to be merged.
-
-* Create a branch for the release:
-
- ```console
- $ git checkout master
- $ git pull
- $ git checkout -b $VERSION-maintenance
- ```
-
-* Mark the release as official:
-
- ```console
- $ sed -e 's/officialRelease = false;/officialRelease = true;/' -i flake.nix
- $ sed -e '/rl-next.md/ d' -i doc/manual/src/SUMMARY.md
- ```
-
- This removes the link to `rl-next.md` from the manual and sets
- `officialRelease = true` in `flake.nix`.
-
-* Commit
-
-* Push the release branch:
-
- ```console
- $ git push --set-upstream origin $VERSION-maintenance
- ```
-
-* Create a jobset for the release branch on Hydra as follows:
-
- * Go to the jobset of the previous release
- (e.g. https://hydra.nixos.org/jobset/nix/maintenance-2.11).
-
- * Select `Actions -> Clone this jobset`.
-
- * Set identifier to `maintenance-$VERSION`.
-
- * Set description to `$VERSION release branch`.
-
- * Set flake URL to `github:NixOS/nix/$VERSION-maintenance`.
-
- * Hit `Create jobset`.
-
-* Wait for the new jobset to evaluate and build. If impatient, go to
- the evaluation and select `Actions -> Bump builds to front of
- queue`.
-
-* When the jobset evaluation has succeeded building, take note of the
- evaluation ID (e.g. `1780832` in
- `https://hydra.nixos.org/eval/1780832`).
-
-* Tag the release and upload the release artifacts to
- [`releases.nixos.org`](https://releases.nixos.org/) and [Docker Hub](https://hub.docker.com/):
-
- ```console
- $ IS_LATEST=1 ./maintainers/upload-release.pl <EVAL-ID>
- ```
-
- Note: `IS_LATEST=1` causes the `latest-release` branch to be
- force-updated. This is used by the `nixos.org` website to get the
- [latest Nix manual](https://nixos.org/manual/nixpkgs/unstable/).
-
- TODO: This script requires the right AWS credentials. Document.
-
- TODO: This script currently requires a
- `/home/eelco/Dev/nix-pristine`.
-
- TODO: trigger nixos.org netlify: https://docs.netlify.com/configure-builds/build-hooks/
-
-* Prepare for the next point release by editing `.version` to
- e.g.
-
- ```console
- $ echo 2.12.1 > .version
- $ git commit -a -m 'Bump version'
- $ git push
- ```
-
- Commit and push this to the maintenance branch.
-
-* Bump the version of `master`:
-
- ```console
- $ git checkout master
- $ git pull
- $ NEW_VERSION=2.13.0
- $ echo $NEW_VERSION > .version
- $ git checkout -b bump-$NEW_VERSION
- $ git commit -a -m 'Bump version'
- $ git push --set-upstream origin bump-$NEW_VERSION
- ```
-
- Make a pull request and auto-merge it.
-
-* Create a milestone for the next release, move all unresolved issues
- from the previous milestone, and close the previous milestone. Set
- the date for the next milestone 6 weeks from now.
-
-* Create a backport label.
-
-* Post an [announcement on Discourse](https://discourse.nixos.org/c/announcements/8), including the contents of
- `rl-$VERSION.md`.
-
-## Creating a point release
-
-* Checkout.
-
- ```console
- $ git checkout XX.YY-maintenance
- ```
-
-* Determine the next patch version.
-
- ```console
- $ export VERSION=XX.YY.ZZ
- ```
-
-* Update release notes.
-
- ```console
- $ ./maintainers/release-notes
- ```
-
-* Push.
-
- ```console
- $ git push
- ```
-
-* Wait for the desired evaluation of the maintenance jobset to finish
- building.
-
-* Run
-
- ```console
- $ IS_LATEST=1 ./maintainers/upload-release.pl <EVAL-ID>
- ```
-
- Omit `IS_LATEST=1` when creating a point release that is not on the
- most recent stable branch. This prevents `nixos.org` to going back
- to an older release.
-
-* Bump the version number of the release branch as above (e.g. to
- `2.12.2`).
-
-## Recovering from mistakes
-
-`upload-release.pl` should be idempotent. For instance a wrong `IS_LATEST` value can be fixed that way, by running the script on the actual latest release.
diff --git a/maintainers/upload-release.pl b/maintainers/upload-release.pl
deleted file mode 100755
index ebc536f12..000000000
--- a/maintainers/upload-release.pl
+++ /dev/null
@@ -1,256 +0,0 @@
-#! /usr/bin/env nix-shell
-#! nix-shell -i perl -p perl perlPackages.LWPUserAgent perlPackages.LWPProtocolHttps perlPackages.FileSlurp perlPackages.NetAmazonS3 gnupg1
-
-use strict;
-use Data::Dumper;
-use File::Basename;
-use File::Path;
-use File::Slurp;
-use File::Copy;
-use JSON::PP;
-use LWP::UserAgent;
-use Net::Amazon::S3;
-
-my $evalId = $ARGV[0] or die "Usage: $0 EVAL-ID\n";
-
-my $releasesBucketName = "nix-releases";
-my $channelsBucketName = "nix-channels";
-
-my $TMPDIR = $ENV{'TMPDIR'} // "/tmp";
-
-my $isLatest = ($ENV{'IS_LATEST'} // "") eq "1";
-
-# FIXME: cut&paste from nixos-channel-scripts.
-sub fetch {
- my ($url, $type) = @_;
-
- my $ua = LWP::UserAgent->new;
- $ua->default_header('Accept', $type) if defined $type;
-
- my $response = $ua->get($url);
- die "could not download $url: ", $response->status_line, "\n" unless $response->is_success;
-
- return $response->decoded_content;
-}
-
-my $evalUrl = "https://hydra.nixos.org/eval/$evalId";
-my $evalInfo = decode_json(fetch($evalUrl, 'application/json'));
-#print Dumper($evalInfo);
-my $flakeUrl = $evalInfo->{flake} or die;
-my $flakeInfo = decode_json(`nix flake metadata --json "$flakeUrl"` or die);
-my $nixRev = $flakeInfo->{revision} or die;
-
-my $buildInfo = decode_json(fetch("$evalUrl/job/build.x86_64-linux", 'application/json'));
-#print Dumper($buildInfo);
-
-my $releaseName = $buildInfo->{nixname};
-$releaseName =~ /nix-(.*)$/ or die;
-my $version = $1;
-
-print STDERR "Flake URL is $flakeUrl, Nix revision is $nixRev, version is $version\n";
-
-my $releaseDir = "nix/$releaseName";
-
-my $tmpDir = "$TMPDIR/nix-release/$releaseName";
-File::Path::make_path($tmpDir);
-
-my $narCache = "$TMPDIR/nar-cache";
-File::Path::make_path($narCache);
-
-my $binaryCache = "https://cache.nixos.org/?local-nar-cache=$narCache";
-
-# S3 setup.
-my $aws_access_key_id = $ENV{'AWS_ACCESS_KEY_ID'} or die "No AWS_ACCESS_KEY_ID given.";
-my $aws_secret_access_key = $ENV{'AWS_SECRET_ACCESS_KEY'} or die "No AWS_SECRET_ACCESS_KEY given.";
-
-my $s3 = Net::Amazon::S3->new(
- { aws_access_key_id => $aws_access_key_id,
- aws_secret_access_key => $aws_secret_access_key,
- retry => 1,
- host => "s3-eu-west-1.amazonaws.com",
- });
-
-my $releasesBucket = $s3->bucket($releasesBucketName) or die;
-
-my $s3_us = Net::Amazon::S3->new(
- { aws_access_key_id => $aws_access_key_id,
- aws_secret_access_key => $aws_secret_access_key,
- retry => 1,
- });
-
-my $channelsBucket = $s3_us->bucket($channelsBucketName) or die;
-
-sub getStorePath {
- my ($jobName, $output) = @_;
- my $buildInfo = decode_json(fetch("$evalUrl/job/$jobName", 'application/json'));
- return $buildInfo->{buildoutputs}->{$output or "out"}->{path} or die "cannot get store path for '$jobName'";
-}
-
-sub copyManual {
- my $manual = getStorePath("build.x86_64-linux", "doc");
- print "$manual\n";
-
- my $manualNar = "$tmpDir/$releaseName-manual.nar.xz";
- print "$manualNar\n";
-
- unless (-e $manualNar) {
- system("NIX_REMOTE=$binaryCache nix store dump-path '$manual' | xz > '$manualNar'.tmp") == 0
- or die "unable to fetch $manual\n";
- rename("$manualNar.tmp", $manualNar) or die;
- }
-
- unless (-e "$tmpDir/manual") {
- system("xz -d < '$manualNar' | nix-store --restore $tmpDir/manual.tmp") == 0
- or die "unable to unpack $manualNar\n";
- rename("$tmpDir/manual.tmp/share/doc/nix/manual", "$tmpDir/manual") or die;
- system("rm -rf '$tmpDir/manual.tmp'") == 0 or die;
- }
-
- system("aws s3 sync '$tmpDir/manual' s3://$releasesBucketName/$releaseDir/manual") == 0
- or die "syncing manual to S3\n";
-}
-
-copyManual;
-
-sub downloadFile {
- my ($jobName, $productNr, $dstName) = @_;
-
- my $buildInfo = decode_json(fetch("$evalUrl/job/$jobName", 'application/json'));
- #print STDERR "$jobName: ", Dumper($buildInfo), "\n";
-
- my $srcFile = $buildInfo->{buildproducts}->{$productNr}->{path} or die "job '$jobName' lacks product $productNr\n";
- $dstName //= basename($srcFile);
- my $tmpFile = "$tmpDir/$dstName";
-
- if (!-e $tmpFile) {
- print STDERR "downloading $srcFile to $tmpFile...\n";
-
- my $fileInfo = decode_json(`NIX_REMOTE=$binaryCache nix store ls --json '$srcFile'`);
-
- $srcFile = $fileInfo->{target} if $fileInfo->{type} eq 'symlink';
-
- #print STDERR $srcFile, " ", Dumper($fileInfo), "\n";
-
- system("NIX_REMOTE=$binaryCache nix store cat '$srcFile' > '$tmpFile'.tmp") == 0
- or die "unable to fetch $srcFile\n";
- rename("$tmpFile.tmp", $tmpFile) or die;
- }
-
- my $sha256_expected = $buildInfo->{buildproducts}->{$productNr}->{sha256hash};
- my $sha256_actual = `nix hash file --base16 --type sha256 '$tmpFile'`;
- chomp $sha256_actual;
- if (defined($sha256_expected) && $sha256_expected ne $sha256_actual) {
- print STDERR "file $tmpFile is corrupt, got $sha256_actual, expected $sha256_expected\n";
- exit 1;
- }
-
- write_file("$tmpFile.sha256", $sha256_actual);
-
- return $sha256_expected;
-}
-
-downloadFile("binaryTarball.i686-linux", "1");
-downloadFile("binaryTarball.x86_64-linux", "1");
-downloadFile("binaryTarball.aarch64-linux", "1");
-downloadFile("binaryTarball.x86_64-darwin", "1");
-downloadFile("binaryTarball.aarch64-darwin", "1");
-downloadFile("binaryTarballCross.x86_64-linux.armv6l-linux", "1");
-downloadFile("binaryTarballCross.x86_64-linux.armv7l-linux", "1");
-downloadFile("installerScript", "1");
-
-# Upload docker images to dockerhub.
-my $dockerManifest = "";
-my $dockerManifestLatest = "";
-
-for my $platforms (["x86_64-linux", "amd64"], ["aarch64-linux", "arm64"]) {
- my $system = $platforms->[0];
- my $dockerPlatform = $platforms->[1];
- my $fn = "nix-$version-docker-image-$dockerPlatform.tar.gz";
- downloadFile("dockerImage.$system", "1", $fn);
-
- print STDERR "loading docker image for $dockerPlatform...\n";
- system("docker load -i $tmpDir/$fn") == 0 or die;
-
- my $tag = "nixos/nix:$version-$dockerPlatform";
- my $latestTag = "nixos/nix:latest-$dockerPlatform";
-
- print STDERR "tagging $version docker image for $dockerPlatform...\n";
- system("docker tag nix:$version $tag") == 0 or die;
-
- if ($isLatest) {
- print STDERR "tagging latest docker image for $dockerPlatform...\n";
- system("docker tag nix:$version $latestTag") == 0 or die;
- }
-
- print STDERR "pushing $version docker image for $dockerPlatform...\n";
- system("docker push -q $tag") == 0 or die;
-
- if ($isLatest) {
- print STDERR "pushing latest docker image for $dockerPlatform...\n";
- system("docker push -q $latestTag") == 0 or die;
- }
-
- $dockerManifest .= " --amend $tag";
- $dockerManifestLatest .= " --amend $latestTag"
-}
-
-print STDERR "creating multi-platform docker manifest...\n";
-system("docker manifest rm nixos/nix:$version");
-system("docker manifest create nixos/nix:$version $dockerManifest") == 0 or die;
-if ($isLatest) {
- print STDERR "creating latest multi-platform docker manifest...\n";
- system("docker manifest rm nixos/nix:latest");
- system("docker manifest create nixos/nix:latest $dockerManifestLatest") == 0 or die;
-}
-
-print STDERR "pushing multi-platform docker manifest...\n";
-system("docker manifest push nixos/nix:$version") == 0 or die;
-
-if ($isLatest) {
- print STDERR "pushing latest multi-platform docker manifest...\n";
- system("docker manifest push nixos/nix:latest") == 0 or die;
-}
-
-# Upload nix-fallback-paths.nix.
-write_file("$tmpDir/fallback-paths.nix",
- "{\n" .
- " x86_64-linux = \"" . getStorePath("build.x86_64-linux") . "\";\n" .
- " i686-linux = \"" . getStorePath("build.i686-linux") . "\";\n" .
- " aarch64-linux = \"" . getStorePath("build.aarch64-linux") . "\";\n" .
- " x86_64-darwin = \"" . getStorePath("build.x86_64-darwin") . "\";\n" .
- " aarch64-darwin = \"" . getStorePath("build.aarch64-darwin") . "\";\n" .
- "}\n");
-
-# Upload release files to S3.
-for my $fn (glob "$tmpDir/*") {
- my $name = basename($fn);
- next if $name eq "manual";
- my $dstKey = "$releaseDir/" . $name;
- unless (defined $releasesBucket->head_key($dstKey)) {
- print STDERR "uploading $fn to s3://$releasesBucketName/$dstKey...\n";
-
- my $configuration = ();
- $configuration->{content_type} = "application/octet-stream";
-
- if ($fn =~ /.sha256|install|\.nix$/) {
- $configuration->{content_type} = "text/plain";
- }
-
- $releasesBucket->add_key_filename($dstKey, $fn, $configuration)
- or die $releasesBucket->err . ": " . $releasesBucket->errstr;
- }
-}
-
-# Update the "latest" symlink.
-$channelsBucket->add_key(
- "nix-latest/install", "",
- { "x-amz-website-redirect-location" => "https://releases.nixos.org/$releaseDir/install" })
- or die $channelsBucket->err . ": " . $channelsBucket->errstr
- if $isLatest;
-
-# Tag the release in Git.
-chdir("/home/eelco/Dev/nix-pristine") or die;
-system("git remote update origin") == 0 or die;
-system("git tag --force --sign $version $nixRev -m 'Tagging release $version'") == 0 or die;
-system("git push --tags") == 0 or die;
-system("git push --force-with-lease origin $nixRev:refs/heads/latest-release") == 0 or die if $isLatest;
diff --git a/misc/pre-commit.nix b/misc/pre-commit.nix
index ea39bc21d..ed2b152a3 100644
--- a/misc/pre-commit.nix
+++ b/misc/pre-commit.nix
@@ -66,6 +66,18 @@ pre-commit-run {
${lib.getExe pkgs.build-release-notes} --change-authors doc/manual/change-authors.yml doc/manual/rl-next doc/manual/rl-next-dev
'';
};
+ change-authors-sorted = {
+ enable = true;
+ package = pkgs.yq;
+ files = ''^doc/manual/change-authors\.yml'';
+ entry = "${pkgs.writeShellScript "change-authors-sorted" ''
+ set -euo pipefail
+ shopt -s inherit_errexit
+
+ echo "changes necessary to sort $1:"
+ diff -U3 <(${lib.getExe pkgs.yq} -y . "$1") <(${lib.getExe pkgs.yq} -Sy . "$1")
+ ''}";
+ };
check-headers = {
enable = true;
package = pkgs.check-headers;
diff --git a/src/libcmd/installable-flake.cc b/src/libcmd/installable-flake.cc
index 615f70945..46bdd411b 100644
--- a/src/libcmd/installable-flake.cc
+++ b/src/libcmd/installable-flake.cc
@@ -105,9 +105,14 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
fmt("while evaluating the flake output attribute '%s'", attrPath)))
{
return { *derivedPathWithInfo };
+ } else {
+ throw Error(
+ "expected flake output attribute '%s' to be a derivation or path but found %s: %s",
+ attrPath,
+ showType(v),
+ ValuePrinter(*this->state, v, errorPrintOptions)
+ );
}
- else
- throw Error("flake output attribute '%s' is not a derivation or path", attrPath);
}
auto drvPath = attr->forceDerivation();
diff --git a/src/libcmd/repl-interacter.cc b/src/libcmd/repl-interacter.cc
index 829383add..41589cda1 100644
--- a/src/libcmd/repl-interacter.cc
+++ b/src/libcmd/repl-interacter.cc
@@ -1,6 +1,8 @@
#include <cstdio>
#include <iostream>
#include <string>
+#include <string_view>
+#include <cerrno>
#ifdef READLINE
#include <readline/history.h>
@@ -175,14 +177,43 @@ bool ReadlineLikeInteracter::getLine(std::string & input, ReplPromptType promptT
if (!s)
return false;
+
+ this->writeHistory();
input += s;
input += '\n';
return true;
}
+void ReadlineLikeInteracter::writeHistory()
+{
+ int ret = write_history(historyFile.c_str());
+ int writeHistErr = errno;
+
+ if (ret == 0) {
+ return;
+ }
+
+ // If the open fails, editline returns EOF. If the close fails, editline
+ // forwards the return value of fclose(), which is EOF on error.
+ // readline however, returns the errno.
+ // So if we didn't get exactly EOF, then consider the return value the error
+ // code; otherwise use the errno we saved above.
+ // https://github.com/troglobit/editline/issues/66
+ if (ret != EOF) {
+ writeHistErr = ret;
+ }
+
+ // In any of these cases, we should explicitly ignore the error, but log
+ // them so the user isn't confused why their history is getting eaten.
+
+ std::string_view const errMsg(std::strerror(writeHistErr));
+ warn("ignoring error writing repl history to %s: %s", this->historyFile, errMsg);
+
+}
+
ReadlineLikeInteracter::~ReadlineLikeInteracter()
{
- write_history(historyFile.c_str());
+ this->writeHistory();
}
AutomationInteracter::Guard AutomationInteracter::init(detail::ReplCompleterMixin *)
diff --git a/src/libcmd/repl-interacter.hh b/src/libcmd/repl-interacter.hh
index c31b1a1e6..8f815fceb 100644
--- a/src/libcmd/repl-interacter.hh
+++ b/src/libcmd/repl-interacter.hh
@@ -42,6 +42,11 @@ public:
}
virtual Guard init(detail::ReplCompleterMixin * repl) override;
virtual bool getLine(std::string & input, ReplPromptType promptType) override;
+ /** Writes the current history to the history file.
+ *
+ * This function logs but ignores errors from readline's write_history().
+ */
+ virtual void writeHistory();
virtual ~ReadlineLikeInteracter() override;
};
diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc
index 525c25560..46b6d57ed 100644
--- a/src/libcmd/repl.cc
+++ b/src/libcmd/repl.cc
@@ -90,7 +90,8 @@ struct NixRepl
Strings loadedFiles;
std::function<AnnotatedValues()> getValues;
- const static int envSize = 32768;
+ // Uses 8MiB of memory. It's fine.
+ const static int envSize = 1 << 20;
std::shared_ptr<StaticEnv> staticEnv;
Env * env;
int displ;
@@ -375,6 +376,9 @@ StringSet NixRepl::completePrefix(const std::string & prefix)
// Quietly ignore evaluation errors.
} catch (BadURL & e) {
// Quietly ignore BadURL flake-related errors.
+ } catch (SysError & e) {
+ // Quietly ignore system errors which can for example be raised by
+ // a non-existent file being `import`-ed.
}
}
@@ -854,6 +858,11 @@ void NixRepl::loadReplOverlays()
replInitFilesFunction->determinePos(noPos)
);
+ // n.b. this does in fact load the stuff into the environment twice (once
+ // from the superset of the environment returned by repl-overlays and once
+ // from the thing itself), but it's not fixable because clearEnv here could
+ // lead to dangling references to the old environment in thunks.
+ // https://git.lix.systems/lix-project/lix/issues/337#issuecomment-3745
addAttrsToScope(newAttrs);
}
diff --git a/src/libexpr/primops/context.cc b/src/libexpr/primops/context.cc
index 1eec8b316..36692aafb 100644
--- a/src/libexpr/primops/context.cc
+++ b/src/libexpr/primops/context.cc
@@ -36,7 +36,7 @@ static RegisterPrimOp primop_hasContext({
> **Example**
>
- > Many operations require a string context to be empty because they are intended only to work with "regular" strings, and also to help users avoid unintentionally loosing track of string context elements.
+ > Many operations require a string context to be empty because they are intended only to work with "regular" strings, and also to help users avoid unintentionally losing track of string context elements.
> `builtins.hasContext` can help create better domain-specific errors in those case.
>
> ```nix
@@ -137,14 +137,14 @@ static RegisterPrimOp primop_addDrvOutputDependencies({
.name = "__addDrvOutputDependencies",
.args = {"s"},
.doc = R"(
- Create a copy of the given string where a single consant string context element is turned into a "derivation deep" string context element.
+ Create a copy of the given string where a single constant string context element is turned into a "derivation deep" string context element.
The store path that is the constant string context element should point to a valid derivation, and end in `.drv`.
The original string context element must not be empty or have multiple elements, and it must not have any other type of element other than a constant or derivation deep element.
The latter is supported so this function is idempotent.
- This is the opposite of [`builtins.unsafeDiscardOutputDependency`](#builtins-addDrvOutputDependencies).
+ This is the opposite of [`builtins.unsafeDiscardOutputDependency`](#builtins-unsafeDiscardOutputDependency).
)",
.fun = prim_addDrvOutputDependencies
});
diff --git a/src/libfetchers/cache.cc b/src/libfetchers/cache.cc
index 0c8ecac9d..672e1e0bc 100644
--- a/src/libfetchers/cache.cc
+++ b/src/libfetchers/cache.cc
@@ -34,7 +34,16 @@ struct CacheImpl : Cache
auto state(_state.lock());
auto dbPath = getCacheDir() + "/nix/fetcher-cache-v1.sqlite";
- createDirs(dirOf(dbPath));
+ // It would be silly to fail fetcher operations if e.g. the user has no
+ // XDG_CACHE_HOME and their HOME directory doesn't exist.
+ // We'll warn the user if that happens, but fallback to an in-memory
+ // backend for the SQLite database.
+ try {
+ createDirs(dirOf(dbPath));
+ } catch (SysError const & ex) {
+ warn("ignoring error initializing Lix fetcher cache: %s", ex.what());
+ dbPath = ":memory:";
+ }
state->db = SQLite(dbPath);
state->db.isCache();
diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc
index 3f24da276..5fa5deb7c 100644
--- a/src/libstore/build/derivation-goal.cc
+++ b/src/libstore/build/derivation-goal.cc
@@ -786,13 +786,6 @@ void DerivationGoal::tryLocalBuild() {
}
-static void chmod_(const Path & path, mode_t mode)
-{
- if (chmod(path.c_str(), mode) == -1)
- throw SysError("setting permissions on '%s'", path);
-}
-
-
/* Move/rename path 'src' to 'dst'. Temporarily make 'src' writable if
it's a directory and we're not root (to be able to update the
directory's parent link ".."). */
@@ -803,12 +796,12 @@ static void movePath(const Path & src, const Path & dst)
bool changePerm = (geteuid() && S_ISDIR(st.st_mode) && !(st.st_mode & S_IWUSR));
if (changePerm)
- chmod_(src, st.st_mode | S_IWUSR);
+ chmodPath(src, st.st_mode | S_IWUSR);
renameFile(src, dst);
if (changePerm)
- chmod_(dst, st.st_mode);
+ chmodPath(dst, st.st_mode);
}
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc
index cdbd0f5a7..5c36a3ac2 100644
--- a/src/libstore/build/local-derivation-goal.cc
+++ b/src/libstore/build/local-derivation-goal.cc
@@ -272,12 +272,6 @@ void LocalDerivationGoal::tryLocalBuild()
started();
}
-static void chmod_(const Path & path, mode_t mode)
-{
- if (chmod(path.c_str(), mode) == -1)
- throw SysError("setting permissions on '%s'", path);
-}
-
/* Move/rename path 'src' to 'dst'. Temporarily make 'src' writable if
it's a directory and we're not root (to be able to update the
@@ -289,12 +283,12 @@ static void movePath(const Path & src, const Path & dst)
bool changePerm = (geteuid() && S_ISDIR(st.st_mode) && !(st.st_mode & S_IWUSR));
if (changePerm)
- chmod_(src, st.st_mode | S_IWUSR);
+ chmodPath(src, st.st_mode | S_IWUSR);
renameFile(src, dst);
if (changePerm)
- chmod_(dst, st.st_mode);
+ chmodPath(dst, st.st_mode);
}
@@ -696,7 +690,7 @@ void LocalDerivationGoal::startBuilder()
instead.) */
Path chrootTmpDir = chrootRootDir + "/tmp";
createDirs(chrootTmpDir);
- chmod_(chrootTmpDir, 01777);
+ chmodPath(chrootTmpDir, 01777);
/* Create a /etc/passwd with entries for the build user and the
nobody account. The latter is kind of a hack to support
@@ -721,7 +715,7 @@ void LocalDerivationGoal::startBuilder()
build user. */
Path chrootStoreDir = chrootRootDir + worker.store.storeDir;
createDirs(chrootStoreDir);
- chmod_(chrootStoreDir, 01775);
+ chmodPath(chrootStoreDir, 01775);
if (buildUser && chown(chrootStoreDir.c_str(), 0, buildUser->getGID()) == -1)
throw SysError("cannot change ownership of '%1%'", chrootStoreDir);
@@ -1862,7 +1856,7 @@ void LocalDerivationGoal::runChild()
auto dst = chrootRootDir + i.first;
createDirs(dirOf(dst));
writeFile(dst, std::string_view((const char *) sh, sizeof(sh)));
- chmod_(dst, 0555);
+ chmodPath(dst, 0555);
} else
#endif
doBind(i.second.source, chrootRootDir + i.first, i.second.optional);
@@ -1900,7 +1894,7 @@ void LocalDerivationGoal::runChild()
/* Make sure /dev/pts/ptmx is world-writable. With some
Linux versions, it is created with permissions 0. */
- chmod_(chrootRootDir + "/dev/pts/ptmx", 0666);
+ chmodPath(chrootRootDir + "/dev/pts/ptmx", 0666);
} else {
if (errno != EINVAL)
throw SysError("mounting /dev/pts");
@@ -1911,7 +1905,7 @@ void LocalDerivationGoal::runChild()
/* Make /etc unwritable */
if (!parsedDrv->useUidRange())
- chmod_(chrootRootDir + "/etc", 0555);
+ chmodPath(chrootRootDir + "/etc", 0555);
/* Unshare this mount namespace. This is necessary because
pivot_root() below changes the root of the mount
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc
index 00536c1e1..a18c54ebf 100644
--- a/src/libutil/archive.cc
+++ b/src/libutil/archive.cc
@@ -389,13 +389,4 @@ void copyNAR(Source & source, Sink & sink)
}
-void copyPath(const Path & from, const Path & to)
-{
- auto source = sinkToSource([&](Sink & sink) {
- dumpPath(from, sink);
- });
- restorePath(to, *source);
-}
-
-
}
diff --git a/src/libutil/archive.hh b/src/libutil/archive.hh
index 2cf164a41..017b6633c 100644
--- a/src/libutil/archive.hh
+++ b/src/libutil/archive.hh
@@ -124,8 +124,6 @@ void restorePath(const Path & path, Source & source);
*/
void copyNAR(Source & source, Sink & sink);
-void copyPath(const Path & from, const Path & to);
-
inline constexpr std::string_view narVersionMagic1 = "nix-archive-1";
diff --git a/src/libutil/error.hh b/src/libutil/error.hh
index 924366580..323365d65 100644
--- a/src/libutil/error.hh
+++ b/src/libutil/error.hh
@@ -110,6 +110,8 @@ protected:
public:
BaseError(const BaseError &) = default;
+ BaseError & operator=(BaseError const & rhs) = default;
+
template<typename... Args>
BaseError(unsigned int status, const Args & ... args)
: err { .level = lvlError, .msg = HintFmt(args...), .status = status }
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index bc2dd1802..2c0fcc897 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -184,6 +184,11 @@ Path canonPath(PathView path, bool resolveSymlinks)
return s.empty() ? "/" : std::move(s);
}
+void chmodPath(const Path & path, mode_t mode)
+{
+ if (chmod(path.c_str(), mode) == -1)
+ throw SysError("setting permissions on '%s'", path);
+}
Path dirOf(const PathView path)
{
@@ -1799,8 +1804,7 @@ AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode)
bind(fdSocket.get(), path);
- if (chmod(path.c_str(), mode) == -1)
- throw SysError("changing permissions on '%1%'", path);
+ chmodPath(path.c_str(), mode);
if (listen(fdSocket.get(), 100) == -1)
throw SysError("cannot listen on socket '%1%'", path);
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 914d6cce0..14868776c 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -78,6 +78,13 @@ Path absPath(Path path,
Path canonPath(PathView path, bool resolveSymlinks = false);
/**
+ * Change the permissions of a path
+ * Not called `chmod` as it shadows and could be confused with
+ * `int chmod(char *, mode_t)`, which does not handle errors
+ */
+void chmodPath(const Path & path, mode_t mode);
+
+/**
* @return The directory part of the given canonical path, i.e.,
* everything before the final `/`. If the path is the root or an
* immediate child thereof (e.g., `/foo`), this means `/`