libcmd/profiles: keep derivations if keep-env-derivations = true

nix3 CLI never honored that setting.

When we update a nix3 profile element with new built store paths for
which we know the deriver (the derivation path which built it), we add
the derivation paths to the profile element to prevent garbage
collection the same way the nix2 CLI logic does.

Fixes #1095.

Change-Id: Icc236d174c5ce5ffe042d1c8e1968f6cb5b50359
Signed-off-by: Raito Bezarius <raito@lix.systems>
This commit is contained in:
Raito Bezarius
2026-03-03 22:13:02 +00:00
parent fc649250ec
commit e8015836e3
3 changed files with 54 additions and 0 deletions
+37
View File
@@ -2,6 +2,7 @@ import re
import json
import pytest
from textwrap import dedent
from pathlib import Path
from testlib.fixtures.file_helper import File, with_files
from testlib.fixtures.nix import Nix
@@ -279,3 +280,39 @@ def test_conflict_resolution_cppnix_8284(nix: Nix):
expr = f'(builtins.getFlake "./flake2").packages.{system}.default'
nix.nix(["profile", "install", "--impure", "--expr", expr]).run().expect(1)
class TestKeepEnvDerivations:
@with_files({"flake1": flake})
def test_keep_derivations_enabled(self, nix: Nix, env: ManagedEnv):
nix.settings["keep-env-derivations"] = "true"
nix.settings["keep-derivations"] = "false" # NOTE: This defaults to `true`.
nix.nix(["profile", "install", "./flake1", "-L"]).run().ok()
assert run_hello(env) == "Hello World\n"
res = nix.nix(["eval", "--raw", "./flake1#default.drvPath"]).run().ok()
drv_path = Path(res.stdout_s.strip())
assert drv_path.exists()
# The derivation should NOT be collected because `keep-env-derivations` is true
nix.nix(["store", "gc"]).run().ok()
assert drv_path.exists()
@with_files({"flake1": flake})
def test_keep_derivations_disabled(self, nix: Nix, env: ManagedEnv):
nix.settings["keep-derivations"] = "false" # NOTE: This defaults to `true`
nix.nix(["profile", "install", "./flake1", "-L"]).run().ok()
assert run_hello(env) == "Hello World\n"
res = nix.nix(["eval", "--raw", "./flake1#default.drvPath"]).run().ok()
drv_path = Path(res.stdout_s.strip())
assert drv_path.exists()
# The derivation should be collected because `keep-env-derivations` is false AND `keep-derivations` is false.
res = nix.nix(["store", "gc"]).run().ok()
assert not drv_path.exists()