mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-24 14:56:15 +02:00
Merge remote-tracking branch 'nixos/master'
This commit is contained in:
commit
5ecd820c18
59 changed files with 998 additions and 226 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -154,6 +154,8 @@ result-*
|
||||||
.vscode/
|
.vscode/
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
.pre-commit-config.yaml
|
||||||
|
|
||||||
# clangd and possibly more
|
# clangd and possibly more
|
||||||
.cache/
|
.cache/
|
||||||
|
|
||||||
|
|
1
Makefile
1
Makefile
|
@ -27,6 +27,7 @@ makefiles = \
|
||||||
ifdef HOST_UNIX
|
ifdef HOST_UNIX
|
||||||
makefiles += \
|
makefiles += \
|
||||||
scripts/local.mk \
|
scripts/local.mk \
|
||||||
|
maintainers/local.mk \
|
||||||
misc/bash/local.mk \
|
misc/bash/local.mk \
|
||||||
misc/fish/local.mk \
|
misc/fish/local.mk \
|
||||||
misc/zsh/local.mk \
|
misc/zsh/local.mk \
|
||||||
|
|
11
configure.ac
11
configure.ac
|
@ -317,6 +317,17 @@ case "$host_os" in
|
||||||
[CXXFLAGS="$LIBSECCOMP_CFLAGS $CXXFLAGS"])
|
[CXXFLAGS="$LIBSECCOMP_CFLAGS $CXXFLAGS"])
|
||||||
have_seccomp=1
|
have_seccomp=1
|
||||||
AC_DEFINE([HAVE_SECCOMP], [1], [Whether seccomp is available and should be used for sandboxing.])
|
AC_DEFINE([HAVE_SECCOMP], [1], [Whether seccomp is available and should be used for sandboxing.])
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_SOURCE([[
|
||||||
|
#include <seccomp.h>
|
||||||
|
#ifndef __SNR_fchmodat2
|
||||||
|
# error "Missing support for fchmodat2"
|
||||||
|
#endif
|
||||||
|
]])
|
||||||
|
], [], [
|
||||||
|
echo "libseccomp is missing __SNR_fchmodat2. Please provide libseccomp 2.5.5 or later"
|
||||||
|
exit 1
|
||||||
|
])
|
||||||
else
|
else
|
||||||
have_seccomp=
|
have_seccomp=
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -273,6 +273,29 @@ Configure your editor to use the `clangd` from the `.#native-clangStdenvPackages
|
||||||
> Some other editors (e.g. Emacs, Vim) need a plugin to support LSP servers in general (e.g. [lsp-mode](https://github.com/emacs-lsp/lsp-mode) for Emacs and [vim-lsp](https://github.com/prabirshrestha/vim-lsp) for vim).
|
> Some other editors (e.g. Emacs, Vim) need a plugin to support LSP servers in general (e.g. [lsp-mode](https://github.com/emacs-lsp/lsp-mode) for Emacs and [vim-lsp](https://github.com/prabirshrestha/vim-lsp) for vim).
|
||||||
> Editor-specific setup is typically opinionated, so we will not cover it here in more detail.
|
> Editor-specific setup is typically opinionated, so we will not cover it here in more detail.
|
||||||
|
|
||||||
|
## Formatting and pre-commit hooks
|
||||||
|
|
||||||
|
You may run the formatters as a one-off using:
|
||||||
|
|
||||||
|
```console
|
||||||
|
make format
|
||||||
|
```
|
||||||
|
|
||||||
|
If you'd like to run the formatters before every commit, install the hooks:
|
||||||
|
|
||||||
|
```
|
||||||
|
pre-commit-hooks-install
|
||||||
|
```
|
||||||
|
|
||||||
|
This installs [pre-commit](https://pre-commit.com) using [cachix/git-hooks.nix](https://github.com/cachix/git-hooks.nix).
|
||||||
|
|
||||||
|
When making a commit, pay attention to the console output.
|
||||||
|
If it fails, run `git add --patch` to approve the suggestions _and commit again_.
|
||||||
|
|
||||||
|
To refresh pre-commit hook's config file, do the following:
|
||||||
|
1. Exit the development shell and start it again by running `nix develop`.
|
||||||
|
2. If you also use the pre-commit hook, also run `pre-commit-hooks-install` again.
|
||||||
|
|
||||||
## Add a release note
|
## Add a release note
|
||||||
|
|
||||||
`doc/manual/rl-next` contains release notes entries for all unreleased changes.
|
`doc/manual/rl-next` contains release notes entries for all unreleased changes.
|
||||||
|
|
|
@ -295,6 +295,25 @@
|
||||||
[path]: ./language/values.md#type-path
|
[path]: ./language/values.md#type-path
|
||||||
[attribute name]: ./language/values.md#attribute-set
|
[attribute name]: ./language/values.md#attribute-set
|
||||||
|
|
||||||
|
- [base directory]{#gloss-base-directory}
|
||||||
|
|
||||||
|
The location from which relative paths are resolved.
|
||||||
|
|
||||||
|
- For expressions in a file, the base directory is the directory containing that file.
|
||||||
|
This is analogous to the directory of a [base URL](https://datatracker.ietf.org/doc/html/rfc1808#section-3.3).
|
||||||
|
<!-- which is sufficient for resolving non-empty URLs -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The wording here may look awkward, but it's for these reasons:
|
||||||
|
* "with --expr": it's a flag, and not an option with an accompanying value
|
||||||
|
* "written in": the expression itself must be written as an argument,
|
||||||
|
whereas the more natural "passed as an argument" allows an interpretation
|
||||||
|
where the expression could be passed by file name.
|
||||||
|
-->
|
||||||
|
- For expressions written in command line arguments with [`--expr`](@docroot@/command-ref/opt-common.html#opt-expr), the base directory is the current working directory.
|
||||||
|
|
||||||
|
[base directory]: #gloss-base-directory
|
||||||
|
|
||||||
- [experimental feature]{#gloss-experimental-feature}
|
- [experimental feature]{#gloss-experimental-feature}
|
||||||
|
|
||||||
Not yet stabilized functionality guarded by named experimental feature flags.
|
Not yet stabilized functionality guarded by named experimental feature flags.
|
||||||
|
|
|
@ -50,7 +50,7 @@ Supported systems:
|
||||||
To explicitly instruct the installer to perform a multi-user installation on your system:
|
To explicitly instruct the installer to perform a multi-user installation on your system:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ curl -L https://nixos.org/nix/install | sh -s -- --daemon
|
$ bash <(curl -L https://nixos.org/nix/install) --daemon
|
||||||
```
|
```
|
||||||
|
|
||||||
You can run this under your usual user account or `root`.
|
You can run this under your usual user account or `root`.
|
||||||
|
@ -61,7 +61,7 @@ The script will invoke `sudo` as needed.
|
||||||
To explicitly select a single-user installation on your system:
|
To explicitly select a single-user installation on your system:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ curl -L https://nixos.org/nix/install | sh -s -- --no-daemon
|
$ bash <(curl -L https://nixos.org/nix/install) --no-daemon
|
||||||
```
|
```
|
||||||
|
|
||||||
In a single-user installation, `/nix` is owned by the invoking user.
|
In a single-user installation, `/nix` is owned by the invoking user.
|
||||||
|
|
|
@ -5,8 +5,9 @@
|
||||||
If you have a [single-user installation](./installing-binary.md#single-user-installation) of Nix, uninstall it by running:
|
If you have a [single-user installation](./installing-binary.md#single-user-installation) of Nix, uninstall it by running:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ rm -rf /nix
|
$ rm -rf /nix ~/.nix-channels ~/.nix-defexpr ~/.nix-profile
|
||||||
```
|
```
|
||||||
|
You might also want to manually remove references to Nix from your `~/.profile`.
|
||||||
|
|
||||||
## Multi User
|
## Multi User
|
||||||
|
|
||||||
|
|
|
@ -97,8 +97,8 @@
|
||||||
is not a path: it's parsed as an expression that selects the
|
is not a path: it's parsed as an expression that selects the
|
||||||
attribute `sh` from the variable `builder`. If the file name is
|
attribute `sh` from the variable `builder`. If the file name is
|
||||||
relative, i.e., if it does not begin with a slash, it is made
|
relative, i.e., if it does not begin with a slash, it is made
|
||||||
absolute at parse time relative to the directory of the Nix
|
absolute at parse time relative to the [base directory](@docroot@/glossary.md#gloss-base-directory).
|
||||||
expression that contained it. For instance, if a Nix expression in
|
For instance, if a Nix expression in
|
||||||
`/foo/bar/bla.nix` refers to `../xyzzy/fnord.nix`, the absolute path
|
`/foo/bar/bla.nix` refers to `../xyzzy/fnord.nix`, the absolute path
|
||||||
is `/foo/xyzzy/fnord.nix`.
|
is `/foo/xyzzy/fnord.nix`.
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
e.g. `~/foo` would be equivalent to `/home/edolstra/foo` for a user
|
e.g. `~/foo` would be equivalent to `/home/edolstra/foo` for a user
|
||||||
whose home directory is `/home/edolstra`.
|
whose home directory is `/home/edolstra`.
|
||||||
|
|
||||||
For instance, evaluating `"${./foo.txt}"` will cause `foo.txt` in the current directory to be copied into the Nix store and result in the string `"/nix/store/<hash>-foo.txt"`.
|
For instance, evaluating `"${./foo.txt}"` will cause `foo.txt` in the base directory to be copied into the Nix store and result in the string `"/nix/store/<hash>-foo.txt"`.
|
||||||
|
|
||||||
Note that the Nix language assumes that all input files will remain _unchanged_ while evaluating a Nix expression.
|
Note that the Nix language assumes that all input files will remain _unchanged_ while evaluating a Nix expression.
|
||||||
For example, assume you used a file path in an interpolated string during a `nix repl` session.
|
For example, assume you used a file path in an interpolated string during a `nix repl` session.
|
||||||
|
|
65
flake.lock
65
flake.lock
|
@ -16,6 +16,41 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1712014858,
|
||||||
|
"narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1667395993,
|
||||||
|
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"libgit2": {
|
"libgit2": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
|
@ -64,12 +99,40 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"pre-commit-hooks": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": [],
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"gitignore": [],
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"nixpkgs-stable": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1712897695,
|
||||||
|
"narHash": "sha256-nMirxrGteNAl9sWiOhoN5tIHyjBbVi5e2tgZUgZlK3Y=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "pre-commit-hooks.nix",
|
||||||
|
"rev": "40e6053ecb65fcbf12863338a6dcefb3f55f1bf8",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "pre-commit-hooks.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat",
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
"libgit2": "libgit2",
|
"libgit2": "libgit2",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"nixpkgs-regression": "nixpkgs-regression"
|
"nixpkgs-regression": "nixpkgs-regression",
|
||||||
|
"pre-commit-hooks": "pre-commit-hooks"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
55
flake.nix
55
flake.nix
|
@ -13,7 +13,19 @@
|
||||||
inputs.flake-compat = { url = "github:edolstra/flake-compat"; flake = false; };
|
inputs.flake-compat = { url = "github:edolstra/flake-compat"; flake = false; };
|
||||||
inputs.libgit2 = { url = "github:libgit2/libgit2"; flake = false; };
|
inputs.libgit2 = { url = "github:libgit2/libgit2"; flake = false; };
|
||||||
|
|
||||||
outputs = { self, nixpkgs, nixpkgs-regression, libgit2, ... }:
|
# dev tooling
|
||||||
|
inputs.flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
|
inputs.pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix";
|
||||||
|
# work around https://github.com/NixOS/nix/issues/7730
|
||||||
|
inputs.flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||||
|
inputs.pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
inputs.pre-commit-hooks.inputs.nixpkgs-stable.follows = "nixpkgs";
|
||||||
|
# work around 7730 and https://github.com/NixOS/nix/issues/7807
|
||||||
|
inputs.pre-commit-hooks.inputs.flake-compat.follows = "";
|
||||||
|
inputs.pre-commit-hooks.inputs.gitignore.follows = "";
|
||||||
|
|
||||||
|
outputs = inputs@{ self, nixpkgs, nixpkgs-regression, libgit2, ... }:
|
||||||
|
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (nixpkgs) lib;
|
inherit (nixpkgs) lib;
|
||||||
|
@ -62,6 +74,17 @@
|
||||||
})
|
})
|
||||||
stdenvs);
|
stdenvs);
|
||||||
|
|
||||||
|
|
||||||
|
# We don't apply flake-parts to the whole flake so that non-development attributes
|
||||||
|
# load without fetching any development inputs.
|
||||||
|
devFlake = inputs.flake-parts.lib.mkFlake { inherit inputs; } {
|
||||||
|
imports = [ ./maintainers/flake-module.nix ];
|
||||||
|
systems = lib.subtractLists crossSystems systems;
|
||||||
|
perSystem = { system, ... }: {
|
||||||
|
_module.args.pkgs = nixpkgsFor.${system}.native;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# Memoize nixpkgs for different platforms for efficiency.
|
# Memoize nixpkgs for different platforms for efficiency.
|
||||||
nixpkgsFor = forAllSystems
|
nixpkgsFor = forAllSystems
|
||||||
(system: let
|
(system: let
|
||||||
|
@ -191,6 +214,13 @@
|
||||||
inherit fileset stdenv;
|
inherit fileset stdenv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# See https://github.com/NixOS/nixpkgs/pull/214409
|
||||||
|
# Remove when fixed in this flake's nixpkgs
|
||||||
|
pre-commit =
|
||||||
|
if prev.stdenv.hostPlatform.system == "i686-linux"
|
||||||
|
then (prev.pre-commit.override (o: { dotnet-sdk = ""; })).overridePythonAttrs (o: { doCheck = false; })
|
||||||
|
else prev.pre-commit;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
@ -366,7 +396,8 @@
|
||||||
# Since the support is only best-effort there, disable the perl
|
# Since the support is only best-effort there, disable the perl
|
||||||
# bindings
|
# bindings
|
||||||
perlBindings = self.hydraJobs.perlBindings.${system};
|
perlBindings = self.hydraJobs.perlBindings.${system};
|
||||||
});
|
} // devFlake.checks.${system} or {}
|
||||||
|
);
|
||||||
|
|
||||||
packages = forAllSystems (system: rec {
|
packages = forAllSystems (system: rec {
|
||||||
inherit (nixpkgsFor.${system}.native) nix changelog-d-nix;
|
inherit (nixpkgsFor.${system}.native) nix changelog-d-nix;
|
||||||
|
@ -401,7 +432,11 @@
|
||||||
stdenvs)));
|
stdenvs)));
|
||||||
|
|
||||||
devShells = let
|
devShells = let
|
||||||
makeShell = pkgs: stdenv: (pkgs.nix.override { inherit stdenv; forDevShell = true; }).overrideAttrs (attrs: {
|
makeShell = pkgs: stdenv: (pkgs.nix.override { inherit stdenv; forDevShell = true; }).overrideAttrs (attrs:
|
||||||
|
let
|
||||||
|
modular = devFlake.getSystem stdenv.buildPlatform.system;
|
||||||
|
in {
|
||||||
|
pname = "shell-for-" + attrs.pname;
|
||||||
installFlags = "sysconfdir=$(out)/etc";
|
installFlags = "sysconfdir=$(out)/etc";
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
PATH=$prefix/bin:$PATH
|
PATH=$prefix/bin:$PATH
|
||||||
|
@ -412,7 +447,21 @@
|
||||||
XDG_DATA_DIRS+=:$out/share
|
XDG_DATA_DIRS+=:$out/share
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# We use this shell with the local checkout, not unpackPhase.
|
||||||
|
src = null;
|
||||||
|
|
||||||
|
env = {
|
||||||
|
# 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}";
|
||||||
|
};
|
||||||
|
|
||||||
nativeBuildInputs = attrs.nativeBuildInputs or []
|
nativeBuildInputs = attrs.nativeBuildInputs or []
|
||||||
|
++ [
|
||||||
|
modular.pre-commit.settings.package
|
||||||
|
(pkgs.writeScriptBin "pre-commit-hooks-install"
|
||||||
|
modular.pre-commit.settings.installationScript)
|
||||||
|
]
|
||||||
# TODO: Remove the darwin check once
|
# TODO: Remove the darwin check once
|
||||||
# https://github.com/NixOS/nixpkgs/pull/291814 is available
|
# 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.buildPlatform.isDarwin) pkgs.buildPackages.bear
|
||||||
|
|
436
maintainers/flake-module.nix
Normal file
436
maintainers/flake-module.nix
Normal file
|
@ -0,0 +1,436 @@
|
||||||
|
{ lib, getSystem, inputs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
inputs.pre-commit-hooks.flakeModule
|
||||||
|
];
|
||||||
|
|
||||||
|
perSystem = { config, pkgs, ... }: {
|
||||||
|
|
||||||
|
# https://flake.parts/options/pre-commit-hooks-nix.html#options
|
||||||
|
pre-commit.settings = {
|
||||||
|
hooks = {
|
||||||
|
clang-format.enable = true;
|
||||||
|
# TODO: nixfmt, https://github.com/NixOS/nixfmt/issues/153
|
||||||
|
};
|
||||||
|
|
||||||
|
excludes = [
|
||||||
|
# We don't want to format test data
|
||||||
|
# ''tests/(?!nixos/).*\.nix''
|
||||||
|
''^tests/.*''
|
||||||
|
|
||||||
|
# Don't format vendored code
|
||||||
|
''^src/toml11/.*''
|
||||||
|
''^doc/manual/redirects\.js$''
|
||||||
|
''^doc/manual/theme/highlight\.js$''
|
||||||
|
|
||||||
|
# We haven't applied formatting to these files yet
|
||||||
|
''^doc/manual/redirects\.js$''
|
||||||
|
''^doc/manual/theme/highlight\.js$''
|
||||||
|
''^precompiled-headers\.h$''
|
||||||
|
''^src/build-remote/build-remote\.cc$''
|
||||||
|
''^src/libcmd/built-path\.cc$''
|
||||||
|
''^src/libcmd/built-path\.hh$''
|
||||||
|
''^src/libcmd/command\.cc$''
|
||||||
|
''^src/libcmd/command\.hh$''
|
||||||
|
''^src/libcmd/common-eval-args\.cc$''
|
||||||
|
''^src/libcmd/common-eval-args\.hh$''
|
||||||
|
''^src/libcmd/editor-for\.cc$''
|
||||||
|
''^src/libcmd/installable-attr-path\.cc$''
|
||||||
|
''^src/libcmd/installable-attr-path\.hh$''
|
||||||
|
''^src/libcmd/installable-derived-path\.cc$''
|
||||||
|
''^src/libcmd/installable-derived-path\.hh$''
|
||||||
|
''^src/libcmd/installable-flake\.cc$''
|
||||||
|
''^src/libcmd/installable-flake\.hh$''
|
||||||
|
''^src/libcmd/installable-value\.cc$''
|
||||||
|
''^src/libcmd/installable-value\.hh$''
|
||||||
|
''^src/libcmd/installables\.cc$''
|
||||||
|
''^src/libcmd/installables\.hh$''
|
||||||
|
''^src/libcmd/legacy\.hh$''
|
||||||
|
''^src/libcmd/markdown\.cc$''
|
||||||
|
''^src/libcmd/misc-store-flags\.cc$''
|
||||||
|
''^src/libcmd/repl-interacter\.cc$''
|
||||||
|
''^src/libcmd/repl-interacter\.hh$''
|
||||||
|
''^src/libcmd/repl\.cc$''
|
||||||
|
''^src/libcmd/repl\.hh$''
|
||||||
|
''^src/libexpr-c/nix_api_expr\.cc$''
|
||||||
|
''^src/libexpr-c/nix_api_external\.cc$''
|
||||||
|
''^src/libexpr/attr-path\.cc$''
|
||||||
|
''^src/libexpr/attr-path\.hh$''
|
||||||
|
''^src/libexpr/attr-set\.cc$''
|
||||||
|
''^src/libexpr/attr-set\.hh$''
|
||||||
|
''^src/libexpr/eval-cache\.cc$''
|
||||||
|
''^src/libexpr/eval-cache\.hh$''
|
||||||
|
''^src/libexpr/eval-error\.cc$''
|
||||||
|
''^src/libexpr/eval-inline\.hh$''
|
||||||
|
''^src/libexpr/eval-settings\.cc$''
|
||||||
|
''^src/libexpr/eval-settings\.hh$''
|
||||||
|
''^src/libexpr/eval\.cc$''
|
||||||
|
''^src/libexpr/eval\.hh$''
|
||||||
|
''^src/libexpr/flake/config\.cc$''
|
||||||
|
''^src/libexpr/flake/flake\.cc$''
|
||||||
|
''^src/libexpr/flake/flake\.hh$''
|
||||||
|
''^src/libexpr/flake/flakeref\.cc$''
|
||||||
|
''^src/libexpr/flake/flakeref\.hh$''
|
||||||
|
''^src/libexpr/flake/lockfile\.cc$''
|
||||||
|
''^src/libexpr/flake/lockfile\.hh$''
|
||||||
|
''^src/libexpr/flake/url-name\.cc$''
|
||||||
|
''^src/libexpr/function-trace\.cc$''
|
||||||
|
''^src/libexpr/gc-small-vector\.hh$''
|
||||||
|
''^src/libexpr/get-drvs\.cc$''
|
||||||
|
''^src/libexpr/get-drvs\.hh$''
|
||||||
|
''^src/libexpr/json-to-value\.cc$''
|
||||||
|
''^src/libexpr/nixexpr\.cc$''
|
||||||
|
''^src/libexpr/nixexpr\.hh$''
|
||||||
|
''^src/libexpr/parser-state\.hh$''
|
||||||
|
''^src/libexpr/pos-table\.hh$''
|
||||||
|
''^src/libexpr/primops\.cc$''
|
||||||
|
''^src/libexpr/primops\.hh$''
|
||||||
|
''^src/libexpr/primops/context\.cc$''
|
||||||
|
''^src/libexpr/primops/fetchClosure\.cc$''
|
||||||
|
''^src/libexpr/primops/fetchMercurial\.cc$''
|
||||||
|
''^src/libexpr/primops/fetchTree\.cc$''
|
||||||
|
''^src/libexpr/primops/fromTOML\.cc$''
|
||||||
|
''^src/libexpr/print-ambiguous\.cc$''
|
||||||
|
''^src/libexpr/print-ambiguous\.hh$''
|
||||||
|
''^src/libexpr/print-options\.hh$''
|
||||||
|
''^src/libexpr/print\.cc$''
|
||||||
|
''^src/libexpr/print\.hh$''
|
||||||
|
''^src/libexpr/search-path\.cc$''
|
||||||
|
''^src/libexpr/symbol-table\.hh$''
|
||||||
|
''^src/libexpr/value-to-json\.cc$''
|
||||||
|
''^src/libexpr/value-to-json\.hh$''
|
||||||
|
''^src/libexpr/value-to-xml\.cc$''
|
||||||
|
''^src/libexpr/value-to-xml\.hh$''
|
||||||
|
''^src/libexpr/value\.hh$''
|
||||||
|
''^src/libexpr/value/context\.cc$''
|
||||||
|
''^src/libexpr/value/context\.hh$''
|
||||||
|
''^src/libfetchers/attrs\.cc$''
|
||||||
|
''^src/libfetchers/cache\.cc$''
|
||||||
|
''^src/libfetchers/cache\.hh$''
|
||||||
|
''^src/libfetchers/fetch-settings\.cc$''
|
||||||
|
''^src/libfetchers/fetch-settings\.hh$''
|
||||||
|
''^src/libfetchers/fetch-to-store\.cc$''
|
||||||
|
''^src/libfetchers/fetchers\.cc$''
|
||||||
|
''^src/libfetchers/fetchers\.hh$''
|
||||||
|
''^src/libfetchers/filtering-input-accessor\.cc$''
|
||||||
|
''^src/libfetchers/filtering-input-accessor\.hh$''
|
||||||
|
''^src/libfetchers/fs-input-accessor\.cc$''
|
||||||
|
''^src/libfetchers/fs-input-accessor\.hh$''
|
||||||
|
''^src/libfetchers/git-utils\.cc$''
|
||||||
|
''^src/libfetchers/git-utils\.hh$''
|
||||||
|
''^src/libfetchers/github\.cc$''
|
||||||
|
''^src/libfetchers/indirect\.cc$''
|
||||||
|
''^src/libfetchers/memory-input-accessor\.cc$''
|
||||||
|
''^src/libfetchers/path\.cc$''
|
||||||
|
''^src/libfetchers/registry\.cc$''
|
||||||
|
''^src/libfetchers/registry\.hh$''
|
||||||
|
''^src/libfetchers/tarball\.cc$''
|
||||||
|
''^src/libfetchers/tarball\.hh$''
|
||||||
|
''^src/libfetchers/unix/git\.cc$''
|
||||||
|
''^src/libfetchers/unix/mercurial\.cc$''
|
||||||
|
''^src/libmain/common-args\.cc$''
|
||||||
|
''^src/libmain/common-args\.hh$''
|
||||||
|
''^src/libmain/loggers\.cc$''
|
||||||
|
''^src/libmain/loggers\.hh$''
|
||||||
|
''^src/libmain/progress-bar\.cc$''
|
||||||
|
''^src/libmain/shared\.cc$''
|
||||||
|
''^src/libmain/shared\.hh$''
|
||||||
|
''^src/libmain/unix/stack\.cc$''
|
||||||
|
''^src/libstore/binary-cache-store\.cc$''
|
||||||
|
''^src/libstore/binary-cache-store\.hh$''
|
||||||
|
''^src/libstore/build-result\.hh$''
|
||||||
|
''^src/libstore/builtins\.hh$''
|
||||||
|
''^src/libstore/builtins/buildenv\.cc$''
|
||||||
|
''^src/libstore/builtins/buildenv\.hh$''
|
||||||
|
''^src/libstore/common-protocol-impl\.hh$''
|
||||||
|
''^src/libstore/common-protocol\.cc$''
|
||||||
|
''^src/libstore/common-protocol\.hh$''
|
||||||
|
''^src/libstore/content-address\.cc$''
|
||||||
|
''^src/libstore/content-address\.hh$''
|
||||||
|
''^src/libstore/daemon\.cc$''
|
||||||
|
''^src/libstore/daemon\.hh$''
|
||||||
|
''^src/libstore/derivations\.cc$''
|
||||||
|
''^src/libstore/derivations\.hh$''
|
||||||
|
''^src/libstore/derived-path-map\.cc$''
|
||||||
|
''^src/libstore/derived-path-map\.hh$''
|
||||||
|
''^src/libstore/derived-path\.cc$''
|
||||||
|
''^src/libstore/derived-path\.hh$''
|
||||||
|
''^src/libstore/downstream-placeholder\.cc$''
|
||||||
|
''^src/libstore/downstream-placeholder\.hh$''
|
||||||
|
''^src/libstore/dummy-store\.cc$''
|
||||||
|
''^src/libstore/export-import\.cc$''
|
||||||
|
''^src/libstore/filetransfer\.cc$''
|
||||||
|
''^src/libstore/filetransfer\.hh$''
|
||||||
|
''^src/libstore/gc-store\.hh$''
|
||||||
|
''^src/libstore/globals\.cc$''
|
||||||
|
''^src/libstore/globals\.hh$''
|
||||||
|
''^src/libstore/http-binary-cache-store\.cc$''
|
||||||
|
''^src/libstore/legacy-ssh-store\.cc$''
|
||||||
|
''^src/libstore/legacy-ssh-store\.hh$''
|
||||||
|
''^src/libstore/length-prefixed-protocol-helper\.hh$''
|
||||||
|
''^src/libstore/linux/personality\.cc$''
|
||||||
|
''^src/libstore/linux/personality\.hh$''
|
||||||
|
''^src/libstore/local-binary-cache-store\.cc$''
|
||||||
|
''^src/libstore/local-fs-store\.cc$''
|
||||||
|
''^src/libstore/local-fs-store\.hh$''
|
||||||
|
''^src/libstore/log-store\.cc$''
|
||||||
|
''^src/libstore/log-store\.hh$''
|
||||||
|
''^src/libstore/machines\.cc$''
|
||||||
|
''^src/libstore/machines\.hh$''
|
||||||
|
''^src/libstore/make-content-addressed\.cc$''
|
||||||
|
''^src/libstore/make-content-addressed\.hh$''
|
||||||
|
''^src/libstore/misc\.cc$''
|
||||||
|
''^src/libstore/names\.cc$''
|
||||||
|
''^src/libstore/names\.hh$''
|
||||||
|
''^src/libstore/nar-accessor\.cc$''
|
||||||
|
''^src/libstore/nar-accessor\.hh$''
|
||||||
|
''^src/libstore/nar-info-disk-cache\.cc$''
|
||||||
|
''^src/libstore/nar-info-disk-cache\.hh$''
|
||||||
|
''^src/libstore/nar-info\.cc$''
|
||||||
|
''^src/libstore/nar-info\.hh$''
|
||||||
|
''^src/libstore/outputs-spec\.cc$''
|
||||||
|
''^src/libstore/outputs-spec\.hh$''
|
||||||
|
''^src/libstore/parsed-derivations\.cc$''
|
||||||
|
''^src/libstore/path-info\.cc$''
|
||||||
|
''^src/libstore/path-info\.hh$''
|
||||||
|
''^src/libstore/path-references\.cc$''
|
||||||
|
''^src/libstore/path-regex\.hh$''
|
||||||
|
''^src/libstore/path-with-outputs\.cc$''
|
||||||
|
''^src/libstore/path\.cc$''
|
||||||
|
''^src/libstore/path\.hh$''
|
||||||
|
''^src/libstore/pathlocks\.cc$''
|
||||||
|
''^src/libstore/pathlocks\.hh$''
|
||||||
|
''^src/libstore/profiles\.cc$''
|
||||||
|
''^src/libstore/profiles\.hh$''
|
||||||
|
''^src/libstore/realisation\.cc$''
|
||||||
|
''^src/libstore/realisation\.hh$''
|
||||||
|
''^src/libstore/remote-fs-accessor\.cc$''
|
||||||
|
''^src/libstore/remote-fs-accessor\.hh$''
|
||||||
|
''^src/libstore/remote-store-connection\.hh$''
|
||||||
|
''^src/libstore/remote-store\.cc$''
|
||||||
|
''^src/libstore/remote-store\.hh$''
|
||||||
|
''^src/libstore/s3-binary-cache-store\.cc$''
|
||||||
|
''^src/libstore/s3\.hh$''
|
||||||
|
''^src/libstore/serve-protocol-impl\.cc$''
|
||||||
|
''^src/libstore/serve-protocol-impl\.hh$''
|
||||||
|
''^src/libstore/serve-protocol\.cc$''
|
||||||
|
''^src/libstore/serve-protocol\.hh$''
|
||||||
|
''^src/libstore/sqlite\.cc$''
|
||||||
|
''^src/libstore/sqlite\.hh$''
|
||||||
|
''^src/libstore/ssh-store-config\.hh$''
|
||||||
|
''^src/libstore/ssh-store\.cc$''
|
||||||
|
''^src/libstore/ssh\.cc$''
|
||||||
|
''^src/libstore/ssh\.hh$''
|
||||||
|
''^src/libstore/store-api\.cc$''
|
||||||
|
''^src/libstore/store-api\.hh$''
|
||||||
|
''^src/libstore/store-dir-config\.hh$''
|
||||||
|
''^src/libstore/unix/build/derivation-goal\.cc$''
|
||||||
|
''^src/libstore/unix/build/derivation-goal\.hh$''
|
||||||
|
''^src/libstore/unix/build/drv-output-substitution-goal\.cc$''
|
||||||
|
''^src/libstore/unix/build/drv-output-substitution-goal\.hh$''
|
||||||
|
''^src/libstore/unix/build/entry-points\.cc$''
|
||||||
|
''^src/libstore/unix/build/goal\.cc$''
|
||||||
|
''^src/libstore/unix/build/goal\.hh$''
|
||||||
|
''^src/libstore/unix/build/hook-instance\.cc$''
|
||||||
|
''^src/libstore/unix/build/local-derivation-goal\.cc$''
|
||||||
|
''^src/libstore/unix/build/local-derivation-goal\.hh$''
|
||||||
|
''^src/libstore/unix/build/substitution-goal\.cc$''
|
||||||
|
''^src/libstore/unix/build/substitution-goal\.hh$''
|
||||||
|
''^src/libstore/unix/build/worker\.cc$''
|
||||||
|
''^src/libstore/unix/build/worker\.hh$''
|
||||||
|
''^src/libstore/unix/builtins/fetchurl\.cc$''
|
||||||
|
''^src/libstore/unix/builtins/unpack-channel\.cc$''
|
||||||
|
''^src/libstore/unix/gc\.cc$''
|
||||||
|
''^src/libstore/unix/local-overlay-store\.cc$''
|
||||||
|
''^src/libstore/unix/local-overlay-store\.hh$''
|
||||||
|
''^src/libstore/unix/local-store\.cc$''
|
||||||
|
''^src/libstore/unix/local-store\.hh$''
|
||||||
|
''^src/libstore/unix/lock\.cc$''
|
||||||
|
''^src/libstore/unix/lock\.hh$''
|
||||||
|
''^src/libstore/unix/optimise-store\.cc$''
|
||||||
|
''^src/libstore/unix/pathlocks\.cc$''
|
||||||
|
''^src/libstore/unix/posix-fs-canonicalise\.cc$''
|
||||||
|
''^src/libstore/unix/posix-fs-canonicalise\.hh$''
|
||||||
|
''^src/libstore/unix/uds-remote-store\.cc$''
|
||||||
|
''^src/libstore/unix/uds-remote-store\.hh$''
|
||||||
|
''^src/libstore/windows/build\.cc$''
|
||||||
|
''^src/libstore/worker-protocol-impl\.hh$''
|
||||||
|
''^src/libstore/worker-protocol\.cc$''
|
||||||
|
''^src/libstore/worker-protocol\.hh$''
|
||||||
|
''^src/libutil-c/nix_api_util_internal\.h$''
|
||||||
|
''^src/libutil/archive\.cc$''
|
||||||
|
''^src/libutil/archive\.hh$''
|
||||||
|
''^src/libutil/args\.cc$''
|
||||||
|
''^src/libutil/args\.hh$''
|
||||||
|
''^src/libutil/args/root\.hh$''
|
||||||
|
''^src/libutil/callback\.hh$''
|
||||||
|
''^src/libutil/canon-path\.cc$''
|
||||||
|
''^src/libutil/canon-path\.hh$''
|
||||||
|
''^src/libutil/chunked-vector\.hh$''
|
||||||
|
''^src/libutil/closure\.hh$''
|
||||||
|
''^src/libutil/comparator\.hh$''
|
||||||
|
''^src/libutil/compute-levels\.cc$''
|
||||||
|
''^src/libutil/config-impl\.hh$''
|
||||||
|
''^src/libutil/config\.cc$''
|
||||||
|
''^src/libutil/config\.hh$''
|
||||||
|
''^src/libutil/current-process\.cc$''
|
||||||
|
''^src/libutil/current-process\.hh$''
|
||||||
|
''^src/libutil/english\.cc$''
|
||||||
|
''^src/libutil/english\.hh$''
|
||||||
|
''^src/libutil/environment-variables\.cc$''
|
||||||
|
''^src/libutil/error\.cc$''
|
||||||
|
''^src/libutil/error\.hh$''
|
||||||
|
''^src/libutil/exit\.hh$''
|
||||||
|
''^src/libutil/experimental-features\.cc$''
|
||||||
|
''^src/libutil/experimental-features\.hh$''
|
||||||
|
''^src/libutil/file-content-address\.cc$''
|
||||||
|
''^src/libutil/file-content-address\.hh$''
|
||||||
|
''^src/libutil/file-descriptor\.cc$''
|
||||||
|
''^src/libutil/file-descriptor\.hh$''
|
||||||
|
''^src/libutil/file-path-impl\.hh$''
|
||||||
|
''^src/libutil/file-path\.hh$''
|
||||||
|
''^src/libutil/file-system\.cc$''
|
||||||
|
''^src/libutil/file-system\.hh$''
|
||||||
|
''^src/libutil/finally\.hh$''
|
||||||
|
''^src/libutil/fmt\.hh$''
|
||||||
|
''^src/libutil/fs-sink\.cc$''
|
||||||
|
''^src/libutil/fs-sink\.hh$''
|
||||||
|
''^src/libutil/git\.cc$''
|
||||||
|
''^src/libutil/git\.hh$''
|
||||||
|
''^src/libutil/hash\.cc$''
|
||||||
|
''^src/libutil/hash\.hh$''
|
||||||
|
''^src/libutil/hilite\.cc$''
|
||||||
|
''^src/libutil/hilite\.hh$''
|
||||||
|
''^src/libutil/input-accessor\.hh$''
|
||||||
|
''^src/libutil/json-impls\.hh$''
|
||||||
|
''^src/libutil/json-utils\.cc$''
|
||||||
|
''^src/libutil/json-utils\.hh$''
|
||||||
|
''^src/libutil/linux/cgroup\.cc$''
|
||||||
|
''^src/libutil/linux/namespaces\.cc$''
|
||||||
|
''^src/libutil/logging\.cc$''
|
||||||
|
''^src/libutil/logging\.hh$''
|
||||||
|
''^src/libutil/lru-cache\.hh$''
|
||||||
|
''^src/libutil/memory-source-accessor\.cc$''
|
||||||
|
''^src/libutil/memory-source-accessor\.hh$''
|
||||||
|
''^src/libutil/pool\.hh$''
|
||||||
|
''^src/libutil/position\.cc$''
|
||||||
|
''^src/libutil/position\.hh$''
|
||||||
|
''^src/libutil/posix-source-accessor\.cc$''
|
||||||
|
''^src/libutil/posix-source-accessor\.hh$''
|
||||||
|
''^src/libutil/processes\.hh$''
|
||||||
|
''^src/libutil/ref\.hh$''
|
||||||
|
''^src/libutil/references\.cc$''
|
||||||
|
''^src/libutil/references\.hh$''
|
||||||
|
''^src/libutil/regex-combinators\.hh$''
|
||||||
|
''^src/libutil/serialise\.cc$''
|
||||||
|
''^src/libutil/serialise\.hh$''
|
||||||
|
''^src/libutil/signals\.hh$''
|
||||||
|
''^src/libutil/signature/local-keys\.cc$''
|
||||||
|
''^src/libutil/signature/local-keys\.hh$''
|
||||||
|
''^src/libutil/signature/signer\.cc$''
|
||||||
|
''^src/libutil/signature/signer\.hh$''
|
||||||
|
''^src/libutil/source-accessor\.cc$''
|
||||||
|
''^src/libutil/source-accessor\.hh$''
|
||||||
|
''^src/libutil/source-path\.cc$''
|
||||||
|
''^src/libutil/source-path\.hh$''
|
||||||
|
''^src/libutil/split\.hh$''
|
||||||
|
''^src/libutil/suggestions\.cc$''
|
||||||
|
''^src/libutil/suggestions\.hh$''
|
||||||
|
''^src/libutil/sync\.hh$''
|
||||||
|
''^src/libutil/terminal\.cc$''
|
||||||
|
''^src/libutil/terminal\.hh$''
|
||||||
|
''^src/libutil/thread-pool\.cc$''
|
||||||
|
''^src/libutil/thread-pool\.hh$''
|
||||||
|
''^src/libutil/topo-sort\.hh$''
|
||||||
|
''^src/libutil/types\.hh$''
|
||||||
|
''^src/libutil/unix/file-descriptor\.cc$''
|
||||||
|
''^src/libutil/unix/file-path\.cc$''
|
||||||
|
''^src/libutil/unix/monitor-fd\.hh$''
|
||||||
|
''^src/libutil/unix/processes\.cc$''
|
||||||
|
''^src/libutil/unix/signals-impl\.hh$''
|
||||||
|
''^src/libutil/unix/signals\.cc$''
|
||||||
|
''^src/libutil/unix/unix-domain-socket\.cc$''
|
||||||
|
''^src/libutil/unix/users\.cc$''
|
||||||
|
''^src/libutil/url-parts\.hh$''
|
||||||
|
''^src/libutil/url\.cc$''
|
||||||
|
''^src/libutil/url\.hh$''
|
||||||
|
''^src/libutil/users\.cc$''
|
||||||
|
''^src/libutil/users\.hh$''
|
||||||
|
''^src/libutil/util\.cc$''
|
||||||
|
''^src/libutil/util\.hh$''
|
||||||
|
''^src/libutil/variant-wrapper\.hh$''
|
||||||
|
''^src/libutil/windows/environment-variables\.cc$''
|
||||||
|
''^src/libutil/windows/file-descriptor\.cc$''
|
||||||
|
''^src/libutil/windows/file-path\.cc$''
|
||||||
|
''^src/libutil/windows/processes\.cc$''
|
||||||
|
''^src/libutil/windows/users\.cc$''
|
||||||
|
''^src/libutil/windows/windows-error\.cc$''
|
||||||
|
''^src/libutil/windows/windows-error\.hh$''
|
||||||
|
''^src/libutil/xml-writer\.cc$''
|
||||||
|
''^src/libutil/xml-writer\.hh$''
|
||||||
|
''^src/nix-build/nix-build\.cc$''
|
||||||
|
''^src/nix-channel/nix-channel\.cc$''
|
||||||
|
''^src/nix-collect-garbage/nix-collect-garbage\.cc$''
|
||||||
|
''^src/nix-env/buildenv.nix$''
|
||||||
|
''^src/nix-env/nix-env\.cc$''
|
||||||
|
''^src/nix-env/user-env\.cc$''
|
||||||
|
''^src/nix-env/user-env\.hh$''
|
||||||
|
''^src/nix-instantiate/nix-instantiate\.cc$''
|
||||||
|
''^src/nix-store/dotgraph\.cc$''
|
||||||
|
''^src/nix-store/graphml\.cc$''
|
||||||
|
''^src/nix-store/nix-store\.cc$''
|
||||||
|
''^src/nix/add-to-store\.cc$''
|
||||||
|
''^src/nix/app\.cc$''
|
||||||
|
''^src/nix/build\.cc$''
|
||||||
|
''^src/nix/bundle\.cc$''
|
||||||
|
''^src/nix/cat\.cc$''
|
||||||
|
''^src/nix/config-check\.cc$''
|
||||||
|
''^src/nix/config\.cc$''
|
||||||
|
''^src/nix/copy\.cc$''
|
||||||
|
''^src/nix/derivation-add\.cc$''
|
||||||
|
''^src/nix/derivation-show\.cc$''
|
||||||
|
''^src/nix/derivation\.cc$''
|
||||||
|
''^src/nix/develop\.cc$''
|
||||||
|
''^src/nix/diff-closures\.cc$''
|
||||||
|
''^src/nix/dump-path\.cc$''
|
||||||
|
''^src/nix/edit\.cc$''
|
||||||
|
''^src/nix/eval\.cc$''
|
||||||
|
''^src/nix/flake\.cc$''
|
||||||
|
''^src/nix/fmt\.cc$''
|
||||||
|
''^src/nix/hash\.cc$''
|
||||||
|
''^src/nix/log\.cc$''
|
||||||
|
''^src/nix/ls\.cc$''
|
||||||
|
''^src/nix/main\.cc$''
|
||||||
|
''^src/nix/make-content-addressed\.cc$''
|
||||||
|
''^src/nix/nar\.cc$''
|
||||||
|
''^src/nix/optimise-store\.cc$''
|
||||||
|
''^src/nix/path-from-hash-part\.cc$''
|
||||||
|
''^src/nix/path-info\.cc$''
|
||||||
|
''^src/nix/prefetch\.cc$''
|
||||||
|
''^src/nix/profile\.cc$''
|
||||||
|
''^src/nix/realisation\.cc$''
|
||||||
|
''^src/nix/registry\.cc$''
|
||||||
|
''^src/nix/repl\.cc$''
|
||||||
|
''^src/nix/run\.cc$''
|
||||||
|
''^src/nix/run\.hh$''
|
||||||
|
''^src/nix/search\.cc$''
|
||||||
|
''^src/nix/sigs\.cc$''
|
||||||
|
''^src/nix/store-copy-log\.cc$''
|
||||||
|
''^src/nix/store-delete\.cc$''
|
||||||
|
''^src/nix/store-gc\.cc$''
|
||||||
|
''^src/nix/store-info\.cc$''
|
||||||
|
''^src/nix/store-repair\.cc$''
|
||||||
|
''^src/nix/store\.cc$''
|
||||||
|
''^src/nix/unix/daemon\.cc$''
|
||||||
|
''^src/nix/upgrade-nix\.cc$''
|
||||||
|
''^src/nix/verify\.cc$''
|
||||||
|
''^src/nix/why-depends\.cc$''
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
# We'll be pulling from this in the main flake
|
||||||
|
flake.getSystem = getSystem;
|
||||||
|
}
|
15
maintainers/local.mk
Normal file
15
maintainers/local.mk
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
.PHONY: format
|
||||||
|
print-top-help += echo ' format: Format source code'
|
||||||
|
|
||||||
|
# This uses the cached .pre-commit-hooks.yaml file
|
||||||
|
format:
|
||||||
|
@if ! type -p pre-commit &>/dev/null; then \
|
||||||
|
echo "make format: pre-commit not found. Please use \`nix develop\`."; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
if test -z "$$_NIX_PRE_COMMIT_HOOKS_CONFIG"; then \
|
||||||
|
echo "make format: _NIX_PRE_COMMIT_HOOKS_CONFIG not set. Please use \`nix develop\`."; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
pre-commit run --config $$_NIX_PRE_COMMIT_HOOKS_CONFIG --all-files
|
11
package.nix
11
package.nix
|
@ -1,4 +1,5 @@
|
||||||
{ lib
|
{ lib
|
||||||
|
, fetchurl
|
||||||
, stdenv
|
, stdenv
|
||||||
, releaseTools
|
, releaseTools
|
||||||
, autoconf-archive
|
, autoconf-archive
|
||||||
|
@ -167,6 +168,8 @@ in {
|
||||||
./m4
|
./m4
|
||||||
# TODO: do we really need README.md? It doesn't seem used in the build.
|
# TODO: do we really need README.md? It doesn't seem used in the build.
|
||||||
./README.md
|
./README.md
|
||||||
|
# This could be put behind a conditional
|
||||||
|
./maintainers/local.mk
|
||||||
# For make, regardless of what we are building
|
# For make, regardless of what we are building
|
||||||
./local.mk
|
./local.mk
|
||||||
./Makefile
|
./Makefile
|
||||||
|
@ -246,7 +249,13 @@ in {
|
||||||
] ++ lib.optionals buildUnitTests [
|
] ++ lib.optionals buildUnitTests [
|
||||||
gtest
|
gtest
|
||||||
rapidcheck
|
rapidcheck
|
||||||
] ++ lib.optional stdenv.isLinux libseccomp
|
] ++ lib.optional stdenv.isLinux (libseccomp.overrideAttrs (_: rec {
|
||||||
|
version = "2.5.5";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/seccomp/libseccomp/releases/download/v${version}/libseccomp-${version}.tar.gz";
|
||||||
|
hash = "sha256-JIosik2bmFiqa69ScSw0r+/PnJ6Ut23OAsHJqiX7M3U=";
|
||||||
|
};
|
||||||
|
}))
|
||||||
++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid
|
++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid
|
||||||
# There have been issues building these dependencies
|
# There have been issues building these dependencies
|
||||||
++ lib.optional (stdenv.hostPlatform == stdenv.buildPlatform && (stdenv.isLinux || stdenv.isDarwin))
|
++ lib.optional (stdenv.hostPlatform == stdenv.buildPlatform && (stdenv.isLinux || stdenv.isDarwin))
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include "experimental-features.hh"
|
#include "experimental-features.hh"
|
||||||
|
|
||||||
using namespace nix;
|
using namespace nix;
|
||||||
using namespace nix::unix;
|
|
||||||
using std::cin;
|
using std::cin;
|
||||||
|
|
||||||
static void handleAlarm(int sig) {
|
static void handleAlarm(int sig) {
|
||||||
|
|
|
@ -128,10 +128,10 @@ ref<EvalState> EvalCommand::getEvalState()
|
||||||
evalState =
|
evalState =
|
||||||
#if HAVE_BOEHMGC
|
#if HAVE_BOEHMGC
|
||||||
std::allocate_shared<EvalState>(traceable_allocator<EvalState>(),
|
std::allocate_shared<EvalState>(traceable_allocator<EvalState>(),
|
||||||
searchPath, getEvalStore(), getStore())
|
lookupPath, getEvalStore(), getStore())
|
||||||
#else
|
#else
|
||||||
std::make_shared<EvalState>(
|
std::make_shared<EvalState>(
|
||||||
searchPath, getEvalStore(), getStore())
|
lookupPath, getEvalStore(), getStore())
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ MixEvalArgs::MixEvalArgs()
|
||||||
.category = category,
|
.category = category,
|
||||||
.labels = {"path"},
|
.labels = {"path"},
|
||||||
.handler = {[&](std::string s) {
|
.handler = {[&](std::string s) {
|
||||||
searchPath.elements.emplace_back(SearchPath::Elem::parse(s));
|
lookupPath.elements.emplace_back(LookupPath::Elem::parse(s));
|
||||||
}}
|
}}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ struct MixEvalArgs : virtual Args, virtual MixRepair
|
||||||
|
|
||||||
Bindings * getAutoArgs(EvalState & state);
|
Bindings * getAutoArgs(EvalState & state);
|
||||||
|
|
||||||
SearchPath searchPath;
|
LookupPath lookupPath;
|
||||||
|
|
||||||
std::optional<std::string> evalStoreUrl;
|
std::optional<std::string> evalStoreUrl;
|
||||||
|
|
||||||
|
@ -38,6 +38,9 @@ private:
|
||||||
std::map<std::string, AutoArg> autoArgs;
|
std::map<std::string, AutoArg> autoArgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param baseDir Optional [base directory](https://nixos.org/manual/nix/unstable/glossary#gloss-base-directory)
|
||||||
|
*/
|
||||||
SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * baseDir = nullptr);
|
SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * baseDir = nullptr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ struct NixRepl
|
||||||
|
|
||||||
std::unique_ptr<ReplInteracter> interacter;
|
std::unique_ptr<ReplInteracter> interacter;
|
||||||
|
|
||||||
NixRepl(const SearchPath & searchPath, nix::ref<Store> store,ref<EvalState> state,
|
NixRepl(const LookupPath & lookupPath, nix::ref<Store> store,ref<EvalState> state,
|
||||||
std::function<AnnotatedValues()> getValues);
|
std::function<AnnotatedValues()> getValues);
|
||||||
virtual ~NixRepl() = default;
|
virtual ~NixRepl() = default;
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ std::string removeWhitespace(std::string s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NixRepl::NixRepl(const SearchPath & searchPath, nix::ref<Store> store, ref<EvalState> state,
|
NixRepl::NixRepl(const LookupPath & lookupPath, nix::ref<Store> store, ref<EvalState> state,
|
||||||
std::function<NixRepl::AnnotatedValues()> getValues)
|
std::function<NixRepl::AnnotatedValues()> getValues)
|
||||||
: AbstractNixRepl(state)
|
: AbstractNixRepl(state)
|
||||||
, debugTraceIndex(0)
|
, debugTraceIndex(0)
|
||||||
|
@ -508,7 +508,7 @@ ProcessLineResult NixRepl::processLine(std::string line)
|
||||||
|
|
||||||
// runProgram redirects stdout to a StringSink,
|
// runProgram redirects stdout to a StringSink,
|
||||||
// using runProgram2 to allow editors to display their UI
|
// using runProgram2 to allow editors to display their UI
|
||||||
runProgram2(RunOptions { .program = editor, .searchPath = true, .args = args });
|
runProgram2(RunOptions { .program = editor, .lookupPath = true, .args = args });
|
||||||
|
|
||||||
// Reload right after exiting the editor
|
// Reload right after exiting the editor
|
||||||
state->resetFileCache();
|
state->resetFileCache();
|
||||||
|
@ -784,11 +784,11 @@ void NixRepl::evalString(std::string s, Value & v)
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<AbstractNixRepl> AbstractNixRepl::create(
|
std::unique_ptr<AbstractNixRepl> AbstractNixRepl::create(
|
||||||
const SearchPath & searchPath, nix::ref<Store> store, ref<EvalState> state,
|
const LookupPath & lookupPath, nix::ref<Store> store, ref<EvalState> state,
|
||||||
std::function<AnnotatedValues()> getValues)
|
std::function<AnnotatedValues()> getValues)
|
||||||
{
|
{
|
||||||
return std::make_unique<NixRepl>(
|
return std::make_unique<NixRepl>(
|
||||||
searchPath,
|
lookupPath,
|
||||||
openStore(),
|
openStore(),
|
||||||
state,
|
state,
|
||||||
getValues
|
getValues
|
||||||
|
@ -804,9 +804,9 @@ ReplExitStatus AbstractNixRepl::runSimple(
|
||||||
NixRepl::AnnotatedValues values;
|
NixRepl::AnnotatedValues values;
|
||||||
return values;
|
return values;
|
||||||
};
|
};
|
||||||
SearchPath searchPath = {};
|
LookupPath lookupPath = {};
|
||||||
auto repl = std::make_unique<NixRepl>(
|
auto repl = std::make_unique<NixRepl>(
|
||||||
searchPath,
|
lookupPath,
|
||||||
openStore(),
|
openStore(),
|
||||||
evalState,
|
evalState,
|
||||||
getValues
|
getValues
|
||||||
|
|
|
@ -20,7 +20,7 @@ struct AbstractNixRepl
|
||||||
typedef std::vector<std::pair<Value*,std::string>> AnnotatedValues;
|
typedef std::vector<std::pair<Value*,std::string>> AnnotatedValues;
|
||||||
|
|
||||||
static std::unique_ptr<AbstractNixRepl> create(
|
static std::unique_ptr<AbstractNixRepl> create(
|
||||||
const SearchPath & searchPath, nix::ref<Store> store, ref<EvalState> state,
|
const LookupPath & lookupPath, nix::ref<Store> store, ref<EvalState> state,
|
||||||
std::function<AnnotatedValues()> getValues);
|
std::function<AnnotatedValues()> getValues);
|
||||||
|
|
||||||
static ReplExitStatus runSimple(
|
static ReplExitStatus runSimple(
|
||||||
|
|
|
@ -85,17 +85,17 @@ nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, Value *
|
||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
EvalState * nix_state_create(nix_c_context * context, const char ** searchPath_c, Store * store)
|
EvalState * nix_state_create(nix_c_context * context, const char ** lookupPath_c, Store * store)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
try {
|
try {
|
||||||
nix::Strings searchPath;
|
nix::Strings lookupPath;
|
||||||
if (searchPath_c != nullptr)
|
if (lookupPath_c != nullptr)
|
||||||
for (size_t i = 0; searchPath_c[i] != nullptr; i++)
|
for (size_t i = 0; lookupPath_c[i] != nullptr; i++)
|
||||||
searchPath.push_back(searchPath_c[i]);
|
lookupPath.push_back(lookupPath_c[i]);
|
||||||
|
|
||||||
return new EvalState{nix::EvalState(nix::SearchPath::parse(searchPath), store->ptr)};
|
return new EvalState{nix::EvalState(nix::LookupPath::parse(lookupPath), store->ptr)};
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS_NULL
|
NIXC_CATCH_ERRS_NULL
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,11 +140,11 @@ nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, Value *
|
||||||
* @brief Create a new Nix language evaluator state.
|
* @brief Create a new Nix language evaluator state.
|
||||||
*
|
*
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
* @param[in] searchPath Array of strings corresponding to entries in NIX_PATH.
|
* @param[in] lookupPath Array of strings corresponding to entries in NIX_PATH.
|
||||||
* @param[in] store The Nix store to use.
|
* @param[in] store The Nix store to use.
|
||||||
* @return A new Nix state or NULL on failure.
|
* @return A new Nix state or NULL on failure.
|
||||||
*/
|
*/
|
||||||
EvalState * nix_state_create(nix_c_context * context, const char ** searchPath, Store * store);
|
EvalState * nix_state_create(nix_c_context * context, const char ** lookupPath, Store * store);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Frees a Nix state.
|
* @brief Frees a Nix state.
|
||||||
|
|
|
@ -343,7 +343,7 @@ void initGC()
|
||||||
}
|
}
|
||||||
|
|
||||||
EvalState::EvalState(
|
EvalState::EvalState(
|
||||||
const SearchPath & _searchPath,
|
const LookupPath & _lookupPath,
|
||||||
ref<Store> store,
|
ref<Store> store,
|
||||||
std::shared_ptr<Store> buildStore)
|
std::shared_ptr<Store> buildStore)
|
||||||
: sWith(symbols.create("<with>"))
|
: sWith(symbols.create("<with>"))
|
||||||
|
@ -448,16 +448,16 @@ EvalState::EvalState(
|
||||||
|
|
||||||
/* Initialise the Nix expression search path. */
|
/* Initialise the Nix expression search path. */
|
||||||
if (!evalSettings.pureEval) {
|
if (!evalSettings.pureEval) {
|
||||||
for (auto & i : _searchPath.elements)
|
for (auto & i : _lookupPath.elements)
|
||||||
searchPath.elements.emplace_back(SearchPath::Elem {i});
|
lookupPath.elements.emplace_back(LookupPath::Elem {i});
|
||||||
for (auto & i : evalSettings.nixPath.get())
|
for (auto & i : evalSettings.nixPath.get())
|
||||||
searchPath.elements.emplace_back(SearchPath::Elem::parse(i));
|
lookupPath.elements.emplace_back(LookupPath::Elem::parse(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allow access to all paths in the search path. */
|
/* Allow access to all paths in the search path. */
|
||||||
if (rootFS.dynamic_pointer_cast<AllowListInputAccessor>())
|
if (rootFS.dynamic_pointer_cast<AllowListInputAccessor>())
|
||||||
for (auto & i : searchPath.elements)
|
for (auto & i : lookupPath.elements)
|
||||||
resolveSearchPathPath(i.path, true);
|
resolveLookupPathPath(i.path, true);
|
||||||
|
|
||||||
corepkgsFS->addFile(
|
corepkgsFS->addFile(
|
||||||
CanonPath("fetchurl.nix"),
|
CanonPath("fetchurl.nix"),
|
||||||
|
@ -2820,19 +2820,19 @@ Expr * EvalState::parseStdin()
|
||||||
|
|
||||||
SourcePath EvalState::findFile(const std::string_view path)
|
SourcePath EvalState::findFile(const std::string_view path)
|
||||||
{
|
{
|
||||||
return findFile(searchPath, path);
|
return findFile(lookupPath, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SourcePath EvalState::findFile(const SearchPath & searchPath, const std::string_view path, const PosIdx pos)
|
SourcePath EvalState::findFile(const LookupPath & lookupPath, const std::string_view path, const PosIdx pos)
|
||||||
{
|
{
|
||||||
for (auto & i : searchPath.elements) {
|
for (auto & i : lookupPath.elements) {
|
||||||
auto suffixOpt = i.prefix.suffixIfPotentialMatch(path);
|
auto suffixOpt = i.prefix.suffixIfPotentialMatch(path);
|
||||||
|
|
||||||
if (!suffixOpt) continue;
|
if (!suffixOpt) continue;
|
||||||
auto suffix = *suffixOpt;
|
auto suffix = *suffixOpt;
|
||||||
|
|
||||||
auto rOpt = resolveSearchPathPath(i.path);
|
auto rOpt = resolveLookupPathPath(i.path);
|
||||||
if (!rOpt) continue;
|
if (!rOpt) continue;
|
||||||
auto r = *rOpt;
|
auto r = *rOpt;
|
||||||
|
|
||||||
|
@ -2852,11 +2852,11 @@ SourcePath EvalState::findFile(const SearchPath & searchPath, const std::string_
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::optional<std::string> EvalState::resolveSearchPathPath(const SearchPath::Path & value0, bool initAccessControl)
|
std::optional<std::string> EvalState::resolveLookupPathPath(const LookupPath::Path & value0, bool initAccessControl)
|
||||||
{
|
{
|
||||||
auto & value = value0.s;
|
auto & value = value0.s;
|
||||||
auto i = searchPathResolved.find(value);
|
auto i = lookupPathResolved.find(value);
|
||||||
if (i != searchPathResolved.end()) return i->second;
|
if (i != lookupPathResolved.end()) return i->second;
|
||||||
|
|
||||||
std::optional<std::string> res;
|
std::optional<std::string> res;
|
||||||
|
|
||||||
|
@ -2912,7 +2912,7 @@ std::optional<std::string> EvalState::resolveSearchPathPath(const SearchPath::Pa
|
||||||
else
|
else
|
||||||
debug("failed to resolve search path element '%s'", value);
|
debug("failed to resolve search path element '%s'", value);
|
||||||
|
|
||||||
searchPathResolved.emplace(value, res);
|
lookupPathResolved.emplace(value, res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,9 +161,6 @@ struct DebugTrace {
|
||||||
bool isError;
|
bool isError;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Don't want Windows function
|
|
||||||
#undef SearchPath
|
|
||||||
|
|
||||||
class EvalState : public std::enable_shared_from_this<EvalState>
|
class EvalState : public std::enable_shared_from_this<EvalState>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -311,9 +308,9 @@ private:
|
||||||
#endif
|
#endif
|
||||||
FileEvalCache fileEvalCache;
|
FileEvalCache fileEvalCache;
|
||||||
|
|
||||||
SearchPath searchPath;
|
LookupPath lookupPath;
|
||||||
|
|
||||||
std::map<std::string, std::optional<std::string>> searchPathResolved;
|
std::map<std::string, std::optional<std::string>> lookupPathResolved;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache used by prim_match().
|
* Cache used by prim_match().
|
||||||
|
@ -335,12 +332,12 @@ private:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
EvalState(
|
EvalState(
|
||||||
const SearchPath & _searchPath,
|
const LookupPath & _lookupPath,
|
||||||
ref<Store> store,
|
ref<Store> store,
|
||||||
std::shared_ptr<Store> buildStore = nullptr);
|
std::shared_ptr<Store> buildStore = nullptr);
|
||||||
~EvalState();
|
~EvalState();
|
||||||
|
|
||||||
SearchPath getSearchPath() { return searchPath; }
|
LookupPath getLookupPath() { return lookupPath; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a `SourcePath` that refers to `path` in the root
|
* Return a `SourcePath` that refers to `path` in the root
|
||||||
|
@ -409,7 +406,7 @@ public:
|
||||||
* Look up a file in the search path.
|
* Look up a file in the search path.
|
||||||
*/
|
*/
|
||||||
SourcePath findFile(const std::string_view path);
|
SourcePath findFile(const std::string_view path);
|
||||||
SourcePath findFile(const SearchPath & searchPath, const std::string_view path, const PosIdx pos = noPos);
|
SourcePath findFile(const LookupPath & lookupPath, const std::string_view path, const PosIdx pos = noPos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to resolve a search path value (not the optional key part).
|
* Try to resolve a search path value (not the optional key part).
|
||||||
|
@ -418,8 +415,8 @@ public:
|
||||||
*
|
*
|
||||||
* If it is not found, return `std::nullopt`
|
* If it is not found, return `std::nullopt`
|
||||||
*/
|
*/
|
||||||
std::optional<std::string> resolveSearchPathPath(
|
std::optional<std::string> resolveLookupPathPath(
|
||||||
const SearchPath::Path & elem,
|
const LookupPath::Path & elem,
|
||||||
bool initAccessControl = false);
|
bool initAccessControl = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -68,24 +68,39 @@ struct FlakeRef
|
||||||
|
|
||||||
std::ostream & operator << (std::ostream & str, const FlakeRef & flakeRef);
|
std::ostream & operator << (std::ostream & str, const FlakeRef & flakeRef);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param baseDir Optional [base directory](https://nixos.org/manual/nix/unstable/glossary#gloss-base-directory)
|
||||||
|
*/
|
||||||
FlakeRef parseFlakeRef(
|
FlakeRef parseFlakeRef(
|
||||||
const std::string & url,
|
const std::string & url,
|
||||||
const std::optional<Path> & baseDir = {},
|
const std::optional<Path> & baseDir = {},
|
||||||
bool allowMissing = false,
|
bool allowMissing = false,
|
||||||
bool isFlake = true);
|
bool isFlake = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param baseDir Optional [base directory](https://nixos.org/manual/nix/unstable/glossary#gloss-base-directory)
|
||||||
|
*/
|
||||||
std::optional<FlakeRef> maybeParseFlake(
|
std::optional<FlakeRef> maybeParseFlake(
|
||||||
const std::string & url, const std::optional<Path> & baseDir = {});
|
const std::string & url, const std::optional<Path> & baseDir = {});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param baseDir Optional [base directory](https://nixos.org/manual/nix/unstable/glossary#gloss-base-directory)
|
||||||
|
*/
|
||||||
std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
|
std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
|
||||||
const std::string & url,
|
const std::string & url,
|
||||||
const std::optional<Path> & baseDir = {},
|
const std::optional<Path> & baseDir = {},
|
||||||
bool allowMissing = false,
|
bool allowMissing = false,
|
||||||
bool isFlake = true);
|
bool isFlake = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param baseDir Optional [base directory](https://nixos.org/manual/nix/unstable/glossary#gloss-base-directory)
|
||||||
|
*/
|
||||||
std::optional<std::pair<FlakeRef, std::string>> maybeParseFlakeRefWithFragment(
|
std::optional<std::pair<FlakeRef, std::string>> maybeParseFlakeRefWithFragment(
|
||||||
const std::string & url, const std::optional<Path> & baseDir = {});
|
const std::string & url, const std::optional<Path> & baseDir = {});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param baseDir Optional [base directory](https://nixos.org/manual/nix/unstable/glossary#gloss-base-directory)
|
||||||
|
*/
|
||||||
std::tuple<FlakeRef, std::string, ExtendedOutputsSpec> parseFlakeRefWithFragmentAndExtendedOutputsSpec(
|
std::tuple<FlakeRef, std::string, ExtendedOutputsSpec> parseFlakeRefWithFragmentAndExtendedOutputsSpec(
|
||||||
const std::string & url,
|
const std::string & url,
|
||||||
const std::optional<Path> & baseDir = {},
|
const std::optional<Path> & baseDir = {},
|
||||||
|
|
|
@ -1716,7 +1716,7 @@ static void prim_findFile(EvalState & state, const PosIdx pos, Value * * args, V
|
||||||
{
|
{
|
||||||
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.findFile");
|
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.findFile");
|
||||||
|
|
||||||
SearchPath searchPath;
|
LookupPath lookupPath;
|
||||||
|
|
||||||
for (auto v2 : args[0]->listItems()) {
|
for (auto v2 : args[0]->listItems()) {
|
||||||
state.forceAttrs(*v2, pos, "while evaluating an element of the list passed to builtins.findFile");
|
state.forceAttrs(*v2, pos, "while evaluating an element of the list passed to builtins.findFile");
|
||||||
|
@ -1744,15 +1744,15 @@ static void prim_findFile(EvalState & state, const PosIdx pos, Value * * args, V
|
||||||
).atPos(pos).debugThrow();
|
).atPos(pos).debugThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
searchPath.elements.emplace_back(SearchPath::Elem {
|
lookupPath.elements.emplace_back(LookupPath::Elem {
|
||||||
.prefix = SearchPath::Prefix { .s = prefix },
|
.prefix = LookupPath::Prefix { .s = prefix },
|
||||||
.path = SearchPath::Path { .s = path },
|
.path = LookupPath::Path { .s = path },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
auto path = state.forceStringNoCtx(*args[1], pos, "while evaluating the second argument passed to builtins.findFile");
|
auto path = state.forceStringNoCtx(*args[1], pos, "while evaluating the second argument passed to builtins.findFile");
|
||||||
|
|
||||||
v.mkPath(state.findFile(searchPath, path, pos));
|
v.mkPath(state.findFile(lookupPath, path, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_findFile(PrimOp {
|
static RegisterPrimOp primop_findFile(PrimOp {
|
||||||
|
@ -4637,8 +4637,8 @@ void EvalState::createBaseEnv()
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Add a value containing the current Nix expression search path. */
|
/* Add a value containing the current Nix expression search path. */
|
||||||
auto list = buildList(searchPath.elements.size());
|
auto list = buildList(lookupPath.elements.size());
|
||||||
for (const auto & [n, i] : enumerate(searchPath.elements)) {
|
for (const auto & [n, i] : enumerate(lookupPath.elements)) {
|
||||||
auto attrs = buildBindings(2);
|
auto attrs = buildBindings(2);
|
||||||
attrs.alloc("path").mkString(i.path.s);
|
attrs.alloc("path").mkString(i.path.s);
|
||||||
attrs.alloc("prefix").mkString(i.prefix.s);
|
attrs.alloc("prefix").mkString(i.prefix.s);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
std::optional<std::string_view> SearchPath::Prefix::suffixIfPotentialMatch(
|
std::optional<std::string_view> LookupPath::Prefix::suffixIfPotentialMatch(
|
||||||
std::string_view path) const
|
std::string_view path) const
|
||||||
{
|
{
|
||||||
auto n = s.size();
|
auto n = s.size();
|
||||||
|
@ -27,11 +27,11 @@ std::optional<std::string_view> SearchPath::Prefix::suffixIfPotentialMatch(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SearchPath::Elem SearchPath::Elem::parse(std::string_view rawElem)
|
LookupPath::Elem LookupPath::Elem::parse(std::string_view rawElem)
|
||||||
{
|
{
|
||||||
size_t pos = rawElem.find('=');
|
size_t pos = rawElem.find('=');
|
||||||
|
|
||||||
return SearchPath::Elem {
|
return LookupPath::Elem {
|
||||||
.prefix = Prefix {
|
.prefix = Prefix {
|
||||||
.s = pos == std::string::npos
|
.s = pos == std::string::npos
|
||||||
? std::string { "" }
|
? std::string { "" }
|
||||||
|
@ -44,11 +44,11 @@ SearchPath::Elem SearchPath::Elem::parse(std::string_view rawElem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SearchPath SearchPath::parse(const Strings & rawElems)
|
LookupPath LookupPath::parse(const Strings & rawElems)
|
||||||
{
|
{
|
||||||
SearchPath res;
|
LookupPath res;
|
||||||
for (auto & rawElem : rawElems)
|
for (auto & rawElem : rawElems)
|
||||||
res.elements.emplace_back(SearchPath::Elem::parse(rawElem));
|
res.elements.emplace_back(LookupPath::Elem::parse(rawElem));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,17 +8,14 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
// Do not want the windows macro (alias to `SearchPathA`)
|
|
||||||
#undef SearchPath
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A "search path" is a list of ways look for something, used with
|
* A "search path" is a list of ways look for something, used with
|
||||||
* `builtins.findFile` and `< >` lookup expressions.
|
* `builtins.findFile` and `< >` lookup expressions.
|
||||||
*/
|
*/
|
||||||
struct SearchPath
|
struct LookupPath
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* A single element of a `SearchPath`.
|
* A single element of a `LookupPath`.
|
||||||
*
|
*
|
||||||
* Each element is tried in succession when looking up a path. The first
|
* Each element is tried in succession when looking up a path. The first
|
||||||
* element to completely match wins.
|
* element to completely match wins.
|
||||||
|
@ -26,16 +23,16 @@ struct SearchPath
|
||||||
struct Elem;
|
struct Elem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The first part of a `SearchPath::Elem` pair.
|
* The first part of a `LookupPath::Elem` pair.
|
||||||
*
|
*
|
||||||
* Called a "prefix" because it takes the form of a prefix of a file
|
* Called a "prefix" because it takes the form of a prefix of a file
|
||||||
* path (first `n` path components). When looking up a path, to use
|
* path (first `n` path components). When looking up a path, to use
|
||||||
* a `SearchPath::Elem`, its `Prefix` must match the path.
|
* a `LookupPath::Elem`, its `Prefix` must match the path.
|
||||||
*/
|
*/
|
||||||
struct Prefix;
|
struct Prefix;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The second part of a `SearchPath::Elem` pair.
|
* The second part of a `LookupPath::Elem` pair.
|
||||||
*
|
*
|
||||||
* It is either a path or a URL (with certain restrictions / extra
|
* It is either a path or a URL (with certain restrictions / extra
|
||||||
* structure).
|
* structure).
|
||||||
|
@ -43,7 +40,7 @@ struct SearchPath
|
||||||
* If the prefix of the path we are looking up matches, we then
|
* If the prefix of the path we are looking up matches, we then
|
||||||
* check if the rest of the path points to something that exists
|
* check if the rest of the path points to something that exists
|
||||||
* within the directory denoted by this. If so, the
|
* within the directory denoted by this. If so, the
|
||||||
* `SearchPath::Elem` as a whole matches, and that *something* being
|
* `LookupPath::Elem` as a whole matches, and that *something* being
|
||||||
* pointed to by the rest of the path we are looking up is the
|
* pointed to by the rest of the path we are looking up is the
|
||||||
* result.
|
* result.
|
||||||
*/
|
*/
|
||||||
|
@ -54,24 +51,24 @@ struct SearchPath
|
||||||
* when looking up. (The actual lookup entry point is in `EvalState`
|
* when looking up. (The actual lookup entry point is in `EvalState`
|
||||||
* not in this class.)
|
* not in this class.)
|
||||||
*/
|
*/
|
||||||
std::list<SearchPath::Elem> elements;
|
std::list<LookupPath::Elem> elements;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a string into a `SearchPath`
|
* Parse a string into a `LookupPath`
|
||||||
*/
|
*/
|
||||||
static SearchPath parse(const Strings & rawElems);
|
static LookupPath parse(const Strings & rawElems);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SearchPath::Prefix
|
struct LookupPath::Prefix
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Underlying string
|
* Underlying string
|
||||||
*
|
*
|
||||||
* @todo Should we normalize this when constructing a `SearchPath::Prefix`?
|
* @todo Should we normalize this when constructing a `LookupPath::Prefix`?
|
||||||
*/
|
*/
|
||||||
std::string s;
|
std::string s;
|
||||||
|
|
||||||
GENERATE_CMP(SearchPath::Prefix, me->s);
|
GENERATE_CMP(LookupPath::Prefix, me->s);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the path possibly matches this search path element, return the
|
* If the path possibly matches this search path element, return the
|
||||||
|
@ -82,7 +79,7 @@ struct SearchPath::Prefix
|
||||||
std::optional<std::string_view> suffixIfPotentialMatch(std::string_view path) const;
|
std::optional<std::string_view> suffixIfPotentialMatch(std::string_view path) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SearchPath::Path
|
struct LookupPath::Path
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The location of a search path item, as a path or URL.
|
* The location of a search path item, as a path or URL.
|
||||||
|
@ -91,21 +88,21 @@ struct SearchPath::Path
|
||||||
*/
|
*/
|
||||||
std::string s;
|
std::string s;
|
||||||
|
|
||||||
GENERATE_CMP(SearchPath::Path, me->s);
|
GENERATE_CMP(LookupPath::Path, me->s);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SearchPath::Elem
|
struct LookupPath::Elem
|
||||||
{
|
{
|
||||||
|
|
||||||
Prefix prefix;
|
Prefix prefix;
|
||||||
Path path;
|
Path path;
|
||||||
|
|
||||||
GENERATE_CMP(SearchPath::Elem, me->prefix, me->path);
|
GENERATE_CMP(LookupPath::Elem, me->prefix, me->path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a string into a `SearchPath::Elem`
|
* Parse a string into a `LookupPath::Elem`
|
||||||
*/
|
*/
|
||||||
static SearchPath::Elem parse(std::string_view rawElem);
|
static LookupPath::Elem parse(std::string_view rawElem);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,7 +385,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
||||||
|
|
||||||
runProgram(RunOptions {
|
runProgram(RunOptions {
|
||||||
.program = "git",
|
.program = "git",
|
||||||
.searchPath = true,
|
.lookupPath = true,
|
||||||
// FIXME: git stderr messes up our progress indicator, so
|
// FIXME: git stderr messes up our progress indicator, so
|
||||||
// we're using --quiet for now. Should process its stderr.
|
// we're using --quiet for now. Should process its stderr.
|
||||||
.args = gitArgs,
|
.args = gitArgs,
|
||||||
|
|
|
@ -24,7 +24,7 @@ static RunOptions hgOptions(const Strings & args)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
.program = "hg",
|
.program = "hg",
|
||||||
.searchPath = true,
|
.lookupPath = true,
|
||||||
.args = args,
|
.args = args,
|
||||||
.environment = env
|
.environment = env
|
||||||
};
|
};
|
||||||
|
|
|
@ -113,7 +113,7 @@ static void sigHandler(int signo) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void initNix()
|
void initNix(bool loadConfig)
|
||||||
{
|
{
|
||||||
/* Turn on buffering for cerr. */
|
/* Turn on buffering for cerr. */
|
||||||
#if HAVE_PUBSETBUF
|
#if HAVE_PUBSETBUF
|
||||||
|
@ -121,7 +121,7 @@ void initNix()
|
||||||
std::cerr.rdbuf()->pubsetbuf(buf, sizeof(buf));
|
std::cerr.rdbuf()->pubsetbuf(buf, sizeof(buf));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
initLibStore();
|
initLibStore(loadConfig);
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
unix::startSignalHandlerThread();
|
unix::startSignalHandlerThread();
|
||||||
|
|
|
@ -21,8 +21,9 @@ int handleExceptions(const std::string & programName, std::function<void()> fun)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Don't forget to call initPlugins() after settings are initialized!
|
* Don't forget to call initPlugins() after settings are initialized!
|
||||||
|
* @param loadConfig Whether to load configuration from `nix.conf`, `NIX_CONFIG`, etc. May be disabled for unit tests.
|
||||||
*/
|
*/
|
||||||
void initNix();
|
void initNix(bool loadConfig = true);
|
||||||
|
|
||||||
void parseCmdLine(int argc, char * * argv,
|
void parseCmdLine(int argc, char * * argv,
|
||||||
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg);
|
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg);
|
||||||
|
|
|
@ -19,6 +19,16 @@ nix_err nix_libstore_init(nix_c_context * context)
|
||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nix_err nix_libstore_init_no_load_config(nix_c_context * context)
|
||||||
|
{
|
||||||
|
if (context)
|
||||||
|
context->last_err_code = NIX_OK;
|
||||||
|
try {
|
||||||
|
nix::initLibStore(false);
|
||||||
|
}
|
||||||
|
NIXC_CATCH_ERRS
|
||||||
|
}
|
||||||
|
|
||||||
nix_err nix_init_plugins(nix_c_context * context)
|
nix_err nix_init_plugins(nix_c_context * context)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
|
|
|
@ -35,6 +35,13 @@ typedef struct StorePath StorePath;
|
||||||
*/
|
*/
|
||||||
nix_err nix_libstore_init(nix_c_context * context);
|
nix_err nix_libstore_init(nix_c_context * context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Like nix_libstore_init, but does not load the Nix configuration.
|
||||||
|
*
|
||||||
|
* This is useful when external configuration is not desired, such as when running unit tests.
|
||||||
|
*/
|
||||||
|
nix_err nix_libstore_init_no_load_config(nix_c_context * context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Loads the plugins specified in Nix's plugin-files setting.
|
* @brief Loads the plugins specified in Nix's plugin-files setting.
|
||||||
*
|
*
|
||||||
|
|
|
@ -427,12 +427,13 @@ void assertLibStoreInitialized() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void initLibStore() {
|
void initLibStore(bool loadConfig) {
|
||||||
if (initLibStoreDone) return;
|
if (initLibStoreDone) return;
|
||||||
|
|
||||||
initLibUtil();
|
initLibUtil();
|
||||||
|
|
||||||
loadConfFile();
|
if (loadConfig)
|
||||||
|
loadConfFile();
|
||||||
|
|
||||||
preloadNSS();
|
preloadNSS();
|
||||||
|
|
||||||
|
|
|
@ -1279,9 +1279,10 @@ std::vector<Path> getUserConfigFiles();
|
||||||
extern const std::string nixVersion;
|
extern const std::string nixVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NB: This is not sufficient. You need to call initNix()
|
* @param loadConfig Whether to load configuration from `nix.conf`, `NIX_CONFIG`, etc. May be disabled for unit tests.
|
||||||
|
* @note When using libexpr, and/or libmain, This is not sufficient. See initNix().
|
||||||
*/
|
*/
|
||||||
void initLibStore();
|
void initLibStore(bool loadConfig = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It's important to initialize before doing _anything_, which is why we
|
* It's important to initialize before doing _anything_, which is why we
|
||||||
|
|
|
@ -5,10 +5,26 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open (possibly create) a lock file and return the file descriptor.
|
||||||
|
* -1 is returned if create is false and the lock could not be opened
|
||||||
|
* because it doesn't exist. Any other error throws an exception.
|
||||||
|
*/
|
||||||
|
AutoCloseFD openLockFile(const Path & path, bool create);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an open lock file.
|
||||||
|
*/
|
||||||
|
void deleteLockFile(const Path & path, Descriptor desc);
|
||||||
|
|
||||||
|
enum LockType { ltRead, ltWrite, ltNone };
|
||||||
|
|
||||||
|
bool lockFile(Descriptor desc, LockType lockType, bool wait);
|
||||||
|
|
||||||
class PathLocks
|
class PathLocks
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef std::pair<int, Path> FDPair;
|
typedef std::pair<Descriptor, Path> FDPair;
|
||||||
std::list<FDPair> fds;
|
std::list<FDPair> fds;
|
||||||
bool deletePaths;
|
bool deletePaths;
|
||||||
|
|
||||||
|
@ -24,6 +40,18 @@ public:
|
||||||
void setDeletion(bool deletePaths);
|
void setDeletion(bool deletePaths);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
struct FdLock
|
||||||
|
{
|
||||||
|
Descriptor desc;
|
||||||
|
bool acquired = false;
|
||||||
|
|
||||||
#include "pathlocks-impl.hh"
|
FdLock(Descriptor desc, LockType lockType, bool wait, std::string_view waitMsg);
|
||||||
|
|
||||||
|
~FdLock()
|
||||||
|
{
|
||||||
|
if (acquired)
|
||||||
|
lockFile(desc, ltNone, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ void handleDiffHook(
|
||||||
try {
|
try {
|
||||||
auto diffRes = runProgram(RunOptions {
|
auto diffRes = runProgram(RunOptions {
|
||||||
.program = diffHook,
|
.program = diffHook,
|
||||||
.searchPath = true,
|
.lookupPath = true,
|
||||||
.args = {tryA, tryB, drvPath, tmpDir},
|
.args = {tryA, tryB, drvPath, tmpDir},
|
||||||
.uid = uid,
|
.uid = uid,
|
||||||
.gid = gid,
|
.gid = gid,
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
using namespace nix::unix;
|
|
||||||
|
|
||||||
#if __linux__
|
#if __linux__
|
||||||
|
|
||||||
static std::vector<gid_t> get_group_list(const char *username, gid_t group_id)
|
static std::vector<gid_t> get_group_list(const char *username, gid_t group_id)
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
#pragma once
|
|
||||||
///@file
|
|
||||||
|
|
||||||
#include "file-descriptor.hh"
|
|
||||||
|
|
||||||
namespace nix::unix {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open (possibly create) a lock file and return the file descriptor.
|
|
||||||
* -1 is returned if create is false and the lock could not be opened
|
|
||||||
* because it doesn't exist. Any other error throws an exception.
|
|
||||||
*/
|
|
||||||
AutoCloseFD openLockFile(const Path & path, bool create);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete an open lock file.
|
|
||||||
*/
|
|
||||||
void deleteLockFile(const Path & path, int fd);
|
|
||||||
|
|
||||||
enum LockType { ltRead, ltWrite, ltNone };
|
|
||||||
|
|
||||||
bool lockFile(int fd, LockType lockType, bool wait);
|
|
||||||
|
|
||||||
struct FdLock
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
bool acquired = false;
|
|
||||||
|
|
||||||
FdLock(int fd, LockType lockType, bool wait, std::string_view waitMsg);
|
|
||||||
|
|
||||||
~FdLock()
|
|
||||||
{
|
|
||||||
if (acquired)
|
|
||||||
lockFile(fd, ltNone, false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -14,9 +14,7 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
using namespace nix::unix;
|
AutoCloseFD openLockFile(const Path & path, bool create)
|
||||||
|
|
||||||
AutoCloseFD unix::openLockFile(const Path & path, bool create)
|
|
||||||
{
|
{
|
||||||
AutoCloseFD fd;
|
AutoCloseFD fd;
|
||||||
|
|
||||||
|
@ -28,20 +26,20 @@ AutoCloseFD unix::openLockFile(const Path & path, bool create)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void unix::deleteLockFile(const Path & path, int fd)
|
void deleteLockFile(const Path & path, Descriptor desc)
|
||||||
{
|
{
|
||||||
/* Get rid of the lock file. Have to be careful not to introduce
|
/* Get rid of the lock file. Have to be careful not to introduce
|
||||||
races. Write a (meaningless) token to the file to indicate to
|
races. Write a (meaningless) token to the file to indicate to
|
||||||
other processes waiting on this lock that the lock is stale
|
other processes waiting on this lock that the lock is stale
|
||||||
(deleted). */
|
(deleted). */
|
||||||
unlink(path.c_str());
|
unlink(path.c_str());
|
||||||
writeFull(fd, "d");
|
writeFull(desc, "d");
|
||||||
/* Note that the result of unlink() is ignored; removing the lock
|
/* Note that the result of unlink() is ignored; removing the lock
|
||||||
file is an optimisation, not a necessity. */
|
file is an optimisation, not a necessity. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool unix::lockFile(int fd, LockType lockType, bool wait)
|
bool lockFile(Descriptor desc, LockType lockType, bool wait)
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
if (lockType == ltRead) type = LOCK_SH;
|
if (lockType == ltRead) type = LOCK_SH;
|
||||||
|
@ -50,7 +48,7 @@ bool unix::lockFile(int fd, LockType lockType, bool wait)
|
||||||
else abort();
|
else abort();
|
||||||
|
|
||||||
if (wait) {
|
if (wait) {
|
||||||
while (flock(fd, type) != 0) {
|
while (flock(desc, type) != 0) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
if (errno != EINTR)
|
if (errno != EINTR)
|
||||||
throw SysError("acquiring/releasing lock");
|
throw SysError("acquiring/releasing lock");
|
||||||
|
@ -58,7 +56,7 @@ bool unix::lockFile(int fd, LockType lockType, bool wait)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (flock(fd, type | LOCK_NB) != 0) {
|
while (flock(desc, type | LOCK_NB) != 0) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
if (errno == EWOULDBLOCK) return false;
|
if (errno == EWOULDBLOCK) return false;
|
||||||
if (errno != EINTR)
|
if (errno != EINTR)
|
||||||
|
@ -149,16 +147,16 @@ void PathLocks::unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FdLock::FdLock(int fd, LockType lockType, bool wait, std::string_view waitMsg)
|
FdLock::FdLock(Descriptor desc, LockType lockType, bool wait, std::string_view waitMsg)
|
||||||
: fd(fd)
|
: desc(desc)
|
||||||
{
|
{
|
||||||
if (wait) {
|
if (wait) {
|
||||||
if (!lockFile(fd, lockType, false)) {
|
if (!lockFile(desc, lockType, false)) {
|
||||||
printInfo("%s", waitMsg);
|
printInfo("%s", waitMsg);
|
||||||
acquired = lockFile(fd, lockType, true);
|
acquired = lockFile(desc, lockType, true);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
acquired = lockFile(fd, lockType, false);
|
acquired = lockFile(desc, lockType, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
#pragma once
|
|
||||||
///@file Needed because Unix-specific counterpart
|
|
|
@ -1,16 +1,149 @@
|
||||||
#include "logging.hh"
|
#include "logging.hh"
|
||||||
#include "pathlocks.hh"
|
#include "pathlocks.hh"
|
||||||
|
#include "signals.hh"
|
||||||
|
#include "util.hh"
|
||||||
|
#include <errhandlingapi.h>
|
||||||
|
#include <fileapi.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include "windows-error.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
bool PathLocks::lockPaths(const PathSet & _paths, const std::string & waitMsg, bool wait)
|
void deleteLockFile(const Path & path, Descriptor desc)
|
||||||
{
|
{
|
||||||
return true;
|
|
||||||
|
int exit = DeleteFileA(path.c_str());
|
||||||
|
if (exit == 0)
|
||||||
|
warn("%s: &s", path, std::to_string(GetLastError()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathLocks::unlock()
|
void PathLocks::unlock()
|
||||||
{
|
{
|
||||||
warn("PathLocks::unlock: not yet implemented");
|
for (auto & i : fds) {
|
||||||
|
if (deletePaths)
|
||||||
|
deleteLockFile(i.second, i.first);
|
||||||
|
|
||||||
|
if (CloseHandle(i.first) == -1)
|
||||||
|
printError("error (ignored): cannot close lock file on '%1%'", i.second);
|
||||||
|
|
||||||
|
debug("lock released on '%1%'", i.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
fds.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoCloseFD openLockFile(const Path & path, bool create)
|
||||||
|
{
|
||||||
|
AutoCloseFD desc = CreateFileA(
|
||||||
|
path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||||||
|
create ? OPEN_ALWAYS : OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_POSIX_SEMANTICS, NULL);
|
||||||
|
if (desc.get() == INVALID_HANDLE_VALUE)
|
||||||
|
warn("%s: %s", path, std::to_string(GetLastError()));
|
||||||
|
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lockFile(Descriptor desc, LockType lockType, bool wait)
|
||||||
|
{
|
||||||
|
switch (lockType) {
|
||||||
|
case ltNone: {
|
||||||
|
OVERLAPPED ov = {0};
|
||||||
|
if (!UnlockFileEx(desc, 0, 2, 0, &ov)) {
|
||||||
|
WinError winError("Failed to unlock file desc %s", desc);
|
||||||
|
throw winError;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case ltRead: {
|
||||||
|
OVERLAPPED ov = {0};
|
||||||
|
if (!LockFileEx(desc, wait ? 0 : LOCKFILE_FAIL_IMMEDIATELY, 0, 1, 0, &ov)) {
|
||||||
|
WinError winError("Failed to lock file desc %s", desc);
|
||||||
|
if (winError.lastError == ERROR_LOCK_VIOLATION)
|
||||||
|
return false;
|
||||||
|
throw winError;
|
||||||
|
}
|
||||||
|
|
||||||
|
ov.Offset = 1;
|
||||||
|
if (!UnlockFileEx(desc, 0, 1, 0, &ov)) {
|
||||||
|
WinError winError("Failed to unlock file desc %s", desc);
|
||||||
|
if (winError.lastError != ERROR_NOT_LOCKED)
|
||||||
|
throw winError;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case ltWrite: {
|
||||||
|
OVERLAPPED ov = {0};
|
||||||
|
ov.Offset = 1;
|
||||||
|
if (!LockFileEx(desc, LOCKFILE_EXCLUSIVE_LOCK | (wait ? 0 : LOCKFILE_FAIL_IMMEDIATELY), 0, 1, 0, &ov)) {
|
||||||
|
WinError winError("Failed to lock file desc %s", desc);
|
||||||
|
if (winError.lastError == ERROR_LOCK_VIOLATION)
|
||||||
|
return false;
|
||||||
|
throw winError;
|
||||||
|
}
|
||||||
|
|
||||||
|
ov.Offset = 0;
|
||||||
|
if (!UnlockFileEx(desc, 0, 1, 0, &ov)) {
|
||||||
|
WinError winError("Failed to unlock file desc %s", desc);
|
||||||
|
if (winError.lastError != ERROR_NOT_LOCKED)
|
||||||
|
throw winError;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PathLocks::lockPaths(const PathSet & paths, const std::string & waitMsg, bool wait)
|
||||||
|
{
|
||||||
|
assert(fds.empty());
|
||||||
|
|
||||||
|
for (auto & path : paths) {
|
||||||
|
checkInterrupt();
|
||||||
|
Path lockPath = path + ".lock";
|
||||||
|
debug("locking path '%1%'", path);
|
||||||
|
|
||||||
|
AutoCloseFD fd;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
fd = openLockFile(lockPath, true);
|
||||||
|
if (!lockFile(fd.get(), ltWrite, false)) {
|
||||||
|
if (wait) {
|
||||||
|
if (waitMsg != "")
|
||||||
|
printError(waitMsg);
|
||||||
|
lockFile(fd.get(), ltWrite, true);
|
||||||
|
} else {
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("lock aquired on '%1%'", lockPath);
|
||||||
|
|
||||||
|
struct _stat st;
|
||||||
|
if (_fstat(fromDescriptorReadOnly(fd.get()), &st) == -1)
|
||||||
|
throw SysError("statting lock file '%1%'", lockPath);
|
||||||
|
if (st.st_size != 0)
|
||||||
|
debug("open lock file '%1%' has become stale", lockPath);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fds.push_back(FDPair(fd.release(), lockPath));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FdLock::FdLock(Descriptor desc, LockType lockType, bool wait, std::string_view waitMsg)
|
||||||
|
: desc(desc)
|
||||||
|
{
|
||||||
|
if (wait) {
|
||||||
|
if (!lockFile(desc, lockType, false)) {
|
||||||
|
printInfo("%s", waitMsg);
|
||||||
|
acquired = lockFile(desc, lockType, true);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
acquired = lockFile(desc, lockType, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
virtual std::string doc() { return ""; }
|
virtual std::string doc() { return ""; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the base directory for the command.
|
* @brief Get the [base directory](https://nixos.org/manual/nix/unstable/glossary#gloss-base-directory) for the command.
|
||||||
*
|
*
|
||||||
* @return Generally the working directory, but in case of a shebang
|
* @return Generally the working directory, but in case of a shebang
|
||||||
* interpreter, returns the directory of the script.
|
* interpreter, returns the directory of the script.
|
||||||
|
|
|
@ -80,14 +80,14 @@ pid_t startProcess(std::function<void()> fun, const ProcessOptions & options = P
|
||||||
* Run a program and return its stdout in a string (i.e., like the
|
* Run a program and return its stdout in a string (i.e., like the
|
||||||
* shell backtick operator).
|
* shell backtick operator).
|
||||||
*/
|
*/
|
||||||
std::string runProgram(Path program, bool searchPath = false,
|
std::string runProgram(Path program, bool lookupPath = false,
|
||||||
const Strings & args = Strings(),
|
const Strings & args = Strings(),
|
||||||
const std::optional<std::string> & input = {}, bool isInteractive = false);
|
const std::optional<std::string> & input = {}, bool isInteractive = false);
|
||||||
|
|
||||||
struct RunOptions
|
struct RunOptions
|
||||||
{
|
{
|
||||||
Path program;
|
Path program;
|
||||||
bool searchPath = true;
|
bool lookupPath = true;
|
||||||
Strings args;
|
Strings args;
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
std::optional<uid_t> uid;
|
std::optional<uid_t> uid;
|
||||||
|
|
|
@ -245,10 +245,10 @@ pid_t startProcess(std::function<void()> fun, const ProcessOptions & options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string runProgram(Path program, bool searchPath, const Strings & args,
|
std::string runProgram(Path program, bool lookupPath, const Strings & args,
|
||||||
const std::optional<std::string> & input, bool isInteractive)
|
const std::optional<std::string> & input, bool isInteractive)
|
||||||
{
|
{
|
||||||
auto res = runProgram(RunOptions {.program = program, .searchPath = searchPath, .args = args, .input = input, .isInteractive = isInteractive});
|
auto res = runProgram(RunOptions {.program = program, .lookupPath = lookupPath, .args = args, .input = input, .isInteractive = isInteractive});
|
||||||
|
|
||||||
if (!statusOk(res.first))
|
if (!statusOk(res.first))
|
||||||
throw ExecError(res.first, "program '%1%' %2%", program, statusToString(res.first));
|
throw ExecError(res.first, "program '%1%' %2%", program, statusToString(res.first));
|
||||||
|
@ -335,7 +335,7 @@ void runProgram2(const RunOptions & options)
|
||||||
|
|
||||||
restoreProcessContext();
|
restoreProcessContext();
|
||||||
|
|
||||||
if (options.searchPath)
|
if (options.lookupPath)
|
||||||
execvp(options.program.c_str(), stringsToCharPtrs(args_).data());
|
execvp(options.program.c_str(), stringsToCharPtrs(args_).data());
|
||||||
// This allows you to refer to a program with a pathname relative
|
// This allows you to refer to a program with a pathname relative
|
||||||
// to the PATH variable.
|
// to the PATH variable.
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
std::string runProgram(Path program, bool searchPath, const Strings & args,
|
std::string runProgram(Path program, bool lookupPath, const Strings & args,
|
||||||
const std::optional<std::string> & input, bool isInteractive)
|
const std::optional<std::string> & input, bool isInteractive)
|
||||||
{
|
{
|
||||||
throw UnimplementedError("Cannot shell out to git on Windows yet");
|
throw UnimplementedError("Cannot shell out to git on Windows yet");
|
||||||
|
|
|
@ -258,7 +258,7 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
auto store = openStore();
|
auto store = openStore();
|
||||||
auto evalStore = myArgs.evalStoreUrl ? openStore(*myArgs.evalStoreUrl) : store;
|
auto evalStore = myArgs.evalStoreUrl ? openStore(*myArgs.evalStoreUrl) : store;
|
||||||
|
|
||||||
auto state = std::make_unique<EvalState>(myArgs.searchPath, evalStore, store);
|
auto state = std::make_unique<EvalState>(myArgs.lookupPath, evalStore, store);
|
||||||
state->repair = myArgs.repair;
|
state->repair = myArgs.repair;
|
||||||
if (myArgs.repair) buildMode = bmRepair;
|
if (myArgs.repair) buildMode = bmRepair;
|
||||||
|
|
||||||
|
|
|
@ -1525,7 +1525,7 @@ static int main_nix_env(int argc, char * * argv)
|
||||||
|
|
||||||
auto store = openStore();
|
auto store = openStore();
|
||||||
|
|
||||||
globals.state = std::shared_ptr<EvalState>(new EvalState(myArgs.searchPath, store));
|
globals.state = std::shared_ptr<EvalState>(new EvalState(myArgs.lookupPath, store));
|
||||||
globals.state->repair = myArgs.repair;
|
globals.state->repair = myArgs.repair;
|
||||||
|
|
||||||
globals.instSource.nixExprPath = std::make_shared<SourcePath>(
|
globals.instSource.nixExprPath = std::make_shared<SourcePath>(
|
||||||
|
|
|
@ -157,7 +157,7 @@ static int main_nix_instantiate(int argc, char * * argv)
|
||||||
auto store = openStore();
|
auto store = openStore();
|
||||||
auto evalStore = myArgs.evalStoreUrl ? openStore(*myArgs.evalStoreUrl) : store;
|
auto evalStore = myArgs.evalStoreUrl ? openStore(*myArgs.evalStoreUrl) : store;
|
||||||
|
|
||||||
auto state = std::make_unique<EvalState>(myArgs.searchPath, evalStore, store);
|
auto state = std::make_unique<EvalState>(myArgs.lookupPath, evalStore, store);
|
||||||
state->repair = myArgs.repair;
|
state->repair = myArgs.repair;
|
||||||
|
|
||||||
Bindings & autoArgs = *myArgs.getAutoArgs(*state);
|
Bindings & autoArgs = *myArgs.getAutoArgs(*state);
|
||||||
|
|
|
@ -687,7 +687,7 @@ struct CmdDevelop : Common, MixEnvironment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runProgramInStore(store, UseSearchPath::Use, shell, args, buildEnvironment.getSystem());
|
runProgramInStore(store, UseLookupPath::Use, shell, args, buildEnvironment.getSystem());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -454,11 +454,6 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
if (v.payload.lambda.fun->hasFormals()
|
if (v.payload.lambda.fun->hasFormals()
|
||||||
|| !argHasName(v.payload.lambda.fun->arg, "final"))
|
|| !argHasName(v.payload.lambda.fun->arg, "final"))
|
||||||
throw Error("overlay does not take an argument named 'final'");
|
throw Error("overlay does not take an argument named 'final'");
|
||||||
auto body = dynamic_cast<ExprLambda *>(v.payload.lambda.fun->body);
|
|
||||||
if (!body
|
|
||||||
|| body->hasFormals()
|
|
||||||
|| !argHasName(body->arg, "prev"))
|
|
||||||
throw Error("overlay does not take an argument named 'prev'");
|
|
||||||
// FIXME: if we have a 'nixpkgs' input, use it to
|
// FIXME: if we have a 'nixpkgs' input, use it to
|
||||||
// evaluate the overlay.
|
// evaluate the overlay.
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
|
|
|
@ -49,7 +49,7 @@ struct CmdFmt : SourceExprCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runProgramInStore(store, UseSearchPath::DontUse, app.program, programArgs);
|
runProgramInStore(store, UseLookupPath::DontUse, app.program, programArgs);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ static int main_nix_prefetch_url(int argc, char * * argv)
|
||||||
startProgressBar();
|
startProgressBar();
|
||||||
|
|
||||||
auto store = openStore();
|
auto store = openStore();
|
||||||
auto state = std::make_unique<EvalState>(myArgs.searchPath, store);
|
auto state = std::make_unique<EvalState>(myArgs.lookupPath, store);
|
||||||
|
|
||||||
Bindings & autoArgs = *myArgs.getAutoArgs(*state);
|
Bindings & autoArgs = *myArgs.getAutoArgs(*state);
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ struct CmdRepl : RawInstallablesCommand
|
||||||
return values;
|
return values;
|
||||||
};
|
};
|
||||||
auto repl = AbstractNixRepl::create(
|
auto repl = AbstractNixRepl::create(
|
||||||
searchPath,
|
lookupPath,
|
||||||
openStore(),
|
openStore(),
|
||||||
state,
|
state,
|
||||||
getValues
|
getValues
|
||||||
|
|
|
@ -26,7 +26,7 @@ std::string chrootHelperName = "__run_in_chroot";
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
void runProgramInStore(ref<Store> store,
|
void runProgramInStore(ref<Store> store,
|
||||||
UseSearchPath useSearchPath,
|
UseLookupPath useLookupPath,
|
||||||
const std::string & program,
|
const std::string & program,
|
||||||
const Strings & args,
|
const Strings & args,
|
||||||
std::optional<std::string_view> system)
|
std::optional<std::string_view> system)
|
||||||
|
@ -62,7 +62,7 @@ void runProgramInStore(ref<Store> store,
|
||||||
linux::setPersonality(*system);
|
linux::setPersonality(*system);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (useSearchPath == UseSearchPath::Use)
|
if (useLookupPath == UseLookupPath::Use)
|
||||||
execvp(program.c_str(), stringsToCharPtrs(args).data());
|
execvp(program.c_str(), stringsToCharPtrs(args).data());
|
||||||
else
|
else
|
||||||
execv(program.c_str(), stringsToCharPtrs(args).data());
|
execv(program.c_str(), stringsToCharPtrs(args).data());
|
||||||
|
@ -183,7 +183,7 @@ struct CmdShell : InstallablesCommand, MixEnvironment
|
||||||
Strings args;
|
Strings args;
|
||||||
for (auto & arg : command) args.push_back(arg);
|
for (auto & arg : command) args.push_back(arg);
|
||||||
|
|
||||||
runProgramInStore(store, UseSearchPath::Use, *command.begin(), args);
|
runProgramInStore(store, UseLookupPath::Use, *command.begin(), args);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ struct CmdRun : InstallableValueCommand
|
||||||
Strings allArgs{app.program};
|
Strings allArgs{app.program};
|
||||||
for (auto & i : args) allArgs.push_back(i);
|
for (auto & i : args) allArgs.push_back(i);
|
||||||
|
|
||||||
runProgramInStore(store, UseSearchPath::DontUse, app.program, allArgs);
|
runProgramInStore(store, UseLookupPath::DontUse, app.program, allArgs);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
enum struct UseSearchPath {
|
enum struct UseLookupPath {
|
||||||
Use,
|
Use,
|
||||||
DontUse
|
DontUse
|
||||||
};
|
};
|
||||||
|
|
||||||
void runProgramInStore(ref<Store> store,
|
void runProgramInStore(ref<Store> store,
|
||||||
UseSearchPath useSearchPath,
|
UseLookupPath useLookupPath,
|
||||||
const std::string & program,
|
const std::string & program,
|
||||||
const Strings & args,
|
const Strings & args,
|
||||||
std::optional<std::string_view> system = std::nullopt);
|
std::optional<std::string_view> system = std::nullopt);
|
||||||
|
|
|
@ -147,7 +147,7 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand
|
||||||
auto req = FileTransferRequest((std::string&) settings.upgradeNixStorePathUrl);
|
auto req = FileTransferRequest((std::string&) settings.upgradeNixStorePathUrl);
|
||||||
auto res = getFileTransfer()->download(req);
|
auto res = getFileTransfer()->download(req);
|
||||||
|
|
||||||
auto state = std::make_unique<EvalState>(SearchPath{}, store);
|
auto state = std::make_unique<EvalState>(LookupPath{}, store);
|
||||||
auto v = state->allocValue();
|
auto v = state->allocValue();
|
||||||
state->eval(state->parseExprFromString(res.data, state->rootPath(CanonPath("/no-such-path"))), *v);
|
state->eval(state->parseExprFromString(res.data, state->rootPath(CanonPath("/no-such-path"))), *v);
|
||||||
Bindings & bindings(*state->allocBindings(0));
|
Bindings & bindings(*state->allocBindings(0));
|
||||||
|
|
|
@ -5,85 +5,85 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
TEST(SearchPathElem, parse_justPath) {
|
TEST(LookupPathElem, parse_justPath) {
|
||||||
ASSERT_EQ(
|
ASSERT_EQ(
|
||||||
SearchPath::Elem::parse("foo"),
|
LookupPath::Elem::parse("foo"),
|
||||||
(SearchPath::Elem {
|
(LookupPath::Elem {
|
||||||
.prefix = SearchPath::Prefix { .s = "" },
|
.prefix = LookupPath::Prefix { .s = "" },
|
||||||
.path = SearchPath::Path { .s = "foo" },
|
.path = LookupPath::Path { .s = "foo" },
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SearchPathElem, parse_emptyPrefix) {
|
TEST(LookupPathElem, parse_emptyPrefix) {
|
||||||
ASSERT_EQ(
|
ASSERT_EQ(
|
||||||
SearchPath::Elem::parse("=foo"),
|
LookupPath::Elem::parse("=foo"),
|
||||||
(SearchPath::Elem {
|
(LookupPath::Elem {
|
||||||
.prefix = SearchPath::Prefix { .s = "" },
|
.prefix = LookupPath::Prefix { .s = "" },
|
||||||
.path = SearchPath::Path { .s = "foo" },
|
.path = LookupPath::Path { .s = "foo" },
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SearchPathElem, parse_oneEq) {
|
TEST(LookupPathElem, parse_oneEq) {
|
||||||
ASSERT_EQ(
|
ASSERT_EQ(
|
||||||
SearchPath::Elem::parse("foo=bar"),
|
LookupPath::Elem::parse("foo=bar"),
|
||||||
(SearchPath::Elem {
|
(LookupPath::Elem {
|
||||||
.prefix = SearchPath::Prefix { .s = "foo" },
|
.prefix = LookupPath::Prefix { .s = "foo" },
|
||||||
.path = SearchPath::Path { .s = "bar" },
|
.path = LookupPath::Path { .s = "bar" },
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SearchPathElem, parse_twoEqs) {
|
TEST(LookupPathElem, parse_twoEqs) {
|
||||||
ASSERT_EQ(
|
ASSERT_EQ(
|
||||||
SearchPath::Elem::parse("foo=bar=baz"),
|
LookupPath::Elem::parse("foo=bar=baz"),
|
||||||
(SearchPath::Elem {
|
(LookupPath::Elem {
|
||||||
.prefix = SearchPath::Prefix { .s = "foo" },
|
.prefix = LookupPath::Prefix { .s = "foo" },
|
||||||
.path = SearchPath::Path { .s = "bar=baz" },
|
.path = LookupPath::Path { .s = "bar=baz" },
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST(SearchPathElem, suffixIfPotentialMatch_justPath) {
|
TEST(LookupPathElem, suffixIfPotentialMatch_justPath) {
|
||||||
SearchPath::Prefix prefix { .s = "" };
|
LookupPath::Prefix prefix { .s = "" };
|
||||||
ASSERT_EQ(prefix.suffixIfPotentialMatch("any/thing"), std::optional { "any/thing" });
|
ASSERT_EQ(prefix.suffixIfPotentialMatch("any/thing"), std::optional { "any/thing" });
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SearchPathElem, suffixIfPotentialMatch_misleadingPrefix1) {
|
TEST(LookupPathElem, suffixIfPotentialMatch_misleadingPrefix1) {
|
||||||
SearchPath::Prefix prefix { .s = "foo" };
|
LookupPath::Prefix prefix { .s = "foo" };
|
||||||
ASSERT_EQ(prefix.suffixIfPotentialMatch("fooX"), std::nullopt);
|
ASSERT_EQ(prefix.suffixIfPotentialMatch("fooX"), std::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SearchPathElem, suffixIfPotentialMatch_misleadingPrefix2) {
|
TEST(LookupPathElem, suffixIfPotentialMatch_misleadingPrefix2) {
|
||||||
SearchPath::Prefix prefix { .s = "foo" };
|
LookupPath::Prefix prefix { .s = "foo" };
|
||||||
ASSERT_EQ(prefix.suffixIfPotentialMatch("fooX/bar"), std::nullopt);
|
ASSERT_EQ(prefix.suffixIfPotentialMatch("fooX/bar"), std::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SearchPathElem, suffixIfPotentialMatch_partialPrefix) {
|
TEST(LookupPathElem, suffixIfPotentialMatch_partialPrefix) {
|
||||||
SearchPath::Prefix prefix { .s = "fooX" };
|
LookupPath::Prefix prefix { .s = "fooX" };
|
||||||
ASSERT_EQ(prefix.suffixIfPotentialMatch("foo"), std::nullopt);
|
ASSERT_EQ(prefix.suffixIfPotentialMatch("foo"), std::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SearchPathElem, suffixIfPotentialMatch_exactPrefix) {
|
TEST(LookupPathElem, suffixIfPotentialMatch_exactPrefix) {
|
||||||
SearchPath::Prefix prefix { .s = "foo" };
|
LookupPath::Prefix prefix { .s = "foo" };
|
||||||
ASSERT_EQ(prefix.suffixIfPotentialMatch("foo"), std::optional { "" });
|
ASSERT_EQ(prefix.suffixIfPotentialMatch("foo"), std::optional { "" });
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SearchPathElem, suffixIfPotentialMatch_multiKey) {
|
TEST(LookupPathElem, suffixIfPotentialMatch_multiKey) {
|
||||||
SearchPath::Prefix prefix { .s = "foo/bar" };
|
LookupPath::Prefix prefix { .s = "foo/bar" };
|
||||||
ASSERT_EQ(prefix.suffixIfPotentialMatch("foo/bar/baz"), std::optional { "baz" });
|
ASSERT_EQ(prefix.suffixIfPotentialMatch("foo/bar/baz"), std::optional { "baz" });
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SearchPathElem, suffixIfPotentialMatch_trailingSlash) {
|
TEST(LookupPathElem, suffixIfPotentialMatch_trailingSlash) {
|
||||||
SearchPath::Prefix prefix { .s = "foo" };
|
LookupPath::Prefix prefix { .s = "foo" };
|
||||||
ASSERT_EQ(prefix.suffixIfPotentialMatch("foo/"), std::optional { "" });
|
ASSERT_EQ(prefix.suffixIfPotentialMatch("foo/"), std::optional { "" });
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SearchPathElem, suffixIfPotentialMatch_trailingDoubleSlash) {
|
TEST(LookupPathElem, suffixIfPotentialMatch_trailingDoubleSlash) {
|
||||||
SearchPath::Prefix prefix { .s = "foo" };
|
LookupPath::Prefix prefix { .s = "foo" };
|
||||||
ASSERT_EQ(prefix.suffixIfPotentialMatch("foo//"), std::optional { "/" });
|
ASSERT_EQ(prefix.suffixIfPotentialMatch("foo//"), std::optional { "/" });
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SearchPathElem, suffixIfPotentialMatch_trailingPath) {
|
TEST(LookupPathElem, suffixIfPotentialMatch_trailingPath) {
|
||||||
SearchPath::Prefix prefix { .s = "foo" };
|
LookupPath::Prefix prefix { .s = "foo" };
|
||||||
ASSERT_EQ(prefix.suffixIfPotentialMatch("foo/bar/baz"), std::optional { "bar/baz" });
|
ASSERT_EQ(prefix.suffixIfPotentialMatch("foo/bar/baz"), std::optional { "bar/baz" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace nix {
|
||||||
class LibStoreTest : public virtual ::testing::Test {
|
class LibStoreTest : public virtual ::testing::Test {
|
||||||
public:
|
public:
|
||||||
static void SetUpTestSuite() {
|
static void SetUpTestSuite() {
|
||||||
initLibStore();
|
initLibStore(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Reference in a new issue