Merge remote-tracking branch 'upstream/master' into indexed-store-path-outputs
This commit is contained in:
commit
5c1f2e0fb1
|
@ -6,7 +6,8 @@ options:
|
|||
concatStrings (map
|
||||
(name:
|
||||
let option = options.${name}; in
|
||||
" - `${name}` \n\n"
|
||||
" - [`${name}`](#conf-${name})"
|
||||
+ "<p id=\"conf-${name}\"></p>\n\n"
|
||||
+ concatStrings (map (s: " ${s}\n") (splitLines option.description)) + "\n\n"
|
||||
+ (if option.documentDefault
|
||||
then " **Default:** " + (
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Release X.Y (2022-03-07)
|
||||
# Release 2.7 (2022-03-07)
|
||||
|
||||
* Nix will now make some helpful suggestions when you mistype
|
||||
something on the command line. For instance, if you type `nix build
|
||||
|
|
|
@ -32,3 +32,11 @@
|
|||
paths. Like fixed-output derivations, impure derivations have access
|
||||
to the network. Only fixed-output derivations and impure derivations
|
||||
can depend on an impure derivation.
|
||||
|
||||
* The `nixosModule` flake output attribute has been renamed consistent
|
||||
with the `.default` renames in nix 2.7.
|
||||
|
||||
* `nixosModule` → `nixosModules.default`
|
||||
|
||||
As before, the old output will continue to work, but `nix flake check` will
|
||||
issue a warning about it.
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1632864508,
|
||||
"narHash": "sha256-d127FIvGR41XbVRDPVvozUPQ/uRHbHwvfyKHwEt5xFM=",
|
||||
"lastModified": 1645296114,
|
||||
"narHash": "sha256-y53N7TyIkXsjMpOG7RhvqJFGDacLs9HlyHeSTBioqYU=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "82891b5e2c2359d7e58d08849e4c89511ab94234",
|
||||
"rev": "530a53dcbc9437363471167a5e4762c5fcfa34a1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -14,7 +14,7 @@ curl -sS -H 'Accept: application/json' https://hydra.nixos.org/jobset/nix/master
|
|||
someBuildFailed=0
|
||||
|
||||
for buildId in $BUILDS_FOR_LATEST_EVAL; do
|
||||
buildInfo=$(curl -sS -H 'Accept: application/json' "https://hydra.nixos.org/build/$buildId")
|
||||
buildInfo=$(curl --fail -sS -H 'Accept: application/json' "https://hydra.nixos.org/build/$buildId")
|
||||
|
||||
finished=$(echo "$buildInfo" | jq -r '.finished')
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ poly_configure_nix_daemon_service() {
|
|||
ln -sfn /nix/var/nix/profiles/default/$TMPFILES_SRC $TMPFILES_DEST
|
||||
|
||||
_sudo "to run systemd-tmpfiles once to pick that path up" \
|
||||
systemd-tmpfiles create --prefix=/nix/var/nix
|
||||
systemd-tmpfiles --create --prefix=/nix/var/nix
|
||||
|
||||
_sudo "to set up the nix-daemon service" \
|
||||
systemctl link "/nix/var/nix/profiles/default$SERVICE_SRC"
|
||||
|
|
|
@ -82,7 +82,7 @@ if [ "$(uname -s)" != "Darwin" ]; then
|
|||
fi
|
||||
|
||||
if command -v curl > /dev/null 2>&1; then
|
||||
fetch() { curl -L "$1" -o "$2"; }
|
||||
fetch() { curl --fail -L "$1" -o "$2"; }
|
||||
elif command -v wget > /dev/null 2>&1; then
|
||||
fetch() { wget "$1" -O "$2"; }
|
||||
else
|
||||
|
|
|
@ -991,7 +991,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
|||
bool contentAddressed = false;
|
||||
bool isImpure = false;
|
||||
std::optional<std::string> outputHash;
|
||||
std::optional<std::string> outputHashAlgo;
|
||||
std::string outputHashAlgo;
|
||||
std::optional<FileIngestionMethod> ingestionMethod;
|
||||
|
||||
StringSet outputs;
|
||||
|
@ -1190,8 +1190,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
|||
.errPos = posDrvName
|
||||
});
|
||||
|
||||
std::optional<HashType> ht = parseHashTypeOpt(outputHashAlgo.value_or("sha256"));
|
||||
Hash h = newHashAllowEmpty(*outputHash, ht);
|
||||
auto h = newHashAllowEmpty(*outputHash, parseHashTypeOpt(outputHashAlgo));
|
||||
|
||||
auto method = ingestionMethod.value_or(FileIngestionMethod::Flat);
|
||||
auto outPath = state.store->makeFixedOutputPath(method, h, drvName);
|
||||
|
@ -1212,7 +1211,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
|||
.errPos = posDrvName
|
||||
});
|
||||
|
||||
auto ht = parseHashType(outputHashAlgo.value_or("sha256"));
|
||||
auto ht = parseHashTypeOpt(outputHashAlgo).value_or(htSHA256);
|
||||
auto method = ingestionMethod.value_or(FileIngestionMethod::Recursive);
|
||||
|
||||
for (auto & i : outputs) {
|
||||
|
|
|
@ -61,6 +61,12 @@ static void prim_fetchClosure(EvalState & state, const Pos & pos, Value * * args
|
|||
.errPos = pos
|
||||
});
|
||||
|
||||
if (!parsedURL.query.empty())
|
||||
throw Error({
|
||||
.msg = hintfmt("'fetchClosure' does not support URL query parameters (in '%s')", *fromStoreUrl),
|
||||
.errPos = pos
|
||||
});
|
||||
|
||||
auto fromStore = openStore(parsedURL.to_string());
|
||||
|
||||
if (toCA) {
|
||||
|
@ -87,7 +93,8 @@ static void prim_fetchClosure(EvalState & state, const Pos & pos, Value * * args
|
|||
});
|
||||
}
|
||||
} else {
|
||||
copyClosure(*fromStore, *state.store, RealisedPath::Set { *fromPath });
|
||||
if (!state.store->isValidPath(*fromPath))
|
||||
copyClosure(*fromStore, *state.store, RealisedPath::Set { *fromPath });
|
||||
toPath = fromPath;
|
||||
}
|
||||
|
||||
|
|
|
@ -285,9 +285,11 @@ struct GitInputScheme : InputScheme
|
|||
auto files = tokenizeString<std::set<std::string>>(
|
||||
runProgram("git", true, gitOpts), "\0"s);
|
||||
|
||||
Path actualPath(absPath(actualUrl));
|
||||
|
||||
PathFilter filter = [&](const Path & p) -> bool {
|
||||
assert(hasPrefix(p, actualUrl));
|
||||
std::string file(p, actualUrl.size() + 1);
|
||||
assert(hasPrefix(p, actualPath));
|
||||
std::string file(p, actualPath.size() + 1);
|
||||
|
||||
auto st = lstat(p);
|
||||
|
||||
|
@ -300,13 +302,13 @@ struct GitInputScheme : InputScheme
|
|||
return files.count(file);
|
||||
};
|
||||
|
||||
auto storePath = store->addToStore(input.getName(), actualUrl, FileIngestionMethod::Recursive, htSHA256, filter);
|
||||
auto storePath = store->addToStore(input.getName(), actualPath, FileIngestionMethod::Recursive, htSHA256, filter);
|
||||
|
||||
// FIXME: maybe we should use the timestamp of the last
|
||||
// modified dirty file?
|
||||
input.attrs.insert_or_assign(
|
||||
"lastModified",
|
||||
hasHead ? std::stoull(runProgram("git", true, { "-C", actualUrl, "log", "-1", "--format=%ct", "--no-show-signature", "HEAD" })) : 0);
|
||||
hasHead ? std::stoull(runProgram("git", true, { "-C", actualPath, "log", "-1", "--format=%ct", "--no-show-signature", "HEAD" })) : 0);
|
||||
|
||||
return {std::move(storePath), input};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "realisation.hh"
|
||||
#include "derived-path.hh"
|
||||
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
|
|
|
@ -41,7 +41,7 @@ void DrvOutputSubstitutionGoal::tryNext()
|
|||
if (subs.size() == 0) {
|
||||
/* None left. Terminate this goal and let someone else deal
|
||||
with it. */
|
||||
debug("drv output '%s' is required, but there is no substituter that can provide it", id.to_string());
|
||||
debug("derivation output '%s' is required, but there is no substituter that can provide it", id.to_string());
|
||||
|
||||
/* Hack: don't indicate failure if there were no substituters.
|
||||
In that case the calling derivation should just do a
|
||||
|
|
|
@ -24,9 +24,16 @@ PathSubstitutionGoal::~PathSubstitutionGoal()
|
|||
}
|
||||
|
||||
|
||||
void PathSubstitutionGoal::done(ExitCode result, BuildResult::Status status)
|
||||
void PathSubstitutionGoal::done(
|
||||
ExitCode result,
|
||||
BuildResult::Status status,
|
||||
std::optional<std::string> errorMsg)
|
||||
{
|
||||
buildResult.status = status;
|
||||
if (errorMsg) {
|
||||
debug(*errorMsg);
|
||||
buildResult.errorMsg = *errorMsg;
|
||||
}
|
||||
amDone(result);
|
||||
}
|
||||
|
||||
|
@ -67,12 +74,14 @@ void PathSubstitutionGoal::tryNext()
|
|||
if (subs.size() == 0) {
|
||||
/* None left. Terminate this goal and let someone else deal
|
||||
with it. */
|
||||
debug("path '%s' is required, but there is no substituter that can build it", worker.store.printStorePath(storePath));
|
||||
|
||||
/* Hack: don't indicate failure if there were no substituters.
|
||||
In that case the calling derivation should just do a
|
||||
build. */
|
||||
done(substituterFailed ? ecFailed : ecNoSubstituters, BuildResult::NoSubstituters);
|
||||
done(
|
||||
substituterFailed ? ecFailed : ecNoSubstituters,
|
||||
BuildResult::NoSubstituters,
|
||||
fmt("path '%s' is required, but there is no substituter that can build it", worker.store.printStorePath(storePath)));
|
||||
|
||||
if (substituterFailed) {
|
||||
worker.failedSubstitutions++;
|
||||
|
@ -169,10 +178,10 @@ void PathSubstitutionGoal::referencesValid()
|
|||
trace("all references realised");
|
||||
|
||||
if (nrFailed > 0) {
|
||||
debug("some references of path '%s' could not be realised", worker.store.printStorePath(storePath));
|
||||
done(
|
||||
nrNoSubstituters > 0 || nrIncompleteClosure > 0 ? ecIncompleteClosure : ecFailed,
|
||||
BuildResult::DependencyFailed);
|
||||
BuildResult::DependencyFailed,
|
||||
fmt("some references of path '%s' could not be realised", worker.store.printStorePath(storePath)));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,10 @@ struct PathSubstitutionGoal : public Goal
|
|||
/* Content address for recomputing store path */
|
||||
std::optional<ContentAddress> ca;
|
||||
|
||||
void done(ExitCode result, BuildResult::Status status);
|
||||
void done(
|
||||
ExitCode result,
|
||||
BuildResult::Status status,
|
||||
std::optional<std::string> errorMsg = {});
|
||||
|
||||
public:
|
||||
PathSubstitutionGoal(const StorePath & storePath, Worker & worker, RepairFlag repair = NoRepair, std::optional<ContentAddress> ca = std::nullopt);
|
||||
|
|
|
@ -1259,9 +1259,9 @@ template<class C> C tokenizeString(std::string_view s, std::string_view separato
|
|||
{
|
||||
C result;
|
||||
auto pos = s.find_first_not_of(separators, 0);
|
||||
while (pos != std::string::npos) {
|
||||
while (pos != std::string_view::npos) {
|
||||
auto end = s.find_first_of(separators, pos + 1);
|
||||
if (end == std::string::npos) end = s.size();
|
||||
if (end == std::string_view::npos) end = s.size();
|
||||
result.insert(result.end(), std::string(s, pos, end - pos));
|
||||
pos = s.find_first_not_of(separators, end);
|
||||
}
|
||||
|
@ -1471,6 +1471,7 @@ constexpr char base64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
|
|||
std::string base64Encode(std::string_view s)
|
||||
{
|
||||
std::string res;
|
||||
res.reserve((s.size() + 2) / 3 * 4);
|
||||
int data = 0, nbits = 0;
|
||||
|
||||
for (char c : s) {
|
||||
|
@ -1502,6 +1503,9 @@ std::string base64Decode(std::string_view s)
|
|||
}();
|
||||
|
||||
std::string res;
|
||||
// Some sequences are missing the padding consisting of up to two '='.
|
||||
// vvv
|
||||
res.reserve((s.size() + 2) / 4 * 3);
|
||||
unsigned int d = 0, bits = 0;
|
||||
|
||||
for (char c : s) {
|
||||
|
@ -1688,7 +1692,9 @@ void setStackSize(size_t stackSize)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if __linux__
|
||||
static AutoCloseFD fdSavedMountNamespace;
|
||||
#endif
|
||||
|
||||
void saveMountNamespace()
|
||||
{
|
||||
|
@ -1707,8 +1713,13 @@ void restoreMountNamespace()
|
|||
{
|
||||
#if __linux__
|
||||
try {
|
||||
auto savedCwd = absPath(".");
|
||||
|
||||
if (fdSavedMountNamespace && setns(fdSavedMountNamespace.get(), CLONE_NEWNS) == -1)
|
||||
throw SysError("restoring parent mount namespace");
|
||||
if (chdir(savedCwd.c_str()) == -1) {
|
||||
throw SysError("restoring cwd");
|
||||
}
|
||||
} catch (Error & e) {
|
||||
debug(e.msg());
|
||||
}
|
||||
|
|
|
@ -24,12 +24,12 @@ std::string formatProtocol(unsigned int proto)
|
|||
}
|
||||
|
||||
bool checkPass(const std::string & msg) {
|
||||
logger->log(ANSI_GREEN "[PASS] " ANSI_NORMAL + msg);
|
||||
notice(ANSI_GREEN "[PASS] " ANSI_NORMAL + msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool checkFail(const std::string & msg) {
|
||||
logger->log(ANSI_RED "[FAIL] " ANSI_NORMAL + msg);
|
||||
notice(ANSI_RED "[FAIL] " ANSI_NORMAL + msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -463,7 +463,7 @@ struct CmdFlakeCheck : FlakeCommand
|
|||
|
||||
for (auto & attr : *v.attrs) {
|
||||
std::string name(attr.name);
|
||||
if (name != "path" && name != "description")
|
||||
if (name != "path" && name != "description" && name != "welcomeText")
|
||||
throw Error("template '%s' has unsupported attribute '%s'", attrPath, name);
|
||||
}
|
||||
} catch (Error & e) {
|
||||
|
@ -508,6 +508,7 @@ struct CmdFlakeCheck : FlakeCommand
|
|||
name == "defaultBundler" ? "bundlers.<system>.default" :
|
||||
name == "overlay" ? "overlays.default" :
|
||||
name == "devShell" ? "devShells.<system>.default" :
|
||||
name == "nixosModule" ? "nixosModules.default" :
|
||||
"";
|
||||
if (replacement != "")
|
||||
warn("flake output attribute '%s' is deprecated; use '%s' instead", name, replacement);
|
||||
|
|
|
@ -97,19 +97,30 @@ struct ProfileManifest
|
|||
auto json = nlohmann::json::parse(readFile(manifestPath));
|
||||
|
||||
auto version = json.value("version", 0);
|
||||
if (version != 1)
|
||||
throw Error("profile manifest '%s' has unsupported version %d", manifestPath, version);
|
||||
std::string sUrl;
|
||||
std::string sOriginalUrl;
|
||||
switch(version){
|
||||
case 1:
|
||||
sUrl = "uri";
|
||||
sOriginalUrl = "originalUri";
|
||||
break;
|
||||
case 2:
|
||||
sUrl = "url";
|
||||
sOriginalUrl = "originalUrl";
|
||||
break;
|
||||
default:
|
||||
throw Error("profile manifest '%s' has unsupported version %d", manifestPath, version);
|
||||
}
|
||||
|
||||
for (auto & e : json["elements"]) {
|
||||
ProfileElement element;
|
||||
for (auto & p : e["storePaths"])
|
||||
element.storePaths.insert(state.store->parseStorePath((std::string) p));
|
||||
element.active = e["active"];
|
||||
if (e.value("uri", "") != "") {
|
||||
auto originalUrl = e.value("originalUrl", e["originalUri"]);
|
||||
if (e.value(sUrl,"") != "") {
|
||||
element.source = ProfileElementSource{
|
||||
parseFlakeRef(originalUrl),
|
||||
parseFlakeRef(e["uri"]),
|
||||
parseFlakeRef(e[sOriginalUrl]),
|
||||
parseFlakeRef(e[sUrl]),
|
||||
e["attrPath"]
|
||||
};
|
||||
}
|
||||
|
@ -144,13 +155,13 @@ struct ProfileManifest
|
|||
obj["active"] = element.active;
|
||||
if (element.source) {
|
||||
obj["originalUrl"] = element.source->originalRef.to_string();
|
||||
obj["uri"] = element.source->resolvedRef.to_string();
|
||||
obj["url"] = element.source->resolvedRef.to_string();
|
||||
obj["attrPath"] = element.source->attrPath;
|
||||
}
|
||||
array.push_back(obj);
|
||||
}
|
||||
nlohmann::json json;
|
||||
json["version"] = 1;
|
||||
json["version"] = 2;
|
||||
json["elements"] = array;
|
||||
return json.dump();
|
||||
}
|
||||
|
|
|
@ -182,6 +182,7 @@ struct CmdRun : InstallableCommand
|
|||
{
|
||||
auto state = getEvalState();
|
||||
|
||||
lockFlags.applyNixConfig = true;
|
||||
auto app = installable->toApp(*state).resolve(getEvalStore(), store);
|
||||
|
||||
Strings allArgs{app.program};
|
||||
|
|
|
@ -64,8 +64,7 @@ rec {
|
|||
dependentFixedOutput = mkDerivation {
|
||||
name = "dependent-fixed-output";
|
||||
outputHashMode = "recursive";
|
||||
outputHashAlgo = "sha256";
|
||||
outputHash = "sha256-QvtAMbUl/uvi+LCObmqOhvNOapHdA2raiI4xG5zI5pA=";
|
||||
outputHash = "sha512-7aJcmSuEuYP5tGKcmGY8bRr/lrCjJlOxP2mIUjO/vMQeg6gx/65IbzRWES8EKiPDOs9z+wF30lEfcwxM/cT4pw==";
|
||||
buildCommand = ''
|
||||
cat ${dependentCA}/dep
|
||||
echo foo > $out
|
||||
|
|
|
@ -56,3 +56,15 @@ nix copy --to file://$cacheDir $caPath
|
|||
fromPath = $caPath;
|
||||
}
|
||||
") = $caPath ]]
|
||||
|
||||
# Check that URL query parameters aren't allowed.
|
||||
clearStore
|
||||
narCache=$TEST_ROOT/nar-cache
|
||||
rm -rf $narCache
|
||||
(! nix eval -v --raw --expr "
|
||||
builtins.fetchClosure {
|
||||
fromStore = \"file://$cacheDir?local-nar-cache=$narCache\";
|
||||
fromPath = $caPath;
|
||||
}
|
||||
")
|
||||
(! [ -e $narCache ])
|
||||
|
|
|
@ -7,7 +7,9 @@ fi
|
|||
|
||||
clearStore
|
||||
|
||||
repo=$TEST_ROOT/git
|
||||
# Intentionally not in a canonical form
|
||||
# See https://github.com/NixOS/nix/issues/6195
|
||||
repo=$TEST_ROOT/./git
|
||||
|
||||
export _NIX_FORCE_HTTP=1
|
||||
|
||||
|
|
|
@ -376,6 +376,9 @@ cat > $templatesDir/flake.nix <<EOF
|
|||
trivial = {
|
||||
path = ./trivial;
|
||||
description = "A trivial flake";
|
||||
welcomeText = ''
|
||||
Welcome to my trivial flake
|
||||
'';
|
||||
};
|
||||
default = trivial;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue