diff --git a/Makefile b/Makefile
index 6658e3490..4f4ac0c6e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,7 @@
+-include Makefile.config
+clean-files += Makefile.config
+
+ifeq ($(ENABLE_BUILD), yes)
makefiles = \
mk/precompiled-headers.mk \
local.mk \
@@ -18,15 +22,18 @@ makefiles = \
misc/upstart/local.mk \
doc/manual/local.mk \
doc/internal-api/local.mk
+endif
--include Makefile.config
-
-ifeq ($(tests), yes)
+ifeq ($(ENABLE_BUILD)_$(ENABLE_TESTS), yes_yes)
UNIT_TEST_ENV = _NIX_TEST_UNIT_DATA=unit-test-data
makefiles += \
src/libutil/tests/local.mk \
src/libstore/tests/local.mk \
- src/libexpr/tests/local.mk \
+ src/libexpr/tests/local.mk
+endif
+
+ifeq ($(ENABLE_TESTS), yes)
+makefiles += \
tests/functional/local.mk \
tests/functional/ca/local.mk \
tests/functional/dyn-drv/local.mk \
diff --git a/Makefile.config.in b/Makefile.config.in
index 707cfe0e3..19992fa20 100644
--- a/Makefile.config.in
+++ b/Makefile.config.in
@@ -46,5 +46,6 @@ sandbox_shell = @sandbox_shell@
storedir = @storedir@
sysconfdir = @sysconfdir@
system = @system@
-tests = @tests@
+ENABLE_BUILD = @ENABLE_BUILD@
+ENABLE_TESTS = @ENABLE_TESTS@
internal_api_docs = @internal_api_docs@
diff --git a/configure.ac b/configure.ac
index 6d78237f0..225baf6b5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -152,12 +152,17 @@ if test "x$GCC_ATOMIC_BUILTINS_NEED_LIBATOMIC" = xyes; then
LDFLAGS="-latomic $LDFLAGS"
fi
+# Running the functional tests without building Nix is useful for testing
+# different pre-built versions of Nix against each other.
+AC_ARG_ENABLE(build, AS_HELP_STRING([--disable-build],[Do not build nix]),
+ ENABLE_BUILD=$enableval, ENABLE_BUILD=yes)
+AC_SUBST(ENABLE_BUILD)
# Building without tests is useful for bootstrapping with a smaller footprint
# or running the tests in a separate derivation. Otherwise, we do compile and
# run them.
AC_ARG_ENABLE(tests, AS_HELP_STRING([--disable-tests],[Do not build the tests]),
- tests=$enableval, tests=yes)
-AC_SUBST(tests)
+ ENABLE_TESTS=$enableval, ENABLE_TESTS=yes)
+AC_SUBST(ENABLE_TESTS)
# Building without API docs is the default as Nix' C++ interfaces are internal and unstable.
AC_ARG_ENABLE(internal_api_docs, AS_HELP_STRING([--enable-internal-api-docs],[Build API docs for Nix's internal unstable C++ interfaces]),
@@ -289,7 +294,7 @@ if test "$gc" = yes; then
fi
-if test "$tests" = yes; then
+if test "$ENABLE_TESTS" = yes; then
# Look for gtest.
PKG_CHECK_MODULES([GTEST], [gtest_main])
diff --git a/doc/manual/redirects.js b/doc/manual/redirects.js
index b2fad19bb..9d083a43d 100644
--- a/doc/manual/redirects.js
+++ b/doc/manual/redirects.js
@@ -336,7 +336,6 @@ const redirects = {
"simple-values": "#primitives",
"lists": "#list",
"strings": "#string",
- "lists": "#list",
"attribute-sets": "#attribute-set",
},
"installation/installing-binary.html": {
diff --git a/doc/manual/src/command-ref/env-common.md b/doc/manual/src/command-ref/env-common.md
index b4a9bb2a9..34e0dbfbd 100644
--- a/doc/manual/src/command-ref/env-common.md
+++ b/doc/manual/src/command-ref/env-common.md
@@ -2,109 +2,124 @@
Most Nix commands interpret the following environment variables:
- - [`IN_NIX_SHELL`](#env-IN_NIX_SHELL)\
- Indicator that tells if the current environment was set up by
- `nix-shell`. It can have the values `pure` or `impure`.
+- [`IN_NIX_SHELL`](#env-IN_NIX_SHELL)
- - [`NIX_PATH`](#env-NIX_PATH)\
- A colon-separated list of directories used to look up the location of Nix
- expressions using [paths](@docroot@/language/values.md#type-path)
- enclosed in angle brackets (i.e., ``),
- e.g. `/home/eelco/Dev:/etc/nixos`. It can be extended using the
- [`-I` option](@docroot@/command-ref/opt-common.md#opt-I).
+ Indicator that tells if the current environment was set up by
+ `nix-shell`. It can have the values `pure` or `impure`.
- If `NIX_PATH` is not set at all, Nix will fall back to the following list in [impure](@docroot@/command-ref/conf-file.md#conf-pure-eval) and [unrestricted](@docroot@/command-ref/conf-file.md#conf-restrict-eval) evaluation mode:
+- [`NIX_PATH`](#env-NIX_PATH)
- 1. `$HOME/.nix-defexpr/channels`
- 2. `nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixpkgs`
- 3. `/nix/var/nix/profiles/per-user/root/channels`
+ A colon-separated list of directories used to look up the location of Nix
+ expressions using [paths](@docroot@/language/values.md#type-path)
+ enclosed in angle brackets (i.e., ``),
+ e.g. `/home/eelco/Dev:/etc/nixos`. It can be extended using the
+ [`-I` option](@docroot@/command-ref/opt-common.md#opt-I).
- If `NIX_PATH` is set to an empty string, resolving search paths will always fail.
- For example, attempting to use `` will produce:
+ If `NIX_PATH` is not set at all, Nix will fall back to the following list in [impure](@docroot@/command-ref/conf-file.md#conf-pure-eval) and [unrestricted](@docroot@/command-ref/conf-file.md#conf-restrict-eval) evaluation mode:
- error: file 'nixpkgs' was not found in the Nix search path
+ 1. `$HOME/.nix-defexpr/channels`
+ 2. `nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixpkgs`
+ 3. `/nix/var/nix/profiles/per-user/root/channels`
- - [`NIX_IGNORE_SYMLINK_STORE`](#env-NIX_IGNORE_SYMLINK_STORE)\
- Normally, the Nix store directory (typically `/nix/store`) is not
- allowed to contain any symlink components. This is to prevent
- “impure” builds. Builders sometimes “canonicalise” paths by
- resolving all symlink components. Thus, builds on different machines
- (with `/nix/store` resolving to different locations) could yield
- different results. This is generally not a problem, except when
- builds are deployed to machines where `/nix/store` resolves
- differently. If you are sure that you’re not going to do that, you
- can set `NIX_IGNORE_SYMLINK_STORE` to `1`.
+ If `NIX_PATH` is set to an empty string, resolving search paths will always fail.
+ For example, attempting to use `` will produce:
- Note that if you’re symlinking the Nix store so that you can put it
- on another file system than the root file system, on Linux you’re
- better off using `bind` mount points, e.g.,
+ error: file 'nixpkgs' was not found in the Nix search path
- ```console
- $ mkdir /nix
- $ mount -o bind /mnt/otherdisk/nix /nix
- ```
+- [`NIX_IGNORE_SYMLINK_STORE`](#env-NIX_IGNORE_SYMLINK_STORE)
- Consult the mount 8 manual page for details.
+ Normally, the Nix store directory (typically `/nix/store`) is not
+ allowed to contain any symlink components. This is to prevent
+ “impure” builds. Builders sometimes “canonicalise” paths by
+ resolving all symlink components. Thus, builds on different machines
+ (with `/nix/store` resolving to different locations) could yield
+ different results. This is generally not a problem, except when
+ builds are deployed to machines where `/nix/store` resolves
+ differently. If you are sure that you’re not going to do that, you
+ can set `NIX_IGNORE_SYMLINK_STORE` to `1`.
- - [`NIX_STORE_DIR`](#env-NIX_STORE_DIR)\
- Overrides the location of the Nix store (default `prefix/store`).
+ Note that if you’re symlinking the Nix store so that you can put it
+ on another file system than the root file system, on Linux you’re
+ better off using `bind` mount points, e.g.,
- - [`NIX_DATA_DIR`](#env-NIX_DATA_DIR)\
- Overrides the location of the Nix static data directory (default
- `prefix/share`).
+ ```console
+ $ mkdir /nix
+ $ mount -o bind /mnt/otherdisk/nix /nix
+ ```
- - [`NIX_LOG_DIR`](#env-NIX_LOG_DIR)\
- Overrides the location of the Nix log directory (default
- `prefix/var/log/nix`).
+ Consult the mount 8 manual page for details.
- - [`NIX_STATE_DIR`](#env-NIX_STATE_DIR)\
- Overrides the location of the Nix state directory (default
- `prefix/var/nix`).
+- [`NIX_STORE_DIR`](#env-NIX_STORE_DIR)
- - [`NIX_CONF_DIR`](#env-NIX_CONF_DIR)\
- Overrides the location of the system Nix configuration directory
- (default `prefix/etc/nix`).
+ Overrides the location of the Nix store (default `prefix/store`).
- - [`NIX_CONFIG`](#env-NIX_CONFIG)\
- Applies settings from Nix configuration from the environment.
- The content is treated as if it was read from a Nix configuration file.
- Settings are separated by the newline character.
+- [`NIX_DATA_DIR`](#env-NIX_DATA_DIR)
- - [`NIX_USER_CONF_FILES`](#env-NIX_USER_CONF_FILES)\
- Overrides the location of the Nix user configuration files to load from.
+ Overrides the location of the Nix static data directory (default
+ `prefix/share`).
- The default are the locations according to the [XDG Base Directory Specification].
- See the [XDG Base Directories](#xdg-base-directories) sub-section for details.
+- [`NIX_LOG_DIR`](#env-NIX_LOG_DIR)
- The variable is treated as a list separated by the `:` token.
+ Overrides the location of the Nix log directory (default
+ `prefix/var/log/nix`).
- - [`TMPDIR`](#env-TMPDIR)\
- Use the specified directory to store temporary files. In particular,
- this includes temporary build directories; these can take up
- substantial amounts of disk space. The default is `/tmp`.
+- [`NIX_STATE_DIR`](#env-NIX_STATE_DIR)
- - [`NIX_REMOTE`](#env-NIX_REMOTE)\
- This variable should be set to `daemon` if you want to use the Nix
- daemon to execute Nix operations. This is necessary in [multi-user
- Nix installations](@docroot@/installation/multi-user.md). If the Nix
- daemon's Unix socket is at some non-standard path, this variable
- should be set to `unix://path/to/socket`. Otherwise, it should be
- left unset.
+ Overrides the location of the Nix state directory (default
+ `prefix/var/nix`).
- - [`NIX_SHOW_STATS`](#env-NIX_SHOW_STATS)\
- If set to `1`, Nix will print some evaluation statistics, such as
- the number of values allocated.
+- [`NIX_CONF_DIR`](#env-NIX_CONF_DIR)
- - [`NIX_COUNT_CALLS`](#env-NIX_COUNT_CALLS)\
- If set to `1`, Nix will print how often functions were called during
- Nix expression evaluation. This is useful for profiling your Nix
- expressions.
+ Overrides the location of the system Nix configuration directory
+ (default `prefix/etc/nix`).
- - [`GC_INITIAL_HEAP_SIZE`](#env-GC_INITIAL_HEAP_SIZE)\
- If Nix has been configured to use the Boehm garbage collector, this
- variable sets the initial size of the heap in bytes. It defaults to
- 384 MiB. Setting it to a low value reduces memory consumption, but
- will increase runtime due to the overhead of garbage collection.
+- [`NIX_CONFIG`](#env-NIX_CONFIG)
+
+ Applies settings from Nix configuration from the environment.
+ The content is treated as if it was read from a Nix configuration file.
+ Settings are separated by the newline character.
+
+- [`NIX_USER_CONF_FILES`](#env-NIX_USER_CONF_FILES)
+
+ Overrides the location of the Nix user configuration files to load from.
+
+ The default are the locations according to the [XDG Base Directory Specification].
+ See the [XDG Base Directories](#xdg-base-directories) sub-section for details.
+
+ The variable is treated as a list separated by the `:` token.
+
+- [`TMPDIR`](#env-TMPDIR)
+
+ Use the specified directory to store temporary files. In particular,
+ this includes temporary build directories; these can take up
+ substantial amounts of disk space. The default is `/tmp`.
+
+- [`NIX_REMOTE`](#env-NIX_REMOTE)
+
+ This variable should be set to `daemon` if you want to use the Nix
+ daemon to execute Nix operations. This is necessary in [multi-user
+ Nix installations](@docroot@/installation/multi-user.md). If the Nix
+ daemon's Unix socket is at some non-standard path, this variable
+ should be set to `unix://path/to/socket`. Otherwise, it should be
+ left unset.
+
+- [`NIX_SHOW_STATS`](#env-NIX_SHOW_STATS)
+
+ If set to `1`, Nix will print some evaluation statistics, such as
+ the number of values allocated.
+
+- [`NIX_COUNT_CALLS`](#env-NIX_COUNT_CALLS)
+
+ If set to `1`, Nix will print how often functions were called during
+ Nix expression evaluation. This is useful for profiling your Nix
+ expressions.
+
+- [`GC_INITIAL_HEAP_SIZE`](#env-GC_INITIAL_HEAP_SIZE)
+
+ If Nix has been configured to use the Boehm garbage collector, this
+ variable sets the initial size of the heap in bytes. It defaults to
+ 384 MiB. Setting it to a low value reduces memory consumption, but
+ will increase runtime due to the overhead of garbage collection.
## XDG Base Directories
diff --git a/doc/manual/src/language/string-interpolation.md b/doc/manual/src/language/string-interpolation.md
index ddc6b8230..2e650e348 100644
--- a/doc/manual/src/language/string-interpolation.md
+++ b/doc/manual/src/language/string-interpolation.md
@@ -1,19 +1,12 @@
# String interpolation
-String interpolation is a language feature where a [string], [path], or [attribute name] can contain expressions enclosed in `${ }` (dollar-sign with curly brackets).
+String interpolation is a language feature where a [string], [path], or [attribute name][attribute set] can contain expressions enclosed in `${ }` (dollar-sign with curly brackets).
-Such a string is an *interpolated string*, and an expression inside is an *interpolated expression*.
-
-Interpolated expressions must evaluate to one of the following:
-
-- a [string]
-- a [path]
-- a [derivation]
+Such a construct is called *interpolated string*, and the expression inside is an [interpolated expression](#interpolated-expression).
[string]: ./values.md#type-string
[path]: ./values.md#type-path
-[attribute name]: ./values.md#attribute-set
-[derivation]: ../glossary.md#gloss-derivation
+[attribute set]: ./values.md#attribute-set
## Examples
@@ -70,13 +63,136 @@ you can instead write
### Attribute name
-Attribute names can be created dynamically with string interpolation:
+
-```nix
-let name = "foo"; in
-{
- ${name} = "bar";
-}
-```
+Attribute names can be interpolated strings.
- { foo = "bar"; }
+> **Example**
+>
+> ```nix
+> let name = "foo"; in
+> { ${name} = 123; }
+> ```
+>
+> { foo = 123; }
+
+Attributes can be selected with interpolated strings.
+
+> **Example**
+>
+> ```nix
+> let name = "foo"; in
+> { foo = 123; }.${name}
+> ```
+>
+> 123
+
+# Interpolated expression
+
+An interpolated expression must evaluate to one of the following:
+
+- a [string]
+- a [path]
+- an [attribute set] that has a `__toString` attribute or an `outPath` attribute
+
+ - `__toString` must be a function that takes the attribute set itself and returns a string
+ - `outPath` must be a string
+
+ This includes [derivations](./derivations.md) or [flake inputs](@docroot@/command-ref/new-cli/nix3-flake.md#flake-inputs) (experimental).
+
+A string interpolates to itself.
+
+A path in an interpolated expression is first copied into the Nix store, and the resulting string is the [store path] of the newly created [store object](../glossary.md#gloss-store-object).
+
+[store path]: ../glossary.md#gloss-store-path
+
+> **Example**
+>
+> ```console
+> $ mkdir foo
+> ```
+>
+> Reference the empty directory in an interpolated expression:
+>
+> ```nix
+> "${./foo}"
+> ```
+>
+> "/nix/store/2hhl2nz5v0khbn06ys82nrk99aa1xxdw-foo"
+
+A derivation interpolates to the [store path] of its first [output](./derivations.md#attr-outputs).
+
+> **Example**
+>
+> ```nix
+> let
+> pkgs = import {};
+> in
+> "${pkgs.hello}"
+> ```
+>
+> "/nix/store/4xpfqf29z4m8vbhrqcz064wfmb46w5r7-hello-2.12.1"
+
+An attribute set interpolates to the return value of the function in the `__toString` applied to the attribute set itself.
+
+> **Example**
+>
+> ```nix
+> let
+> a = {
+> value = 1;
+> __toString = self: toString (self.value + 1);
+> };
+> in
+> "${a}"
+> ```
+>
+> "2"
+
+An attribute set also interpolates to the value of its `outPath` attribute.
+
+> **Example**
+>
+> ```nix
+> let
+> a = { outPath = "foo"; };
+> in
+> "${a}"
+> ```
+>
+> "foo"
+
+If both `__toString` and `outPath` are present in an attribute set, `__toString` takes precedence.
+
+> **Example**
+>
+> ```nix
+> let
+> a = { __toString = _: "yes"; outPath = throw "no"; };
+> in
+> "${a}"
+> ```
+>
+> "yes"
+
+If neither is present, an error is thrown.
+
+> **Example**
+>
+> ```nix
+> let
+> a = {};
+> in
+> "${a}"
+> ```
+>
+> error: cannot coerce a set to a string
+>
+> at «string»:4:2:
+>
+> 3| in
+> 4| "${a}"
+> | ^
diff --git a/doc/manual/src/language/values.md b/doc/manual/src/language/values.md
index 4d8950e85..8856d33ae 100644
--- a/doc/manual/src/language/values.md
+++ b/doc/manual/src/language/values.md
@@ -107,18 +107,16 @@
e.g. `~/foo` would be equivalent to `/home/edolstra/foo` for a user
whose home directory is `/home/edolstra`.
- When an [interpolated string][string interpolation] evaluates to a path, the path is first copied into the Nix store and the resulting string is the [store path] of the newly created [store object].
-
- [store path]: ../glossary.md#gloss-store-path
- [store object]: ../glossary.md#gloss-store-object
-
For instance, evaluating `"${./foo.txt}"` will cause `foo.txt` in the current directory to be copied into the Nix store and result in the string `"/nix/store/-foo.txt"`.
Note that the Nix language assumes that all input files will remain _unchanged_ while evaluating a Nix expression.
For example, assume you used a file path in an interpolated string during a `nix repl` session.
- Later in the same session, after having changed the file contents, evaluating the interpolated string with the file path again might not return a new store path, since Nix might not re-read the file contents.
+ Later in the same session, after having changed the file contents, evaluating the interpolated string with the file path again might not return a new [store path], since Nix might not re-read the file contents.
- Paths support [string interpolation].
+ [store path]: ../glossary.md#gloss-store-path
+
+ Paths can include [string interpolation] and can themselves be [interpolated in other expressions].
+ [interpolated in other expressions]: ./string-interpolation.md#interpolated-expressions
At least one slash (`/`) must appear *before* any interpolated expression for the result to be recognized as a path.
diff --git a/flake.nix b/flake.nix
index c331b2651..301e65545 100644
--- a/flake.nix
+++ b/flake.nix
@@ -59,29 +59,40 @@
# that would interfere with repo semantics.
fileset.fileFilter (f: f.name != ".gitignore") ./.;
+ configureFiles = fileset.unions [
+ ./.version
+ ./configure.ac
+ ./m4
+ # TODO: do we really need README.md? It doesn't seem used in the build.
+ ./README.md
+ ];
+
+ topLevelBuildFiles = fileset.unions [
+ ./local.mk
+ ./Makefile
+ ./Makefile.config.in
+ ./mk
+ ];
+
+ functionalTestFiles = fileset.unions [
+ ./tests/functional
+ (fileset.fileFilter (f: lib.strings.hasPrefix "nix-profile" f.name) ./scripts)
+ ];
+
nixSrc = fileset.toSource {
root = ./.;
fileset = fileset.intersect baseFiles (fileset.unions [
- ./.version
+ configureFiles
+ topLevelBuildFiles
./boehmgc-coroutine-sp-fallback.diff
- ./bootstrap.sh
- ./configure.ac
./doc
- ./local.mk
- ./m4
- ./Makefile
- ./Makefile.config.in
./misc
- ./mk
./precompiled-headers.h
./src
- ./tests/functional
./unit-test-data
./COPYING
./scripts/local.mk
- (fileset.fileFilter (f: lib.strings.hasPrefix "nix-profile" f.name) ./scripts)
- # TODO: do we really need README.md? It doesn't seem used in the build.
- ./README.md
+ functionalTestFiles
]);
};
@@ -252,7 +263,6 @@
testNixVersions = pkgs: client: daemon: with commonDeps { inherit pkgs; }; with pkgs.lib; pkgs.stdenv.mkDerivation {
NIX_DAEMON_PACKAGE = daemon;
NIX_CLIENT_PACKAGE = client;
- HAVE_LOCAL_NIX_BUILD = false;
name =
"nix-tests"
+ optionalString
@@ -261,7 +271,14 @@
"-${client.version}-against-${daemon.version}";
inherit version;
- src = nixSrc;
+ src = fileset.toSource {
+ root = ./.;
+ fileset = fileset.intersect baseFiles (fileset.unions [
+ configureFiles
+ topLevelBuildFiles
+ functionalTestFiles
+ ]);
+ };
VERSION_SUFFIX = versionSuffix;
@@ -271,19 +288,20 @@
enableParallelBuilding = true;
- configureFlags = testConfigureFlags; # otherwise configure fails
+ configureFlags =
+ testConfigureFlags # otherwise configure fails
+ ++ [ "--disable-build" ];
+ dontBuild = true;
doInstallCheck = true;
- buildPhase = ''
- # Remove the source files to make sure that we're not accidentally rebuilding Nix
- rm src/**/*.cc
- '';
-
installPhase = ''
mkdir -p $out
'';
- installCheckPhase = "make installcheck -j$NIX_BUILD_CORES -l$NIX_BUILD_CORES";
+ installCheckPhase = ''
+ mkdir -p src/nix-channel
+ make installcheck -j$NIX_BUILD_CORES -l$NIX_BUILD_CORES
+ '';
};
binaryTarball = nix: pkgs:
@@ -459,7 +477,15 @@
passthru.perl-bindings = with final; perl.pkgs.toPerlModule (currentStdenv.mkDerivation {
name = "nix-perl-${version}";
- src = self;
+ src = fileset.toSource {
+ root = ./.;
+ fileset = fileset.intersect baseFiles (fileset.unions [
+ ./perl
+ ./.version
+ ./m4
+ ./mk
+ ]);
+ };
nativeBuildInputs =
[ buildPackages.autoconf-archive
@@ -509,18 +535,6 @@
};
};
- nixos-lib = import (nixpkgs + "/nixos/lib") { };
-
- # https://nixos.org/manual/nixos/unstable/index.html#sec-calling-nixos-tests
- runNixOSTestFor = system: test: nixos-lib.runTest {
- imports = [ test ];
- hostPkgs = nixpkgsFor.${system}.native;
- defaults = {
- nixpkgs.pkgs = nixpkgsFor.${system}.native;
- };
- _module.args.nixpkgs = nixpkgs;
- };
-
in {
# A Nixpkgs overlay that overrides the 'nix' and
# 'nix.perl-bindings' packages.
@@ -627,49 +641,29 @@
};
# System tests.
- tests.authorization = runNixOSTestFor "x86_64-linux" ./tests/nixos/authorization.nix;
+ tests = import ./tests/nixos { inherit lib nixpkgs nixpkgsFor; } // {
- tests.remoteBuilds = runNixOSTestFor "x86_64-linux" ./tests/nixos/remote-builds.nix;
+ # 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) = ff451c521e61e4fe72bdbe2d0ca5d1809affa733 ]]
+ mkdir $out
+ '';
- tests.nix-copy-closure = runNixOSTestFor "x86_64-linux" ./tests/nixos/nix-copy-closure.nix;
-
- tests.nix-copy = runNixOSTestFor "x86_64-linux" ./tests/nixos/nix-copy.nix;
-
- tests.nssPreload = runNixOSTestFor "x86_64-linux" ./tests/nixos/nss-preload.nix;
-
- tests.githubFlakes = runNixOSTestFor "x86_64-linux" ./tests/nixos/github-flakes.nix;
-
- tests.sourcehutFlakes = runNixOSTestFor "x86_64-linux" ./tests/nixos/sourcehut-flakes.nix;
-
- tests.tarballFlakes = runNixOSTestFor "x86_64-linux" ./tests/nixos/tarball-flakes.nix;
-
- tests.containers = runNixOSTestFor "x86_64-linux" ./tests/nixos/containers/containers.nix;
-
- tests.setuid = lib.genAttrs
- ["i686-linux" "x86_64-linux"]
- (system: runNixOSTestFor system ./tests/nixos/setuid.nix);
-
-
- # Make sure that nix-env still produces the exact same result
- # on a particular version of Nixpkgs.
- tests.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) = ff451c521e61e4fe72bdbe2d0ca5d1809affa733 ]]
- mkdir $out
- '';
-
- tests.nixpkgsLibTests =
- forAllSystems (system:
- import (nixpkgs + "/lib/tests/release.nix")
- { pkgs = nixpkgsFor.${system}.native;
- nixVersions = [ self.packages.${system}.nix ];
- }
- );
+ nixpkgsLibTests =
+ forAllSystems (system:
+ import (nixpkgs + "/lib/tests/release.nix")
+ { pkgs = nixpkgsFor.${system}.native;
+ nixVersions = [ self.packages.${system}.nix ];
+ }
+ );
+ };
metrics.nixpkgs = import "${nixpkgs-regression}/pkgs/top-level/metrics.nix" {
pkgs = nixpkgsFor.x86_64-linux.native;
diff --git a/local.mk b/local.mk
index 6951c179e..3f3abb9f0 100644
--- a/local.mk
+++ b/local.mk
@@ -1,5 +1,3 @@
-clean-files += Makefile.config
-
GLOBAL_CXXFLAGS += -Wno-deprecated-declarations -Werror=switch
# Allow switch-enum to be overridden for files that do not support it, usually because of dependency headers.
ERROR_SWITCH_ENUM = -Werror=switch-enum
diff --git a/perl/Makefile b/perl/Makefile
index c2c95f255..832668dd1 100644
--- a/perl/Makefile
+++ b/perl/Makefile
@@ -1,6 +1,12 @@
makefiles = local.mk
-GLOBAL_CXXFLAGS += -g -Wall -std=c++2a -I ../src
+GLOBAL_CXXFLAGS += -g -Wall -std=c++2a
+
+# A convenience for concurrent development of Nix and its Perl bindings.
+# Not needed in a standalone build of the Perl bindings.
+ifneq ("$(wildcard ../src)", "")
+ GLOBAL_CXXFLAGS += -I ../src
+endif
-include Makefile.config
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index a8cb4ccfe..bfcac7510 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -258,64 +258,71 @@ static RegisterPrimOp primop_import({
.args = {"path"},
// TODO turn "normal path values" into link below
.doc = R"(
- Load, parse and return the Nix expression in the file *path*.
-
- The value *path* can be a path, a string, or an attribute set with an
- `__toString` attribute or a `outPath` attribute (as derivations or flake
- inputs typically have).
-
- If *path* is a directory, the file `default.nix` in that directory
- is loaded.
-
- Evaluation aborts if the file doesn’t exist or contains
- an incorrect Nix expression. `import` implements Nix’s module
- system: you can put any Nix expression (such as a set or a
- function) in a separate file, and use it from Nix expressions in
- other files.
+ Load, parse, and return the Nix expression in the file *path*.
> **Note**
>
> Unlike some languages, `import` is a regular function in Nix.
- > Paths using the angle bracket syntax (e.g., `import` *\*)
- > are normal [path values](@docroot@/language/values.md#type-path).
- A Nix expression loaded by `import` must not contain any *free
- variables* (identifiers that are not defined in the Nix expression
- itself and are not built-in). Therefore, it cannot refer to
- variables that are in scope at the call site. For instance, if you
- have a calling expression
+ The *path* argument must meet the same criteria as an [interpolated expression](@docroot@/language/string-interpolation.md#interpolated-expression).
- ```nix
- rec {
- x = 123;
- y = import ./foo.nix;
- }
- ```
+ If *path* is a directory, the file `default.nix` in that directory is used if it exists.
- then the following `foo.nix` will give an error:
+ > **Example**
+ >
+ > ```console
+ > $ echo 123 > default.nix
+ > ```
+ >
+ > Import `default.nix` from the current directory.
+ >
+ > ```nix
+ > import ./.
+ > ```
+ >
+ > 123
- ```nix
- x + 456
- ```
+ Evaluation aborts if the file doesn’t exist or contains an invalid Nix expression.
- since `x` is not in scope in `foo.nix`. If you want `x` to be
- available in `foo.nix`, you should pass it as a function argument:
+ A Nix expression loaded by `import` must not contain any *free variables*, that is, identifiers that are not defined in the Nix expression itself and are not built-in.
+ Therefore, it cannot refer to variables that are in scope at the call site.
- ```nix
- rec {
- x = 123;
- y = import ./foo.nix x;
- }
- ```
-
- and
-
- ```nix
- x: x + 456
- ```
-
- (The function argument doesn’t have to be called `x` in `foo.nix`;
- any name would work.)
+ > **Example**
+ >
+ > If you have a calling expression
+ >
+ > ```nix
+ > rec {
+ > x = 123;
+ > y = import ./foo.nix;
+ > }
+ > ```
+ >
+ > then the following `foo.nix` will give an error:
+ >
+ > ```nix
+ > # foo.nix
+ > x + 456
+ > ```
+ >
+ > since `x` is not in scope in `foo.nix`.
+ > If you want `x` to be available in `foo.nix`, pass it as a function argument:
+ >
+ > ```nix
+ > rec {
+ > x = 123;
+ > y = import ./foo.nix x;
+ > }
+ > ```
+ >
+ > and
+ >
+ > ```nix
+ > # foo.nix
+ > x: x + 456
+ > ```
+ >
+ > The function argument doesn’t have to be called `x` in `foo.nix`; any name would work.
)",
.fun = [](EvalState & state, const PosIdx pos, Value * * args, Value & v)
{
diff --git a/tests/functional/local.mk b/tests/functional/local.mk
index 4d29f60a1..6f6c94fe6 100644
--- a/tests/functional/local.mk
+++ b/tests/functional/local.mk
@@ -1,7 +1,3 @@
-# whether to run the tests that assume that we have a local build of
-# Nix
-HAVE_LOCAL_NIX_BUILD ?= 1
-
nix_tests = \
test-infra.sh \
init.sh \
@@ -131,7 +127,7 @@ ifeq ($(HAVE_LIBCPUID), 1)
nix_tests += compute-levels.sh
endif
-ifeq ($(HAVE_LOCAL_NIX_BUILD), 1)
+ifeq ($(ENABLE_BUILD), yes)
nix_tests += test-libstoreconsumer.sh
ifeq ($(BUILD_SHARED_LIBS), 1)
diff --git a/tests/nixos/default.nix b/tests/nixos/default.nix
new file mode 100644
index 000000000..b391d7ef2
--- /dev/null
+++ b/tests/nixos/default.nix
@@ -0,0 +1,41 @@
+{ lib, nixpkgs, nixpkgsFor }:
+
+let
+
+ nixos-lib = import (nixpkgs + "/nixos/lib") { };
+
+ # https://nixos.org/manual/nixos/unstable/index.html#sec-calling-nixos-tests
+ runNixOSTestFor = system: test: nixos-lib.runTest {
+ imports = [ test ];
+ hostPkgs = nixpkgsFor.${system}.native;
+ defaults = {
+ nixpkgs.pkgs = nixpkgsFor.${system}.native;
+ };
+ _module.args.nixpkgs = nixpkgs;
+ };
+
+in
+
+{
+ authorization = runNixOSTestFor "x86_64-linux" ./authorization.nix;
+
+ remoteBuilds = runNixOSTestFor "x86_64-linux" ./remote-builds.nix;
+
+ nix-copy-closure = runNixOSTestFor "x86_64-linux" ./nix-copy-closure.nix;
+
+ nix-copy = runNixOSTestFor "x86_64-linux" ./nix-copy.nix;
+
+ nssPreload = runNixOSTestFor "x86_64-linux" ./nss-preload.nix;
+
+ githubFlakes = runNixOSTestFor "x86_64-linux" ./github-flakes.nix;
+
+ sourcehutFlakes = runNixOSTestFor "x86_64-linux" ./sourcehut-flakes.nix;
+
+ tarballFlakes = runNixOSTestFor "x86_64-linux" ./tarball-flakes.nix;
+
+ containers = runNixOSTestFor "x86_64-linux" ./containers/containers.nix;
+
+ setuid = lib.genAttrs
+ ["i686-linux" "x86_64-linux"]
+ (system: runNixOSTestFor system ./setuid.nix);
+}