mirror of
https://github.com/NixOS/nix
synced 2025-06-25 10:41:16 +02:00
Merge remote-tracking branch 'origin/master' into flake-substitution
This commit is contained in:
commit
ecb418e163
157 changed files with 881 additions and 670 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -214,4 +214,4 @@ jobs:
|
||||||
path: flake-regressions/tests
|
path: flake-regressions/tests
|
||||||
- uses: DeterminateSystems/nix-installer-action@main
|
- uses: DeterminateSystems/nix-installer-action@main
|
||||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||||
- run: nix build --out-link ./new-nix && PATH=$(pwd)/new-nix/bin:$PATH scripts/flake-regressions.sh
|
- run: nix build --out-link ./new-nix && PATH=$(pwd)/new-nix/bin:$PATH MAX_FLAKES=25 flake-regressions/eval-all.sh
|
||||||
|
|
1
Makefile
1
Makefile
|
@ -91,6 +91,7 @@ ifdef HOST_WINDOWS
|
||||||
#
|
#
|
||||||
# TODO do not do this, and instead do fine-grained export annotations.
|
# TODO do not do this, and instead do fine-grained export annotations.
|
||||||
GLOBAL_LDFLAGS += -Wl,--export-all-symbols
|
GLOBAL_LDFLAGS += -Wl,--export-all-symbols
|
||||||
|
GLOBAL_CXXFLAGS += -D_WIN32_WINNT=0x0602
|
||||||
endif
|
endif
|
||||||
|
|
||||||
GLOBAL_CXXFLAGS += -g -Wall -Wdeprecated-copy -Wignored-qualifiers -Wimplicit-fallthrough -Werror=unused-result -Werror=suggest-override -include $(buildprefix)config.h -std=c++2a -I src
|
GLOBAL_CXXFLAGS += -g -Wall -Wdeprecated-copy -Wignored-qualifiers -Wimplicit-fallthrough -Werror=unused-result -Werror=suggest-override -include $(buildprefix)config.h -std=c++2a -I src
|
||||||
|
|
8
build-utils-meson/libatomic/meson.build
Normal file
8
build-utils-meson/libatomic/meson.build
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
# Check if -latomic is needed
|
||||||
|
# This is needed for std::atomic on some platforms
|
||||||
|
# We did not manage to test this reliably on all platforms, so we hardcode
|
||||||
|
# it for now.
|
||||||
|
if host_machine.cpu_family() == 'arm'
|
||||||
|
deps_other += cxx.find_library('atomic')
|
||||||
|
endif
|
6
build-utils-meson/windows-version/meson.build
Normal file
6
build-utils-meson/windows-version/meson.build
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
if host_machine.system() == 'windows'
|
||||||
|
# https://learn.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt?view=msvc-170
|
||||||
|
# #define _WIN32_WINNT_WIN8 0x0602
|
||||||
|
# We currently don't use any API which requires higher than this.
|
||||||
|
add_project_arguments([ '-D_WIN32_WINNT=0x0602' ], language: 'cpp')
|
||||||
|
endif
|
|
@ -1,25 +0,0 @@
|
||||||
---
|
|
||||||
synopsis: Show package descriptions with `nix flake show`
|
|
||||||
issues: [10977]
|
|
||||||
prs: [10980]
|
|
||||||
---
|
|
||||||
|
|
||||||
`nix flake show` will now display a package's `meta.description` if it exists. If the description does not fit in the terminal it will be truncated to fit the terminal width. If the size of the terminal width is unknown the description will be capped at 80 characters.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ nix flake show
|
|
||||||
└───packages
|
|
||||||
└───x86_64-linux
|
|
||||||
├───builderImage: package 'docker-image-ara-builder-image.tar.gz' - 'Docker image hosting the nix build environment'
|
|
||||||
└───runnerImage: package 'docker-image-gitlab-runner.tar.gz' - 'Docker image hosting the gitlab-runner executable'
|
|
||||||
```
|
|
||||||
|
|
||||||
In a narrower terminal:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ nix flake show
|
|
||||||
└───packages
|
|
||||||
└───x86_64-linux
|
|
||||||
├───builderImage: package 'docker-image-ara-builder-image.tar.gz' - 'Docker image hosting the nix b...
|
|
||||||
└───runnerImage: package 'docker-image-gitlab-runner.tar.gz' - 'Docker image hosting the gitlab-run...
|
|
||||||
```
|
|
|
@ -121,6 +121,7 @@
|
||||||
- [Development](development/index.md)
|
- [Development](development/index.md)
|
||||||
- [Building](development/building.md)
|
- [Building](development/building.md)
|
||||||
- [Testing](development/testing.md)
|
- [Testing](development/testing.md)
|
||||||
|
- [Debugging](development/debugging.md)
|
||||||
- [Documentation](development/documentation.md)
|
- [Documentation](development/documentation.md)
|
||||||
- [CLI guideline](development/cli-guideline.md)
|
- [CLI guideline](development/cli-guideline.md)
|
||||||
- [JSON guideline](development/json-guideline.md)
|
- [JSON guideline](development/json-guideline.md)
|
||||||
|
|
62
doc/manual/source/development/debugging.md
Normal file
62
doc/manual/source/development/debugging.md
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# Debugging Nix
|
||||||
|
|
||||||
|
This section shows how to build and debug Nix with debug symbols enabled.
|
||||||
|
|
||||||
|
## Building Nix with Debug Symbols
|
||||||
|
|
||||||
|
In the development shell, set the `mesonBuildType` environment variable to `debug` before configuring the build:
|
||||||
|
|
||||||
|
```console
|
||||||
|
[nix-shell]$ export mesonBuildType=debugoptimized
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, proceed to build Nix as described in [Building Nix](./building.md).
|
||||||
|
This will build Nix with debug symbols, which are essential for effective debugging.
|
||||||
|
|
||||||
|
## Debugging the Nix Binary
|
||||||
|
|
||||||
|
Obtain your preferred debugger within the development shell:
|
||||||
|
|
||||||
|
```console
|
||||||
|
[nix-shell]$ nix-shell -p gdb
|
||||||
|
```
|
||||||
|
|
||||||
|
On macOS, use `lldb`:
|
||||||
|
|
||||||
|
```console
|
||||||
|
[nix-shell]$ nix-shell -p lldb
|
||||||
|
```
|
||||||
|
|
||||||
|
### Launching the Debugger
|
||||||
|
|
||||||
|
To debug the Nix binary, run:
|
||||||
|
|
||||||
|
```console
|
||||||
|
[nix-shell]$ gdb --args ../outputs/out/bin/nix
|
||||||
|
```
|
||||||
|
|
||||||
|
On macOS, use `lldb`:
|
||||||
|
|
||||||
|
```console
|
||||||
|
[nix-shell]$ lldb -- ../outputs/out/bin/nix
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using the Debugger
|
||||||
|
|
||||||
|
Inside the debugger, you can set breakpoints, run the program, and inspect variables.
|
||||||
|
|
||||||
|
```gdb
|
||||||
|
(gdb) break main
|
||||||
|
(gdb) run <arguments>
|
||||||
|
```
|
||||||
|
|
||||||
|
Refer to the [GDB Documentation](https://www.gnu.org/software/gdb/documentation/) for comprehensive usage instructions.
|
||||||
|
|
||||||
|
On macOS, use `lldb`:
|
||||||
|
|
||||||
|
```lldb
|
||||||
|
(lldb) breakpoint set --name main
|
||||||
|
(lldb) process launch -- <arguments>
|
||||||
|
```
|
||||||
|
|
||||||
|
Refer to the [LLDB Tutorial](https://lldb.llvm.org/use/tutorial.html) for comprehensive usage instructions.
|
|
@ -29,7 +29,7 @@ The unit tests are defined using the [googletest] and [rapidcheck] frameworks.
|
||||||
> ```
|
> ```
|
||||||
> src
|
> src
|
||||||
> ├── libexpr
|
> ├── libexpr
|
||||||
> │ ├── local.mk
|
> │ ├── meson.build
|
||||||
> │ ├── value/context.hh
|
> │ ├── value/context.hh
|
||||||
> │ ├── value/context.cc
|
> │ ├── value/context.cc
|
||||||
> │ …
|
> │ …
|
||||||
|
@ -37,25 +37,24 @@ The unit tests are defined using the [googletest] and [rapidcheck] frameworks.
|
||||||
> ├── tests
|
> ├── tests
|
||||||
> │ │
|
> │ │
|
||||||
> │ …
|
> │ …
|
||||||
> │ └── unit
|
> │ ├── libutil-tests
|
||||||
> │ ├── libutil
|
> │ │ ├── meson.build
|
||||||
> │ │ ├── local.mk
|
> │ │ …
|
||||||
> │ │ …
|
> │ │ └── data
|
||||||
> │ │ └── data
|
> │ │ ├── git/tree.txt
|
||||||
> │ │ ├── git/tree.txt
|
> │ │ …
|
||||||
> │ │ …
|
> │ │
|
||||||
> │ │
|
> │ ├── libexpr-test-support
|
||||||
> │ ├── libexpr-support
|
> │ │ ├── meson.build
|
||||||
> │ │ ├── local.mk
|
> │ │ └── tests
|
||||||
> │ │ └── tests
|
> │ │ ├── value/context.hh
|
||||||
> │ │ ├── value/context.hh
|
> │ │ ├── value/context.cc
|
||||||
> │ │ ├── value/context.cc
|
> │ │ …
|
||||||
> │ │ …
|
> │ │
|
||||||
> │ │
|
> │ ├── libexpr-tests
|
||||||
> │ ├── libexpr
|
> │ … ├── meson.build
|
||||||
> │ … ├── local.mk
|
> │ ├── value/context.cc
|
||||||
> │ ├── value/context.cc
|
> │ …
|
||||||
> │ …
|
|
||||||
> …
|
> …
|
||||||
> ```
|
> ```
|
||||||
|
|
||||||
|
@ -128,7 +127,7 @@ On other platforms they wouldn't be run at all.
|
||||||
|
|
||||||
## Functional tests
|
## Functional tests
|
||||||
|
|
||||||
The functional tests reside under the `tests/functional` directory and are listed in `tests/functional/local.mk`.
|
The functional tests reside under the `tests/functional` directory and are listed in `tests/functional/meson.build`.
|
||||||
Each test is a bash script.
|
Each test is a bash script.
|
||||||
|
|
||||||
Functional tests are run during `installCheck` in the `nix` package build, as well as separately from the build, in VM tests.
|
Functional tests are run during `installCheck` in the `nix` package build, as well as separately from the build, in VM tests.
|
||||||
|
|
|
@ -102,7 +102,7 @@ The `+` operator is overloaded to also work on strings and paths.
|
||||||
>
|
>
|
||||||
> *string* `+` *string*
|
> *string* `+` *string*
|
||||||
|
|
||||||
Concatenate two [strings][string] and merge their string contexts.
|
Concatenate two [strings][string] and merge their [string contexts](./string-context.md).
|
||||||
|
|
||||||
[String concatenation]: #string-concatenation
|
[String concatenation]: #string-concatenation
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ The result is a path.
|
||||||
|
|
||||||
> **Note**
|
> **Note**
|
||||||
>
|
>
|
||||||
> The string must not have a string context that refers to a [store path].
|
> The string must not have a [string context](./string-context.md) that refers to a [store path].
|
||||||
|
|
||||||
[Path and string concatenation]: #path-and-string-concatenation
|
[Path and string concatenation]: #path-and-string-concatenation
|
||||||
|
|
||||||
|
|
119
flake.nix
119
flake.nix
|
@ -294,109 +294,24 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
devShells = let
|
devShells = let
|
||||||
makeShell = pkgs: stdenv: (pkgs.nix.override { inherit stdenv; forDevShell = true; }).overrideAttrs (attrs:
|
makeShell = import ./packaging/dev-shell.nix { inherit lib devFlake; };
|
||||||
let
|
prefixAttrs = prefix: lib.concatMapAttrs (k: v: { "${prefix}-${k}" = v; });
|
||||||
buildCanExecuteHost = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
|
in
|
||||||
modular = devFlake.getSystem stdenv.buildPlatform.system;
|
|
||||||
transformFlag = prefix: flag:
|
|
||||||
assert builtins.isString flag;
|
|
||||||
let
|
|
||||||
rest = builtins.substring 2 (builtins.stringLength flag) flag;
|
|
||||||
in
|
|
||||||
"-D${prefix}:${rest}";
|
|
||||||
havePerl = stdenv.buildPlatform == stdenv.hostPlatform && stdenv.hostPlatform.isUnix;
|
|
||||||
ignoreCrossFile = flags: builtins.filter (flag: !(lib.strings.hasInfix "cross-file" flag)) flags;
|
|
||||||
in {
|
|
||||||
pname = "shell-for-" + attrs.pname;
|
|
||||||
|
|
||||||
# Remove the version suffix to avoid unnecessary attempts to substitute in nix develop
|
|
||||||
version = lib.fileContents ./.version;
|
|
||||||
name = attrs.pname;
|
|
||||||
|
|
||||||
installFlags = "sysconfdir=$(out)/etc";
|
|
||||||
shellHook = ''
|
|
||||||
PATH=$prefix/bin:$PATH
|
|
||||||
unset PYTHONPATH
|
|
||||||
export MANPATH=$out/share/man:$MANPATH
|
|
||||||
|
|
||||||
# Make bash completion work.
|
|
||||||
XDG_DATA_DIRS+=:$out/share
|
|
||||||
'';
|
|
||||||
|
|
||||||
# We use this shell with the local checkout, not unpackPhase.
|
|
||||||
src = null;
|
|
||||||
|
|
||||||
env = {
|
|
||||||
# Needed for Meson to find Boost.
|
|
||||||
# https://github.com/NixOS/nixpkgs/issues/86131.
|
|
||||||
BOOST_INCLUDEDIR = "${lib.getDev pkgs.nixDependencies.boost}/include";
|
|
||||||
BOOST_LIBRARYDIR = "${lib.getLib pkgs.nixDependencies.boost}/lib";
|
|
||||||
# For `make format`, to work without installing pre-commit
|
|
||||||
_NIX_PRE_COMMIT_HOOKS_CONFIG =
|
|
||||||
"${(pkgs.formats.yaml { }).generate "pre-commit-config.yaml" modular.pre-commit.settings.rawConfig}";
|
|
||||||
};
|
|
||||||
|
|
||||||
mesonFlags =
|
|
||||||
map (transformFlag "libutil") (ignoreCrossFile pkgs.nixComponents.nix-util.mesonFlags)
|
|
||||||
++ map (transformFlag "libstore") (ignoreCrossFile pkgs.nixComponents.nix-store.mesonFlags)
|
|
||||||
++ map (transformFlag "libfetchers") (ignoreCrossFile pkgs.nixComponents.nix-fetchers.mesonFlags)
|
|
||||||
++ lib.optionals havePerl (map (transformFlag "perl") (ignoreCrossFile pkgs.nixComponents.nix-perl-bindings.mesonFlags))
|
|
||||||
++ map (transformFlag "libexpr") (ignoreCrossFile pkgs.nixComponents.nix-expr.mesonFlags)
|
|
||||||
++ map (transformFlag "libcmd") (ignoreCrossFile pkgs.nixComponents.nix-cmd.mesonFlags)
|
|
||||||
;
|
|
||||||
|
|
||||||
nativeBuildInputs = attrs.nativeBuildInputs or []
|
|
||||||
++ pkgs.nixComponents.nix-util.nativeBuildInputs
|
|
||||||
++ pkgs.nixComponents.nix-store.nativeBuildInputs
|
|
||||||
++ pkgs.nixComponents.nix-fetchers.nativeBuildInputs
|
|
||||||
++ lib.optionals havePerl pkgs.nixComponents.nix-perl-bindings.nativeBuildInputs
|
|
||||||
++ lib.optionals buildCanExecuteHost pkgs.nixComponents.nix-manual.externalNativeBuildInputs
|
|
||||||
++ pkgs.nixComponents.nix-internal-api-docs.nativeBuildInputs
|
|
||||||
++ pkgs.nixComponents.nix-external-api-docs.nativeBuildInputs
|
|
||||||
++ pkgs.nixComponents.nix-functional-tests.externalNativeBuildInputs
|
|
||||||
++ lib.optional
|
|
||||||
(!buildCanExecuteHost
|
|
||||||
# Hack around https://github.com/nixos/nixpkgs/commit/bf7ad8cfbfa102a90463433e2c5027573b462479
|
|
||||||
&& !(stdenv.hostPlatform.isWindows && stdenv.buildPlatform.isDarwin)
|
|
||||||
&& stdenv.hostPlatform.emulatorAvailable pkgs.buildPackages
|
|
||||||
&& lib.meta.availableOn stdenv.buildPlatform (stdenv.hostPlatform.emulator pkgs.buildPackages))
|
|
||||||
pkgs.buildPackages.mesonEmulatorHook
|
|
||||||
++ [
|
|
||||||
pkgs.buildPackages.cmake
|
|
||||||
pkgs.buildPackages.shellcheck
|
|
||||||
pkgs.buildPackages.changelog-d
|
|
||||||
modular.pre-commit.settings.package
|
|
||||||
(pkgs.writeScriptBin "pre-commit-hooks-install"
|
|
||||||
modular.pre-commit.settings.installationScript)
|
|
||||||
]
|
|
||||||
# TODO: Remove the darwin check once
|
|
||||||
# https://github.com/NixOS/nixpkgs/pull/291814 is available
|
|
||||||
++ lib.optional (stdenv.cc.isClang && !stdenv.buildPlatform.isDarwin) pkgs.buildPackages.bear
|
|
||||||
++ lib.optional (stdenv.cc.isClang && stdenv.hostPlatform == stdenv.buildPlatform) (lib.hiPrio pkgs.buildPackages.clang-tools);
|
|
||||||
|
|
||||||
buildInputs = attrs.buildInputs or []
|
|
||||||
++ [
|
|
||||||
pkgs.gtest
|
|
||||||
pkgs.rapidcheck
|
|
||||||
]
|
|
||||||
++ lib.optional havePerl pkgs.perl
|
|
||||||
;
|
|
||||||
});
|
|
||||||
in
|
|
||||||
forAllSystems (system:
|
forAllSystems (system:
|
||||||
let
|
prefixAttrs "native" (forAllStdenvs (stdenvName: makeShell {
|
||||||
makeShells = prefix: pkgs:
|
pkgs = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages";
|
||||||
lib.mapAttrs'
|
})) //
|
||||||
(k: v: lib.nameValuePair "${prefix}-${k}" v)
|
lib.optionalAttrs (!nixpkgsFor.${system}.native.stdenv.isDarwin) (
|
||||||
(forAllStdenvs (stdenvName: makeShell pkgs pkgs.${stdenvName}));
|
prefixAttrs "static" (forAllStdenvs (stdenvName: makeShell {
|
||||||
in
|
pkgs = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".pkgsStatic;
|
||||||
(makeShells "native" nixpkgsFor.${system}.native) //
|
})) //
|
||||||
(lib.optionalAttrs (!nixpkgsFor.${system}.native.stdenv.isDarwin)
|
prefixAttrs "cross" (forAllCrossSystems (crossSystem: makeShell {
|
||||||
(makeShells "static" nixpkgsFor.${system}.static) //
|
pkgs = nixpkgsFor.${system}.cross.${crossSystem};
|
||||||
(forAllCrossSystems (crossSystem: let pkgs = nixpkgsFor.${system}.cross.${crossSystem}; in makeShell pkgs pkgs.stdenv))) //
|
}))
|
||||||
{
|
) //
|
||||||
default = self.devShells.${system}.native-stdenvPackages;
|
{
|
||||||
}
|
default = self.devShells.${system}.native-stdenvPackages;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
''^src/build-remote/build-remote\.cc$''
|
''^src/build-remote/build-remote\.cc$''
|
||||||
''^src/libcmd/built-path\.cc$''
|
''^src/libcmd/built-path\.cc$''
|
||||||
''^src/libcmd/built-path\.hh$''
|
''^src/libcmd/built-path\.hh$''
|
||||||
''^src/libcmd/command\.cc$''
|
|
||||||
''^src/libcmd/command\.hh$''
|
|
||||||
''^src/libcmd/common-eval-args\.cc$''
|
''^src/libcmd/common-eval-args\.cc$''
|
||||||
''^src/libcmd/common-eval-args\.hh$''
|
''^src/libcmd/common-eval-args\.hh$''
|
||||||
''^src/libcmd/editor-for\.cc$''
|
''^src/libcmd/editor-for\.cc$''
|
||||||
|
@ -547,7 +545,6 @@
|
||||||
''^tests/functional/flakes/absolute-paths\.sh$''
|
''^tests/functional/flakes/absolute-paths\.sh$''
|
||||||
''^tests/functional/flakes/check\.sh$''
|
''^tests/functional/flakes/check\.sh$''
|
||||||
''^tests/functional/flakes/config\.sh$''
|
''^tests/functional/flakes/config\.sh$''
|
||||||
''^tests/functional/flakes/develop\.sh$''
|
|
||||||
''^tests/functional/flakes/flakes\.sh$''
|
''^tests/functional/flakes/flakes\.sh$''
|
||||||
''^tests/functional/flakes/follow-paths\.sh$''
|
''^tests/functional/flakes/follow-paths\.sh$''
|
||||||
''^tests/functional/flakes/prefetch\.sh$''
|
''^tests/functional/flakes/prefetch\.sh$''
|
||||||
|
|
30
meson.build
30
meson.build
|
@ -22,10 +22,12 @@ subproject('libcmd')
|
||||||
subproject('nix')
|
subproject('nix')
|
||||||
|
|
||||||
# Docs
|
# Docs
|
||||||
subproject('internal-api-docs')
|
if get_option('doc-gen')
|
||||||
subproject('external-api-docs')
|
subproject('internal-api-docs')
|
||||||
if not meson.is_cross_build()
|
subproject('external-api-docs')
|
||||||
subproject('nix-manual')
|
if not meson.is_cross_build()
|
||||||
|
subproject('nix-manual')
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# External C wrapper libraries
|
# External C wrapper libraries
|
||||||
|
@ -35,17 +37,19 @@ subproject('libexpr-c')
|
||||||
subproject('libmain-c')
|
subproject('libmain-c')
|
||||||
|
|
||||||
# Language Bindings
|
# Language Bindings
|
||||||
if not meson.is_cross_build()
|
if get_option('bindings') and not meson.is_cross_build()
|
||||||
subproject('perl')
|
subproject('perl')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Testing
|
# Testing
|
||||||
subproject('libutil-test-support')
|
if get_option('unit-tests')
|
||||||
subproject('libutil-tests')
|
subproject('libutil-test-support')
|
||||||
subproject('libstore-test-support')
|
subproject('libutil-tests')
|
||||||
subproject('libstore-tests')
|
subproject('libstore-test-support')
|
||||||
subproject('libfetchers-tests')
|
subproject('libstore-tests')
|
||||||
subproject('libexpr-test-support')
|
subproject('libfetchers-tests')
|
||||||
subproject('libexpr-tests')
|
subproject('libexpr-test-support')
|
||||||
subproject('libflake-tests')
|
subproject('libexpr-tests')
|
||||||
|
subproject('libflake-tests')
|
||||||
|
endif
|
||||||
subproject('nix-functional-tests')
|
subproject('nix-functional-tests')
|
||||||
|
|
13
meson.options
Normal file
13
meson.options
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# vim: filetype=meson
|
||||||
|
|
||||||
|
option('doc-gen', type : 'boolean', value : true,
|
||||||
|
description : 'Generate documentation',
|
||||||
|
)
|
||||||
|
|
||||||
|
option('unit-tests', type : 'boolean', value : true,
|
||||||
|
description : 'Build unit tests',
|
||||||
|
)
|
||||||
|
|
||||||
|
option('bindings', type : 'boolean', value : true,
|
||||||
|
description : 'Build language bindings (e.g. Perl)',
|
||||||
|
)
|
|
@ -9,13 +9,21 @@ test_name=$(echo -n "${test?must be defined by caller (test runner)}" | sed \
|
||||||
-e "s|\.sh$||" \
|
-e "s|\.sh$||" \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Layer violation, but I am not inclined to care too much, as this code
|
||||||
|
# is about to be deleted.
|
||||||
|
src_dir=$(realpath tests/functional)
|
||||||
|
|
||||||
# shellcheck disable=SC2016
|
# shellcheck disable=SC2016
|
||||||
TESTS_ENVIRONMENT=(
|
TESTS_ENVIRONMENT=(
|
||||||
"TEST_NAME=$test_name"
|
"TEST_NAME=$test_name"
|
||||||
'NIX_REMOTE='
|
'NIX_REMOTE='
|
||||||
'PS4=+(${BASH_SOURCE[0]-$0}:$LINENO) '
|
'PS4=+(${BASH_SOURCE[0]-$0}:$LINENO) '
|
||||||
|
"_NIX_TEST_SOURCE_DIR=${src_dir}"
|
||||||
|
"_NIX_TEST_BUILD_DIR=${src_dir}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
unset src_dir
|
||||||
|
|
||||||
read -r -a bash <<< "${BASH:-/usr/bin/env bash}"
|
read -r -a bash <<< "${BASH:-/usr/bin/env bash}"
|
||||||
|
|
||||||
run () {
|
run () {
|
||||||
|
|
96
packaging/dev-shell.nix
Normal file
96
packaging/dev-shell.nix
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
{ lib, devFlake }:
|
||||||
|
|
||||||
|
{ pkgs }:
|
||||||
|
|
||||||
|
(pkgs.nix.override { forDevShell = true; }).overrideAttrs (attrs:
|
||||||
|
|
||||||
|
let
|
||||||
|
stdenv = pkgs.nixDependencies.stdenv;
|
||||||
|
buildCanExecuteHost = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
|
||||||
|
modular = devFlake.getSystem stdenv.buildPlatform.system;
|
||||||
|
transformFlag = prefix: flag:
|
||||||
|
assert builtins.isString flag;
|
||||||
|
let
|
||||||
|
rest = builtins.substring 2 (builtins.stringLength flag) flag;
|
||||||
|
in
|
||||||
|
"-D${prefix}:${rest}";
|
||||||
|
havePerl = stdenv.buildPlatform == stdenv.hostPlatform && stdenv.hostPlatform.isUnix;
|
||||||
|
ignoreCrossFile = flags: builtins.filter (flag: !(lib.strings.hasInfix "cross-file" flag)) flags;
|
||||||
|
in {
|
||||||
|
pname = "shell-for-" + attrs.pname;
|
||||||
|
|
||||||
|
# Remove the version suffix to avoid unnecessary attempts to substitute in nix develop
|
||||||
|
version = lib.fileContents ../.version;
|
||||||
|
name = attrs.pname;
|
||||||
|
|
||||||
|
installFlags = "sysconfdir=$(out)/etc";
|
||||||
|
shellHook = ''
|
||||||
|
PATH=$prefix/bin:$PATH
|
||||||
|
unset PYTHONPATH
|
||||||
|
export MANPATH=$out/share/man:$MANPATH
|
||||||
|
|
||||||
|
# Make bash completion work.
|
||||||
|
XDG_DATA_DIRS+=:$out/share
|
||||||
|
'';
|
||||||
|
|
||||||
|
# We use this shell with the local checkout, not unpackPhase.
|
||||||
|
src = null;
|
||||||
|
|
||||||
|
env = {
|
||||||
|
# Needed for Meson to find Boost.
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/86131.
|
||||||
|
BOOST_INCLUDEDIR = "${lib.getDev pkgs.nixDependencies.boost}/include";
|
||||||
|
BOOST_LIBRARYDIR = "${lib.getLib pkgs.nixDependencies.boost}/lib";
|
||||||
|
# For `make format`, to work without installing pre-commit
|
||||||
|
_NIX_PRE_COMMIT_HOOKS_CONFIG =
|
||||||
|
"${(pkgs.formats.yaml { }).generate "pre-commit-config.yaml" modular.pre-commit.settings.rawConfig}";
|
||||||
|
};
|
||||||
|
|
||||||
|
mesonFlags =
|
||||||
|
map (transformFlag "libutil") (ignoreCrossFile pkgs.nixComponents.nix-util.mesonFlags)
|
||||||
|
++ map (transformFlag "libstore") (ignoreCrossFile pkgs.nixComponents.nix-store.mesonFlags)
|
||||||
|
++ map (transformFlag "libfetchers") (ignoreCrossFile pkgs.nixComponents.nix-fetchers.mesonFlags)
|
||||||
|
++ lib.optionals havePerl (map (transformFlag "perl") (ignoreCrossFile pkgs.nixComponents.nix-perl-bindings.mesonFlags))
|
||||||
|
++ map (transformFlag "libexpr") (ignoreCrossFile pkgs.nixComponents.nix-expr.mesonFlags)
|
||||||
|
++ map (transformFlag "libcmd") (ignoreCrossFile pkgs.nixComponents.nix-cmd.mesonFlags)
|
||||||
|
;
|
||||||
|
|
||||||
|
nativeBuildInputs = attrs.nativeBuildInputs or []
|
||||||
|
++ pkgs.nixComponents.nix-util.nativeBuildInputs
|
||||||
|
++ pkgs.nixComponents.nix-store.nativeBuildInputs
|
||||||
|
++ pkgs.nixComponents.nix-fetchers.nativeBuildInputs
|
||||||
|
++ pkgs.nixComponents.nix-expr.nativeBuildInputs
|
||||||
|
++ lib.optionals havePerl pkgs.nixComponents.nix-perl-bindings.nativeBuildInputs
|
||||||
|
++ lib.optionals buildCanExecuteHost pkgs.nixComponents.nix-manual.externalNativeBuildInputs
|
||||||
|
++ pkgs.nixComponents.nix-internal-api-docs.nativeBuildInputs
|
||||||
|
++ pkgs.nixComponents.nix-external-api-docs.nativeBuildInputs
|
||||||
|
++ pkgs.nixComponents.nix-functional-tests.externalNativeBuildInputs
|
||||||
|
++ lib.optional
|
||||||
|
(!buildCanExecuteHost
|
||||||
|
# Hack around https://github.com/nixos/nixpkgs/commit/bf7ad8cfbfa102a90463433e2c5027573b462479
|
||||||
|
&& !(stdenv.hostPlatform.isWindows && stdenv.buildPlatform.isDarwin)
|
||||||
|
&& stdenv.hostPlatform.emulatorAvailable pkgs.buildPackages
|
||||||
|
&& lib.meta.availableOn stdenv.buildPlatform (stdenv.hostPlatform.emulator pkgs.buildPackages))
|
||||||
|
pkgs.buildPackages.mesonEmulatorHook
|
||||||
|
++ [
|
||||||
|
pkgs.buildPackages.cmake
|
||||||
|
pkgs.buildPackages.shellcheck
|
||||||
|
pkgs.buildPackages.changelog-d
|
||||||
|
modular.pre-commit.settings.package
|
||||||
|
(pkgs.writeScriptBin "pre-commit-hooks-install"
|
||||||
|
modular.pre-commit.settings.installationScript)
|
||||||
|
]
|
||||||
|
# TODO: Remove the darwin check once
|
||||||
|
# https://github.com/NixOS/nixpkgs/pull/291814 is available
|
||||||
|
++ lib.optional (stdenv.cc.isClang && !stdenv.buildPlatform.isDarwin) pkgs.buildPackages.bear
|
||||||
|
++ lib.optional (stdenv.cc.isClang && stdenv.hostPlatform == stdenv.buildPlatform) (lib.hiPrio pkgs.buildPackages.clang-tools);
|
||||||
|
|
||||||
|
buildInputs = attrs.buildInputs or []
|
||||||
|
++ pkgs.nixComponents.nix-util.buildInputs
|
||||||
|
++ pkgs.nixComponents.nix-store.buildInputs
|
||||||
|
++ pkgs.nixComponents.nix-fetchers.buildInputs
|
||||||
|
++ pkgs.nixComponents.nix-expr.buildInputs
|
||||||
|
++ pkgs.nixComponents.nix-store-tests.externalBuildInputs
|
||||||
|
++ lib.optional havePerl pkgs.perl
|
||||||
|
;
|
||||||
|
})
|
|
@ -16,25 +16,16 @@ let
|
||||||
inherit tarballs;
|
inherit tarballs;
|
||||||
};
|
};
|
||||||
|
|
||||||
testNixVersions = pkgs: client: daemon:
|
testNixVersions = pkgs: daemon:
|
||||||
pkgs.nixComponents.callPackage ../package.nix {
|
pkgs.nixComponents.nix-functional-tests.override {
|
||||||
pname =
|
pname =
|
||||||
"nix-tests"
|
"nix-tests"
|
||||||
+ lib.optionalString
|
+ lib.optionalString
|
||||||
(lib.versionAtLeast daemon.version "2.4pre20211005" &&
|
(lib.versionAtLeast daemon.version "2.4pre20211005" &&
|
||||||
lib.versionAtLeast client.version "2.4pre20211005")
|
lib.versionAtLeast pkgs.nix.version "2.4pre20211005")
|
||||||
"-${client.version}-against-${daemon.version}";
|
"-${pkgs.nix.version}-against-${daemon.version}";
|
||||||
|
|
||||||
test-client = client;
|
|
||||||
test-daemon = daemon;
|
test-daemon = daemon;
|
||||||
|
|
||||||
doBuild = false;
|
|
||||||
|
|
||||||
# This could be more accurate, but a shorter version will match the
|
|
||||||
# fine version with rev. This functionality is already covered in
|
|
||||||
# the normal test, so it's fine.
|
|
||||||
version = pkgs.nixComponents.version;
|
|
||||||
versionSuffix = pkgs.nixComponents.versionSuffix;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Technically we could just return `pkgs.nixComponents`, but for Hydra it's
|
# Technically we could just return `pkgs.nixComponents`, but for Hydra it's
|
||||||
|
@ -71,7 +62,9 @@ in
|
||||||
build = forAllPackages (pkgName:
|
build = forAllPackages (pkgName:
|
||||||
forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.${pkgName}));
|
forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.${pkgName}));
|
||||||
|
|
||||||
shellInputs = forAllSystems (system: self.devShells.${system}.default.inputDerivation);
|
shellInputs = removeAttrs
|
||||||
|
(forAllSystems (system: self.devShells.${system}.default.inputDerivation))
|
||||||
|
[ "i686-linux" ];
|
||||||
|
|
||||||
buildStatic = forAllPackages (pkgName:
|
buildStatic = forAllPackages (pkgName:
|
||||||
lib.genAttrs linux64BitSystems (system: nixpkgsFor.${system}.static.nixComponents.${pkgName}));
|
lib.genAttrs linux64BitSystems (system: nixpkgsFor.${system}.static.nixComponents.${pkgName}));
|
||||||
|
@ -82,20 +75,28 @@ in
|
||||||
(forAllCrossSystems (crossSystem:
|
(forAllCrossSystems (crossSystem:
|
||||||
lib.genAttrs [ "x86_64-linux" ] (system: nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName}))));
|
lib.genAttrs [ "x86_64-linux" ] (system: nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName}))));
|
||||||
|
|
||||||
buildNoGc = forAllSystems (system:
|
buildNoGc = let
|
||||||
self.packages.${system}.nix.override { enableGC = false; }
|
components = forAllSystems (system:
|
||||||
);
|
nixpkgsFor.${system}.native.nixComponents.overrideScope (self: super: {
|
||||||
|
nix-expr = super.nix-expr.override { enableGC = false; };
|
||||||
|
})
|
||||||
|
);
|
||||||
|
in forAllPackages (pkgName: forAllSystems (system: components.${system}.${pkgName}));
|
||||||
|
|
||||||
buildNoTests = forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.nix-cli);
|
buildNoTests = forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.nix-cli);
|
||||||
|
|
||||||
# Toggles some settings for better coverage. Windows needs these
|
# Toggles some settings for better coverage. Windows needs these
|
||||||
# library combinations, and Debian build Nix with GNU readline too.
|
# library combinations, and Debian build Nix with GNU readline too.
|
||||||
buildReadlineNoMarkdown = forAllSystems (system:
|
buildReadlineNoMarkdown = let
|
||||||
self.packages.${system}.nix.override {
|
components = forAllSystems (system:
|
||||||
enableMarkdown = false;
|
nixpkgsFor.${system}.native.nixComponents.overrideScope (self: super: {
|
||||||
readlineFlavor = "readline";
|
nix-cmd = super.nix-cmd.override {
|
||||||
}
|
enableMarkdown = false;
|
||||||
);
|
readlineFlavor = "readline";
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
in forAllPackages (pkgName: forAllSystems (system: components.${system}.${pkgName}));
|
||||||
|
|
||||||
# Perl bindings for various platforms.
|
# Perl bindings for various platforms.
|
||||||
perlBindings = forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.nix-perl-bindings);
|
perlBindings = forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.nix-perl-bindings);
|
||||||
|
@ -196,15 +197,15 @@ in
|
||||||
let pkgs = nixpkgsFor.${system}.native; in
|
let pkgs = nixpkgsFor.${system}.native; in
|
||||||
pkgs.runCommand "install-tests"
|
pkgs.runCommand "install-tests"
|
||||||
{
|
{
|
||||||
againstSelf = testNixVersions pkgs pkgs.nix pkgs.pkgs.nix;
|
againstSelf = testNixVersions pkgs pkgs.nix;
|
||||||
againstCurrentLatest =
|
againstCurrentLatest =
|
||||||
# FIXME: temporarily disable this on macOS because of #3605.
|
# FIXME: temporarily disable this on macOS because of #3605.
|
||||||
if system == "x86_64-linux"
|
if system == "x86_64-linux"
|
||||||
then testNixVersions pkgs pkgs.nix pkgs.nixVersions.latest
|
then testNixVersions pkgs pkgs.nixVersions.latest
|
||||||
else null;
|
else null;
|
||||||
# Disabled because the latest stable version doesn't handle
|
# Disabled because the latest stable version doesn't handle
|
||||||
# `NIX_DAEMON_SOCKET_PATH` which is required for the tests to work
|
# `NIX_DAEMON_SOCKET_PATH` which is required for the tests to work
|
||||||
# againstLatestStable = testNixVersions pkgs pkgs.nix pkgs.nixStable;
|
# againstLatestStable = testNixVersions pkgs pkgs.nixStable;
|
||||||
} "touch $out");
|
} "touch $out");
|
||||||
|
|
||||||
installerTests = import ../tests/installer {
|
installerTests = import ../tests/installer {
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
#! /usr/bin/env bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "Nix version:"
|
|
||||||
nix --version
|
|
||||||
|
|
||||||
cd flake-regressions
|
|
||||||
|
|
||||||
status=0
|
|
||||||
|
|
||||||
flakes=$(find tests -mindepth 3 -maxdepth 3 -type d -not -path '*/.*' | sort | head -n25)
|
|
||||||
|
|
||||||
echo "Running flake tests..."
|
|
||||||
|
|
||||||
for flake in $flakes; do
|
|
||||||
|
|
||||||
if ! REGENERATE=0 ./eval-flake.sh "$flake"; then
|
|
||||||
status=1
|
|
||||||
echo "❌ $flake"
|
|
||||||
else
|
|
||||||
echo "✅ $flake"
|
|
||||||
fi
|
|
||||||
|
|
||||||
done
|
|
||||||
|
|
||||||
exit "$status"
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <algorithm>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include "command.hh"
|
#include "command.hh"
|
||||||
|
@ -9,8 +10,7 @@
|
||||||
#include "profiles.hh"
|
#include "profiles.hh"
|
||||||
#include "repl.hh"
|
#include "repl.hh"
|
||||||
#include "strings.hh"
|
#include "strings.hh"
|
||||||
|
#include "environment-variables.hh"
|
||||||
extern char * * environ __attribute__((weak));
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
@ -23,7 +23,8 @@ nix::Commands RegisterCommand::getCommandsFor(const std::vector<std::string> & p
|
||||||
if (name.size() == prefix.size() + 1) {
|
if (name.size() == prefix.size() + 1) {
|
||||||
bool equal = true;
|
bool equal = true;
|
||||||
for (size_t i = 0; i < prefix.size(); ++i)
|
for (size_t i = 0; i < prefix.size(); ++i)
|
||||||
if (name[i] != prefix[i]) equal = false;
|
if (name[i] != prefix[i])
|
||||||
|
equal = false;
|
||||||
if (equal)
|
if (equal)
|
||||||
res.insert_or_assign(name[prefix.size()], command);
|
res.insert_or_assign(name[prefix.size()], command);
|
||||||
}
|
}
|
||||||
|
@ -42,16 +43,16 @@ void NixMultiCommand::run()
|
||||||
std::set<std::string> subCommandTextLines;
|
std::set<std::string> subCommandTextLines;
|
||||||
for (auto & [name, _] : commands)
|
for (auto & [name, _] : commands)
|
||||||
subCommandTextLines.insert(fmt("- `%s`", name));
|
subCommandTextLines.insert(fmt("- `%s`", name));
|
||||||
std::string markdownError = fmt("`nix %s` requires a sub-command. Available sub-commands:\n\n%s\n",
|
std::string markdownError =
|
||||||
commandName, concatStringsSep("\n", subCommandTextLines));
|
fmt("`nix %s` requires a sub-command. Available sub-commands:\n\n%s\n",
|
||||||
|
commandName,
|
||||||
|
concatStringsSep("\n", subCommandTextLines));
|
||||||
throw UsageError(renderMarkdownToTerminal(markdownError));
|
throw UsageError(renderMarkdownToTerminal(markdownError));
|
||||||
}
|
}
|
||||||
command->second->run();
|
command->second->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
StoreCommand::StoreCommand()
|
StoreCommand::StoreCommand() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ref<Store> StoreCommand::getStore()
|
ref<Store> StoreCommand::getStore()
|
||||||
{
|
{
|
||||||
|
@ -126,10 +127,8 @@ ref<Store> EvalCommand::getEvalStore()
|
||||||
ref<EvalState> EvalCommand::getEvalState()
|
ref<EvalState> EvalCommand::getEvalState()
|
||||||
{
|
{
|
||||||
if (!evalState) {
|
if (!evalState) {
|
||||||
evalState =
|
evalState = std::allocate_shared<EvalState>(
|
||||||
std::allocate_shared<EvalState>(
|
traceable_allocator<EvalState>(), lookupPath, getEvalStore(), fetchSettings, evalSettings, getStore());
|
||||||
traceable_allocator<EvalState>(),
|
|
||||||
lookupPath, getEvalStore(), fetchSettings, evalSettings, getStore());
|
|
||||||
|
|
||||||
evalState->repair = repair;
|
evalState->repair = repair;
|
||||||
|
|
||||||
|
@ -144,7 +143,8 @@ MixOperateOnOptions::MixOperateOnOptions()
|
||||||
{
|
{
|
||||||
addFlag({
|
addFlag({
|
||||||
.longName = "derivation",
|
.longName = "derivation",
|
||||||
.description = "Operate on the [store derivation](@docroot@/glossary.md#gloss-store-derivation) rather than its outputs.",
|
.description =
|
||||||
|
"Operate on the [store derivation](@docroot@/glossary.md#gloss-store-derivation) rather than its outputs.",
|
||||||
.category = installablesCategory,
|
.category = installablesCategory,
|
||||||
.handler = {&operateOn, OperateOn::Derivation},
|
.handler = {&operateOn, OperateOn::Derivation},
|
||||||
});
|
});
|
||||||
|
@ -233,46 +233,48 @@ void StorePathCommand::run(ref<Store> store, StorePaths && storePaths)
|
||||||
|
|
||||||
MixProfile::MixProfile()
|
MixProfile::MixProfile()
|
||||||
{
|
{
|
||||||
addFlag({
|
addFlag(
|
||||||
.longName = "profile",
|
{.longName = "profile",
|
||||||
.description = "The profile to operate on.",
|
.description = "The profile to operate on.",
|
||||||
.labels = {"path"},
|
.labels = {"path"},
|
||||||
.handler = {&profile},
|
.handler = {&profile},
|
||||||
.completer = completePath
|
.completer = completePath});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixProfile::updateProfile(const StorePath & storePath)
|
void MixProfile::updateProfile(const StorePath & storePath)
|
||||||
{
|
{
|
||||||
if (!profile) return;
|
if (!profile)
|
||||||
|
return;
|
||||||
auto store = getStore().dynamic_pointer_cast<LocalFSStore>();
|
auto store = getStore().dynamic_pointer_cast<LocalFSStore>();
|
||||||
if (!store) throw Error("'--profile' is not supported for this Nix store");
|
if (!store)
|
||||||
|
throw Error("'--profile' is not supported for this Nix store");
|
||||||
auto profile2 = absPath(*profile);
|
auto profile2 = absPath(*profile);
|
||||||
switchLink(profile2,
|
switchLink(profile2, createGeneration(*store, profile2, storePath));
|
||||||
createGeneration(*store, profile2, storePath));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixProfile::updateProfile(const BuiltPaths & buildables)
|
void MixProfile::updateProfile(const BuiltPaths & buildables)
|
||||||
{
|
{
|
||||||
if (!profile) return;
|
if (!profile)
|
||||||
|
return;
|
||||||
|
|
||||||
StorePaths result;
|
StorePaths result;
|
||||||
|
|
||||||
for (auto & buildable : buildables) {
|
for (auto & buildable : buildables) {
|
||||||
std::visit(overloaded {
|
std::visit(
|
||||||
[&](const BuiltPath::Opaque & bo) {
|
overloaded{
|
||||||
result.push_back(bo.path);
|
[&](const BuiltPath::Opaque & bo) { result.push_back(bo.path); },
|
||||||
|
[&](const BuiltPath::Built & bfd) {
|
||||||
|
for (auto & output : bfd.outputs) {
|
||||||
|
result.push_back(output.second);
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
[&](const BuiltPath::Built & bfd) {
|
buildable.raw());
|
||||||
for (auto & output : bfd.outputs) {
|
|
||||||
result.push_back(output.second);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}, buildable.raw());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.size() != 1)
|
if (result.size() != 1)
|
||||||
throw UsageError("'--profile' requires that the arguments produce a single store path, but there are %d", result.size());
|
throw UsageError(
|
||||||
|
"'--profile' requires that the arguments produce a single store path, but there are %d", result.size());
|
||||||
|
|
||||||
updateProfile(result[0]);
|
updateProfile(result[0]);
|
||||||
}
|
}
|
||||||
|
@ -282,51 +284,85 @@ MixDefaultProfile::MixDefaultProfile()
|
||||||
profile = getDefaultProfile();
|
profile = getDefaultProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
MixEnvironment::MixEnvironment() : ignoreEnvironment(false)
|
MixEnvironment::MixEnvironment()
|
||||||
|
: ignoreEnvironment(false)
|
||||||
{
|
{
|
||||||
addFlag({
|
addFlag({
|
||||||
.longName = "ignore-environment",
|
.longName = "ignore-env",
|
||||||
|
.aliases = {"ignore-environment"},
|
||||||
.shortName = 'i',
|
.shortName = 'i',
|
||||||
.description = "Clear the entire environment (except those specified with `--keep`).",
|
.description = "Clear the entire environment, except for those specified with `--keep-env-var`.",
|
||||||
|
.category = environmentVariablesCategory,
|
||||||
.handler = {&ignoreEnvironment, true},
|
.handler = {&ignoreEnvironment, true},
|
||||||
});
|
});
|
||||||
|
|
||||||
addFlag({
|
addFlag({
|
||||||
.longName = "keep",
|
.longName = "keep-env-var",
|
||||||
|
.aliases = {"keep"},
|
||||||
.shortName = 'k',
|
.shortName = 'k',
|
||||||
.description = "Keep the environment variable *name*.",
|
.description = "Keep the environment variable *name*, when using `--ignore-env`.",
|
||||||
|
.category = environmentVariablesCategory,
|
||||||
.labels = {"name"},
|
.labels = {"name"},
|
||||||
.handler = {[&](std::string s) { keep.insert(s); }},
|
.handler = {[&](std::string s) { keepVars.insert(s); }},
|
||||||
});
|
});
|
||||||
|
|
||||||
addFlag({
|
addFlag({
|
||||||
.longName = "unset",
|
.longName = "unset-env-var",
|
||||||
|
.aliases = {"unset"},
|
||||||
.shortName = 'u',
|
.shortName = 'u',
|
||||||
.description = "Unset the environment variable *name*.",
|
.description = "Unset the environment variable *name*.",
|
||||||
|
.category = environmentVariablesCategory,
|
||||||
.labels = {"name"},
|
.labels = {"name"},
|
||||||
.handler = {[&](std::string s) { unset.insert(s); }},
|
.handler = {[&](std::string name) {
|
||||||
|
if (setVars.contains(name))
|
||||||
|
throw UsageError("Cannot unset environment variable '%s' that is set with '%s'", name, "--set-env-var");
|
||||||
|
|
||||||
|
unsetVars.insert(name);
|
||||||
|
}},
|
||||||
|
});
|
||||||
|
|
||||||
|
addFlag({
|
||||||
|
.longName = "set-env-var",
|
||||||
|
.shortName = 's',
|
||||||
|
.description = "Sets an environment variable *name* with *value*.",
|
||||||
|
.category = environmentVariablesCategory,
|
||||||
|
.labels = {"name", "value"},
|
||||||
|
.handler = {[&](std::string name, std::string value) {
|
||||||
|
if (unsetVars.contains(name))
|
||||||
|
throw UsageError(
|
||||||
|
"Cannot set environment variable '%s' that is unset with '%s'", name, "--unset-env-var");
|
||||||
|
|
||||||
|
if (setVars.contains(name))
|
||||||
|
throw UsageError(
|
||||||
|
"Duplicate definition of environment variable '%s' with '%s' is ambiguous", name, "--set-env-var");
|
||||||
|
|
||||||
|
setVars.insert_or_assign(name, value);
|
||||||
|
}},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixEnvironment::setEnviron() {
|
void MixEnvironment::setEnviron()
|
||||||
if (ignoreEnvironment) {
|
{
|
||||||
if (!unset.empty())
|
if (ignoreEnvironment && !unsetVars.empty())
|
||||||
throw UsageError("--unset does not make sense with --ignore-environment");
|
throw UsageError("--unset-env-var does not make sense with --ignore-env");
|
||||||
|
|
||||||
for (const auto & var : keep) {
|
if (!ignoreEnvironment && !keepVars.empty())
|
||||||
auto val = getenv(var.c_str());
|
throw UsageError("--keep-env-var does not make sense without --ignore-env");
|
||||||
if (val) stringsEnv.emplace_back(fmt("%s=%s", var.c_str(), val));
|
|
||||||
}
|
|
||||||
|
|
||||||
vectorEnv = stringsToCharPtrs(stringsEnv);
|
auto env = getEnv();
|
||||||
environ = vectorEnv.data();
|
|
||||||
} else {
|
|
||||||
if (!keep.empty())
|
|
||||||
throw UsageError("--keep does not make sense without --ignore-environment");
|
|
||||||
|
|
||||||
for (const auto & var : unset)
|
if (ignoreEnvironment)
|
||||||
unsetenv(var.c_str());
|
std::erase_if(env, [&](const auto & var) { return !keepVars.contains(var.first); });
|
||||||
}
|
|
||||||
|
for (const auto & [name, value] : setVars)
|
||||||
|
env[name] = value;
|
||||||
|
|
||||||
|
if (!unsetVars.empty())
|
||||||
|
std::erase_if(env, [&](const auto & var) { return unsetVars.contains(var.first); });
|
||||||
|
|
||||||
|
replaceEnv(env);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace nix {
|
||||||
|
|
||||||
extern std::string programPath;
|
extern std::string programPath;
|
||||||
|
|
||||||
extern char * * savedArgv;
|
extern char ** savedArgv;
|
||||||
|
|
||||||
class EvalState;
|
class EvalState;
|
||||||
struct Pos;
|
struct Pos;
|
||||||
|
@ -24,7 +24,8 @@ static constexpr Command::Category catSecondary = 100;
|
||||||
static constexpr Command::Category catUtility = 101;
|
static constexpr Command::Category catUtility = 101;
|
||||||
static constexpr Command::Category catNixInstallation = 102;
|
static constexpr Command::Category catNixInstallation = 102;
|
||||||
|
|
||||||
static constexpr auto installablesCategory = "Options that change the interpretation of [installables](@docroot@/command-ref/new-cli/nix.md#installables)";
|
static constexpr auto installablesCategory =
|
||||||
|
"Options that change the interpretation of [installables](@docroot@/command-ref/new-cli/nix.md#installables)";
|
||||||
|
|
||||||
struct NixMultiCommand : MultiCommand, virtual Command
|
struct NixMultiCommand : MultiCommand, virtual Command
|
||||||
{
|
{
|
||||||
|
@ -112,7 +113,9 @@ struct MixFlakeOptions : virtual Args, EvalCommand
|
||||||
* arguments) so that the completions for these flags can use them.
|
* arguments) so that the completions for these flags can use them.
|
||||||
*/
|
*/
|
||||||
virtual std::vector<FlakeRef> getFlakeRefsForCompletion()
|
virtual std::vector<FlakeRef> getFlakeRefsForCompletion()
|
||||||
{ return {}; }
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SourceExprCommand : virtual Args, MixFlakeOptions
|
struct SourceExprCommand : virtual Args, MixFlakeOptions
|
||||||
|
@ -122,11 +125,9 @@ struct SourceExprCommand : virtual Args, MixFlakeOptions
|
||||||
|
|
||||||
SourceExprCommand();
|
SourceExprCommand();
|
||||||
|
|
||||||
Installables parseInstallables(
|
Installables parseInstallables(ref<Store> store, std::vector<std::string> ss);
|
||||||
ref<Store> store, std::vector<std::string> ss);
|
|
||||||
|
|
||||||
ref<Installable> parseInstallable(
|
ref<Installable> parseInstallable(ref<Store> store, const std::string & installable);
|
||||||
ref<Store> store, const std::string & installable);
|
|
||||||
|
|
||||||
virtual Strings getDefaultFlakeAttrPaths();
|
virtual Strings getDefaultFlakeAttrPaths();
|
||||||
|
|
||||||
|
@ -272,10 +273,10 @@ struct RegisterCommand
|
||||||
typedef std::map<std::vector<std::string>, std::function<ref<Command>()>> Commands;
|
typedef std::map<std::vector<std::string>, std::function<ref<Command>()>> Commands;
|
||||||
static Commands * commands;
|
static Commands * commands;
|
||||||
|
|
||||||
RegisterCommand(std::vector<std::string> && name,
|
RegisterCommand(std::vector<std::string> && name, std::function<ref<Command>()> command)
|
||||||
std::function<ref<Command>()> command)
|
|
||||||
{
|
{
|
||||||
if (!commands) commands = new Commands;
|
if (!commands)
|
||||||
|
commands = new Commands;
|
||||||
commands->emplace(name, command);
|
commands->emplace(name, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,13 +286,13 @@ struct RegisterCommand
|
||||||
template<class T>
|
template<class T>
|
||||||
static RegisterCommand registerCommand(const std::string & name)
|
static RegisterCommand registerCommand(const std::string & name)
|
||||||
{
|
{
|
||||||
return RegisterCommand({name}, [](){ return make_ref<T>(); });
|
return RegisterCommand({name}, []() { return make_ref<T>(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static RegisterCommand registerCommand2(std::vector<std::string> && name)
|
static RegisterCommand registerCommand2(std::vector<std::string> && name)
|
||||||
{
|
{
|
||||||
return RegisterCommand(std::move(name), [](){ return make_ref<T>(); });
|
return RegisterCommand(std::move(name), []() { return make_ref<T>(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MixProfile : virtual StoreCommand
|
struct MixProfile : virtual StoreCommand
|
||||||
|
@ -313,19 +314,21 @@ struct MixDefaultProfile : MixProfile
|
||||||
MixDefaultProfile();
|
MixDefaultProfile();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MixEnvironment : virtual Args {
|
struct MixEnvironment : virtual Args
|
||||||
|
{
|
||||||
|
|
||||||
StringSet keep, unset;
|
StringSet keepVars;
|
||||||
Strings stringsEnv;
|
StringSet unsetVars;
|
||||||
std::vector<char*> vectorEnv;
|
std::map<std::string, std::string> setVars;
|
||||||
bool ignoreEnvironment;
|
bool ignoreEnvironment;
|
||||||
|
|
||||||
MixEnvironment();
|
MixEnvironment();
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Modify global environ based on `ignoreEnvironment`, `keep`, and
|
* Modify global environ based on `ignoreEnvironment`, `keep`,
|
||||||
* `unset`. It's expected that exec will be called before this class
|
* `unset`, and `added`. It's expected that exec will be called
|
||||||
* goes out of scope, otherwise `environ` will become invalid.
|
* before this class goes out of scope, otherwise `environ` will
|
||||||
|
* become invalid.
|
||||||
*/
|
*/
|
||||||
void setEnviron();
|
void setEnviron();
|
||||||
};
|
};
|
||||||
|
@ -349,9 +352,6 @@ void completeFlakeRefWithFragment(
|
||||||
std::string showVersions(const std::set<std::string> & versions);
|
std::string showVersions(const std::set<std::string> & versions);
|
||||||
|
|
||||||
void printClosureDiff(
|
void printClosureDiff(
|
||||||
ref<Store> store,
|
ref<Store> store, const StorePath & beforePath, const StorePath & afterPath, std::string_view indent);
|
||||||
const StorePath & beforePath,
|
|
||||||
const StorePath & afterPath,
|
|
||||||
std::string_view indent);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,7 @@ headers = [config_h] + files(
|
||||||
headers += files('nix_api_expr_internal.h')
|
headers += files('nix_api_expr_internal.h')
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('build-utils-meson/export-all-symbols')
|
||||||
|
subdir('build-utils-meson/windows-version')
|
||||||
|
|
||||||
this_library = library(
|
this_library = library(
|
||||||
'nixexprc',
|
'nixexprc',
|
||||||
|
|
|
@ -56,6 +56,7 @@ headers = files(
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('build-utils-meson/export-all-symbols')
|
||||||
|
subdir('build-utils-meson/windows-version')
|
||||||
|
|
||||||
this_library = library(
|
this_library = library(
|
||||||
'nix-expr-test-support',
|
'nix-expr-test-support',
|
||||||
|
|
|
@ -28,6 +28,7 @@ subdir('build-utils-meson/subprojects')
|
||||||
subdir('build-utils-meson/threads')
|
subdir('build-utils-meson/threads')
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('build-utils-meson/export-all-symbols')
|
||||||
|
subdir('build-utils-meson/windows-version')
|
||||||
|
|
||||||
rapidcheck = dependency('rapidcheck')
|
rapidcheck = dependency('rapidcheck')
|
||||||
deps_private += rapidcheck
|
deps_private += rapidcheck
|
||||||
|
|
|
@ -2834,7 +2834,9 @@ void EvalState::printStatistics()
|
||||||
#endif
|
#endif
|
||||||
#if HAVE_BOEHMGC
|
#if HAVE_BOEHMGC
|
||||||
{GC_is_incremental_mode() ? "gcNonIncremental" : "gc", gcFullOnlyTime},
|
{GC_is_incremental_mode() ? "gcNonIncremental" : "gc", gcFullOnlyTime},
|
||||||
|
#ifndef _WIN32 // TODO implement
|
||||||
{GC_is_incremental_mode() ? "gcNonIncrementalFraction" : "gcFraction", gcFullOnlyTime / cpuTime},
|
{GC_is_incremental_mode() ? "gcNonIncrementalFraction" : "gcFraction", gcFullOnlyTime / cpuTime},
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
topObj["envs"] = {
|
topObj["envs"] = {
|
||||||
|
|
|
@ -27,6 +27,7 @@ subdir('build-utils-meson/subprojects')
|
||||||
subdir('build-utils-meson/threads')
|
subdir('build-utils-meson/threads')
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('build-utils-meson/export-all-symbols')
|
||||||
|
subdir('build-utils-meson/windows-version')
|
||||||
|
|
||||||
rapidcheck = dependency('rapidcheck')
|
rapidcheck = dependency('rapidcheck')
|
||||||
deps_private += rapidcheck
|
deps_private += rapidcheck
|
||||||
|
|
|
@ -217,8 +217,12 @@ static void initRepoAtomically(std::filesystem::path &path, bool bare) {
|
||||||
try {
|
try {
|
||||||
std::filesystem::rename(tmpDir, path);
|
std::filesystem::rename(tmpDir, path);
|
||||||
} catch (std::filesystem::filesystem_error & e) {
|
} catch (std::filesystem::filesystem_error & e) {
|
||||||
if (e.code() == std::errc::file_exists) // Someone might race us to create the repository.
|
// Someone may race us to create the repository.
|
||||||
|
if (e.code() == std::errc::file_exists
|
||||||
|
// `path` may be attempted to be deleted by s::f::rename, in which case the code is:
|
||||||
|
|| e.code() == std::errc::directory_not_empty) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
throw SysError("moving temporary git repository from %s to %s", tmpDir, path);
|
throw SysError("moving temporary git repository from %s to %s", tmpDir, path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ subdir('build-utils-meson/subprojects')
|
||||||
subdir('build-utils-meson/threads')
|
subdir('build-utils-meson/threads')
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('build-utils-meson/export-all-symbols')
|
||||||
|
subdir('build-utils-meson/windows-version')
|
||||||
|
|
||||||
rapidcheck = dependency('rapidcheck')
|
rapidcheck = dependency('rapidcheck')
|
||||||
deps_private += rapidcheck
|
deps_private += rapidcheck
|
||||||
|
|
|
@ -68,6 +68,7 @@ headers = [config_h] + files(
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('build-utils-meson/export-all-symbols')
|
||||||
|
subdir('build-utils-meson/windows-version')
|
||||||
|
|
||||||
this_library = library(
|
this_library = library(
|
||||||
'nixmainc',
|
'nixmainc',
|
||||||
|
|
|
@ -543,7 +543,7 @@ public:
|
||||||
auto state(state_.lock());
|
auto state(state_.lock());
|
||||||
if (!state->active) return {};
|
if (!state->active) return {};
|
||||||
std::cerr << fmt("\r\e[K%s ", msg);
|
std::cerr << fmt("\r\e[K%s ", msg);
|
||||||
auto s = trim(readLine(STDIN_FILENO));
|
auto s = trim(readLine(getStandardInput(), true));
|
||||||
if (s.size() != 1) return {};
|
if (s.size() != 1) return {};
|
||||||
draw(*state);
|
draw(*state);
|
||||||
return s[0];
|
return s[0];
|
||||||
|
|
|
@ -67,6 +67,7 @@ headers = [config_h] + files(
|
||||||
headers += files('nix_api_store_internal.h')
|
headers += files('nix_api_store_internal.h')
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('build-utils-meson/export-all-symbols')
|
||||||
|
subdir('build-utils-meson/windows-version')
|
||||||
|
|
||||||
this_library = library(
|
this_library = library(
|
||||||
'nixstorec',
|
'nixstorec',
|
||||||
|
|
|
@ -58,6 +58,7 @@ headers = files(
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('build-utils-meson/export-all-symbols')
|
||||||
|
subdir('build-utils-meson/windows-version')
|
||||||
|
|
||||||
this_library = library(
|
this_library = library(
|
||||||
'nix-store-test-support',
|
'nix-store-test-support',
|
||||||
|
|
|
@ -28,6 +28,7 @@ subdir('build-utils-meson/subprojects')
|
||||||
subdir('build-utils-meson/threads')
|
subdir('build-utils-meson/threads')
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('build-utils-meson/export-all-symbols')
|
||||||
|
subdir('build-utils-meson/windows-version')
|
||||||
|
|
||||||
sqlite = dependency('sqlite3', 'sqlite', version : '>=3.6.19')
|
sqlite = dependency('sqlite3', 'sqlite', version : '>=3.6.19')
|
||||||
deps_private += sqlite
|
deps_private += sqlite
|
||||||
|
|
|
@ -38,15 +38,19 @@ mkMesonExecutable (finalAttrs: {
|
||||||
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
||||||
];
|
];
|
||||||
|
|
||||||
buildInputs = [
|
# Hack for sake of the dev shell
|
||||||
nix-store
|
passthru.externalBuildInputs = [
|
||||||
nix-store-c
|
|
||||||
nix-store-test-support
|
|
||||||
sqlite
|
sqlite
|
||||||
rapidcheck
|
rapidcheck
|
||||||
gtest
|
gtest
|
||||||
];
|
];
|
||||||
|
|
||||||
|
buildInputs = finalAttrs.passthru.externalBuildInputs ++ [
|
||||||
|
nix-store
|
||||||
|
nix-store-c
|
||||||
|
nix-store-test-support
|
||||||
|
];
|
||||||
|
|
||||||
preConfigure =
|
preConfigure =
|
||||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||||
# Do the meson utils, without modification.
|
# Do the meson utils, without modification.
|
||||||
|
|
|
@ -459,21 +459,14 @@ TEST_F(ServeProtoTest, handshake_client_truncated_replay_throws)
|
||||||
CharacterizationTest::readTest("handshake-to-client", [&](std::string toClientLog) {
|
CharacterizationTest::readTest("handshake-to-client", [&](std::string toClientLog) {
|
||||||
for (size_t len = 0; len < toClientLog.size(); ++len) {
|
for (size_t len = 0; len < toClientLog.size(); ++len) {
|
||||||
NullBufferedSink nullSink;
|
NullBufferedSink nullSink;
|
||||||
StringSource in {
|
auto substring = toClientLog.substr(0, len);
|
||||||
// truncate
|
StringSource in{substring};
|
||||||
toClientLog.substr(0, len)
|
|
||||||
};
|
|
||||||
if (len < 8) {
|
if (len < 8) {
|
||||||
EXPECT_THROW(
|
EXPECT_THROW(
|
||||||
ServeProto::BasicClientConnection::handshake(
|
ServeProto::BasicClientConnection::handshake(nullSink, in, defaultVersion, "blah"), EndOfFile);
|
||||||
nullSink, in, defaultVersion, "blah"),
|
|
||||||
EndOfFile);
|
|
||||||
} else {
|
} else {
|
||||||
// Not sure why cannot keep on checking for `EndOfFile`.
|
// Not sure why cannot keep on checking for `EndOfFile`.
|
||||||
EXPECT_THROW(
|
EXPECT_THROW(ServeProto::BasicClientConnection::handshake(nullSink, in, defaultVersion, "blah"), Error);
|
||||||
ServeProto::BasicClientConnection::handshake(
|
|
||||||
nullSink, in, defaultVersion, "blah"),
|
|
||||||
Error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -725,21 +725,14 @@ TEST_F(WorkerProtoTest, handshake_client_truncated_replay_throws)
|
||||||
CharacterizationTest::readTest("handshake-to-client", [&](std::string toClientLog) {
|
CharacterizationTest::readTest("handshake-to-client", [&](std::string toClientLog) {
|
||||||
for (size_t len = 0; len < toClientLog.size(); ++len) {
|
for (size_t len = 0; len < toClientLog.size(); ++len) {
|
||||||
NullBufferedSink nullSink;
|
NullBufferedSink nullSink;
|
||||||
StringSource in {
|
auto substring = toClientLog.substr(0, len);
|
||||||
// truncate
|
StringSource in{substring};
|
||||||
toClientLog.substr(0, len)
|
|
||||||
};
|
|
||||||
if (len < 8) {
|
if (len < 8) {
|
||||||
EXPECT_THROW(
|
EXPECT_THROW(
|
||||||
WorkerProto::BasicClientConnection::handshake(
|
WorkerProto::BasicClientConnection::handshake(nullSink, in, defaultVersion, {}), EndOfFile);
|
||||||
nullSink, in, defaultVersion, {}),
|
|
||||||
EndOfFile);
|
|
||||||
} else {
|
} else {
|
||||||
// Not sure why cannot keep on checking for `EndOfFile`.
|
// Not sure why cannot keep on checking for `EndOfFile`.
|
||||||
EXPECT_THROW(
|
EXPECT_THROW(WorkerProto::BasicClientConnection::handshake(nullSink, in, defaultVersion, {}), Error);
|
||||||
WorkerProto::BasicClientConnection::handshake(
|
|
||||||
nullSink, in, defaultVersion, {}),
|
|
||||||
Error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -34,6 +34,8 @@ subdir('build-utils-meson/subprojects')
|
||||||
run_command('ln', '-s',
|
run_command('ln', '-s',
|
||||||
meson.project_build_root() / '__nothing_link_target',
|
meson.project_build_root() / '__nothing_link_target',
|
||||||
meson.project_build_root() / '__nothing_symlink',
|
meson.project_build_root() / '__nothing_symlink',
|
||||||
|
# native doesn't allow dangling symlinks, which the tests require
|
||||||
|
env : { 'MSYS' : 'winsymlinks:lnk' },
|
||||||
check : true,
|
check : true,
|
||||||
)
|
)
|
||||||
can_link_symlink = run_command('ln',
|
can_link_symlink = run_command('ln',
|
||||||
|
@ -74,6 +76,12 @@ if host_machine.system() == 'darwin'
|
||||||
deps_other += [sandbox]
|
deps_other += [sandbox]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if host_machine.system() == 'windows'
|
||||||
|
wsock32 = cxx.find_library('wsock32')
|
||||||
|
deps_other += [wsock32]
|
||||||
|
endif
|
||||||
|
|
||||||
|
subdir('build-utils-meson/libatomic')
|
||||||
subdir('build-utils-meson/threads')
|
subdir('build-utils-meson/threads')
|
||||||
|
|
||||||
boost = dependency(
|
boost = dependency(
|
||||||
|
@ -410,6 +418,7 @@ foreach name, value : cpp_str_defines
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('build-utils-meson/export-all-symbols')
|
||||||
|
subdir('build-utils-meson/windows-version')
|
||||||
|
|
||||||
this_library = library(
|
this_library = library(
|
||||||
'nixstore',
|
'nixstore',
|
||||||
|
|
|
@ -63,6 +63,7 @@ headers = [config_h] + files(
|
||||||
headers += files('nix_api_util_internal.h')
|
headers += files('nix_api_util_internal.h')
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('build-utils-meson/export-all-symbols')
|
||||||
|
subdir('build-utils-meson/windows-version')
|
||||||
|
|
||||||
this_library = library(
|
this_library = library(
|
||||||
'nixutilc',
|
'nixutilc',
|
||||||
|
|
|
@ -53,6 +53,7 @@ headers = files(
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('build-utils-meson/export-all-symbols')
|
||||||
|
subdir('build-utils-meson/windows-version')
|
||||||
|
|
||||||
this_library = library(
|
this_library = library(
|
||||||
'nix-util-test-support',
|
'nix-util-test-support',
|
||||||
|
|
|
@ -28,6 +28,7 @@ subdir('build-utils-meson/subprojects')
|
||||||
subdir('build-utils-meson/threads')
|
subdir('build-utils-meson/threads')
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('build-utils-meson/export-all-symbols')
|
||||||
|
subdir('build-utils-meson/windows-version')
|
||||||
|
|
||||||
rapidcheck = dependency('rapidcheck')
|
rapidcheck = dependency('rapidcheck')
|
||||||
deps_private += rapidcheck
|
deps_private += rapidcheck
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace nixC {
|
namespace nixC {
|
||||||
|
|
||||||
TEST_F(nix_api_util_context, nix_context_error)
|
TEST_F(nix_api_util_context, nix_context_error)
|
||||||
|
@ -57,6 +59,14 @@ struct MySettings : nix::Config
|
||||||
MySettings mySettings;
|
MySettings mySettings;
|
||||||
static nix::GlobalConfig::Register rs(&mySettings);
|
static nix::GlobalConfig::Register rs(&mySettings);
|
||||||
|
|
||||||
|
static auto createOwnedNixContext()
|
||||||
|
{
|
||||||
|
return std::unique_ptr<nix_c_context, decltype([](nix_c_context * ctx) {
|
||||||
|
if (ctx)
|
||||||
|
nix_c_context_free(ctx);
|
||||||
|
})>(nix_c_context_create(), {});
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(nix_api_util_context, nix_setting_get)
|
TEST_F(nix_api_util_context, nix_setting_get)
|
||||||
{
|
{
|
||||||
ASSERT_EQ(ctx->last_err_code, NIX_OK);
|
ASSERT_EQ(ctx->last_err_code, NIX_OK);
|
||||||
|
@ -97,7 +107,8 @@ TEST_F(nix_api_util_context, nix_err_msg)
|
||||||
|
|
||||||
// advanced usage
|
// advanced usage
|
||||||
unsigned int sz;
|
unsigned int sz;
|
||||||
err_msg = nix_err_msg(nix_c_context_create(), ctx, &sz);
|
auto new_ctx = createOwnedNixContext();
|
||||||
|
err_msg = nix_err_msg(new_ctx.get(), ctx, &sz);
|
||||||
ASSERT_EQ(sz, err_msg.size());
|
ASSERT_EQ(sz, err_msg.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +124,8 @@ TEST_F(nix_api_util_context, nix_err_info_msg)
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
nix_context_error(ctx);
|
nix_context_error(ctx);
|
||||||
}
|
}
|
||||||
nix_err_info_msg(nix_c_context_create(), ctx, OBSERVE_STRING(err_info));
|
auto new_ctx = createOwnedNixContext();
|
||||||
|
nix_err_info_msg(new_ctx.get(), ctx, OBSERVE_STRING(err_info));
|
||||||
ASSERT_STREQ("testing error", err_info.c_str());
|
ASSERT_STREQ("testing error", err_info.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +142,8 @@ TEST_F(nix_api_util_context, nix_err_name)
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
nix_context_error(ctx);
|
nix_context_error(ctx);
|
||||||
}
|
}
|
||||||
nix_err_name(nix_c_context_create(), ctx, OBSERVE_STRING(err_name));
|
auto new_ctx = createOwnedNixContext();
|
||||||
|
nix_err_name(new_ctx.get(), ctx, OBSERVE_STRING(err_name));
|
||||||
ASSERT_EQ(std::string(err_name), "nix::Error");
|
ASSERT_EQ(std::string(err_name), "nix::Error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
static constexpr auto environmentVariablesCategory = "Options that change environment variables";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return an environment variable.
|
* @return an environment variable.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -77,8 +77,13 @@ void writeFull(Descriptor fd, std::string_view s, bool allowInterrupts = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a line from a file descriptor.
|
* Read a line from a file descriptor.
|
||||||
|
*
|
||||||
|
* @param fd The file descriptor to read from
|
||||||
|
* @param eofOk If true, return an unterminated line if EOF is reached. (e.g. the empty string)
|
||||||
|
*
|
||||||
|
* @return A line of text ending in `\n`, or a string without `\n` if `eofOk` is true and EOF is reached.
|
||||||
*/
|
*/
|
||||||
std::string readLine(Descriptor fd);
|
std::string readLine(Descriptor fd, bool eofOk = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a line to a file descriptor.
|
* Write a line to a file descriptor.
|
||||||
|
@ -101,8 +106,25 @@ void drainFD(
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get [Standard Input](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_(stdin))
|
||||||
|
*/
|
||||||
[[gnu::always_inline]]
|
[[gnu::always_inline]]
|
||||||
inline Descriptor getStandardOut() {
|
inline Descriptor getStandardInput()
|
||||||
|
{
|
||||||
|
#ifndef _WIN32
|
||||||
|
return STDIN_FILENO;
|
||||||
|
#else
|
||||||
|
return GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get [Standard Output](https://en.wikipedia.org/wiki/Standard_streams#Standard_output_(stdout))
|
||||||
|
*/
|
||||||
|
[[gnu::always_inline]]
|
||||||
|
inline Descriptor getStandardOutput()
|
||||||
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
return STDOUT_FILENO;
|
return STDOUT_FILENO;
|
||||||
#else
|
#else
|
||||||
|
@ -110,6 +132,19 @@ inline Descriptor getStandardOut() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get [Standard Error](https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr))
|
||||||
|
*/
|
||||||
|
[[gnu::always_inline]]
|
||||||
|
inline Descriptor getStandardError()
|
||||||
|
{
|
||||||
|
#ifndef _WIN32
|
||||||
|
return STDERR_FILENO;
|
||||||
|
#else
|
||||||
|
return GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatic cleanup of resources.
|
* Automatic cleanup of resources.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -38,7 +38,7 @@ void Logger::warn(const std::string & msg)
|
||||||
|
|
||||||
void Logger::writeToStdout(std::string_view s)
|
void Logger::writeToStdout(std::string_view s)
|
||||||
{
|
{
|
||||||
Descriptor standard_out = getStandardOut();
|
Descriptor standard_out = getStandardOutput();
|
||||||
writeFull(standard_out, s);
|
writeFull(standard_out, s);
|
||||||
writeFull(standard_out, "\n");
|
writeFull(standard_out, "\n");
|
||||||
}
|
}
|
||||||
|
@ -118,11 +118,7 @@ void writeToStderr(std::string_view s)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
writeFull(
|
writeFull(
|
||||||
#ifdef _WIN32
|
getStandardError(),
|
||||||
GetStdHandle(STD_ERROR_HANDLE),
|
|
||||||
#else
|
|
||||||
STDERR_FILENO,
|
|
||||||
#endif
|
|
||||||
s, false);
|
s, false);
|
||||||
} catch (SystemError & e) {
|
} catch (SystemError & e) {
|
||||||
/* Ignore failing writes to stderr. We need to ignore write
|
/* Ignore failing writes to stderr. We need to ignore write
|
||||||
|
|
|
@ -53,16 +53,9 @@ endforeach
|
||||||
|
|
||||||
configdata.set('HAVE_DECL_AT_SYMLINK_NOFOLLOW', cxx.has_header_symbol('fcntl.h', 'AT_SYMLINK_NOFOLLOW').to_int())
|
configdata.set('HAVE_DECL_AT_SYMLINK_NOFOLLOW', cxx.has_header_symbol('fcntl.h', 'AT_SYMLINK_NOFOLLOW').to_int())
|
||||||
|
|
||||||
|
subdir('build-utils-meson/libatomic')
|
||||||
subdir('build-utils-meson/threads')
|
subdir('build-utils-meson/threads')
|
||||||
|
|
||||||
# Check if -latomic is needed
|
|
||||||
# This is needed for std::atomic on some platforms
|
|
||||||
# We did not manage to test this reliably on all platforms, so we hardcode
|
|
||||||
# it for now.
|
|
||||||
if host_machine.cpu_family() == 'arm'
|
|
||||||
deps_other += cxx.find_library('atomic')
|
|
||||||
endif
|
|
||||||
|
|
||||||
if host_machine.system() == 'windows'
|
if host_machine.system() == 'windows'
|
||||||
socket = cxx.find_library('ws2_32')
|
socket = cxx.find_library('ws2_32')
|
||||||
deps_other += socket
|
deps_other += socket
|
||||||
|
@ -265,6 +258,7 @@ else
|
||||||
endif
|
endif
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('build-utils-meson/export-all-symbols')
|
||||||
|
subdir('build-utils-meson/windows-version')
|
||||||
|
|
||||||
this_library = library(
|
this_library = library(
|
||||||
'nixutil',
|
'nixutil',
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
PosixSourceAccessor::PosixSourceAccessor(std::filesystem::path && root)
|
PosixSourceAccessor::PosixSourceAccessor(std::filesystem::path && argRoot)
|
||||||
: root(std::move(root))
|
: root(std::move(argRoot))
|
||||||
{
|
{
|
||||||
assert(root.empty() || root.is_absolute());
|
assert(root.empty() || root.is_absolute());
|
||||||
displayPrefix = root.string();
|
displayPrefix = root.string();
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
///@file
|
///@file
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
@ -202,7 +203,14 @@ struct StringSource : Source
|
||||||
{
|
{
|
||||||
std::string_view s;
|
std::string_view s;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
|
|
||||||
|
// NOTE: Prevent unintentional dangling views when an implicit conversion
|
||||||
|
// from std::string -> std::string_view occurs when the string is passed
|
||||||
|
// by rvalue.
|
||||||
|
StringSource(std::string &&) = delete;
|
||||||
StringSource(std::string_view s) : s(s), pos(0) { }
|
StringSource(std::string_view s) : s(s), pos(0) { }
|
||||||
|
StringSource(const std::string& str): StringSource(std::string_view(str)) {}
|
||||||
|
|
||||||
size_t read(char * data, size_t len) override;
|
size_t read(char * data, size_t len) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ void writeFull(int fd, std::string_view s, bool allowInterrupts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string readLine(int fd)
|
std::string readLine(int fd, bool eofOk)
|
||||||
{
|
{
|
||||||
std::string s;
|
std::string s;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -58,8 +58,12 @@ std::string readLine(int fd)
|
||||||
if (rd == -1) {
|
if (rd == -1) {
|
||||||
if (errno != EINTR)
|
if (errno != EINTR)
|
||||||
throw SysError("reading a line");
|
throw SysError("reading a line");
|
||||||
} else if (rd == 0)
|
} else if (rd == 0) {
|
||||||
throw EndOfFile("unexpected EOF reading a line");
|
if (eofOk)
|
||||||
|
return s;
|
||||||
|
else
|
||||||
|
throw EndOfFile("unexpected EOF reading a line");
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (ch == '\n') return s;
|
if (ch == '\n') return s;
|
||||||
s += ch;
|
s += ch;
|
||||||
|
|
|
@ -61,7 +61,7 @@ void writeFull(HANDLE handle, std::string_view s, bool allowInterrupts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string readLine(HANDLE handle)
|
std::string readLine(HANDLE handle, bool eofOk)
|
||||||
{
|
{
|
||||||
std::string s;
|
std::string s;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -71,8 +71,12 @@ std::string readLine(HANDLE handle)
|
||||||
DWORD rd;
|
DWORD rd;
|
||||||
if (!ReadFile(handle, &ch, 1, &rd, NULL)) {
|
if (!ReadFile(handle, &ch, 1, &rd, NULL)) {
|
||||||
throw WinError("reading a line");
|
throw WinError("reading a line");
|
||||||
} else if (rd == 0)
|
} else if (rd == 0) {
|
||||||
throw EndOfFile("unexpected EOF reading a line");
|
if (eofOk)
|
||||||
|
return s;
|
||||||
|
else
|
||||||
|
throw EndOfFile("unexpected EOF reading a line");
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (ch == '\n') return s;
|
if (ch == '\n') return s;
|
||||||
s += ch;
|
s += ch;
|
||||||
|
|
|
@ -536,7 +536,7 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
env["__ETC_PROFILE_SOURCED"] = "1";
|
env["__ETC_PROFILE_SOURCED"] = "1";
|
||||||
}
|
}
|
||||||
|
|
||||||
env["NIX_BUILD_TOP"] = env["TMPDIR"] = env["TEMPDIR"] = env["TMP"] = env["TEMP"] = tmpDir.path();
|
env["NIX_BUILD_TOP"] = env["TMPDIR"] = env["TEMPDIR"] = env["TMP"] = env["TEMP"] = tmpDir.path().string();
|
||||||
env["NIX_STORE"] = store->storeDir;
|
env["NIX_STORE"] = store->storeDir;
|
||||||
env["NIX_BUILD_CORES"] = std::to_string(settings.buildCores);
|
env["NIX_BUILD_CORES"] = std::to_string(settings.buildCores);
|
||||||
|
|
||||||
|
|
|
@ -694,7 +694,7 @@ static void opDump(Strings opFlags, Strings opArgs)
|
||||||
if (!opFlags.empty()) throw UsageError("unknown flag");
|
if (!opFlags.empty()) throw UsageError("unknown flag");
|
||||||
if (opArgs.size() != 1) throw UsageError("only one argument allowed");
|
if (opArgs.size() != 1) throw UsageError("only one argument allowed");
|
||||||
|
|
||||||
FdSink sink(getStandardOut());
|
FdSink sink(getStandardOutput());
|
||||||
std::string path = *opArgs.begin();
|
std::string path = *opArgs.begin();
|
||||||
dumpPath(path, sink);
|
dumpPath(path, sink);
|
||||||
sink.flush();
|
sink.flush();
|
||||||
|
@ -722,7 +722,7 @@ static void opExport(Strings opFlags, Strings opArgs)
|
||||||
for (auto & i : opArgs)
|
for (auto & i : opArgs)
|
||||||
paths.insert(store->followLinksToStorePath(i));
|
paths.insert(store->followLinksToStorePath(i));
|
||||||
|
|
||||||
FdSink sink(getStandardOut());
|
FdSink sink(getStandardOutput());
|
||||||
store->exportPaths(paths, sink);
|
store->exportPaths(paths, sink);
|
||||||
sink.flush();
|
sink.flush();
|
||||||
}
|
}
|
||||||
|
@ -835,7 +835,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
||||||
|
|
||||||
FdSource in(STDIN_FILENO);
|
FdSource in(STDIN_FILENO);
|
||||||
FdSink out(getStandardOut());
|
FdSink out(getStandardOutput());
|
||||||
|
|
||||||
/* Exchange the greeting. */
|
/* Exchange the greeting. */
|
||||||
ServeProto::Version clientVersion =
|
ServeProto::Version clientVersion =
|
||||||
|
|
|
@ -16,7 +16,7 @@ struct MixCat : virtual Args
|
||||||
throw Error("path '%1%' is not a regular file", path);
|
throw Error("path '%1%' is not a regular file", path);
|
||||||
stopProgressBar();
|
stopProgressBar();
|
||||||
|
|
||||||
writeFull(getStandardOut(), accessor->readFile(CanonPath(path)));
|
writeFull(getStandardOutput(), accessor->readFile(CanonPath(path)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ struct CmdDumpPath : StorePathCommand
|
||||||
|
|
||||||
void run(ref<Store> store, const StorePath & storePath) override
|
void run(ref<Store> store, const StorePath & storePath) override
|
||||||
{
|
{
|
||||||
FdSink sink(getStandardOut());
|
FdSink sink(getStandardOutput());
|
||||||
store->narFromPath(storePath, sink);
|
store->narFromPath(storePath, sink);
|
||||||
sink.flush();
|
sink.flush();
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ struct CmdDumpPath2 : Command
|
||||||
|
|
||||||
void run() override
|
void run() override
|
||||||
{
|
{
|
||||||
FdSink sink(getStandardOut());
|
FdSink sink(getStandardOutput());
|
||||||
dumpPath(path, sink);
|
dumpPath(path, sink);
|
||||||
sink.flush();
|
sink.flush();
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ struct CmdEval : MixJSON, InstallableValueCommand, MixReadOnlyOption
|
||||||
|
|
||||||
else if (raw) {
|
else if (raw) {
|
||||||
stopProgressBar();
|
stopProgressBar();
|
||||||
writeFull(getStandardOut(), *state->coerceToString(noPos, *v, context, "while generating the eval command output"));
|
writeFull(getStandardOutput(), *state->coerceToString(noPos, *v, context, "while generating the eval command output"));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (json) {
|
else if (json) {
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "eval-cache.hh"
|
#include "eval-cache.hh"
|
||||||
#include "markdown.hh"
|
#include "markdown.hh"
|
||||||
#include "users.hh"
|
#include "users.hh"
|
||||||
#include "terminal.hh"
|
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
@ -1275,97 +1274,25 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
auto showDerivation = [&]()
|
auto showDerivation = [&]()
|
||||||
{
|
{
|
||||||
auto name = visitor.getAttr(state->sName)->getString();
|
auto name = visitor.getAttr(state->sName)->getString();
|
||||||
std::optional<std::string> description;
|
|
||||||
if (auto aMeta = visitor.maybeGetAttr(state->sMeta)) {
|
|
||||||
if (auto aDescription = aMeta->maybeGetAttr(state->sDescription))
|
|
||||||
description = aDescription->getString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
|
std::optional<std::string> description;
|
||||||
|
if (auto aMeta = visitor.maybeGetAttr(state->sMeta)) {
|
||||||
|
if (auto aDescription = aMeta->maybeGetAttr(state->sDescription))
|
||||||
|
description = aDescription->getString();
|
||||||
|
}
|
||||||
j.emplace("type", "derivation");
|
j.emplace("type", "derivation");
|
||||||
j.emplace("name", name);
|
j.emplace("name", name);
|
||||||
j.emplace("description", description ? *description : "");
|
j.emplace("description", description ? *description : "");
|
||||||
} else {
|
} else {
|
||||||
auto type =
|
logger->cout("%s: %s '%s'",
|
||||||
|
headerPrefix,
|
||||||
attrPath.size() == 2 && attrPathS[0] == "devShell" ? "development environment" :
|
attrPath.size() == 2 && attrPathS[0] == "devShell" ? "development environment" :
|
||||||
attrPath.size() >= 2 && attrPathS[0] == "devShells" ? "development environment" :
|
attrPath.size() >= 2 && attrPathS[0] == "devShells" ? "development environment" :
|
||||||
attrPath.size() == 3 && attrPathS[0] == "checks" ? "derivation" :
|
attrPath.size() == 3 && attrPathS[0] == "checks" ? "derivation" :
|
||||||
attrPath.size() >= 1 && attrPathS[0] == "hydraJobs" ? "derivation" :
|
attrPath.size() >= 1 && attrPathS[0] == "hydraJobs" ? "derivation" :
|
||||||
"package";
|
"package",
|
||||||
if (description && !description->empty()) {
|
name);
|
||||||
|
|
||||||
// Takes a string and returns the # of characters displayed
|
|
||||||
auto columnLengthOfString = [](std::string_view s) -> unsigned int {
|
|
||||||
unsigned int columnCount = 0;
|
|
||||||
for (auto i = s.begin(); i < s.end();) {
|
|
||||||
// Test first character to determine if it is one of
|
|
||||||
// treeConn, treeLast, treeLine
|
|
||||||
if (*i == -30) {
|
|
||||||
i += 3;
|
|
||||||
++columnCount;
|
|
||||||
}
|
|
||||||
// Escape sequences
|
|
||||||
// https://en.wikipedia.org/wiki/ANSI_escape_code
|
|
||||||
else if (*i == '\e') {
|
|
||||||
// Eat '['
|
|
||||||
if (*(++i) == '[') {
|
|
||||||
++i;
|
|
||||||
// Eat parameter bytes
|
|
||||||
while(*i >= 0x30 && *i <= 0x3f) ++i;
|
|
||||||
|
|
||||||
// Eat intermediate bytes
|
|
||||||
while(*i >= 0x20 && *i <= 0x2f) ++i;
|
|
||||||
|
|
||||||
// Eat final byte
|
|
||||||
if(*i >= 0x40 && *i <= 0x73) ++i;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Eat Fe Escape sequence
|
|
||||||
if (*i >= 0x40 && *i <= 0x5f) ++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
++i;
|
|
||||||
++columnCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return columnCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Maximum length to print
|
|
||||||
size_t maxLength = getWindowSize().second > 0 ? getWindowSize().second : 80;
|
|
||||||
|
|
||||||
// Trim the description and only use the first line
|
|
||||||
auto trimmed = trim(*description);
|
|
||||||
auto newLinePos = trimmed.find('\n');
|
|
||||||
auto length = newLinePos != std::string::npos ? newLinePos : trimmed.length();
|
|
||||||
|
|
||||||
auto beginningOfLine = fmt("%s: %s '%s'", headerPrefix, type, name);
|
|
||||||
auto line = fmt("%s: %s '%s' - '%s'", headerPrefix, type, name, trimmed.substr(0, length));
|
|
||||||
|
|
||||||
// If we are already over the maximum length then do not trim
|
|
||||||
// and don't print the description (preserves existing behavior)
|
|
||||||
if (columnLengthOfString(beginningOfLine) >= maxLength) {
|
|
||||||
logger->cout("%s", beginningOfLine);
|
|
||||||
}
|
|
||||||
// If the entire line fits then print that
|
|
||||||
else if (columnLengthOfString(line) < maxLength) {
|
|
||||||
logger->cout("%s", line);
|
|
||||||
}
|
|
||||||
// Otherwise we need to truncate
|
|
||||||
else {
|
|
||||||
auto lineLength = columnLengthOfString(line);
|
|
||||||
auto chopOff = lineLength - maxLength;
|
|
||||||
line.resize(line.length() - chopOff);
|
|
||||||
line = line.replace(line.length() - 3, 3, "...");
|
|
||||||
|
|
||||||
logger->cout("%s", line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
logger->cout("%s: %s '%s'", headerPrefix, type, name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ struct CmdLog : InstallableCommand
|
||||||
if (!log) continue;
|
if (!log) continue;
|
||||||
stopProgressBar();
|
stopProgressBar();
|
||||||
printInfo("got build log for '%s' from '%s'", installable->what(), logSub.getUri());
|
printInfo("got build log for '%s' from '%s'", installable->what(), logSub.getUri());
|
||||||
writeFull(getStandardOut(), *log);
|
writeFull(getStandardOutput(), *log);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ subdir('build-utils-meson/subprojects')
|
||||||
subdir('build-utils-meson/threads')
|
subdir('build-utils-meson/threads')
|
||||||
|
|
||||||
subdir('build-utils-meson/export-all-symbols')
|
subdir('build-utils-meson/export-all-symbols')
|
||||||
|
subdir('build-utils-meson/windows-version')
|
||||||
|
|
||||||
configdata = configuration_data()
|
configdata = configuration_data()
|
||||||
|
|
||||||
|
@ -229,6 +230,8 @@ foreach linkname : nix_symlinks
|
||||||
t = custom_target(
|
t = custom_target(
|
||||||
command: ['ln', '-sf', fs.name(this_exe), '@OUTPUT@'],
|
command: ['ln', '-sf', fs.name(this_exe), '@OUTPUT@'],
|
||||||
output: linkname + executable_suffix,
|
output: linkname + executable_suffix,
|
||||||
|
# native doesn't allow dangling symlinks, but the target executable often doesn't exist at this time
|
||||||
|
env : { 'MSYS' : 'winsymlinks:lnk' },
|
||||||
# TODO(Ericson2314): Don't do this once we have the `meson.override_find_program` working)
|
# TODO(Ericson2314): Don't do this once we have the `meson.override_find_program` working)
|
||||||
build_by_default: true
|
build_by_default: true
|
||||||
)
|
)
|
||||||
|
@ -247,6 +250,8 @@ install_symlink(
|
||||||
custom_target(
|
custom_target(
|
||||||
command: ['ln', '-sf', fs.name(this_exe), '@OUTPUT@'],
|
command: ['ln', '-sf', fs.name(this_exe), '@OUTPUT@'],
|
||||||
output: 'build-remote' + executable_suffix,
|
output: 'build-remote' + executable_suffix,
|
||||||
|
# native doesn't allow dangling symlinks, but the target executable often doesn't exist at this time
|
||||||
|
env : { 'MSYS' : 'winsymlinks:lnk' },
|
||||||
# TODO(Ericson2314): Don't do this once we have the `meson.override_find_program` working)
|
# TODO(Ericson2314): Don't do this once we have the `meson.override_find_program` working)
|
||||||
build_by_default: true
|
build_by_default: true
|
||||||
)
|
)
|
||||||
|
|
|
@ -177,7 +177,7 @@ struct CmdKeyGenerateSecret : Command
|
||||||
throw UsageError("required argument '--key-name' is missing");
|
throw UsageError("required argument '--key-name' is missing");
|
||||||
|
|
||||||
stopProgressBar();
|
stopProgressBar();
|
||||||
writeFull(getStandardOut(), SecretKey::generate(*keyName).to_string());
|
writeFull(getStandardOutput(), SecretKey::generate(*keyName).to_string());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ struct CmdKeyConvertSecretToPublic : Command
|
||||||
{
|
{
|
||||||
SecretKey secretKey(drainFD(STDIN_FILENO));
|
SecretKey secretKey(drainFD(STDIN_FILENO));
|
||||||
stopProgressBar();
|
stopProgressBar();
|
||||||
writeFull(getStandardOut(), secretKey.toPublicKey().to_string());
|
writeFull(getStandardOutput(), secretKey.toPublicKey().to_string());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -238,7 +238,7 @@ clearCache
|
||||||
# preserve quotes variables in the single-quoted string
|
# preserve quotes variables in the single-quoted string
|
||||||
# shellcheck disable=SC2016
|
# shellcheck disable=SC2016
|
||||||
outPath=$(nix-build --no-out-link -E '
|
outPath=$(nix-build --no-out-link -E '
|
||||||
with import ./config.nix;
|
with import '"${config_nix}"';
|
||||||
mkDerivation {
|
mkDerivation {
|
||||||
name = "nar-listing";
|
name = "nar-listing";
|
||||||
buildCommand = "mkdir $out; echo foo > $out/bar; ln -s xyzzy $out/link";
|
buildCommand = "mkdir $out; echo foo > $out/bar; ln -s xyzzy $out/link";
|
||||||
|
@ -258,7 +258,7 @@ clearCache
|
||||||
# preserve quotes variables in the single-quoted string
|
# preserve quotes variables in the single-quoted string
|
||||||
# shellcheck disable=SC2016
|
# shellcheck disable=SC2016
|
||||||
outPath=$(nix-build --no-out-link -E '
|
outPath=$(nix-build --no-out-link -E '
|
||||||
with import ./config.nix;
|
with import '"${config_nix}"';
|
||||||
mkDerivation {
|
mkDerivation {
|
||||||
name = "debug-info";
|
name = "debug-info";
|
||||||
buildCommand = "mkdir -p $out/lib/debug/.build-id/02; echo foo > $out/lib/debug/.build-id/02/623eda209c26a59b1a8638ff7752f6b945c26b.debug";
|
buildCommand = "mkdir -p $out/lib/debug/.build-id/02; echo foo > $out/lib/debug/.build-id/02/623eda209c26a59b1a8638ff7752f6b945c26b.debug";
|
||||||
|
@ -276,7 +276,7 @@ diff -u \
|
||||||
# preserve quotes variables in the single-quoted string
|
# preserve quotes variables in the single-quoted string
|
||||||
# shellcheck disable=SC2016
|
# shellcheck disable=SC2016
|
||||||
expr='
|
expr='
|
||||||
with import ./config.nix;
|
with import '"${config_nix}"';
|
||||||
mkDerivation {
|
mkDerivation {
|
||||||
name = "multi-output";
|
name = "multi-output";
|
||||||
buildCommand = "mkdir -p $out; echo foo > $doc; echo $doc > $out/docref";
|
buildCommand = "mkdir -p $out; echo foo > $doc; echo $doc > $out/docref";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{ busybox }:
|
{ busybox }:
|
||||||
|
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix";
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{ busybox, contentAddressed ? false }:
|
{ busybox, contentAddressed ? false }:
|
||||||
|
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix";
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/ca/config.nix";
|
||||||
|
|
||||||
let mkCADerivation = args: mkDerivation ({
|
let mkCADerivation = args: mkDerivation ({
|
||||||
__contentAddressed = true;
|
__contentAddressed = true;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
#
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
export NIX_TESTS_CA_BY_DEFAULT=1
|
export NIX_TESTS_CA_BY_DEFAULT=1
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
source ./common.sh
|
source common.sh
|
||||||
|
|
||||||
requireDaemonNewerThan "2.4pre20210625"
|
requireDaemonNewerThan "2.4pre20210625"
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
export NIX_TESTS_CA_BY_DEFAULT=1
|
export NIX_TESTS_CA_BY_DEFAULT=1
|
||||||
|
|
|
@ -29,5 +29,5 @@ suites += {
|
||||||
'substitute.sh',
|
'substitute.sh',
|
||||||
'why-depends.sh',
|
'why-depends.sh',
|
||||||
],
|
],
|
||||||
'workdir': meson.current_build_dir(),
|
'workdir': meson.current_source_dir(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
export NIX_TESTS_CA_BY_DEFAULT=1
|
export NIX_TESTS_CA_BY_DEFAULT=1
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
FLAKE_PATH=path:$PWD
|
flakeDir="$TEST_HOME/flake"
|
||||||
|
mkdir -p "${flakeDir}"
|
||||||
|
cp flake.nix "${_NIX_TEST_BUILD_DIR}/ca/config.nix" content-addressed.nix "${flakeDir}"
|
||||||
|
|
||||||
nix run --no-write-lock-file "$FLAKE_PATH#runnable"
|
# `config.nix` cannot be gotten via build dir / env var (runs afoul pure eval). Instead get from flake.
|
||||||
|
removeBuildDirRef "$flakeDir"/*.nix
|
||||||
|
|
||||||
|
nix run --no-write-lock-file "path:${flakeDir}#runnable"
|
||||||
|
|
|
@ -5,4 +5,3 @@ source common.sh
|
||||||
CONTENT_ADDRESSED=true
|
CONTENT_ADDRESSED=true
|
||||||
cd ..
|
cd ..
|
||||||
source ./nix-shell.sh
|
source ./nix-shell.sh
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/ca/config.nix";
|
||||||
|
|
||||||
let mkCADerivation = args: mkDerivation ({
|
let mkCADerivation = args: mkDerivation ({
|
||||||
__contentAddressed = true;
|
__contentAddressed = true;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# build it at once.
|
# build it at once.
|
||||||
|
|
||||||
|
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/ca/config.nix";
|
||||||
|
|
||||||
mkDerivation {
|
mkDerivation {
|
||||||
name = "simple";
|
name = "simple";
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
export NIX_TESTS_CA_BY_DEFAULT=1
|
export NIX_TESTS_CA_BY_DEFAULT=1
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
export NIX_TESTS_CA_BY_DEFAULT=1
|
export NIX_TESTS_CA_BY_DEFAULT=1
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix";
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix";
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
dep1 = mkDerivation {
|
dep1 = mkDerivation {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{checkBuildId ? 0}:
|
{checkBuildId ? 0}:
|
||||||
|
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix";
|
||||||
|
|
||||||
{
|
{
|
||||||
nondeterministic = mkDerivation {
|
nondeterministic = mkDerivation {
|
||||||
|
|
|
@ -37,7 +37,10 @@ if canUseSandbox; then
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cp simple.nix shell.nix simple.builder.sh config.nix "$flakeDir/"
|
cp simple.nix shell.nix simple.builder.sh "${config_nix}" "$flakeDir/"
|
||||||
|
|
||||||
|
# `config.nix` cannot be gotten via build dir / env var (runs afoul pure eval). Instead get from flake.
|
||||||
|
removeBuildDirRef "$flakeDir"/*.nix
|
||||||
|
|
||||||
TODO_NixOS
|
TODO_NixOS
|
||||||
|
|
||||||
|
|
|
@ -343,6 +343,15 @@ count() {
|
||||||
echo $#
|
echo $#
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Sometimes, e.g. due to pure eval, restricted eval, or sandboxing, we
|
||||||
|
# cannot look up `config.nix` in the build dir, and have to instead get
|
||||||
|
# it from the current directory. (In this case, the current directly
|
||||||
|
# will be somewhere in `$TEST_ROOT`.)
|
||||||
|
removeBuildDirRef() {
|
||||||
|
# shellcheck disable=SC2016 # The ${} in this is Nix, not shell
|
||||||
|
sed -i -e 's,"${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/[^ ]*config.nix",./config.nix,' "$@"
|
||||||
|
}
|
||||||
|
|
||||||
trap onError ERR
|
trap onError ERR
|
||||||
|
|
||||||
fi # COMMON_FUNCTIONS_SH_SOURCED
|
fi # COMMON_FUNCTIONS_SH_SOURCED
|
||||||
|
|
|
@ -19,7 +19,7 @@ EOF
|
||||||
|
|
||||||
# When we're doing everything in the same store, we need to bring
|
# When we're doing everything in the same store, we need to bring
|
||||||
# dependencies into context.
|
# dependencies into context.
|
||||||
sed -i "$(dirname "${BASH_SOURCE[0]}")"/../config.nix \
|
sed -i "${_NIX_TEST_BUILD_DIR}/config.nix" \
|
||||||
-e 's^\(shell\) = "/nix/store/\([^/]*\)/\(.*\)";^\1 = builtins.appendContext "/nix/store/\2" { "/nix/store/\2".path = true; } + "/\3";^' \
|
-e 's^\(shell\) = "/nix/store/\([^/]*\)/\(.*\)";^\1 = builtins.appendContext "/nix/store/\2" { "/nix/store/\2".path = true; } + "/\3";^' \
|
||||||
-e 's^\(path\) = "/nix/store/\([^/]*\)/\(.*\)";^\1 = builtins.appendContext "/nix/store/\2" { "/nix/store/\2".path = true; } + "/\3";^' \
|
-e 's^\(path\) = "/nix/store/\([^/]*\)/\(.*\)";^\1 = builtins.appendContext "/nix/store/\2" { "/nix/store/\2".path = true; } + "/\3";^' \
|
||||||
;
|
;
|
||||||
|
|
|
@ -8,11 +8,10 @@ COMMON_PATHS_SH_SOURCED=1
|
||||||
|
|
||||||
commonDir="$(readlink -f "$(dirname "${BASH_SOURCE[0]-$0}")")"
|
commonDir="$(readlink -f "$(dirname "${BASH_SOURCE[0]-$0}")")"
|
||||||
|
|
||||||
# Since these are generated files
|
# Just for `isTestOnNixOS`
|
||||||
# shellcheck disable=SC1091
|
|
||||||
source "$commonDir/functions.sh"
|
source "$commonDir/functions.sh"
|
||||||
# shellcheck disable=SC1091
|
# shellcheck disable=SC1091
|
||||||
source "$commonDir/subst-vars.sh"
|
source "${_NIX_TEST_BUILD_DIR}/common/subst-vars.sh"
|
||||||
# Make sure shellcheck knows this will be defined by the above generated snippet
|
# Make sure shellcheck knows this will be defined by the above generated snippet
|
||||||
: "${bash?}" "${bindir?}"
|
: "${bash?}" "${bindir?}"
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# NOTE: instances of @variable@ are substituted as defined in /mk/templates.mk
|
# NOTE: instances of @variable@ are substituted by the build system
|
||||||
|
|
||||||
if [[ -z "${COMMON_SUBST_VARS_SH_SOURCED-}" ]]; then
|
if [[ -z "${COMMON_SUBST_VARS_SH_SOURCED-}" ]]; then
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,14 @@ if [[ -z "${COMMON_VARS_SH_SOURCED-}" ]]; then
|
||||||
|
|
||||||
COMMON_VARS_SH_SOURCED=1
|
COMMON_VARS_SH_SOURCED=1
|
||||||
|
|
||||||
|
_NIX_TEST_SOURCE_DIR=$(realpath "${_NIX_TEST_SOURCE_DIR}")
|
||||||
|
_NIX_TEST_BUILD_DIR=$(realpath "${_NIX_TEST_BUILD_DIR}")
|
||||||
|
|
||||||
commonDir="$(readlink -f "$(dirname "${BASH_SOURCE[0]-$0}")")"
|
commonDir="$(readlink -f "$(dirname "${BASH_SOURCE[0]-$0}")")"
|
||||||
|
|
||||||
# Since this is a generated file
|
# Since this is a generated file
|
||||||
# shellcheck disable=SC1091
|
# shellcheck disable=SC1091
|
||||||
source "$commonDir/subst-vars.sh"
|
source "${_NIX_TEST_BUILD_DIR}/common/subst-vars.sh"
|
||||||
# Make sure shellcheck knows all these will be defined by the above generated snippet
|
# Make sure shellcheck knows all these will be defined by the above generated snippet
|
||||||
: "${bindir?} ${coreutils?} ${dot?} ${SHELL?} ${busybox?} ${version?} ${system?}"
|
: "${bindir?} ${coreutils?} ${dot?} ${SHELL?} ${busybox?} ${version?} ${system?}"
|
||||||
export coreutils dot busybox version system
|
export coreutils dot busybox version system
|
||||||
|
@ -69,4 +72,9 @@ if [[ $(uname) == Linux ]] && [[ -L /proc/self/ns/user ]] && unshare --user true
|
||||||
_canUseSandbox=1
|
_canUseSandbox=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Very common, shorthand helps
|
||||||
|
# Used in other files
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
config_nix="${_NIX_TEST_BUILD_DIR}/config.nix"
|
||||||
|
|
||||||
fi # COMMON_VARS_SH_SOURCED
|
fi # COMMON_VARS_SH_SOURCED
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{ hashInvalidator ? "" }:
|
{ hashInvalidator ? "" }:
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
|
|
||||||
|
|
|
@ -15,5 +15,5 @@ suites += {
|
||||||
'dep-built-drv.sh',
|
'dep-built-drv.sh',
|
||||||
'old-daemon-error-hack.sh',
|
'old-daemon-error-hack.sh',
|
||||||
],
|
],
|
||||||
'workdir': meson.current_build_dir(),
|
'workdir': meson.current_source_dir(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/dyn-drv/config.nix";
|
||||||
|
|
||||||
# A simple content-addressed derivation.
|
# A simple content-addressed derivation.
|
||||||
# The derivation can be arbitrarily modified by passing a different `seed`,
|
# The derivation can be arbitrarily modified by passing a different `seed`,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/dyn-drv/config.nix";
|
||||||
|
|
||||||
let innerName = "foo"; in
|
let innerName = "foo"; in
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/dyn-drv/config.nix";
|
||||||
|
|
||||||
# A simple content-addressed derivation.
|
# A simple content-addressed derivation.
|
||||||
# The derivation can be arbitrarily modified by passing a different `seed`,
|
# The derivation can be arbitrarily modified by passing a different `seed`,
|
||||||
|
|
|
@ -45,7 +45,7 @@ printf 123 > "$TEST_ROOT/xyzzy/default.nix"
|
||||||
[[ $(nix eval --impure --expr "import $TEST_ROOT/foo/bar") = 123 ]]
|
[[ $(nix eval --impure --expr "import $TEST_ROOT/foo/bar") = 123 ]]
|
||||||
|
|
||||||
# Test --arg-from-file.
|
# Test --arg-from-file.
|
||||||
[[ "$(nix eval --raw --arg-from-file foo config.nix --expr '{ foo }: { inherit foo; }' foo)" = "$(cat config.nix)" ]]
|
[[ "$(nix eval --raw --arg-from-file foo "${config_nix}" --expr '{ foo }: { inherit foo; }' foo)" = "$(cat "${config_nix}")" ]]
|
||||||
|
|
||||||
# Check that special(-ish) files are drained.
|
# Check that special(-ish) files are drained.
|
||||||
if [[ -e /proc/version ]]; then
|
if [[ -e /proc/version ]]; then
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix";
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{ destFile, seed }:
|
{ destFile, seed }:
|
||||||
|
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix";
|
||||||
|
|
||||||
mkDerivation {
|
mkDerivation {
|
||||||
name = "simple";
|
name = "simple";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{ busybox }:
|
{ busybox }:
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix";
|
||||||
let
|
let
|
||||||
|
|
||||||
mkDerivation = args:
|
mkDerivation = args:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix";
|
||||||
|
|
||||||
mkDerivation {
|
mkDerivation {
|
||||||
name = "filter";
|
name = "filter";
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
with import ./config.nix;
|
with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix";
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ cat > "$flake1Dir"/flake.nix <<EOF
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cp ../simple.nix ../simple.builder.sh ../config.nix "$flake1Dir/"
|
cp ../simple.nix ../simple.builder.sh "${config_nix}" "$flake1Dir/"
|
||||||
|
|
||||||
echo bar > "$flake1Dir/foo"
|
echo bar > "$flake1Dir/foo"
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
cp ../simple.nix ../simple.builder.sh ../config.nix "$TEST_HOME"
|
cp ../simple.nix ../simple.builder.sh "${config_nix}" "$TEST_HOME"
|
||||||
|
|
||||||
|
# `config.nix` cannot be gotten via build dir / env var (runs afoul pure eval). Instead get from flake.
|
||||||
|
removeBuildDirRef "$TEST_HOME"/*.nix
|
||||||
|
|
||||||
cd "$TEST_HOME"
|
cd "$TEST_HOME"
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,10 @@ writeSimpleFlake() {
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cp ../simple.nix ../shell.nix ../simple.builder.sh ../config.nix "$flakeDir/"
|
cp ../simple.nix ../shell.nix ../simple.builder.sh "${config_nix}" "$flakeDir/"
|
||||||
|
|
||||||
|
# `config.nix` cannot be gotten via build dir / env var (runs afoul pure eval). Instead get from flake.
|
||||||
|
removeBuildDirRef "$flakeDir"/*.nix
|
||||||
}
|
}
|
||||||
|
|
||||||
createSimpleGitFlake() {
|
createSimpleGitFlake() {
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
cp ../simple.nix ../simple.builder.sh ../config.nix $TEST_HOME
|
cp ../simple.nix ../simple.builder.sh "${config_nix}" $TEST_HOME
|
||||||
|
removeBuildDirRef "$TEST_HOME/simple.nix"
|
||||||
|
|
||||||
cd $TEST_HOME
|
cd $TEST_HOME
|
||||||
|
|
||||||
|
@ -26,7 +27,17 @@ cat <<EOF > flake.nix
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Without --accept-flake-config, the post hook should not run.
|
# Without --accept-flake-config, the post hook should not run.
|
||||||
|
# To test variations in stderr tty-ness, we run the command in different ways,
|
||||||
|
# none of which should block on stdin or accept the `nixConfig`s.
|
||||||
nix build < /dev/null
|
nix build < /dev/null
|
||||||
|
nix build < /dev/null 2>&1 | cat
|
||||||
|
# EOF counts as no, even when interactive (throw EOF error before)
|
||||||
|
if type -p script >/dev/null && script -q -c true /dev/null; then
|
||||||
|
echo "script is available and GNU-like, so we can ensure a tty"
|
||||||
|
script -q -c 'nix build < /dev/null' /dev/null
|
||||||
|
else
|
||||||
|
echo "script is not available or not GNU-like, so we skip testing with an added tty"
|
||||||
|
fi
|
||||||
(! [[ -f post-hook-ran ]])
|
(! [[ -f post-hook-ran ]])
|
||||||
TODO_NixOS
|
TODO_NixOS
|
||||||
clearStore
|
clearStore
|
||||||
|
|
|
@ -5,11 +5,11 @@ source ../common.sh
|
||||||
TODO_NixOS
|
TODO_NixOS
|
||||||
|
|
||||||
clearStore
|
clearStore
|
||||||
rm -rf $TEST_HOME/.cache $TEST_HOME/.config $TEST_HOME/.local
|
rm -rf "$TEST_HOME/.cache" "$TEST_HOME/.config" "$TEST_HOME/.local"
|
||||||
|
|
||||||
# Create flake under test.
|
# Create flake under test.
|
||||||
cp ../shell-hello.nix ../config.nix $TEST_HOME/
|
cp ../shell-hello.nix "$config_nix" "$TEST_HOME/"
|
||||||
cat <<EOF >$TEST_HOME/flake.nix
|
cat <<EOF >"$TEST_HOME/flake.nix"
|
||||||
{
|
{
|
||||||
inputs.nixpkgs.url = "$TEST_HOME/nixpkgs";
|
inputs.nixpkgs.url = "$TEST_HOME/nixpkgs";
|
||||||
outputs = {self, nixpkgs}: {
|
outputs = {self, nixpkgs}: {
|
||||||
|
@ -24,9 +24,13 @@ cat <<EOF >$TEST_HOME/flake.nix
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Create fake nixpkgs flake.
|
# Create fake nixpkgs flake.
|
||||||
mkdir -p $TEST_HOME/nixpkgs
|
mkdir -p "$TEST_HOME/nixpkgs"
|
||||||
cp ../config.nix ../shell.nix $TEST_HOME/nixpkgs
|
cp "${config_nix}" ../shell.nix "$TEST_HOME/nixpkgs"
|
||||||
cat <<EOF >$TEST_HOME/nixpkgs/flake.nix
|
|
||||||
|
# `config.nix` cannot be gotten via build dir / env var (runs afoul pure eval). Instead get from flake.
|
||||||
|
removeBuildDirRef "$TEST_HOME/nixpkgs"/*.nix
|
||||||
|
|
||||||
|
cat <<EOF >"$TEST_HOME/nixpkgs/flake.nix"
|
||||||
{
|
{
|
||||||
outputs = {self}: {
|
outputs = {self}: {
|
||||||
legacyPackages.$system.bashInteractive = (import ./shell.nix {}).bashInteractive;
|
legacyPackages.$system.bashInteractive = (import ./shell.nix {}).bashInteractive;
|
||||||
|
@ -34,7 +38,7 @@ cat <<EOF >$TEST_HOME/nixpkgs/flake.nix
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cd $TEST_HOME
|
cd "$TEST_HOME"
|
||||||
|
|
||||||
# Test whether `nix develop` passes through environment variables.
|
# Test whether `nix develop` passes through environment variables.
|
||||||
[[ "$(
|
[[ "$(
|
||||||
|
@ -43,13 +47,86 @@ echo "\$ENVVAR"
|
||||||
EOF
|
EOF
|
||||||
)" = "a" ]]
|
)" = "a" ]]
|
||||||
|
|
||||||
# Test whether `nix develop --ignore-environment` does _not_ pass through environment variables.
|
# Test whether `nix develop --ignore-env` does _not_ pass through environment variables.
|
||||||
[[ -z "$(
|
[[ -z "$(
|
||||||
ENVVAR=a nix develop --ignore-environment --no-write-lock-file .#hello <<EOF
|
ENVVAR=a nix develop --ignore-env --no-write-lock-file .#hello <<EOF
|
||||||
echo "\$ENVVAR"
|
echo "\$ENVVAR"
|
||||||
EOF
|
EOF
|
||||||
)" ]]
|
)" ]]
|
||||||
|
|
||||||
|
# Test wether `--keep-env-var` keeps the environment variable.
|
||||||
|
(
|
||||||
|
expect='BAR'
|
||||||
|
got="$(FOO='BAR' nix develop --ignore-env --keep-env-var FOO --no-write-lock-file .#hello <<EOF
|
||||||
|
echo "\$FOO"
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
[[ "$got" == "$expect" ]]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test wether duplicate `--keep-env-var` keeps the environment variable.
|
||||||
|
(
|
||||||
|
expect='BAR'
|
||||||
|
got="$(FOO='BAR' nix develop --ignore-env --keep-env-var FOO --keep-env-var FOO --no-write-lock-file .#hello <<EOF
|
||||||
|
echo "\$FOO"
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
[[ "$got" == "$expect" ]]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test wether `--set-env-var` sets the environment variable.
|
||||||
|
(
|
||||||
|
expect='BAR'
|
||||||
|
got="$(nix develop --ignore-env --set-env-var FOO 'BAR' --no-write-lock-file .#hello <<EOF
|
||||||
|
echo "\$FOO"
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
[[ "$got" == "$expect" ]]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test that `--set-env-var` overwrites previously set variables.
|
||||||
|
(
|
||||||
|
expect='BLA'
|
||||||
|
got="$(FOO='BAR' nix develop --set-env-var FOO 'BLA' --no-write-lock-file .#hello <<EOF
|
||||||
|
echo "\$FOO"
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
[[ "$got" == "$expect" ]]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test that multiple `--set-env-var` work.
|
||||||
|
(
|
||||||
|
expect='BARFOO'
|
||||||
|
got="$(nix develop --set-env-var FOO 'BAR' --set-env-var BAR 'FOO' --no-write-lock-file .#hello <<EOF | tr -d '\n'
|
||||||
|
echo "\$FOO"
|
||||||
|
echo "\$BAR"
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
[[ "$got" == "$expect" ]]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check that we throw an error when `--keep-env-var` is used without `--ignore-env`.
|
||||||
|
expectStderr 1 nix develop --keep-env-var FOO .#hello |
|
||||||
|
grepQuiet "error: --keep-env-var does not make sense without --ignore-env"
|
||||||
|
|
||||||
|
# Check that we throw an error when `--unset-env-var` is used with `--ignore-env`.
|
||||||
|
expectStderr 1 nix develop --ignore-env --unset-env-var FOO .#hello |
|
||||||
|
grepQuiet "error: --unset-env-var does not make sense with --ignore-env"
|
||||||
|
|
||||||
|
# Test wether multiple occurances of `--set-env-var` throws.
|
||||||
|
expectStderr 1 nix develop --set-env-var FOO 'BAR' --set-env-var FOO 'BLA' --no-write-lock-file .#hello |
|
||||||
|
grepQuiet "error: Duplicate definition of environment variable 'FOO' with '--set-env-var' is ambiguous"
|
||||||
|
|
||||||
|
# Test wether similar `--unset-env-var` and `--set-env-var` throws.
|
||||||
|
expectStderr 1 nix develop --set-env-var FOO 'BAR' --unset-env-var FOO --no-write-lock-file .#hello |
|
||||||
|
grepQuiet "error: Cannot unset environment variable 'FOO' that is set with '--set-env-var'"
|
||||||
|
|
||||||
|
expectStderr 1 nix develop --unset-env-var FOO --set-env-var FOO 'BAR' --no-write-lock-file .#hello |
|
||||||
|
grepQuiet "error: Cannot set environment variable 'FOO' that is unset with '--unset-env-var'"
|
||||||
|
|
||||||
|
# Check that multiple `--ignore-env`'s are okay.
|
||||||
|
expectStderr 0 nix develop --ignore-env --set-env-var FOO 'BAR' --ignore-env .#hello
|
||||||
|
|
||||||
# Determine the bashInteractive executable.
|
# Determine the bashInteractive executable.
|
||||||
nix build --no-write-lock-file './nixpkgs#bashInteractive' --out-link ./bash-interactive
|
nix build --no-write-lock-file './nixpkgs#bashInteractive' --out-link ./bash-interactive
|
||||||
BASH_INTERACTIVE_EXECUTABLE="$PWD/bash-interactive/bin/bash"
|
BASH_INTERACTIVE_EXECUTABLE="$PWD/bash-interactive/bin/bash"
|
||||||
|
@ -63,7 +140,7 @@ EOF
|
||||||
|
|
||||||
# Test whether `nix develop` with ignore environment sets `SHELL` to nixpkgs#bashInteractive shell.
|
# Test whether `nix develop` with ignore environment sets `SHELL` to nixpkgs#bashInteractive shell.
|
||||||
[[ "$(
|
[[ "$(
|
||||||
SHELL=custom nix develop --ignore-environment --no-write-lock-file .#hello <<EOF
|
SHELL=custom nix develop --ignore-env --no-write-lock-file .#hello <<EOF
|
||||||
echo "\$SHELL"
|
echo "\$SHELL"
|
||||||
EOF
|
EOF
|
||||||
)" -ef "$BASH_INTERACTIVE_EXECUTABLE" ]]
|
)" -ef "$BASH_INTERACTIVE_EXECUTABLE" ]]
|
||||||
|
|
|
@ -7,7 +7,7 @@ requireGit
|
||||||
flake1Dir="$TEST_ROOT/eval-cache-flake"
|
flake1Dir="$TEST_ROOT/eval-cache-flake"
|
||||||
|
|
||||||
createGitRepo "$flake1Dir" ""
|
createGitRepo "$flake1Dir" ""
|
||||||
cp ../simple.nix ../simple.builder.sh ../config.nix "$flake1Dir/"
|
cp ../simple.nix ../simple.builder.sh "${config_nix}" "$flake1Dir/"
|
||||||
git -C "$flake1Dir" add simple.nix simple.builder.sh config.nix
|
git -C "$flake1Dir" add simple.nix simple.builder.sh config.nix
|
||||||
git -C "$flake1Dir" commit -m "config.nix"
|
git -C "$flake1Dir" commit -m "config.nix"
|
||||||
|
|
||||||
|
|
|
@ -390,7 +390,7 @@ cat > "$flake3Dir/flake.nix" <<EOF
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cp ../config.nix "$flake3Dir"
|
cp "${config_nix}" "$flake3Dir"
|
||||||
|
|
||||||
git -C "$flake3Dir" add flake.nix config.nix
|
git -C "$flake3Dir" add flake.nix config.nix
|
||||||
git -C "$flake3Dir" commit -m 'Add nonFlakeInputs'
|
git -C "$flake3Dir" commit -m 'Add nonFlakeInputs'
|
||||||
|
|
|
@ -25,5 +25,5 @@ suites += {
|
||||||
'show.sh',
|
'show.sh',
|
||||||
'dubious-query.sh',
|
'dubious-query.sh',
|
||||||
],
|
],
|
||||||
'workdir': meson.current_build_dir(),
|
'workdir': meson.current_source_dir(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,10 @@ TODO_NixOS
|
||||||
|
|
||||||
clearStore
|
clearStore
|
||||||
rm -rf $TEST_HOME/.cache $TEST_HOME/.config $TEST_HOME/.local
|
rm -rf $TEST_HOME/.cache $TEST_HOME/.config $TEST_HOME/.local
|
||||||
cp ../shell-hello.nix ../config.nix $TEST_HOME
|
|
||||||
|
cp ../shell-hello.nix "${config_nix}" $TEST_HOME
|
||||||
|
# `config.nix` cannot be gotten via build dir / env var (runs afoul pure eval). Instead get from flake.
|
||||||
|
removeBuildDirRef "$TEST_HOME"/*.nix
|
||||||
cd $TEST_HOME
|
cd $TEST_HOME
|
||||||
|
|
||||||
cat <<EOF > flake.nix
|
cat <<EOF > flake.nix
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue