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:
|
||||
fetch-depth: 0
|
||||
- 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
|
||||
- uses: cachix/cachix-action@v12
|
||||
if: needs.check_secrets.outputs.cachix == 'true'
|
||||
|
@ -59,6 +61,8 @@ jobs:
|
|||
fetch-depth: 0
|
||||
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
||||
- uses: cachix/install-nix-action@v19
|
||||
with:
|
||||
install_url: https://releases.nixos.org/nix/nix-2.13.3/install
|
||||
- uses: cachix/cachix-action@v12
|
||||
with:
|
||||
name: '${{ env.CACHIX_NAME }}'
|
||||
|
@ -103,6 +107,8 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
- 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 NIX_VERSION="$(nix --experimental-features 'nix-command flakes' eval .\#default.version | tr -d \")" >> $GITHUB_ENV
|
||||
- uses: cachix/cachix-action@v12
|
||||
|
|
19
Makefile
19
Makefile
|
@ -2,13 +2,10 @@ makefiles = \
|
|||
mk/precompiled-headers.mk \
|
||||
local.mk \
|
||||
src/libutil/local.mk \
|
||||
src/libutil/tests/local.mk \
|
||||
src/libstore/local.mk \
|
||||
src/libstore/tests/local.mk \
|
||||
src/libfetchers/local.mk \
|
||||
src/libmain/local.mk \
|
||||
src/libexpr/local.mk \
|
||||
src/libexpr/tests/local.mk \
|
||||
src/libcmd/local.mk \
|
||||
src/nix/local.mk \
|
||||
src/resolve-system-dependencies/local.mk \
|
||||
|
@ -19,12 +16,22 @@ makefiles = \
|
|||
misc/systemd/local.mk \
|
||||
misc/launchd/local.mk \
|
||||
misc/upstart/local.mk \
|
||||
doc/manual/local.mk \
|
||||
tests/local.mk \
|
||||
tests/plugins/local.mk
|
||||
doc/manual/local.mk
|
||||
|
||||
-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
|
||||
|
||||
ifeq ($(OPTIMIZE), 1)
|
||||
|
|
|
@ -45,3 +45,4 @@ sandbox_shell = @sandbox_shell@
|
|||
storedir = @storedir@
|
||||
sysconfdir = @sysconfdir@
|
||||
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"
|
||||
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
|
||||
AC_ARG_ENABLE(lto, AS_HELP_STRING([--enable-lto],[Enable LTO (only supported with GCC) [default=no]]),
|
||||
lto=$enableval, lto=no)
|
||||
|
@ -270,6 +277,8 @@ if test "$gc" = yes; then
|
|||
fi
|
||||
|
||||
|
||||
if test "$tests" = yes; then
|
||||
|
||||
# Look for gtest.
|
||||
PKG_CHECK_MODULES([GTEST], [gtest_main])
|
||||
|
||||
|
@ -282,6 +291,7 @@ dnl No good for C++ libs with mangled symbols
|
|||
dnl AC_CHECK_LIB([rapidcheck], [])
|
||||
AC_LANG_POP(C++)
|
||||
|
||||
fi
|
||||
|
||||
# Look for nlohmann/json.
|
||||
PKG_CHECK_MODULES([NLOHMANN_JSON], [nlohmann_json >= 3.9])
|
||||
|
|
|
@ -71,3 +71,8 @@
|
|||
<http://libcpuid.sourceforge.net>.
|
||||
This is an optional dependency and can be disabled
|
||||
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
|
||||
passed the `--stdin` flag. This is primarily useful when you have a large amount of paths which
|
||||
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 =
|
||||
[
|
||||
"CXXFLAGS=-I${lib.getDev rapidcheck}/extras/gtest/include"
|
||||
] ++ lib.optionals stdenv.isLinux [
|
||||
lib.optionals stdenv.isLinux [
|
||||
"--with-boost=${boost}/lib"
|
||||
"--with-sandbox-shell=${sh}/bin/busybox"
|
||||
]
|
||||
|
@ -99,6 +97,10 @@
|
|||
"LDFLAGS=-fuse-ld=gold"
|
||||
];
|
||||
|
||||
testConfigureFlags = [
|
||||
"CXXFLAGS=-I${lib.getDev rapidcheck}/extras/gtest/include"
|
||||
];
|
||||
|
||||
nativeBuildDeps =
|
||||
[
|
||||
buildPackages.bison
|
||||
|
@ -124,13 +126,16 @@
|
|||
libarchive
|
||||
boost
|
||||
lowdown-nix
|
||||
gtest
|
||||
rapidcheck
|
||||
]
|
||||
++ lib.optionals stdenv.isLinux [libseccomp]
|
||||
++ lib.optional (stdenv.isLinux || stdenv.isDarwin) libsodium
|
||||
++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid;
|
||||
|
||||
checkDeps = [
|
||||
gtest
|
||||
rapidcheck
|
||||
];
|
||||
|
||||
awsDeps = lib.optional (stdenv.isLinux || stdenv.isDarwin)
|
||||
(aws-sdk-cpp.override {
|
||||
apis = ["s3" "transfer"];
|
||||
|
@ -200,7 +205,7 @@
|
|||
VERSION_SUFFIX = versionSuffix;
|
||||
|
||||
nativeBuildInputs = nativeBuildDeps;
|
||||
buildInputs = buildDeps ++ awsDeps;
|
||||
buildInputs = buildDeps ++ awsDeps ++ checkDeps;
|
||||
propagatedBuildInputs = propagatedDeps;
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
@ -305,7 +310,7 @@
|
|||
};
|
||||
let
|
||||
canRunInstalled = currentStdenv.buildPlatform.canExecute currentStdenv.hostPlatform;
|
||||
in currentStdenv.mkDerivation {
|
||||
in currentStdenv.mkDerivation (finalAttrs: {
|
||||
name = "nix-${version}";
|
||||
inherit version;
|
||||
|
||||
|
@ -318,7 +323,8 @@
|
|||
nativeBuildInputs = nativeBuildDeps;
|
||||
buildInputs = buildDeps
|
||||
# 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;
|
||||
|
||||
|
@ -348,6 +354,8 @@
|
|||
configureFlags = configureFlags ++
|
||||
[ "--sysconfdir=/etc" ] ++
|
||||
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";
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
@ -369,7 +377,7 @@
|
|||
''}
|
||||
'';
|
||||
|
||||
doInstallCheck = true;
|
||||
doInstallCheck = finalAttrs.doCheck;
|
||||
installCheckFlags = "sysconfdir=$(out)/etc";
|
||||
|
||||
separateDebugInfo = !currentStdenv.hostPlatform.isStatic;
|
||||
|
@ -411,7 +419,7 @@
|
|||
});
|
||||
|
||||
meta.platforms = lib.platforms.unix;
|
||||
};
|
||||
});
|
||||
|
||||
lowdown-nix = with final; currentStdenv.mkDerivation rec {
|
||||
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"];}));
|
||||
|
||||
buildNoTests = forAllSystems (system:
|
||||
self.packages.${system}.nix.overrideAttrs (a: {
|
||||
doCheck =
|
||||
assert ! a?dontCheck;
|
||||
false;
|
||||
})
|
||||
);
|
||||
|
||||
# Perl bindings for various platforms.
|
||||
perlBindings = forAllSystems (system: nixpkgsFor.${system}.native.nix.perl-bindings);
|
||||
|
||||
|
@ -634,9 +650,9 @@
|
|||
nativeBuildInputs = nativeBuildDeps
|
||||
++ (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;
|
||||
|
||||
|
|
|
@ -123,6 +123,7 @@ release:
|
|||
`/home/eelco/Dev/nixpkgs-pristine`.
|
||||
|
||||
TODO: trigger nixos.org netlify: https://docs.netlify.com/configure-builds/build-hooks/
|
||||
|
||||
* Prepare for the next point release by editing `.version` to
|
||||
e.g.
|
||||
|
||||
|
@ -152,7 +153,7 @@ release:
|
|||
from the previous milestone, and close the previous milestone. Set
|
||||
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
|
||||
`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
|
||||
NIX_LINK_NEW=$HOME/.local/state/nix/profile
|
||||
fi
|
||||
if ! [ -e "$NIX_LINK" ]; then
|
||||
if [ -e "$NIX_LINK_NEW" ]; then
|
||||
NIX_LINK="$NIX_LINK_NEW"
|
||||
else
|
||||
if [ -t 2 ] && [ -e "$NIX_LINK_NEW" ]; then
|
||||
|
|
|
@ -8,7 +8,7 @@ if [ -n "$HOME" ] && [ -n "$USER" ]; then
|
|||
else
|
||||
NIX_LINK_NEW="$HOME/.local/state/nix/profile"
|
||||
fi
|
||||
if ! [ -e "$NIX_LINK" ]; then
|
||||
if [ -e "$NIX_LINK_NEW" ]; then
|
||||
NIX_LINK="$NIX_LINK_NEW"
|
||||
else
|
||||
if [ -t 2 ] && [ -e "$NIX_LINK_NEW" ]; then
|
||||
|
|
|
@ -31,27 +31,24 @@ InstallableDerivedPath InstallableDerivedPath::parse(
|
|||
ExtendedOutputsSpec extendedOutputsSpec)
|
||||
{
|
||||
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 {
|
||||
// First, we accept a symlink chain or an actual store path.
|
||||
auto storePath = store->followLinksToStorePath(prefix);
|
||||
// Second, we see if the store path ends in `.drv` to decide what sort
|
||||
// of derived path they want.
|
||||
//
|
||||
// This handling predates the `^` syntax. The `^*` in
|
||||
// `/nix/store/hash-foo.drv^*` unambiguously means "do the
|
||||
// `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),
|
||||
// Remove this prior to stabilizing the new CLI.
|
||||
if (storePath.isDerivation()) {
|
||||
auto oldDerivedPath = DerivedPath::Built {
|
||||
.drvPath = storePath,
|
||||
.outputs = OutputsSpec::All { },
|
||||
};
|
||||
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.
|
||||
[&](const ExtendedOutputsSpec::Explicit & outputSpec) -> DerivedPath {
|
||||
|
|
|
@ -677,9 +677,12 @@ StorePathSet Installable::toDerivations(
|
|||
for (const auto & b : i->toDerivedPaths())
|
||||
std::visit(overloaded {
|
||||
[&](const DerivedPath::Opaque & bo) {
|
||||
if (!useDeriver)
|
||||
throw Error("argument '%s' did not evaluate to a derivation", i->what());
|
||||
drvPaths.insert(getDeriver(store, *i, bo.path));
|
||||
drvPaths.insert(
|
||||
bo.path.isDerivation()
|
||||
? bo.path
|
||||
: useDeriver
|
||||
? getDeriver(store, *i, bo.path)
|
||||
: throw Error("argument '%s' did not evaluate to a derivation", i->what()));
|
||||
},
|
||||
[&](const DerivedPath::Built & bfd) {
|
||||
drvPaths.insert(bfd.drvPath);
|
||||
|
|
|
@ -63,6 +63,11 @@ public:
|
|||
one that contains a commit hash or content hash. */
|
||||
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 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)) {
|
||||
auto prevPriority = state.priorities[dstFile];
|
||||
if (prevPriority == priority)
|
||||
throw Error(
|
||||
"files '%1%' and '%2%' have the same priority %3%; "
|
||||
"use 'nix-env --set-flag priority NUMBER INSTALLED_PKGNAME' "
|
||||
"or type 'nix profile install --help' if using 'nix profile' to find out how "
|
||||
"to change the priority of one of the conflicting packages"
|
||||
" (0 being the highest priority)",
|
||||
srcFile, readLink(dstFile), priority);
|
||||
throw BuildEnvFileConflictError(
|
||||
readLink(dstFile),
|
||||
srcFile,
|
||||
priority
|
||||
);
|
||||
if (prevPriority < priority)
|
||||
continue;
|
||||
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} {}
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
void buildProfile(const Path & out, Packages && pkgs);
|
||||
|
|
|
@ -88,6 +88,10 @@ struct curlFileTransfer : public FileTransfer
|
|||
{request.uri}, request.parentAct)
|
||||
, callback(std::move(callback))
|
||||
, finalSink([this](std::string_view data) {
|
||||
if (errorSink) {
|
||||
(*errorSink)(data);
|
||||
}
|
||||
|
||||
if (this->request.dataCallback) {
|
||||
auto httpStatus = getHTTPStatus();
|
||||
|
||||
|
@ -163,8 +167,6 @@ struct curlFileTransfer : public FileTransfer
|
|||
}
|
||||
}
|
||||
|
||||
if (errorSink)
|
||||
(*errorSink)({(char *) contents, realSize});
|
||||
(*decompressionSink)({(char *) contents, realSize});
|
||||
|
||||
return realSize;
|
||||
|
|
|
@ -38,8 +38,6 @@ class RemoteStore : public virtual RemoteStoreConfig,
|
|||
{
|
||||
public:
|
||||
|
||||
virtual bool sameMachine() = 0;
|
||||
|
||||
RemoteStore(const Params & params);
|
||||
|
||||
/* Implementations of abstract store API methods. */
|
||||
|
|
|
@ -49,9 +49,6 @@ public:
|
|||
return *uriSchemes().begin() + "://" + host;
|
||||
}
|
||||
|
||||
bool sameMachine() override
|
||||
{ return false; }
|
||||
|
||||
// FIXME extend daemon protocol, move implementation to RemoteStore
|
||||
std::optional<std::string> getBuildLogExact(const StorePath & path) override
|
||||
{ unsupported("getBuildLogExact"); }
|
||||
|
|
|
@ -855,6 +855,7 @@ json Store::pathInfoToJSON(const StorePathSet & storePaths,
|
|||
auto info = queryPathInfo(storePath);
|
||||
|
||||
jsonPath["path"] = printStorePath(info->path);
|
||||
jsonPath["valid"] = true;
|
||||
jsonPath["narHash"] = info->narHash.to_string(hashBase, true);
|
||||
jsonPath["narSize"] = info->narSize;
|
||||
|
||||
|
|
|
@ -29,9 +29,6 @@ public:
|
|||
static std::set<std::string> uriSchemes()
|
||||
{ return {"unix"}; }
|
||||
|
||||
bool sameMachine() override
|
||||
{ return true; }
|
||||
|
||||
ref<FSAccessor> getFSAccessor() override
|
||||
{ return LocalFSStore::getFSAccessor(); }
|
||||
|
||||
|
|
|
@ -32,7 +32,8 @@ void Logger::warn(const std::string & msg)
|
|||
|
||||
void Logger::writeToStdout(std::string_view s)
|
||||
{
|
||||
std::cout << s << "\n";
|
||||
writeFull(STDOUT_FILENO, s);
|
||||
writeFull(STDOUT_FILENO, "\n");
|
||||
}
|
||||
|
||||
class SimpleLogger : public Logger
|
||||
|
@ -84,7 +85,7 @@ public:
|
|||
|
||||
void startActivity(ActivityId act, Verbosity lvl, ActivityType type,
|
||||
const std::string & s, const Fields & fields, ActivityId parent)
|
||||
override
|
||||
override
|
||||
{
|
||||
if (lvl <= verbosity && !s.empty())
|
||||
log(lvl, s + "...");
|
||||
|
|
|
@ -102,11 +102,9 @@ public:
|
|||
virtual void writeToStdout(std::string_view s);
|
||||
|
||||
template<typename... Args>
|
||||
inline void cout(const std::string & fs, const Args & ... args)
|
||||
inline void cout(const Args & ... args)
|
||||
{
|
||||
boost::format f(fs);
|
||||
formatHelper(f, args...);
|
||||
writeToStdout(f.str());
|
||||
writeToStdout(fmt(args...));
|
||||
}
|
||||
|
||||
virtual std::optional<char> ask(std::string_view s)
|
||||
|
|
|
@ -139,11 +139,11 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
|
|||
for (auto & buildable : buildables) {
|
||||
std::visit(overloaded {
|
||||
[&](const BuiltPath::Opaque & bo) {
|
||||
std::cout << store->printStorePath(bo.path) << std::endl;
|
||||
logger->cout(store->printStorePath(bo.path));
|
||||
},
|
||||
[&](const BuiltPath::Built & bfd) {
|
||||
for (auto & output : bfd.outputs) {
|
||||
std::cout << store->printStorePath(output.second) << std::endl;
|
||||
logger->cout(store->printStorePath(output.second));
|
||||
}
|
||||
},
|
||||
}, buildable.path.raw());
|
||||
|
|
|
@ -17,7 +17,7 @@ struct MixCat : virtual Args
|
|||
if (st.type != FSAccessor::Type::tRegular)
|
||||
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();
|
||||
}
|
||||
if (json) {
|
||||
std::cout << res;
|
||||
logger->cout("%s", res);
|
||||
} else {
|
||||
for (auto & [storeName, storeConfig] : res.items()) {
|
||||
std::cout << "## " << storeName << std::endl << std::endl;
|
||||
|
|
|
@ -97,7 +97,7 @@ void printClosureDiff(
|
|||
items.push_back(fmt("%s → %s", showVersions(removed), showVersions(added)));
|
||||
if (showDelta)
|
||||
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) {
|
||||
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) {
|
||||
std::cout << printValueAsJSON(*state, true, *v, pos, context, false).dump() << std::endl;
|
||||
logger->cout("%s", printValueAsJSON(*state, true, *v, pos, context, false));
|
||||
}
|
||||
|
||||
else {
|
||||
|
|
|
@ -952,7 +952,7 @@ struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun
|
|||
{"path", store->printStorePath(flake.flake.sourceInfo->storePath)},
|
||||
{"inputs", traverse(*flake.lockFile.root)},
|
||||
};
|
||||
std::cout << jsonRoot.dump() << std::endl;
|
||||
logger->cout("%s", jsonRoot);
|
||||
} else {
|
||||
traverse(*flake.lockFile.root);
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ struct CmdLog : InstallableCommand
|
|||
if (!log) continue;
|
||||
stopProgressBar();
|
||||
printInfo("got build log for '%s' from '%s'", installable->what(), logSub.getUri());
|
||||
std::cout << *log;
|
||||
writeFull(STDOUT_FILENO, *log);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ struct MixLs : virtual Args, MixJSON
|
|||
if (json) {
|
||||
if (showDirectory)
|
||||
throw UsageError("'--directory' is useless with '--json'");
|
||||
std::cout << listNar(accessor, path, recursive);
|
||||
logger->cout("%s", listNar(accessor, path, recursive));
|
||||
} else
|
||||
listText(accessor);
|
||||
}
|
||||
|
|
|
@ -292,7 +292,7 @@ void mainWrapped(int argc, char * * argv)
|
|||
NixArgs args;
|
||||
|
||||
if (argc == 2 && std::string(argv[1]) == "__dump-args") {
|
||||
std::cout << args.toJSON().dump() << "\n";
|
||||
logger->cout("%s", args.toJSON());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -312,7 +312,7 @@ void mainWrapped(int argc, char * * argv)
|
|||
b["doc"] = trim(stripIndentation(primOp->doc));
|
||||
res[state.symbols[builtin.name]] = std::move(b);
|
||||
}
|
||||
std::cout << res.dump() << "\n";
|
||||
logger->cout("%s", res);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -321,14 +321,14 @@ void mainWrapped(int argc, char * * argv)
|
|||
if (completions) {
|
||||
switch (completionType) {
|
||||
case ctNormal:
|
||||
std::cout << "normal\n"; break;
|
||||
logger->cout("normal"); break;
|
||||
case ctFilenames:
|
||||
std::cout << "filenames\n"; break;
|
||||
logger->cout("filenames"); break;
|
||||
case ctAttrs:
|
||||
std::cout << "attrs\n"; break;
|
||||
logger->cout("attrs"); break;
|
||||
}
|
||||
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();
|
||||
json["rewrites"] = jsonRewrites;
|
||||
std::cout << json.dump();
|
||||
logger->cout("%s", json);
|
||||
} else {
|
||||
for (auto & path : storePaths) {
|
||||
auto i = remappings.find(path);
|
||||
|
|
|
@ -234,9 +234,9 @@ static int main_nix_prefetch_url(int argc, char * * argv)
|
|||
if (!printPath)
|
||||
printInfo("path is '%s'", store->printStorePath(storePath));
|
||||
|
||||
std::cout << printHash16or32(hash) << std::endl;
|
||||
logger->cout(printHash16or32(hash));
|
||||
if (printPath)
|
||||
std::cout << store->printStorePath(storePath) << std::endl;
|
||||
logger->cout(store->printStorePath(storePath));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -228,12 +228,12 @@ struct ProfileManifest
|
|||
|
||||
while (i != prevElems.end() || j != curElems.end()) {
|
||||
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;
|
||||
++j;
|
||||
}
|
||||
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;
|
||||
++i;
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ struct ProfileManifest
|
|||
auto v1 = i->versions();
|
||||
auto v2 = j->versions();
|
||||
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;
|
||||
}
|
||||
++i;
|
||||
|
@ -250,7 +250,7 @@ struct ProfileManifest
|
|||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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) {
|
||||
if (prevGen) {
|
||||
if (!first) std::cout << "\n";
|
||||
if (!first) logger->cout("");
|
||||
first = false;
|
||||
std::cout << fmt("Version %d -> %d:\n", prevGen->number, gen.number);
|
||||
logger->cout("Version %d -> %d:", prevGen->number, gen.number);
|
||||
printClosureDiff(store,
|
||||
store->followLinksToStorePath(prevGen->path),
|
||||
store->followLinksToStorePath(gen.path),
|
||||
|
@ -622,10 +678,10 @@ struct CmdProfileHistory : virtual StoreCommand, EvalCommand, MixDefaultProfile
|
|||
for (auto & gen : gens) {
|
||||
ProfileManifest manifest(*getEvalState(), gen.path);
|
||||
|
||||
if (!first) std::cout << "\n";
|
||||
if (!first) logger->cout("");
|
||||
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,
|
||||
std::put_time(std::gmtime(&gen.creationTime), "%Y-%m-%d"),
|
||||
|
|
|
@ -65,18 +65,16 @@ struct CmdRealisationInfo : BuiltPathsCommand, MixJSON
|
|||
|
||||
res.push_back(currentPath);
|
||||
}
|
||||
std::cout << res.dump();
|
||||
logger->cout("%s", res);
|
||||
}
|
||||
else {
|
||||
for (auto & path : realisations) {
|
||||
if (auto realisation = std::get_if<Realisation>(&path.raw)) {
|
||||
std::cout <<
|
||||
realisation->id.to_string() << " " <<
|
||||
store->printStorePath(realisation->outPath);
|
||||
logger->cout("%s %s",
|
||||
realisation->id.to_string(),
|
||||
store->printStorePath(realisation->outPath));
|
||||
} else
|
||||
std::cout << store->printStorePath(path.path());
|
||||
|
||||
std::cout << std::endl;
|
||||
logger->cout("%s", store->printStorePath(path.path()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,9 +196,8 @@ struct CmdSearch : InstallableCommand, MixJSON
|
|||
for (auto & cursor : installable->getCursors(*state))
|
||||
visit(*cursor, cursor->getAttrPath(), true);
|
||||
|
||||
if (json) {
|
||||
std::cout << jsonOut->dump() << std::endl;
|
||||
}
|
||||
if (json)
|
||||
logger->cout("%s", *jsonOut);
|
||||
|
||||
if (!json && !results)
|
||||
throw Error("no results for the given search term(s)!");
|
||||
|
|
|
@ -57,7 +57,7 @@ struct CmdShowDerivation : InstallablesCommand
|
|||
jsonRoot[store->printStorePath(drvPath)] =
|
||||
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)
|
||||
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
|
||||
{
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
basicDownloadTests() {
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
source common.sh
|
||||
|
||||
drv=$(nix-instantiate --experimental-features ca-derivations ./content-addressed.nix -A rootCA --arg seed 1)
|
||||
nix --experimental-features 'nix-command ca-derivations' show-derivation "$drv" --arg seed 1
|
||||
drv=$(nix-instantiate ./content-addressed.nix -A rootCA --arg seed 1)
|
||||
nix show-derivation "$drv" --arg seed 1
|
||||
|
||||
buildAttr () {
|
||||
local derivationPath=$1
|
||||
local seedValue=$2
|
||||
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+=("$@")
|
||||
nix-build "${args[@]}"
|
||||
}
|
||||
|
@ -46,17 +46,17 @@ testCutoff () {
|
|||
}
|
||||
|
||||
testGC () {
|
||||
nix-instantiate --experimental-features ca-derivations ./content-addressed.nix -A rootCA --arg seed 5
|
||||
nix-collect-garbage --experimental-features ca-derivations --option keep-derivations true
|
||||
nix-instantiate ./content-addressed.nix -A rootCA --arg seed 5
|
||||
nix-collect-garbage --option keep-derivations true
|
||||
clearStore
|
||||
buildAttr rootCA 1 --out-link $TEST_ROOT/rootCA
|
||||
nix-collect-garbage --experimental-features ca-derivations
|
||||
nix-collect-garbage
|
||||
buildAttr rootCA 1 -j0
|
||||
}
|
||||
|
||||
testNixCommand () {
|
||||
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
|
||||
|
|
|
@ -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 rootCA --outputs out
|
||||
|
||||
if isDaemonNewer "2.13"; then
|
||||
pushToStore="../push-to-store.sh"
|
||||
else
|
||||
pushToStore="../push-to-store-old.sh"
|
||||
fi
|
||||
|
||||
# Same thing, but
|
||||
# 1. With non-ca derivations
|
||||
# 2. Erasing the realisations on the remote store
|
||||
|
@ -37,7 +43,7 @@ nix realisation info --file ./content-addressed.nix dependentCA
|
|||
#
|
||||
# Regression test for #4725
|
||||
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
|
||||
rm -r "$REMOTE_STORE_DIR/realisations"
|
||||
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
|
||||
|
||||
# Test the local realisation disk cache
|
||||
buildDrvs --post-build-hook ../push-to-store.sh
|
||||
buildDrvs --post-build-hook "$pushToStore"
|
||||
clearStore
|
||||
# Add the realisations of rootCA to the cachecache
|
||||
clearCacheCache
|
||||
|
|
|
@ -140,6 +140,36 @@ printf World2 > $flake2Dir/who
|
|||
|
||||
nix profile install $flake1Dir
|
||||
[[ $($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
|
||||
[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]]
|
||||
nix profile install $flake2Dir --priority 0
|
||||
|
|
|
@ -9,8 +9,14 @@ echo 'require-sigs = false' >> $NIX_CONF_DIR/nix.conf
|
|||
|
||||
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.
|
||||
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
|
||||
|
||||
|
|
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" ]
|
||||
|
||||
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