mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-24 14:56:15 +02:00
Merge remote-tracking branch 'origin/master' into lazy-trees
This commit is contained in:
commit
fd51cdcdd7
20 changed files with 107 additions and 31 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -88,7 +88,7 @@ jobs:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: cachix/install-nix-action@v17
|
- uses: cachix/install-nix-action@v17
|
||||||
- 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-instantiate --eval -E '(import ./default.nix).defaultPackage.${builtins.currentSystem}.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@v10
|
- uses: cachix/cachix-action@v10
|
||||||
if: needs.check_cachix.outputs.secret == 'true'
|
if: needs.check_cachix.outputs.secret == 'true'
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -12,6 +12,12 @@
|
||||||
[`--dry-run`]
|
[`--dry-run`]
|
||||||
[{`--out-link` | `-o`} *outlink*]
|
[{`--out-link` | `-o`} *outlink*]
|
||||||
|
|
||||||
|
# Disambiguation
|
||||||
|
|
||||||
|
This man page describes the command `nix-build`, which is distinct from `nix
|
||||||
|
build`. For documentation on the latter, run `nix build --help` or see `man
|
||||||
|
nix3-build`.
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
The `nix-build` command builds the derivations described by the Nix
|
The `nix-build` command builds the derivations described by the Nix
|
||||||
|
|
|
@ -15,6 +15,12 @@
|
||||||
[`--keep` *name*]
|
[`--keep` *name*]
|
||||||
{{`--packages` | `-p`} {*packages* | *expressions*} … | [*path*]}
|
{{`--packages` | `-p`} {*packages* | *expressions*} … | [*path*]}
|
||||||
|
|
||||||
|
# Disambiguation
|
||||||
|
|
||||||
|
This man page describes the command `nix-shell`, which is distinct from `nix
|
||||||
|
shell`. For documentation on the latter, run `nix shell --help` or see `man
|
||||||
|
nix3-shell`.
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
The command `nix-shell` will build the dependencies of the specified
|
The command `nix-shell` will build the dependencies of the specified
|
||||||
|
|
|
@ -638,6 +638,17 @@ place_channel_configuration() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_selinux() {
|
||||||
|
if command -v getenforce > /dev/null 2>&1; then
|
||||||
|
if ! [ "$(getenforce)" = "Disabled" ]; then
|
||||||
|
failure <<EOF
|
||||||
|
Nix does not work with selinux enabled yet!
|
||||||
|
see https://github.com/NixOS/nix/issues/2374
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
welcome_to_nix() {
|
welcome_to_nix() {
|
||||||
ok "Welcome to the Multi-User Nix Installation"
|
ok "Welcome to the Multi-User Nix Installation"
|
||||||
|
|
||||||
|
@ -866,6 +877,8 @@ when I need to.
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
check_selinux
|
||||||
|
|
||||||
if [ "$(uname -s)" = "Darwin" ]; then
|
if [ "$(uname -s)" = "Darwin" ]; then
|
||||||
# shellcheck source=./install-darwin-multi-user.sh
|
# shellcheck source=./install-darwin-multi-user.sh
|
||||||
. "$EXTRACTED_NIX_PATH/install-darwin-multi-user.sh"
|
. "$EXTRACTED_NIX_PATH/install-darwin-multi-user.sh"
|
||||||
|
|
|
@ -146,7 +146,8 @@ SourceExprCommand::SourceExprCommand(bool supportReadOnlyMode)
|
||||||
.shortName = 'f',
|
.shortName = 'f',
|
||||||
.description =
|
.description =
|
||||||
"Interpret installables as attribute paths relative to the Nix expression stored in *file*. "
|
"Interpret installables as attribute paths relative to the Nix expression stored in *file*. "
|
||||||
"If *file* is the character -, then a Nix expression will be read from standard input.",
|
"If *file* is the character -, then a Nix expression will be read from standard input. "
|
||||||
|
"Implies `--impure`.",
|
||||||
.category = installablesCategory,
|
.category = installablesCategory,
|
||||||
.labels = {"file"},
|
.labels = {"file"},
|
||||||
.handler = {&file},
|
.handler = {&file},
|
||||||
|
@ -924,6 +925,9 @@ std::vector<std::pair<std::shared_ptr<Installable>, BuiltPath>> Installable::bui
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Realise::Outputs: {
|
case Realise::Outputs: {
|
||||||
|
if (settings.printMissing)
|
||||||
|
printMissing(store, pathsToBuild, lvlInfo);
|
||||||
|
|
||||||
for (auto & buildResult : store->buildPathsWithResults(pathsToBuild, bMode, evalStore)) {
|
for (auto & buildResult : store->buildPathsWithResults(pathsToBuild, bMode, evalStore)) {
|
||||||
if (!buildResult.success())
|
if (!buildResult.success())
|
||||||
buildResult.rethrow();
|
buildResult.rethrow();
|
||||||
|
|
|
@ -1039,6 +1039,11 @@ struct CmdRepl : StoreCommand, MixEvalArgs
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool forceImpureByDefault() override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::string description() override
|
std::string description() override
|
||||||
{
|
{
|
||||||
return "start an interactive environment for evaluating Nix expressions";
|
return "start an interactive environment for evaluating Nix expressions";
|
||||||
|
@ -1053,8 +1058,6 @@ struct CmdRepl : StoreCommand, MixEvalArgs
|
||||||
|
|
||||||
void run(ref<Store> store) override
|
void run(ref<Store> store) override
|
||||||
{
|
{
|
||||||
evalSettings.pureEval = false;
|
|
||||||
|
|
||||||
auto evalState = make_ref<EvalState>(searchPath, store);
|
auto evalState = make_ref<EvalState>(searchPath, store);
|
||||||
|
|
||||||
auto repl = std::make_unique<NixRepl>(evalState);
|
auto repl = std::make_unique<NixRepl>(evalState);
|
||||||
|
|
|
@ -494,9 +494,6 @@ LockedFlake lockFlake(
|
||||||
if (!lockFlags.allowUnlocked && !input.ref->input.isLocked() && !input.ref->input.isRelative())
|
if (!lockFlags.allowUnlocked && !input.ref->input.isLocked() && !input.ref->input.isRelative())
|
||||||
throw Error("cannot update unlocked flake input '%s' in pure mode", inputPathS);
|
throw Error("cannot update unlocked flake input '%s' in pure mode", inputPathS);
|
||||||
|
|
||||||
if (input.isFlake) {
|
|
||||||
auto inputFlake = getInputFlake();
|
|
||||||
|
|
||||||
/* Note: in case of an --override-input, we use
|
/* Note: in case of an --override-input, we use
|
||||||
the *original* ref (input2.ref) for the
|
the *original* ref (input2.ref) for the
|
||||||
"original" field, rather than the
|
"original" field, rather than the
|
||||||
|
@ -504,8 +501,12 @@ LockedFlake lockFlake(
|
||||||
nuked the next time we update the lock
|
nuked the next time we update the lock
|
||||||
file. That is, overrides are sticky unless you
|
file. That is, overrides are sticky unless you
|
||||||
use --no-write-lock-file. */
|
use --no-write-lock-file. */
|
||||||
auto childNode = std::make_shared<LockedNode>(
|
auto ref = input2.ref ? *input2.ref : *input.ref;
|
||||||
inputFlake.lockedRef, input2.ref ? *input2.ref : *input.ref);
|
|
||||||
|
if (input.isFlake) {
|
||||||
|
auto inputFlake = getInputFlake();
|
||||||
|
|
||||||
|
auto childNode = std::make_shared<LockedNode>(inputFlake.lockedRef, ref);
|
||||||
|
|
||||||
node->inputs.insert_or_assign(id, childNode);
|
node->inputs.insert_or_assign(id, childNode);
|
||||||
|
|
||||||
|
@ -536,7 +537,7 @@ LockedFlake lockFlake(
|
||||||
auto [accessor, lockedRef] = resolvedRef.lazyFetch(state.store);
|
auto [accessor, lockedRef] = resolvedRef.lazyFetch(state.store);
|
||||||
|
|
||||||
node->inputs.insert_or_assign(id,
|
node->inputs.insert_or_assign(id,
|
||||||
std::make_shared<LockedNode>(lockedRef, *input.ref, false));
|
std::make_shared<LockedNode>(lockedRef, ref, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,8 +86,8 @@ bool storeCachedHead(const std::string & actualUrl, const std::string & headRef)
|
||||||
{
|
{
|
||||||
Path cacheDir = getCachePath(actualUrl);
|
Path cacheDir = getCachePath(actualUrl);
|
||||||
try {
|
try {
|
||||||
runProgram("git", true, { "-C", cacheDir, "symbolic-ref", "--", "HEAD", headRef });
|
runProgram("git", true, { "-C", cacheDir, "--git-dir", ".", "symbolic-ref", "--", "HEAD", headRef });
|
||||||
} catch (ExecError & e) {
|
} catch (ExecError &e) {
|
||||||
if (!WIFEXITED(e.status)) throw;
|
if (!WIFEXITED(e.status)) throw;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -373,7 +373,7 @@ struct GitInputScheme : InputScheme
|
||||||
if (repoInfo.hasHead) {
|
if (repoInfo.hasHead) {
|
||||||
// Using git diff is preferrable over lower-level operations here,
|
// Using git diff is preferrable over lower-level operations here,
|
||||||
// because it's conceptually simpler and we only need the exit code anyways.
|
// because it's conceptually simpler and we only need the exit code anyways.
|
||||||
auto gitDiffOpts = Strings({ "-C", repoInfo.url, "diff", "HEAD", "--quiet"});
|
auto gitDiffOpts = Strings({ "-C", repoInfo.url, "--git-dir", repoInfo.gitDir, "diff", "HEAD", "--quiet"});
|
||||||
if (!repoInfo.submodules) {
|
if (!repoInfo.submodules) {
|
||||||
// Changes in submodules should only make the tree dirty
|
// Changes in submodules should only make the tree dirty
|
||||||
// when those submodules will be copied as well.
|
// when those submodules will be copied as well.
|
||||||
|
@ -394,7 +394,7 @@ struct GitInputScheme : InputScheme
|
||||||
|
|
||||||
std::set<CanonPath> listFiles(const RepoInfo & repoInfo)
|
std::set<CanonPath> listFiles(const RepoInfo & repoInfo)
|
||||||
{
|
{
|
||||||
auto gitOpts = Strings({ "-C", repoInfo.url, "ls-files", "-z" });
|
auto gitOpts = Strings({ "-C", repoInfo.url, "--git-dir", repoInfo.gitDir, "ls-files", "-z" });
|
||||||
if (repoInfo.submodules)
|
if (repoInfo.submodules)
|
||||||
gitOpts.emplace_back("--recurse-submodules");
|
gitOpts.emplace_back("--recurse-submodules");
|
||||||
|
|
||||||
|
|
|
@ -392,7 +392,7 @@ struct SourceHutInputScheme : GitArchiveInputScheme
|
||||||
|
|
||||||
Headers headers = makeHeadersWithAuthTokens(host);
|
Headers headers = makeHeadersWithAuthTokens(host);
|
||||||
|
|
||||||
std::string ref_uri;
|
std::string refUri;
|
||||||
if (ref == "HEAD") {
|
if (ref == "HEAD") {
|
||||||
auto file = store->toRealPath(
|
auto file = store->toRealPath(
|
||||||
downloadFile(store, fmt("%s/HEAD", base_url), "source", false, headers).storePath);
|
downloadFile(store, fmt("%s/HEAD", base_url), "source", false, headers).storePath);
|
||||||
|
@ -404,10 +404,11 @@ struct SourceHutInputScheme : GitArchiveInputScheme
|
||||||
if (!remoteLine) {
|
if (!remoteLine) {
|
||||||
throw BadURL("in '%d', couldn't resolve HEAD ref '%d'", input.to_string(), ref);
|
throw BadURL("in '%d', couldn't resolve HEAD ref '%d'", input.to_string(), ref);
|
||||||
}
|
}
|
||||||
ref_uri = remoteLine->target;
|
refUri = remoteLine->target;
|
||||||
} else {
|
} else {
|
||||||
ref_uri = fmt("refs/(heads|tags)/%s", ref);
|
refUri = fmt("refs/(heads|tags)/%s", ref);
|
||||||
}
|
}
|
||||||
|
std::regex refRegex(refUri);
|
||||||
|
|
||||||
auto file = store->toRealPath(
|
auto file = store->toRealPath(
|
||||||
downloadFile(store, fmt("%s/info/refs", base_url), "source", false, headers).storePath);
|
downloadFile(store, fmt("%s/info/refs", base_url), "source", false, headers).storePath);
|
||||||
|
@ -417,7 +418,7 @@ struct SourceHutInputScheme : GitArchiveInputScheme
|
||||||
std::optional<std::string> id;
|
std::optional<std::string> id;
|
||||||
while(!id && getline(is, line)) {
|
while(!id && getline(is, line)) {
|
||||||
auto parsedLine = git::parseLsRemoteLine(line);
|
auto parsedLine = git::parseLsRemoteLine(line);
|
||||||
if (parsedLine && parsedLine->reference == ref_uri)
|
if (parsedLine && parsedLine->reference && std::regex_match(*parsedLine->reference, refRegex))
|
||||||
id = parsedLine->target;
|
id = parsedLine->target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,7 @@ void LocalStore::addTempRoot(const StorePath & path)
|
||||||
state->fdRootsSocket.close();
|
state->fdRootsSocket.close();
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +154,7 @@ void LocalStore::addTempRoot(const StorePath & path)
|
||||||
state->fdRootsSocket.close();
|
state->fdRootsSocket.close();
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
throw;
|
||||||
} catch (EndOfFile & e) {
|
} catch (EndOfFile & e) {
|
||||||
debug("GC socket disconnected");
|
debug("GC socket disconnected");
|
||||||
state->fdRootsSocket.close();
|
state->fdRootsSocket.close();
|
||||||
|
|
|
@ -802,7 +802,7 @@ public:
|
||||||
)"};
|
)"};
|
||||||
|
|
||||||
Setting<StringSet> ignoredAcls{
|
Setting<StringSet> ignoredAcls{
|
||||||
this, {"security.selinux", "system.nfs4_acl"}, "ignored-acls",
|
this, {"security.selinux", "system.nfs4_acl", "security.csm"}, "ignored-acls",
|
||||||
R"(
|
R"(
|
||||||
A list of ACLs that should be ignored, normally Nix attempts to
|
A list of ACLs that should be ignored, normally Nix attempts to
|
||||||
remove all ACLs from files and directories in the Nix store, but
|
remove all ACLs from files and directories in the Nix store, but
|
||||||
|
|
|
@ -69,6 +69,7 @@ protected:
|
||||||
} catch (SysError & e) {
|
} catch (SysError & e) {
|
||||||
if (e.errNo == ENOENT)
|
if (e.errNo == ENOENT)
|
||||||
throw NoSuchBinaryCacheFile("file '%s' does not exist in binary cache", path);
|
throw NoSuchBinaryCacheFile("file '%s' does not exist in binary cache", path);
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,13 +67,26 @@ bool UserLock::findFreeUser() {
|
||||||
#if __linux__
|
#if __linux__
|
||||||
/* Get the list of supplementary groups of this build user. This
|
/* Get the list of supplementary groups of this build user. This
|
||||||
is usually either empty or contains a group such as "kvm". */
|
is usually either empty or contains a group such as "kvm". */
|
||||||
supplementaryGIDs.resize(10);
|
int ngroups = 32; // arbitrary initial guess
|
||||||
int ngroups = supplementaryGIDs.size();
|
supplementaryGIDs.resize(ngroups);
|
||||||
int err = getgrouplist(pw->pw_name, pw->pw_gid,
|
|
||||||
supplementaryGIDs.data(), &ngroups);
|
|
||||||
if (err == -1)
|
|
||||||
throw Error("failed to get list of supplementary groups for '%1%'", pw->pw_name);
|
|
||||||
|
|
||||||
|
int err = getgrouplist(pw->pw_name, pw->pw_gid, supplementaryGIDs.data(),
|
||||||
|
&ngroups);
|
||||||
|
|
||||||
|
// Our initial size of 32 wasn't sufficient, the correct size has
|
||||||
|
// been stored in ngroups, so we try again.
|
||||||
|
if (err == -1) {
|
||||||
|
supplementaryGIDs.resize(ngroups);
|
||||||
|
err = getgrouplist(pw->pw_name, pw->pw_gid, supplementaryGIDs.data(),
|
||||||
|
&ngroups);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it failed once more, then something must be broken.
|
||||||
|
if (err == -1)
|
||||||
|
throw Error("failed to get list of supplementary groups for '%1%'",
|
||||||
|
pw->pw_name);
|
||||||
|
|
||||||
|
// Finally, trim back the GID list to its real size
|
||||||
supplementaryGIDs.resize(ngroups);
|
supplementaryGIDs.resize(ngroups);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@ public:
|
||||||
/* Return a short one-line description of the command. */
|
/* Return a short one-line description of the command. */
|
||||||
virtual std::string description() { return ""; }
|
virtual std::string description() { return ""; }
|
||||||
|
|
||||||
|
virtual bool forceImpureByDefault() { return false; }
|
||||||
|
|
||||||
/* Return documentation about this command, in Markdown format. */
|
/* Return documentation about this command, in Markdown format. */
|
||||||
virtual std::string doc() { return ""; }
|
virtual std::string doc() { return ""; }
|
||||||
|
|
||||||
|
|
|
@ -548,6 +548,8 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
|
|
||||||
restoreProcessContext();
|
restoreProcessContext();
|
||||||
|
|
||||||
|
logger->stop();
|
||||||
|
|
||||||
execvp(shell->c_str(), argPtrs.data());
|
execvp(shell->c_str(), argPtrs.data());
|
||||||
|
|
||||||
throw SysError("executing shell '%s'", *shell);
|
throw SysError("executing shell '%s'", *shell);
|
||||||
|
@ -606,6 +608,8 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
outPaths.push_back(outputPath);
|
outPaths.push_back(outputPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger->stop();
|
||||||
|
|
||||||
for (auto & path : outPaths)
|
for (auto & path : outPaths)
|
||||||
std::cout << store->printStorePath(path) << '\n';
|
std::cout << store->printStorePath(path) << '\n';
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ void removeOldGenerations(std::string dir)
|
||||||
link = readLink(path);
|
link = readLink(path);
|
||||||
} catch (SysError & e) {
|
} catch (SysError & e) {
|
||||||
if (e.errNo == ENOENT) continue;
|
if (e.errNo == ENOENT) continue;
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
if (link.find("link") != std::string::npos) {
|
if (link.find("link") != std::string::npos) {
|
||||||
printInfo(format("removing old generations of profile %1%") % path);
|
printInfo(format("removing old generations of profile %1%") % path);
|
||||||
|
|
|
@ -1490,7 +1490,7 @@ static int main_nix_env(int argc, char * * argv)
|
||||||
if (globals.profile == "")
|
if (globals.profile == "")
|
||||||
globals.profile = getDefaultProfile();
|
globals.profile = getDefaultProfile();
|
||||||
|
|
||||||
op(globals, opFlags, opArgs);
|
op(globals, std::move(opFlags), std::move(opArgs));
|
||||||
|
|
||||||
globals.state->printStats();
|
globals.state->printStats();
|
||||||
|
|
||||||
|
|
|
@ -377,6 +377,9 @@ void mainWrapped(int argc, char * * argv)
|
||||||
settings.ttlPositiveNarInfoCache = 0;
|
settings.ttlPositiveNarInfoCache = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args.command->second->forceImpureByDefault() && !evalSettings.pureEval.overridden) {
|
||||||
|
evalSettings.pureEval = false;
|
||||||
|
}
|
||||||
args.command->second->prepare();
|
args.command->second->prepare();
|
||||||
args.command->second->run();
|
args.command->second->run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,11 @@ testRepl () {
|
||||||
echo "$replOutput"
|
echo "$replOutput"
|
||||||
echo "$replOutput" | grep -qs "while evaluating the file" \
|
echo "$replOutput" | grep -qs "while evaluating the file" \
|
||||||
|| fail "nix repl --show-trace doesn't show the trace"
|
|| fail "nix repl --show-trace doesn't show the trace"
|
||||||
|
|
||||||
|
nix repl "${nixArgs[@]}" --option pure-eval true 2>&1 <<< "builtins.currentSystem" \
|
||||||
|
| grep "attribute 'currentSystem' missing"
|
||||||
|
nix repl "${nixArgs[@]}" 2>&1 <<< "builtins.currentSystem" \
|
||||||
|
| grep "$(nix-instantiate --eval -E 'builtins.currentSystem')"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Simple test, try building a drv
|
# Simple test, try building a drv
|
||||||
|
|
|
@ -59,7 +59,7 @@ let
|
||||||
echo 'ref: refs/heads/master' > $out/HEAD
|
echo 'ref: refs/heads/master' > $out/HEAD
|
||||||
|
|
||||||
mkdir -p $out/info
|
mkdir -p $out/info
|
||||||
echo -e '${nixpkgs.rev}\trefs/heads/master' > $out/info/refs
|
echo -e '${nixpkgs.rev}\trefs/heads/master\n${nixpkgs.rev}\trefs/tags/foo-bar' > $out/info/refs
|
||||||
'';
|
'';
|
||||||
|
|
||||||
in
|
in
|
||||||
|
@ -132,6 +132,17 @@ makeTest (
|
||||||
client.succeed("curl -v https://git.sr.ht/ >&2")
|
client.succeed("curl -v https://git.sr.ht/ >&2")
|
||||||
client.succeed("nix registry list | grep nixpkgs")
|
client.succeed("nix registry list | grep nixpkgs")
|
||||||
|
|
||||||
|
# Test that it resolves HEAD
|
||||||
|
rev = client.succeed("nix flake info sourcehut:~NixOS/nixpkgs --json | jq -r .revision")
|
||||||
|
assert rev.strip() == "${nixpkgs.rev}", "revision mismatch"
|
||||||
|
# Test that it resolves branches
|
||||||
|
rev = client.succeed("nix flake info sourcehut:~NixOS/nixpkgs/master --json | jq -r .revision")
|
||||||
|
assert rev.strip() == "${nixpkgs.rev}", "revision mismatch"
|
||||||
|
# Test that it resolves tags
|
||||||
|
rev = client.succeed("nix flake info sourcehut:~NixOS/nixpkgs/foo-bar --json | jq -r .revision")
|
||||||
|
assert rev.strip() == "${nixpkgs.rev}", "revision mismatch"
|
||||||
|
|
||||||
|
# Registry and pinning test
|
||||||
rev = client.succeed("nix flake info nixpkgs --json | jq -r .revision")
|
rev = client.succeed("nix flake info nixpkgs --json | jq -r .revision")
|
||||||
assert rev.strip() == "${nixpkgs.rev}", "revision mismatch"
|
assert rev.strip() == "${nixpkgs.rev}", "revision mismatch"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue