forked from lix-project/lix
Merge branch 'master' into paths-from-stdin
This commit is contained in:
commit
1f394d2107
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
|
@ -20,6 +20,8 @@ jobs:
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: cachix/install-nix-action@v19
|
- uses: cachix/install-nix-action@v19
|
||||||
|
with:
|
||||||
|
install_url: https://releases.nixos.org/nix/nix-2.13.3/install
|
||||||
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
||||||
- uses: cachix/cachix-action@v12
|
- uses: cachix/cachix-action@v12
|
||||||
if: needs.check_secrets.outputs.cachix == 'true'
|
if: needs.check_secrets.outputs.cachix == 'true'
|
||||||
|
@ -59,6 +61,8 @@ jobs:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
||||||
- uses: cachix/install-nix-action@v19
|
- uses: cachix/install-nix-action@v19
|
||||||
|
with:
|
||||||
|
install_url: https://releases.nixos.org/nix/nix-2.13.3/install
|
||||||
- uses: cachix/cachix-action@v12
|
- uses: cachix/cachix-action@v12
|
||||||
with:
|
with:
|
||||||
name: '${{ env.CACHIX_NAME }}'
|
name: '${{ env.CACHIX_NAME }}'
|
||||||
|
@ -103,6 +107,8 @@ jobs:
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: cachix/install-nix-action@v19
|
- uses: cachix/install-nix-action@v19
|
||||||
|
with:
|
||||||
|
install_url: https://releases.nixos.org/nix/nix-2.13.3/install
|
||||||
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
||||||
- run: echo NIX_VERSION="$(nix --experimental-features 'nix-command flakes' eval .\#default.version | tr -d \")" >> $GITHUB_ENV
|
- run: echo NIX_VERSION="$(nix --experimental-features 'nix-command flakes' eval .\#default.version | tr -d \")" >> $GITHUB_ENV
|
||||||
- uses: cachix/cachix-action@v12
|
- uses: cachix/cachix-action@v12
|
||||||
|
|
19
Makefile
19
Makefile
|
@ -2,13 +2,10 @@ makefiles = \
|
||||||
mk/precompiled-headers.mk \
|
mk/precompiled-headers.mk \
|
||||||
local.mk \
|
local.mk \
|
||||||
src/libutil/local.mk \
|
src/libutil/local.mk \
|
||||||
src/libutil/tests/local.mk \
|
|
||||||
src/libstore/local.mk \
|
src/libstore/local.mk \
|
||||||
src/libstore/tests/local.mk \
|
|
||||||
src/libfetchers/local.mk \
|
src/libfetchers/local.mk \
|
||||||
src/libmain/local.mk \
|
src/libmain/local.mk \
|
||||||
src/libexpr/local.mk \
|
src/libexpr/local.mk \
|
||||||
src/libexpr/tests/local.mk \
|
|
||||||
src/libcmd/local.mk \
|
src/libcmd/local.mk \
|
||||||
src/nix/local.mk \
|
src/nix/local.mk \
|
||||||
src/resolve-system-dependencies/local.mk \
|
src/resolve-system-dependencies/local.mk \
|
||||||
|
@ -19,12 +16,22 @@ makefiles = \
|
||||||
misc/systemd/local.mk \
|
misc/systemd/local.mk \
|
||||||
misc/launchd/local.mk \
|
misc/launchd/local.mk \
|
||||||
misc/upstart/local.mk \
|
misc/upstart/local.mk \
|
||||||
doc/manual/local.mk \
|
doc/manual/local.mk
|
||||||
tests/local.mk \
|
|
||||||
tests/plugins/local.mk
|
|
||||||
|
|
||||||
-include Makefile.config
|
-include Makefile.config
|
||||||
|
|
||||||
|
ifeq ($(tests), yes)
|
||||||
|
makefiles += \
|
||||||
|
src/libutil/tests/local.mk \
|
||||||
|
src/libstore/tests/local.mk \
|
||||||
|
src/libexpr/tests/local.mk \
|
||||||
|
tests/local.mk \
|
||||||
|
tests/plugins/local.mk
|
||||||
|
else
|
||||||
|
makefiles += \
|
||||||
|
mk/disable-tests.mk
|
||||||
|
endif
|
||||||
|
|
||||||
OPTIMIZE = 1
|
OPTIMIZE = 1
|
||||||
|
|
||||||
ifeq ($(OPTIMIZE), 1)
|
ifeq ($(OPTIMIZE), 1)
|
||||||
|
|
|
@ -45,3 +45,4 @@ sandbox_shell = @sandbox_shell@
|
||||||
storedir = @storedir@
|
storedir = @storedir@
|
||||||
sysconfdir = @sysconfdir@
|
sysconfdir = @sysconfdir@
|
||||||
system = @system@
|
system = @system@
|
||||||
|
tests = @tests@
|
||||||
|
|
10
configure.ac
10
configure.ac
|
@ -145,6 +145,13 @@ if test "x$GCC_ATOMIC_BUILTINS_NEED_LIBATOMIC" = xyes; then
|
||||||
LDFLAGS="-latomic $LDFLAGS"
|
LDFLAGS="-latomic $LDFLAGS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Building without tests is useful for bootstrapping with a smaller footprint
|
||||||
|
# or running the tests in a separate derivation. Otherwise, we do compile and
|
||||||
|
# run them.
|
||||||
|
AC_ARG_ENABLE(tests, AS_HELP_STRING([--disable-tests],[Do not build the tests]),
|
||||||
|
tests=$enableval, tests=yes)
|
||||||
|
AC_SUBST(tests)
|
||||||
|
|
||||||
# LTO is currently broken with clang for unknown reasons; ld segfaults in the llvm plugin
|
# LTO is currently broken with clang for unknown reasons; ld segfaults in the llvm plugin
|
||||||
AC_ARG_ENABLE(lto, AS_HELP_STRING([--enable-lto],[Enable LTO (only supported with GCC) [default=no]]),
|
AC_ARG_ENABLE(lto, AS_HELP_STRING([--enable-lto],[Enable LTO (only supported with GCC) [default=no]]),
|
||||||
lto=$enableval, lto=no)
|
lto=$enableval, lto=no)
|
||||||
|
@ -270,6 +277,8 @@ if test "$gc" = yes; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test "$tests" = yes; then
|
||||||
|
|
||||||
# Look for gtest.
|
# Look for gtest.
|
||||||
PKG_CHECK_MODULES([GTEST], [gtest_main])
|
PKG_CHECK_MODULES([GTEST], [gtest_main])
|
||||||
|
|
||||||
|
@ -282,6 +291,7 @@ dnl No good for C++ libs with mangled symbols
|
||||||
dnl AC_CHECK_LIB([rapidcheck], [])
|
dnl AC_CHECK_LIB([rapidcheck], [])
|
||||||
AC_LANG_POP(C++)
|
AC_LANG_POP(C++)
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
# Look for nlohmann/json.
|
# Look for nlohmann/json.
|
||||||
PKG_CHECK_MODULES([NLOHMANN_JSON], [nlohmann_json >= 3.9])
|
PKG_CHECK_MODULES([NLOHMANN_JSON], [nlohmann_json >= 3.9])
|
||||||
|
|
|
@ -71,3 +71,8 @@
|
||||||
<http://libcpuid.sourceforge.net>.
|
<http://libcpuid.sourceforge.net>.
|
||||||
This is an optional dependency and can be disabled
|
This is an optional dependency and can be disabled
|
||||||
by providing a `--disable-cpuid` to the `configure` script.
|
by providing a `--disable-cpuid` to the `configure` script.
|
||||||
|
|
||||||
|
- Unless `./configure --disable-tests` is specified, GoogleTest (GTest) and
|
||||||
|
RapidCheck are required, which are available at
|
||||||
|
<https://google.github.io/googletest/> and
|
||||||
|
<https://github.com/emil-e/rapidcheck> respectively.
|
||||||
|
|
|
@ -3,3 +3,20 @@
|
||||||
* Commands which take installables on the command line can now read them from the standard input if
|
* Commands which take installables on the command line can now read them from the standard input if
|
||||||
passed the `--stdin` flag. This is primarily useful when you have a large amount of paths which
|
passed the `--stdin` flag. This is primarily useful when you have a large amount of paths which
|
||||||
exceed the OS arg limit.
|
exceed the OS arg limit.
|
||||||
|
|
||||||
|
* The special handling of an [installable](../command-ref/new-cli/nix.md#installables) with `.drv` suffix being interpreted as all of the given [store derivation](../glossary.md#gloss-store-derivation)'s output paths is removed, and instead taken as the literal store path that it represents.
|
||||||
|
|
||||||
|
The new `^` syntax for store paths introduced in Nix 2.13 allows explicitly referencing output paths of a derivation.
|
||||||
|
Using this is better and more clear than relying on the now-removed `.drv` special handling.
|
||||||
|
|
||||||
|
For example,
|
||||||
|
```shell-session
|
||||||
|
$ nix path-info /nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv
|
||||||
|
```
|
||||||
|
|
||||||
|
now gives info about the derivation itself, while
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ nix path-info /nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv^*
|
||||||
|
```
|
||||||
|
provides information about each of its outputs.
|
40
flake.nix
40
flake.nix
|
@ -89,9 +89,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
configureFlags =
|
configureFlags =
|
||||||
[
|
lib.optionals stdenv.isLinux [
|
||||||
"CXXFLAGS=-I${lib.getDev rapidcheck}/extras/gtest/include"
|
|
||||||
] ++ lib.optionals stdenv.isLinux [
|
|
||||||
"--with-boost=${boost}/lib"
|
"--with-boost=${boost}/lib"
|
||||||
"--with-sandbox-shell=${sh}/bin/busybox"
|
"--with-sandbox-shell=${sh}/bin/busybox"
|
||||||
]
|
]
|
||||||
|
@ -99,6 +97,10 @@
|
||||||
"LDFLAGS=-fuse-ld=gold"
|
"LDFLAGS=-fuse-ld=gold"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
testConfigureFlags = [
|
||||||
|
"CXXFLAGS=-I${lib.getDev rapidcheck}/extras/gtest/include"
|
||||||
|
];
|
||||||
|
|
||||||
nativeBuildDeps =
|
nativeBuildDeps =
|
||||||
[
|
[
|
||||||
buildPackages.bison
|
buildPackages.bison
|
||||||
|
@ -124,13 +126,16 @@
|
||||||
libarchive
|
libarchive
|
||||||
boost
|
boost
|
||||||
lowdown-nix
|
lowdown-nix
|
||||||
gtest
|
|
||||||
rapidcheck
|
|
||||||
]
|
]
|
||||||
++ lib.optionals stdenv.isLinux [libseccomp]
|
++ lib.optionals stdenv.isLinux [libseccomp]
|
||||||
++ lib.optional (stdenv.isLinux || stdenv.isDarwin) libsodium
|
++ lib.optional (stdenv.isLinux || stdenv.isDarwin) libsodium
|
||||||
++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid;
|
++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid;
|
||||||
|
|
||||||
|
checkDeps = [
|
||||||
|
gtest
|
||||||
|
rapidcheck
|
||||||
|
];
|
||||||
|
|
||||||
awsDeps = lib.optional (stdenv.isLinux || stdenv.isDarwin)
|
awsDeps = lib.optional (stdenv.isLinux || stdenv.isDarwin)
|
||||||
(aws-sdk-cpp.override {
|
(aws-sdk-cpp.override {
|
||||||
apis = ["s3" "transfer"];
|
apis = ["s3" "transfer"];
|
||||||
|
@ -200,7 +205,7 @@
|
||||||
VERSION_SUFFIX = versionSuffix;
|
VERSION_SUFFIX = versionSuffix;
|
||||||
|
|
||||||
nativeBuildInputs = nativeBuildDeps;
|
nativeBuildInputs = nativeBuildDeps;
|
||||||
buildInputs = buildDeps ++ awsDeps;
|
buildInputs = buildDeps ++ awsDeps ++ checkDeps;
|
||||||
propagatedBuildInputs = propagatedDeps;
|
propagatedBuildInputs = propagatedDeps;
|
||||||
|
|
||||||
enableParallelBuilding = true;
|
enableParallelBuilding = true;
|
||||||
|
@ -305,7 +310,7 @@
|
||||||
};
|
};
|
||||||
let
|
let
|
||||||
canRunInstalled = currentStdenv.buildPlatform.canExecute currentStdenv.hostPlatform;
|
canRunInstalled = currentStdenv.buildPlatform.canExecute currentStdenv.hostPlatform;
|
||||||
in currentStdenv.mkDerivation {
|
in currentStdenv.mkDerivation (finalAttrs: {
|
||||||
name = "nix-${version}";
|
name = "nix-${version}";
|
||||||
inherit version;
|
inherit version;
|
||||||
|
|
||||||
|
@ -318,7 +323,8 @@
|
||||||
nativeBuildInputs = nativeBuildDeps;
|
nativeBuildInputs = nativeBuildDeps;
|
||||||
buildInputs = buildDeps
|
buildInputs = buildDeps
|
||||||
# There have been issues building these dependencies
|
# There have been issues building these dependencies
|
||||||
++ lib.optionals (currentStdenv.hostPlatform == currentStdenv.buildPlatform) awsDeps;
|
++ lib.optionals (currentStdenv.hostPlatform == currentStdenv.buildPlatform) awsDeps
|
||||||
|
++ lib.optionals finalAttrs.doCheck checkDeps;
|
||||||
|
|
||||||
propagatedBuildInputs = propagatedDeps;
|
propagatedBuildInputs = propagatedDeps;
|
||||||
|
|
||||||
|
@ -348,6 +354,8 @@
|
||||||
configureFlags = configureFlags ++
|
configureFlags = configureFlags ++
|
||||||
[ "--sysconfdir=/etc" ] ++
|
[ "--sysconfdir=/etc" ] ++
|
||||||
lib.optional stdenv.hostPlatform.isStatic "--enable-embedded-sandbox-shell" ++
|
lib.optional stdenv.hostPlatform.isStatic "--enable-embedded-sandbox-shell" ++
|
||||||
|
[ (lib.enableFeature finalAttrs.doCheck "tests") ] ++
|
||||||
|
lib.optionals finalAttrs.doCheck testConfigureFlags ++
|
||||||
lib.optional (!canRunInstalled) "--disable-doc-gen";
|
lib.optional (!canRunInstalled) "--disable-doc-gen";
|
||||||
|
|
||||||
enableParallelBuilding = true;
|
enableParallelBuilding = true;
|
||||||
|
@ -369,7 +377,7 @@
|
||||||
''}
|
''}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
doInstallCheck = true;
|
doInstallCheck = finalAttrs.doCheck;
|
||||||
installCheckFlags = "sysconfdir=$(out)/etc";
|
installCheckFlags = "sysconfdir=$(out)/etc";
|
||||||
|
|
||||||
separateDebugInfo = !currentStdenv.hostPlatform.isStatic;
|
separateDebugInfo = !currentStdenv.hostPlatform.isStatic;
|
||||||
|
@ -411,7 +419,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
meta.platforms = lib.platforms.unix;
|
meta.platforms = lib.platforms.unix;
|
||||||
};
|
});
|
||||||
|
|
||||||
lowdown-nix = with final; currentStdenv.mkDerivation rec {
|
lowdown-nix = with final; currentStdenv.mkDerivation rec {
|
||||||
name = "lowdown-0.9.0";
|
name = "lowdown-0.9.0";
|
||||||
|
@ -462,6 +470,14 @@
|
||||||
|
|
||||||
buildNoGc = forAllSystems (system: self.packages.${system}.nix.overrideAttrs (a: { configureFlags = (a.configureFlags or []) ++ ["--enable-gc=no"];}));
|
buildNoGc = forAllSystems (system: self.packages.${system}.nix.overrideAttrs (a: { configureFlags = (a.configureFlags or []) ++ ["--enable-gc=no"];}));
|
||||||
|
|
||||||
|
buildNoTests = forAllSystems (system:
|
||||||
|
self.packages.${system}.nix.overrideAttrs (a: {
|
||||||
|
doCheck =
|
||||||
|
assert ! a?dontCheck;
|
||||||
|
false;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
# Perl bindings for various platforms.
|
# Perl bindings for various platforms.
|
||||||
perlBindings = forAllSystems (system: nixpkgsFor.${system}.native.nix.perl-bindings);
|
perlBindings = forAllSystems (system: nixpkgsFor.${system}.native.nix.perl-bindings);
|
||||||
|
|
||||||
|
@ -634,9 +650,9 @@
|
||||||
nativeBuildInputs = nativeBuildDeps
|
nativeBuildInputs = nativeBuildDeps
|
||||||
++ (lib.optionals stdenv.cc.isClang [ pkgs.bear pkgs.clang-tools ]);
|
++ (lib.optionals stdenv.cc.isClang [ pkgs.bear pkgs.clang-tools ]);
|
||||||
|
|
||||||
buildInputs = buildDeps ++ propagatedDeps ++ awsDeps;
|
buildInputs = buildDeps ++ propagatedDeps ++ awsDeps ++ checkDeps;
|
||||||
|
|
||||||
inherit configureFlags;
|
configureFlags = configureFlags ++ testConfigureFlags;
|
||||||
|
|
||||||
enableParallelBuilding = true;
|
enableParallelBuilding = true;
|
||||||
|
|
||||||
|
|
|
@ -123,6 +123,7 @@ release:
|
||||||
`/home/eelco/Dev/nixpkgs-pristine`.
|
`/home/eelco/Dev/nixpkgs-pristine`.
|
||||||
|
|
||||||
TODO: trigger nixos.org netlify: https://docs.netlify.com/configure-builds/build-hooks/
|
TODO: trigger nixos.org netlify: https://docs.netlify.com/configure-builds/build-hooks/
|
||||||
|
|
||||||
* Prepare for the next point release by editing `.version` to
|
* Prepare for the next point release by editing `.version` to
|
||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
|
@ -152,7 +153,7 @@ release:
|
||||||
from the previous milestone, and close the previous milestone. Set
|
from the previous milestone, and close the previous milestone. Set
|
||||||
the date for the next milestone 6 weeks from now.
|
the date for the next milestone 6 weeks from now.
|
||||||
|
|
||||||
* Create a backport label
|
* Create a backport label.
|
||||||
|
|
||||||
* Post an [announcement on Discourse](https://discourse.nixos.org/c/announcements/8), including the contents of
|
* Post an [announcement on Discourse](https://discourse.nixos.org/c/announcements/8), including the contents of
|
||||||
`rl-$VERSION.md`.
|
`rl-$VERSION.md`.
|
||||||
|
|
12
mk/disable-tests.mk
Normal file
12
mk/disable-tests.mk
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# This file is only active for `./configure --disable-tests`.
|
||||||
|
# Running `make check` or `make installcheck` would indicate a mistake in the
|
||||||
|
# caller.
|
||||||
|
|
||||||
|
installcheck:
|
||||||
|
@echo "Tests are disabled. Configure without '--disable-tests', or avoid calling 'make installcheck'."
|
||||||
|
@exit 1
|
||||||
|
|
||||||
|
# This currently has little effect.
|
||||||
|
check:
|
||||||
|
@echo "Tests are disabled. Configure without '--disable-tests', or avoid calling 'make check'."
|
||||||
|
@exit 1
|
|
@ -8,7 +8,7 @@ if [ -n "${XDG_STATE_HOME-}" ]; then
|
||||||
else
|
else
|
||||||
NIX_LINK_NEW=$HOME/.local/state/nix/profile
|
NIX_LINK_NEW=$HOME/.local/state/nix/profile
|
||||||
fi
|
fi
|
||||||
if ! [ -e "$NIX_LINK" ]; then
|
if [ -e "$NIX_LINK_NEW" ]; then
|
||||||
NIX_LINK="$NIX_LINK_NEW"
|
NIX_LINK="$NIX_LINK_NEW"
|
||||||
else
|
else
|
||||||
if [ -t 2 ] && [ -e "$NIX_LINK_NEW" ]; then
|
if [ -t 2 ] && [ -e "$NIX_LINK_NEW" ]; then
|
||||||
|
|
|
@ -8,7 +8,7 @@ if [ -n "$HOME" ] && [ -n "$USER" ]; then
|
||||||
else
|
else
|
||||||
NIX_LINK_NEW="$HOME/.local/state/nix/profile"
|
NIX_LINK_NEW="$HOME/.local/state/nix/profile"
|
||||||
fi
|
fi
|
||||||
if ! [ -e "$NIX_LINK" ]; then
|
if [ -e "$NIX_LINK_NEW" ]; then
|
||||||
NIX_LINK="$NIX_LINK_NEW"
|
NIX_LINK="$NIX_LINK_NEW"
|
||||||
else
|
else
|
||||||
if [ -t 2 ] && [ -e "$NIX_LINK_NEW" ]; then
|
if [ -t 2 ] && [ -e "$NIX_LINK_NEW" ]; then
|
||||||
|
|
|
@ -31,27 +31,24 @@ InstallableDerivedPath InstallableDerivedPath::parse(
|
||||||
ExtendedOutputsSpec extendedOutputsSpec)
|
ExtendedOutputsSpec extendedOutputsSpec)
|
||||||
{
|
{
|
||||||
auto derivedPath = std::visit(overloaded {
|
auto derivedPath = std::visit(overloaded {
|
||||||
// If the user did not use ^, we treat the output more liberally.
|
// If the user did not use ^, we treat the output more
|
||||||
|
// liberally: we accept a symlink chain or an actual
|
||||||
|
// store path.
|
||||||
[&](const ExtendedOutputsSpec::Default &) -> DerivedPath {
|
[&](const ExtendedOutputsSpec::Default &) -> DerivedPath {
|
||||||
// First, we accept a symlink chain or an actual store path.
|
|
||||||
auto storePath = store->followLinksToStorePath(prefix);
|
auto storePath = store->followLinksToStorePath(prefix);
|
||||||
// Second, we see if the store path ends in `.drv` to decide what sort
|
// Remove this prior to stabilizing the new CLI.
|
||||||
// of derived path they want.
|
if (storePath.isDerivation()) {
|
||||||
//
|
auto oldDerivedPath = DerivedPath::Built {
|
||||||
// This handling predates the `^` syntax. The `^*` in
|
.drvPath = storePath,
|
||||||
// `/nix/store/hash-foo.drv^*` unambiguously means "do the
|
.outputs = OutputsSpec::All { },
|
||||||
// `DerivedPath::Built` case", so plain `/nix/store/hash-foo.drv` could
|
|
||||||
// also unambiguously mean "do the DerivedPath::Opaque` case".
|
|
||||||
//
|
|
||||||
// Issue #7261 tracks reconsidering this `.drv` dispatching.
|
|
||||||
return storePath.isDerivation()
|
|
||||||
? (DerivedPath) DerivedPath::Built {
|
|
||||||
.drvPath = std::move(storePath),
|
|
||||||
.outputs = OutputsSpec::All {},
|
|
||||||
}
|
|
||||||
: (DerivedPath) DerivedPath::Opaque {
|
|
||||||
.path = std::move(storePath),
|
|
||||||
};
|
};
|
||||||
|
warn(
|
||||||
|
"The interpretation of store paths arguments ending in `.drv` recently changed. If this command is now failing try again with '%s'",
|
||||||
|
oldDerivedPath.to_string(*store));
|
||||||
|
};
|
||||||
|
return DerivedPath::Opaque {
|
||||||
|
.path = std::move(storePath),
|
||||||
|
};
|
||||||
},
|
},
|
||||||
// If the user did use ^, we just do exactly what is written.
|
// If the user did use ^, we just do exactly what is written.
|
||||||
[&](const ExtendedOutputsSpec::Explicit & outputSpec) -> DerivedPath {
|
[&](const ExtendedOutputsSpec::Explicit & outputSpec) -> DerivedPath {
|
||||||
|
|
|
@ -677,9 +677,12 @@ StorePathSet Installable::toDerivations(
|
||||||
for (const auto & b : i->toDerivedPaths())
|
for (const auto & b : i->toDerivedPaths())
|
||||||
std::visit(overloaded {
|
std::visit(overloaded {
|
||||||
[&](const DerivedPath::Opaque & bo) {
|
[&](const DerivedPath::Opaque & bo) {
|
||||||
if (!useDeriver)
|
drvPaths.insert(
|
||||||
throw Error("argument '%s' did not evaluate to a derivation", i->what());
|
bo.path.isDerivation()
|
||||||
drvPaths.insert(getDeriver(store, *i, bo.path));
|
? bo.path
|
||||||
|
: useDeriver
|
||||||
|
? getDeriver(store, *i, bo.path)
|
||||||
|
: throw Error("argument '%s' did not evaluate to a derivation", i->what()));
|
||||||
},
|
},
|
||||||
[&](const DerivedPath::Built & bfd) {
|
[&](const DerivedPath::Built & bfd) {
|
||||||
drvPaths.insert(bfd.drvPath);
|
drvPaths.insert(bfd.drvPath);
|
||||||
|
|
|
@ -63,6 +63,11 @@ public:
|
||||||
one that contains a commit hash or content hash. */
|
one that contains a commit hash or content hash. */
|
||||||
bool isLocked() const { return locked; }
|
bool isLocked() const { return locked; }
|
||||||
|
|
||||||
|
/* Check whether the input carries all necessary info required
|
||||||
|
for cache insertion and substitution.
|
||||||
|
These fields are used to uniquely identify cached trees
|
||||||
|
within the "tarball TTL" window without necessarily
|
||||||
|
indicating that the input's origin is unchanged. */
|
||||||
bool hasAllInfo() const;
|
bool hasAllInfo() const;
|
||||||
|
|
||||||
bool operator ==(const Input & other) const;
|
bool operator ==(const Input & other) const;
|
||||||
|
|
|
@ -92,13 +92,11 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
|
||||||
if (S_ISLNK(dstSt.st_mode)) {
|
if (S_ISLNK(dstSt.st_mode)) {
|
||||||
auto prevPriority = state.priorities[dstFile];
|
auto prevPriority = state.priorities[dstFile];
|
||||||
if (prevPriority == priority)
|
if (prevPriority == priority)
|
||||||
throw Error(
|
throw BuildEnvFileConflictError(
|
||||||
"files '%1%' and '%2%' have the same priority %3%; "
|
readLink(dstFile),
|
||||||
"use 'nix-env --set-flag priority NUMBER INSTALLED_PKGNAME' "
|
srcFile,
|
||||||
"or type 'nix profile install --help' if using 'nix profile' to find out how "
|
priority
|
||||||
"to change the priority of one of the conflicting packages"
|
);
|
||||||
" (0 being the highest priority)",
|
|
||||||
srcFile, readLink(dstFile), priority);
|
|
||||||
if (prevPriority < priority)
|
if (prevPriority < priority)
|
||||||
continue;
|
continue;
|
||||||
if (unlink(dstFile.c_str()) == -1)
|
if (unlink(dstFile.c_str()) == -1)
|
||||||
|
|
|
@ -12,6 +12,32 @@ struct Package {
|
||||||
Package(const Path & path, bool active, int priority) : path{path}, active{active}, priority{priority} {}
|
Package(const Path & path, bool active, int priority) : path{path}, active{active}, priority{priority} {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BuildEnvFileConflictError : public Error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const Path fileA;
|
||||||
|
const Path fileB;
|
||||||
|
int priority;
|
||||||
|
|
||||||
|
BuildEnvFileConflictError(
|
||||||
|
const Path fileA,
|
||||||
|
const Path fileB,
|
||||||
|
int priority
|
||||||
|
)
|
||||||
|
: Error(
|
||||||
|
"Unable to build profile. There is a conflict for the following files:\n"
|
||||||
|
"\n"
|
||||||
|
" %1%\n"
|
||||||
|
" %2%",
|
||||||
|
fileA,
|
||||||
|
fileB
|
||||||
|
)
|
||||||
|
, fileA(fileA)
|
||||||
|
, fileB(fileB)
|
||||||
|
, priority(priority)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
typedef std::vector<Package> Packages;
|
typedef std::vector<Package> Packages;
|
||||||
|
|
||||||
void buildProfile(const Path & out, Packages && pkgs);
|
void buildProfile(const Path & out, Packages && pkgs);
|
||||||
|
|
|
@ -88,6 +88,10 @@ struct curlFileTransfer : public FileTransfer
|
||||||
{request.uri}, request.parentAct)
|
{request.uri}, request.parentAct)
|
||||||
, callback(std::move(callback))
|
, callback(std::move(callback))
|
||||||
, finalSink([this](std::string_view data) {
|
, finalSink([this](std::string_view data) {
|
||||||
|
if (errorSink) {
|
||||||
|
(*errorSink)(data);
|
||||||
|
}
|
||||||
|
|
||||||
if (this->request.dataCallback) {
|
if (this->request.dataCallback) {
|
||||||
auto httpStatus = getHTTPStatus();
|
auto httpStatus = getHTTPStatus();
|
||||||
|
|
||||||
|
@ -163,8 +167,6 @@ struct curlFileTransfer : public FileTransfer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorSink)
|
|
||||||
(*errorSink)({(char *) contents, realSize});
|
|
||||||
(*decompressionSink)({(char *) contents, realSize});
|
(*decompressionSink)({(char *) contents, realSize});
|
||||||
|
|
||||||
return realSize;
|
return realSize;
|
||||||
|
|
|
@ -38,8 +38,6 @@ class RemoteStore : public virtual RemoteStoreConfig,
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual bool sameMachine() = 0;
|
|
||||||
|
|
||||||
RemoteStore(const Params & params);
|
RemoteStore(const Params & params);
|
||||||
|
|
||||||
/* Implementations of abstract store API methods. */
|
/* Implementations of abstract store API methods. */
|
||||||
|
|
|
@ -49,9 +49,6 @@ public:
|
||||||
return *uriSchemes().begin() + "://" + host;
|
return *uriSchemes().begin() + "://" + host;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sameMachine() override
|
|
||||||
{ return false; }
|
|
||||||
|
|
||||||
// FIXME extend daemon protocol, move implementation to RemoteStore
|
// FIXME extend daemon protocol, move implementation to RemoteStore
|
||||||
std::optional<std::string> getBuildLogExact(const StorePath & path) override
|
std::optional<std::string> getBuildLogExact(const StorePath & path) override
|
||||||
{ unsupported("getBuildLogExact"); }
|
{ unsupported("getBuildLogExact"); }
|
||||||
|
|
|
@ -855,6 +855,7 @@ json Store::pathInfoToJSON(const StorePathSet & storePaths,
|
||||||
auto info = queryPathInfo(storePath);
|
auto info = queryPathInfo(storePath);
|
||||||
|
|
||||||
jsonPath["path"] = printStorePath(info->path);
|
jsonPath["path"] = printStorePath(info->path);
|
||||||
|
jsonPath["valid"] = true;
|
||||||
jsonPath["narHash"] = info->narHash.to_string(hashBase, true);
|
jsonPath["narHash"] = info->narHash.to_string(hashBase, true);
|
||||||
jsonPath["narSize"] = info->narSize;
|
jsonPath["narSize"] = info->narSize;
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,6 @@ public:
|
||||||
static std::set<std::string> uriSchemes()
|
static std::set<std::string> uriSchemes()
|
||||||
{ return {"unix"}; }
|
{ return {"unix"}; }
|
||||||
|
|
||||||
bool sameMachine() override
|
|
||||||
{ return true; }
|
|
||||||
|
|
||||||
ref<FSAccessor> getFSAccessor() override
|
ref<FSAccessor> getFSAccessor() override
|
||||||
{ return LocalFSStore::getFSAccessor(); }
|
{ return LocalFSStore::getFSAccessor(); }
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,8 @@ void Logger::warn(const std::string & msg)
|
||||||
|
|
||||||
void Logger::writeToStdout(std::string_view s)
|
void Logger::writeToStdout(std::string_view s)
|
||||||
{
|
{
|
||||||
std::cout << s << "\n";
|
writeFull(STDOUT_FILENO, s);
|
||||||
|
writeFull(STDOUT_FILENO, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
class SimpleLogger : public Logger
|
class SimpleLogger : public Logger
|
||||||
|
@ -84,7 +85,7 @@ public:
|
||||||
|
|
||||||
void startActivity(ActivityId act, Verbosity lvl, ActivityType type,
|
void startActivity(ActivityId act, Verbosity lvl, ActivityType type,
|
||||||
const std::string & s, const Fields & fields, ActivityId parent)
|
const std::string & s, const Fields & fields, ActivityId parent)
|
||||||
override
|
override
|
||||||
{
|
{
|
||||||
if (lvl <= verbosity && !s.empty())
|
if (lvl <= verbosity && !s.empty())
|
||||||
log(lvl, s + "...");
|
log(lvl, s + "...");
|
||||||
|
|
|
@ -102,11 +102,9 @@ public:
|
||||||
virtual void writeToStdout(std::string_view s);
|
virtual void writeToStdout(std::string_view s);
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
inline void cout(const std::string & fs, const Args & ... args)
|
inline void cout(const Args & ... args)
|
||||||
{
|
{
|
||||||
boost::format f(fs);
|
writeToStdout(fmt(args...));
|
||||||
formatHelper(f, args...);
|
|
||||||
writeToStdout(f.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::optional<char> ask(std::string_view s)
|
virtual std::optional<char> ask(std::string_view s)
|
||||||
|
|
|
@ -139,11 +139,11 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
|
||||||
for (auto & buildable : buildables) {
|
for (auto & buildable : buildables) {
|
||||||
std::visit(overloaded {
|
std::visit(overloaded {
|
||||||
[&](const BuiltPath::Opaque & bo) {
|
[&](const BuiltPath::Opaque & bo) {
|
||||||
std::cout << store->printStorePath(bo.path) << std::endl;
|
logger->cout(store->printStorePath(bo.path));
|
||||||
},
|
},
|
||||||
[&](const BuiltPath::Built & bfd) {
|
[&](const BuiltPath::Built & bfd) {
|
||||||
for (auto & output : bfd.outputs) {
|
for (auto & output : bfd.outputs) {
|
||||||
std::cout << store->printStorePath(output.second) << std::endl;
|
logger->cout(store->printStorePath(output.second));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}, buildable.path.raw());
|
}, buildable.path.raw());
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct MixCat : virtual Args
|
||||||
if (st.type != FSAccessor::Type::tRegular)
|
if (st.type != FSAccessor::Type::tRegular)
|
||||||
throw Error("path '%1%' is not a regular file", path);
|
throw Error("path '%1%' is not a regular file", path);
|
||||||
|
|
||||||
std::cout << accessor->readFile(path);
|
writeFull(STDOUT_FILENO, accessor->readFile(path));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ struct CmdDescribeStores : Command, MixJSON
|
||||||
res[storeName] = storeConfig->toJSON();
|
res[storeName] = storeConfig->toJSON();
|
||||||
}
|
}
|
||||||
if (json) {
|
if (json) {
|
||||||
std::cout << res;
|
logger->cout("%s", res);
|
||||||
} else {
|
} else {
|
||||||
for (auto & [storeName, storeConfig] : res.items()) {
|
for (auto & [storeName, storeConfig] : res.items()) {
|
||||||
std::cout << "## " << storeName << std::endl << std::endl;
|
std::cout << "## " << storeName << std::endl << std::endl;
|
||||||
|
|
|
@ -97,7 +97,7 @@ void printClosureDiff(
|
||||||
items.push_back(fmt("%s → %s", showVersions(removed), showVersions(added)));
|
items.push_back(fmt("%s → %s", showVersions(removed), showVersions(added)));
|
||||||
if (showDelta)
|
if (showDelta)
|
||||||
items.push_back(fmt("%s%+.1f KiB" ANSI_NORMAL, sizeDelta > 0 ? ANSI_RED : ANSI_GREEN, sizeDelta / 1024.0));
|
items.push_back(fmt("%s%+.1f KiB" ANSI_NORMAL, sizeDelta > 0 ? ANSI_RED : ANSI_GREEN, sizeDelta / 1024.0));
|
||||||
std::cout << fmt("%s%s: %s\n", indent, name, concatStringsSep(", ", items));
|
logger->cout("%s%s: %s", indent, name, concatStringsSep(", ", items));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,11 +112,11 @@ struct CmdEval : MixJSON, InstallableCommand, MixReadOnlyOption
|
||||||
|
|
||||||
else if (raw) {
|
else if (raw) {
|
||||||
stopProgressBar();
|
stopProgressBar();
|
||||||
std::cout << *state->coerceToString(noPos, *v, context, "while generating the eval command output");
|
writeFull(STDOUT_FILENO, *state->coerceToString(noPos, *v, context, "while generating the eval command output"));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (json) {
|
else if (json) {
|
||||||
std::cout << printValueAsJSON(*state, true, *v, pos, context, false).dump() << std::endl;
|
logger->cout("%s", printValueAsJSON(*state, true, *v, pos, context, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -952,7 +952,7 @@ struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun
|
||||||
{"path", store->printStorePath(flake.flake.sourceInfo->storePath)},
|
{"path", store->printStorePath(flake.flake.sourceInfo->storePath)},
|
||||||
{"inputs", traverse(*flake.lockFile.root)},
|
{"inputs", traverse(*flake.lockFile.root)},
|
||||||
};
|
};
|
||||||
std::cout << jsonRoot.dump() << std::endl;
|
logger->cout("%s", jsonRoot);
|
||||||
} else {
|
} else {
|
||||||
traverse(*flake.lockFile.root);
|
traverse(*flake.lockFile.root);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ struct CmdLog : InstallableCommand
|
||||||
if (!log) continue;
|
if (!log) continue;
|
||||||
stopProgressBar();
|
stopProgressBar();
|
||||||
printInfo("got build log for '%s' from '%s'", installable->what(), logSub.getUri());
|
printInfo("got build log for '%s' from '%s'", installable->what(), logSub.getUri());
|
||||||
std::cout << *log;
|
writeFull(STDOUT_FILENO, *log);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ struct MixLs : virtual Args, MixJSON
|
||||||
if (json) {
|
if (json) {
|
||||||
if (showDirectory)
|
if (showDirectory)
|
||||||
throw UsageError("'--directory' is useless with '--json'");
|
throw UsageError("'--directory' is useless with '--json'");
|
||||||
std::cout << listNar(accessor, path, recursive);
|
logger->cout("%s", listNar(accessor, path, recursive));
|
||||||
} else
|
} else
|
||||||
listText(accessor);
|
listText(accessor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,7 +292,7 @@ void mainWrapped(int argc, char * * argv)
|
||||||
NixArgs args;
|
NixArgs args;
|
||||||
|
|
||||||
if (argc == 2 && std::string(argv[1]) == "__dump-args") {
|
if (argc == 2 && std::string(argv[1]) == "__dump-args") {
|
||||||
std::cout << args.toJSON().dump() << "\n";
|
logger->cout("%s", args.toJSON());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +312,7 @@ void mainWrapped(int argc, char * * argv)
|
||||||
b["doc"] = trim(stripIndentation(primOp->doc));
|
b["doc"] = trim(stripIndentation(primOp->doc));
|
||||||
res[state.symbols[builtin.name]] = std::move(b);
|
res[state.symbols[builtin.name]] = std::move(b);
|
||||||
}
|
}
|
||||||
std::cout << res.dump() << "\n";
|
logger->cout("%s", res);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,14 +321,14 @@ void mainWrapped(int argc, char * * argv)
|
||||||
if (completions) {
|
if (completions) {
|
||||||
switch (completionType) {
|
switch (completionType) {
|
||||||
case ctNormal:
|
case ctNormal:
|
||||||
std::cout << "normal\n"; break;
|
logger->cout("normal"); break;
|
||||||
case ctFilenames:
|
case ctFilenames:
|
||||||
std::cout << "filenames\n"; break;
|
logger->cout("filenames"); break;
|
||||||
case ctAttrs:
|
case ctAttrs:
|
||||||
std::cout << "attrs\n"; break;
|
logger->cout("attrs"); break;
|
||||||
}
|
}
|
||||||
for (auto & s : *completions)
|
for (auto & s : *completions)
|
||||||
std::cout << s.completion << "\t" << trim(s.description) << "\n";
|
logger->cout(s.completion + "\t" + trim(s.description));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ struct CmdMakeContentAddressed : virtual CopyCommand, virtual StorePathsCommand,
|
||||||
}
|
}
|
||||||
auto json = json::object();
|
auto json = json::object();
|
||||||
json["rewrites"] = jsonRewrites;
|
json["rewrites"] = jsonRewrites;
|
||||||
std::cout << json.dump();
|
logger->cout("%s", json);
|
||||||
} else {
|
} else {
|
||||||
for (auto & path : storePaths) {
|
for (auto & path : storePaths) {
|
||||||
auto i = remappings.find(path);
|
auto i = remappings.find(path);
|
||||||
|
|
|
@ -234,9 +234,9 @@ static int main_nix_prefetch_url(int argc, char * * argv)
|
||||||
if (!printPath)
|
if (!printPath)
|
||||||
printInfo("path is '%s'", store->printStorePath(storePath));
|
printInfo("path is '%s'", store->printStorePath(storePath));
|
||||||
|
|
||||||
std::cout << printHash16or32(hash) << std::endl;
|
logger->cout(printHash16or32(hash));
|
||||||
if (printPath)
|
if (printPath)
|
||||||
std::cout << store->printStorePath(storePath) << std::endl;
|
logger->cout(store->printStorePath(storePath));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,12 +228,12 @@ struct ProfileManifest
|
||||||
|
|
||||||
while (i != prevElems.end() || j != curElems.end()) {
|
while (i != prevElems.end() || j != curElems.end()) {
|
||||||
if (j != curElems.end() && (i == prevElems.end() || i->describe() > j->describe())) {
|
if (j != curElems.end() && (i == prevElems.end() || i->describe() > j->describe())) {
|
||||||
std::cout << fmt("%s%s: ∅ -> %s\n", indent, j->describe(), j->versions());
|
logger->cout("%s%s: ∅ -> %s", indent, j->describe(), j->versions());
|
||||||
changes = true;
|
changes = true;
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
else if (i != prevElems.end() && (j == curElems.end() || i->describe() < j->describe())) {
|
else if (i != prevElems.end() && (j == curElems.end() || i->describe() < j->describe())) {
|
||||||
std::cout << fmt("%s%s: %s -> ∅\n", indent, i->describe(), i->versions());
|
logger->cout("%s%s: %s -> ∅", indent, i->describe(), i->versions());
|
||||||
changes = true;
|
changes = true;
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ struct ProfileManifest
|
||||||
auto v1 = i->versions();
|
auto v1 = i->versions();
|
||||||
auto v2 = j->versions();
|
auto v2 = j->versions();
|
||||||
if (v1 != v2) {
|
if (v1 != v2) {
|
||||||
std::cout << fmt("%s%s: %s -> %s\n", indent, i->describe(), v1, v2);
|
logger->cout("%s%s: %s -> %s", indent, i->describe(), v1, v2);
|
||||||
changes = true;
|
changes = true;
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
|
@ -250,7 +250,7 @@ struct ProfileManifest
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!changes)
|
if (!changes)
|
||||||
std::cout << fmt("%sNo changes.\n", indent);
|
logger->cout("%sNo changes.", indent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -330,7 +330,63 @@ struct CmdProfileInstall : InstallablesCommand, MixDefaultProfile
|
||||||
manifest.elements.push_back(std::move(element));
|
manifest.elements.push_back(std::move(element));
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProfile(manifest.build(store));
|
try {
|
||||||
|
updateProfile(manifest.build(store));
|
||||||
|
} catch (BuildEnvFileConflictError & conflictError) {
|
||||||
|
// FIXME use C++20 std::ranges once macOS has it
|
||||||
|
// See https://github.com/NixOS/nix/compare/3efa476c5439f8f6c1968a6ba20a31d1239c2f04..1fe5d172ece51a619e879c4b86f603d9495cc102
|
||||||
|
auto findRefByFilePath = [&]<typename Iterator>(Iterator begin, Iterator end) {
|
||||||
|
for (auto it = begin; it != end; it++) {
|
||||||
|
auto profileElement = *it;
|
||||||
|
for (auto & storePath : profileElement.storePaths) {
|
||||||
|
if (conflictError.fileA.starts_with(store->printStorePath(storePath))) {
|
||||||
|
return std::pair(conflictError.fileA, profileElement.source->originalRef);
|
||||||
|
}
|
||||||
|
if (conflictError.fileB.starts_with(store->printStorePath(storePath))) {
|
||||||
|
return std::pair(conflictError.fileB, profileElement.source->originalRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw conflictError;
|
||||||
|
};
|
||||||
|
// There are 2 conflicting files. We need to find out which one is from the already installed package and
|
||||||
|
// which one is the package that is the new package that is being installed.
|
||||||
|
// The first matching package is the one that was already installed (original).
|
||||||
|
auto [originalConflictingFilePath, originalConflictingRef] = findRefByFilePath(manifest.elements.begin(), manifest.elements.end());
|
||||||
|
// The last matching package is the one that was going to be installed (new).
|
||||||
|
auto [newConflictingFilePath, newConflictingRef] = findRefByFilePath(manifest.elements.rbegin(), manifest.elements.rend());
|
||||||
|
|
||||||
|
throw Error(
|
||||||
|
"An existing package already provides the following file:\n"
|
||||||
|
"\n"
|
||||||
|
" %1%\n"
|
||||||
|
"\n"
|
||||||
|
"This is the conflicting file from the new package:\n"
|
||||||
|
"\n"
|
||||||
|
" %2%\n"
|
||||||
|
"\n"
|
||||||
|
"To remove the existing package:\n"
|
||||||
|
"\n"
|
||||||
|
" nix profile remove %3%\n"
|
||||||
|
"\n"
|
||||||
|
"The new package can also be installed next to the existing one by assigning a different priority.\n"
|
||||||
|
"The conflicting packages have a priority of %5%.\n"
|
||||||
|
"To prioritise the new package:\n"
|
||||||
|
"\n"
|
||||||
|
" nix profile install %4% --priority %6%\n"
|
||||||
|
"\n"
|
||||||
|
"To prioritise the existing package:\n"
|
||||||
|
"\n"
|
||||||
|
" nix profile install %4% --priority %7%\n",
|
||||||
|
originalConflictingFilePath,
|
||||||
|
newConflictingFilePath,
|
||||||
|
originalConflictingRef.to_string(),
|
||||||
|
newConflictingRef.to_string(),
|
||||||
|
conflictError.priority,
|
||||||
|
conflictError.priority - 1,
|
||||||
|
conflictError.priority + 1
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -584,9 +640,9 @@ struct CmdProfileDiffClosures : virtual StoreCommand, MixDefaultProfile
|
||||||
|
|
||||||
for (auto & gen : gens) {
|
for (auto & gen : gens) {
|
||||||
if (prevGen) {
|
if (prevGen) {
|
||||||
if (!first) std::cout << "\n";
|
if (!first) logger->cout("");
|
||||||
first = false;
|
first = false;
|
||||||
std::cout << fmt("Version %d -> %d:\n", prevGen->number, gen.number);
|
logger->cout("Version %d -> %d:", prevGen->number, gen.number);
|
||||||
printClosureDiff(store,
|
printClosureDiff(store,
|
||||||
store->followLinksToStorePath(prevGen->path),
|
store->followLinksToStorePath(prevGen->path),
|
||||||
store->followLinksToStorePath(gen.path),
|
store->followLinksToStorePath(gen.path),
|
||||||
|
@ -622,10 +678,10 @@ struct CmdProfileHistory : virtual StoreCommand, EvalCommand, MixDefaultProfile
|
||||||
for (auto & gen : gens) {
|
for (auto & gen : gens) {
|
||||||
ProfileManifest manifest(*getEvalState(), gen.path);
|
ProfileManifest manifest(*getEvalState(), gen.path);
|
||||||
|
|
||||||
if (!first) std::cout << "\n";
|
if (!first) logger->cout("");
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
std::cout << fmt("Version %s%d" ANSI_NORMAL " (%s)%s:\n",
|
logger->cout("Version %s%d" ANSI_NORMAL " (%s)%s:",
|
||||||
gen.number == curGen ? ANSI_GREEN : ANSI_BOLD,
|
gen.number == curGen ? ANSI_GREEN : ANSI_BOLD,
|
||||||
gen.number,
|
gen.number,
|
||||||
std::put_time(std::gmtime(&gen.creationTime), "%Y-%m-%d"),
|
std::put_time(std::gmtime(&gen.creationTime), "%Y-%m-%d"),
|
||||||
|
|
|
@ -65,18 +65,16 @@ struct CmdRealisationInfo : BuiltPathsCommand, MixJSON
|
||||||
|
|
||||||
res.push_back(currentPath);
|
res.push_back(currentPath);
|
||||||
}
|
}
|
||||||
std::cout << res.dump();
|
logger->cout("%s", res);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (auto & path : realisations) {
|
for (auto & path : realisations) {
|
||||||
if (auto realisation = std::get_if<Realisation>(&path.raw)) {
|
if (auto realisation = std::get_if<Realisation>(&path.raw)) {
|
||||||
std::cout <<
|
logger->cout("%s %s",
|
||||||
realisation->id.to_string() << " " <<
|
realisation->id.to_string(),
|
||||||
store->printStorePath(realisation->outPath);
|
store->printStorePath(realisation->outPath));
|
||||||
} else
|
} else
|
||||||
std::cout << store->printStorePath(path.path());
|
logger->cout("%s", store->printStorePath(path.path()));
|
||||||
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,9 +196,8 @@ struct CmdSearch : InstallableCommand, MixJSON
|
||||||
for (auto & cursor : installable->getCursors(*state))
|
for (auto & cursor : installable->getCursors(*state))
|
||||||
visit(*cursor, cursor->getAttrPath(), true);
|
visit(*cursor, cursor->getAttrPath(), true);
|
||||||
|
|
||||||
if (json) {
|
if (json)
|
||||||
std::cout << jsonOut->dump() << std::endl;
|
logger->cout("%s", *jsonOut);
|
||||||
}
|
|
||||||
|
|
||||||
if (!json && !results)
|
if (!json && !results)
|
||||||
throw Error("no results for the given search term(s)!");
|
throw Error("no results for the given search term(s)!");
|
||||||
|
|
|
@ -57,7 +57,7 @@ struct CmdShowDerivation : InstallablesCommand
|
||||||
jsonRoot[store->printStorePath(drvPath)] =
|
jsonRoot[store->printStorePath(drvPath)] =
|
||||||
store->readDerivation(drvPath).toJSON(*store);
|
store->readDerivation(drvPath).toJSON(*store);
|
||||||
}
|
}
|
||||||
std::cout << jsonRoot.dump(2) << std::endl;
|
logger->cout(jsonRoot.dump(2));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,7 @@ struct CmdKeyGenerateSecret : Command
|
||||||
if (!keyName)
|
if (!keyName)
|
||||||
throw UsageError("required argument '--key-name' is missing");
|
throw UsageError("required argument '--key-name' is missing");
|
||||||
|
|
||||||
std::cout << SecretKey::generate(*keyName).to_string();
|
writeFull(STDOUT_FILENO, SecretKey::generate(*keyName).to_string());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ struct CmdKeyConvertSecretToPublic : Command
|
||||||
void run() override
|
void run() override
|
||||||
{
|
{
|
||||||
SecretKey secretKey(drainFD(STDIN_FILENO));
|
SecretKey secretKey(drainFD(STDIN_FILENO));
|
||||||
std::cout << secretKey.toPublicKey().to_string();
|
writeFull(STDOUT_FILENO, secretKey.toPublicKey().to_string());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ nix log $outPath 2>&1 | grep 'is not available'
|
||||||
nix log --substituters file://$cacheDir $outPath | grep FOO
|
nix log --substituters file://$cacheDir $outPath | grep FOO
|
||||||
|
|
||||||
# Test copying build logs from the binary cache.
|
# Test copying build logs from the binary cache.
|
||||||
nix store copy-log --from file://$cacheDir $(nix-store -qd $outPath)
|
nix store copy-log --from file://$cacheDir $(nix-store -qd $outPath)^'*'
|
||||||
nix log $outPath | grep FOO
|
nix log $outPath | grep FOO
|
||||||
|
|
||||||
basicDownloadTests() {
|
basicDownloadTests() {
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
drv=$(nix-instantiate --experimental-features ca-derivations ./content-addressed.nix -A rootCA --arg seed 1)
|
drv=$(nix-instantiate ./content-addressed.nix -A rootCA --arg seed 1)
|
||||||
nix --experimental-features 'nix-command ca-derivations' show-derivation "$drv" --arg seed 1
|
nix show-derivation "$drv" --arg seed 1
|
||||||
|
|
||||||
buildAttr () {
|
buildAttr () {
|
||||||
local derivationPath=$1
|
local derivationPath=$1
|
||||||
local seedValue=$2
|
local seedValue=$2
|
||||||
shift; shift
|
shift; shift
|
||||||
local args=("--experimental-features" "ca-derivations" "./content-addressed.nix" "-A" "$derivationPath" --arg seed "$seedValue" "--no-out-link")
|
local args=("./content-addressed.nix" "-A" "$derivationPath" --arg seed "$seedValue" "--no-out-link")
|
||||||
args+=("$@")
|
args+=("$@")
|
||||||
nix-build "${args[@]}"
|
nix-build "${args[@]}"
|
||||||
}
|
}
|
||||||
|
@ -46,17 +46,17 @@ testCutoff () {
|
||||||
}
|
}
|
||||||
|
|
||||||
testGC () {
|
testGC () {
|
||||||
nix-instantiate --experimental-features ca-derivations ./content-addressed.nix -A rootCA --arg seed 5
|
nix-instantiate ./content-addressed.nix -A rootCA --arg seed 5
|
||||||
nix-collect-garbage --experimental-features ca-derivations --option keep-derivations true
|
nix-collect-garbage --option keep-derivations true
|
||||||
clearStore
|
clearStore
|
||||||
buildAttr rootCA 1 --out-link $TEST_ROOT/rootCA
|
buildAttr rootCA 1 --out-link $TEST_ROOT/rootCA
|
||||||
nix-collect-garbage --experimental-features ca-derivations
|
nix-collect-garbage
|
||||||
buildAttr rootCA 1 -j0
|
buildAttr rootCA 1 -j0
|
||||||
}
|
}
|
||||||
|
|
||||||
testNixCommand () {
|
testNixCommand () {
|
||||||
clearStore
|
clearStore
|
||||||
nix build --experimental-features 'nix-command ca-derivations' --file ./content-addressed.nix --no-link
|
nix build --file ./content-addressed.nix --no-link
|
||||||
}
|
}
|
||||||
|
|
||||||
# Regression test for https://github.com/NixOS/nix/issues/4775
|
# Regression test for https://github.com/NixOS/nix/issues/4775
|
||||||
|
|
|
@ -28,6 +28,12 @@ nix realisation info --file ./content-addressed.nix transitivelyDependentCA
|
||||||
nix realisation info --file ./content-addressed.nix dependentCA
|
nix realisation info --file ./content-addressed.nix dependentCA
|
||||||
# nix realisation info --file ./content-addressed.nix rootCA --outputs out
|
# nix realisation info --file ./content-addressed.nix rootCA --outputs out
|
||||||
|
|
||||||
|
if isDaemonNewer "2.13"; then
|
||||||
|
pushToStore="../push-to-store.sh"
|
||||||
|
else
|
||||||
|
pushToStore="../push-to-store-old.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
# Same thing, but
|
# Same thing, but
|
||||||
# 1. With non-ca derivations
|
# 1. With non-ca derivations
|
||||||
# 2. Erasing the realisations on the remote store
|
# 2. Erasing the realisations on the remote store
|
||||||
|
@ -37,7 +43,7 @@ nix realisation info --file ./content-addressed.nix dependentCA
|
||||||
#
|
#
|
||||||
# Regression test for #4725
|
# Regression test for #4725
|
||||||
clearStore
|
clearStore
|
||||||
nix build --file ../simple.nix -L --no-link --post-build-hook ../push-to-store.sh
|
nix build --file ../simple.nix -L --no-link --post-build-hook "$pushToStore"
|
||||||
clearStore
|
clearStore
|
||||||
rm -r "$REMOTE_STORE_DIR/realisations"
|
rm -r "$REMOTE_STORE_DIR/realisations"
|
||||||
nix build --file ../simple.nix -L --no-link --substitute --substituters "$REMOTE_STORE" --no-require-sigs -j0
|
nix build --file ../simple.nix -L --no-link --substitute --substituters "$REMOTE_STORE" --no-require-sigs -j0
|
||||||
|
@ -52,7 +58,7 @@ if [[ -z "$(ls "$REMOTE_STORE_DIR/realisations")" ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Test the local realisation disk cache
|
# Test the local realisation disk cache
|
||||||
buildDrvs --post-build-hook ../push-to-store.sh
|
buildDrvs --post-build-hook "$pushToStore"
|
||||||
clearStore
|
clearStore
|
||||||
# Add the realisations of rootCA to the cachecache
|
# Add the realisations of rootCA to the cachecache
|
||||||
clearCacheCache
|
clearCacheCache
|
||||||
|
|
|
@ -140,6 +140,36 @@ printf World2 > $flake2Dir/who
|
||||||
|
|
||||||
nix profile install $flake1Dir
|
nix profile install $flake1Dir
|
||||||
[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]]
|
[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]]
|
||||||
|
expect 1 nix profile install $flake2Dir
|
||||||
|
diff -u <(
|
||||||
|
nix --offline profile install $flake2Dir 2>&1 1> /dev/null \
|
||||||
|
| grep -vE "^warning: " \
|
||||||
|
|| true
|
||||||
|
) <(cat << EOF
|
||||||
|
error: An existing package already provides the following file:
|
||||||
|
|
||||||
|
$(nix build --no-link --print-out-paths ${flake1Dir}"#default.out")/bin/hello
|
||||||
|
|
||||||
|
This is the conflicting file from the new package:
|
||||||
|
|
||||||
|
$(nix build --no-link --print-out-paths ${flake2Dir}"#default.out")/bin/hello
|
||||||
|
|
||||||
|
To remove the existing package:
|
||||||
|
|
||||||
|
nix profile remove path:${flake1Dir}
|
||||||
|
|
||||||
|
The new package can also be installed next to the existing one by assigning a different priority.
|
||||||
|
The conflicting packages have a priority of 5.
|
||||||
|
To prioritise the new package:
|
||||||
|
|
||||||
|
nix profile install path:${flake2Dir} --priority 4
|
||||||
|
|
||||||
|
To prioritise the existing package:
|
||||||
|
|
||||||
|
nix profile install path:${flake2Dir} --priority 6
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]]
|
||||||
nix profile install $flake2Dir --priority 100
|
nix profile install $flake2Dir --priority 100
|
||||||
[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]]
|
[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]]
|
||||||
nix profile install $flake2Dir --priority 0
|
nix profile install $flake2Dir --priority 0
|
||||||
|
|
|
@ -9,8 +9,14 @@ echo 'require-sigs = false' >> $NIX_CONF_DIR/nix.conf
|
||||||
|
|
||||||
restartDaemon
|
restartDaemon
|
||||||
|
|
||||||
|
if isDaemonNewer "2.13"; then
|
||||||
|
pushToStore="$PWD/push-to-store.sh"
|
||||||
|
else
|
||||||
|
pushToStore="$PWD/push-to-store-old.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
# Build the dependencies and push them to the remote store.
|
# Build the dependencies and push them to the remote store.
|
||||||
nix-build -o $TEST_ROOT/result dependencies.nix --post-build-hook $PWD/push-to-store.sh
|
nix-build -o $TEST_ROOT/result dependencies.nix --post-build-hook "$pushToStore"
|
||||||
|
|
||||||
clearStore
|
clearStore
|
||||||
|
|
||||||
|
|
10
tests/push-to-store-old.sh
Executable file
10
tests/push-to-store-old.sh
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -x
|
||||||
|
set -e
|
||||||
|
|
||||||
|
[ -n "$OUT_PATHS" ]
|
||||||
|
[ -n "$DRV_PATH" ]
|
||||||
|
|
||||||
|
echo Pushing "$OUT_PATHS" to "$REMOTE_STORE"
|
||||||
|
printf "%s" "$DRV_PATH" | xargs nix copy --to "$REMOTE_STORE" --no-require-sigs
|
|
@ -7,4 +7,4 @@ set -e
|
||||||
[ -n "$DRV_PATH" ]
|
[ -n "$DRV_PATH" ]
|
||||||
|
|
||||||
echo Pushing "$OUT_PATHS" to "$REMOTE_STORE"
|
echo Pushing "$OUT_PATHS" to "$REMOTE_STORE"
|
||||||
printf "%s" "$DRV_PATH" | xargs nix copy --to "$REMOTE_STORE" --no-require-sigs
|
printf "%s" "$DRV_PATH"^'*' | xargs nix copy --to "$REMOTE_STORE" --no-require-sigs
|
||||||
|
|
Loading…
Reference in a new issue