commit
981f686259
|
@ -139,7 +139,12 @@ GitInfo exportGit(ref<Store> store, std::string uri,
|
||||||
|
|
||||||
// FIXME: git stderr messes up our progress indicator, so
|
// FIXME: git stderr messes up our progress indicator, so
|
||||||
// we're using --quiet for now. Should process its stderr.
|
// we're using --quiet for now. Should process its stderr.
|
||||||
runProgram("git", true, { "-C", repoDir, "fetch", "--quiet", "--force", "--", uri, fmt("%s:%s", *ref, *ref) });
|
try {
|
||||||
|
runProgram("git", true, { "-C", repoDir, "fetch", "--quiet", "--force", "--", uri, fmt("%s:%s", *ref, *ref) });
|
||||||
|
} catch (Error & e) {
|
||||||
|
if (!pathExists(localRefFile)) throw;
|
||||||
|
warn("could not update local clone of Git repository '%s'; continuing with the most recent version", uri);
|
||||||
|
}
|
||||||
|
|
||||||
struct timeval times[2];
|
struct timeval times[2];
|
||||||
times[0].tv_sec = now;
|
times[0].tv_sec = now;
|
||||||
|
|
|
@ -132,6 +132,8 @@ struct ResolvedFlake
|
||||||
|
|
||||||
ResolvedFlake resolveFlake(EvalState &, const FlakeRef &, HandleLockFile);
|
ResolvedFlake resolveFlake(EvalState &, const FlakeRef &, HandleLockFile);
|
||||||
|
|
||||||
|
void callFlake(EvalState & state, const ResolvedFlake & resFlake, Value & v);
|
||||||
|
|
||||||
void updateLockFile(EvalState &, const FlakeRef & flakeRef, bool recreateLockFile);
|
void updateLockFile(EvalState &, const FlakeRef & flakeRef, bool recreateLockFile);
|
||||||
|
|
||||||
void gitCloneFlake(FlakeRef flakeRef, EvalState &, Registries, const Path & destDir);
|
void gitCloneFlake(FlakeRef flakeRef, EvalState &, Registries, const Path & destDir);
|
||||||
|
|
|
@ -194,6 +194,8 @@ std::string FlakeRef::to_string() const
|
||||||
|
|
||||||
else abort();
|
else abort();
|
||||||
|
|
||||||
|
assert(FlakeRef(string) == *this);
|
||||||
|
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "primops/flake.hh"
|
#include "primops/flake.hh"
|
||||||
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
@ -162,6 +163,44 @@ struct InstallableAttrPath : InstallableValue
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void makeFlakeClosureGCRoot(Store & store, const FlakeRef & origFlakeRef, const ResolvedFlake & resFlake)
|
||||||
|
{
|
||||||
|
if (std::get_if<FlakeRef::IsPath>(&origFlakeRef.data)) return;
|
||||||
|
|
||||||
|
/* Get the store paths of all non-local flakes. */
|
||||||
|
PathSet closure;
|
||||||
|
|
||||||
|
std::queue<std::reference_wrapper<const ResolvedFlake>> queue;
|
||||||
|
queue.push(resFlake);
|
||||||
|
|
||||||
|
while (!queue.empty()) {
|
||||||
|
const ResolvedFlake & flake = queue.front();
|
||||||
|
queue.pop();
|
||||||
|
if (!std::get_if<FlakeRef::IsPath>(&flake.flake.resolvedRef.data))
|
||||||
|
closure.insert(flake.flake.storePath);
|
||||||
|
for (const auto & dep : flake.flakeDeps)
|
||||||
|
queue.push(dep.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (closure.empty()) return;
|
||||||
|
|
||||||
|
/* Write the closure to a file in the store. */
|
||||||
|
auto closurePath = store.addTextToStore("flake-closure", concatStringsSep(" ", closure), closure);
|
||||||
|
|
||||||
|
Path cacheDir = getCacheDir() + "/nix/flake-closures";
|
||||||
|
createDirs(cacheDir);
|
||||||
|
|
||||||
|
auto s = origFlakeRef.to_string();
|
||||||
|
assert(s[0] != '.');
|
||||||
|
s = replaceStrings(s, "%", "%25");
|
||||||
|
s = replaceStrings(s, "/", "%2f");
|
||||||
|
s = replaceStrings(s, ":", "%3a");
|
||||||
|
Path symlink = cacheDir + "/" + s;
|
||||||
|
debug("writing GC root '%s' for flake closure of '%s'", symlink, origFlakeRef);
|
||||||
|
replaceSymlink(closurePath, symlink);
|
||||||
|
store.addIndirectRoot(symlink);
|
||||||
|
}
|
||||||
|
|
||||||
struct InstallableFlake : InstallableValue
|
struct InstallableFlake : InstallableValue
|
||||||
{
|
{
|
||||||
FlakeRef flakeRef;
|
FlakeRef flakeRef;
|
||||||
|
@ -182,7 +221,11 @@ struct InstallableFlake : InstallableValue
|
||||||
{
|
{
|
||||||
auto vFlake = state.allocValue();
|
auto vFlake = state.allocValue();
|
||||||
|
|
||||||
makeFlakeValue(state, flakeRef, cmd.getLockFileMode(), *vFlake);
|
auto resFlake = resolveFlake(state, flakeRef, cmd.getLockFileMode());
|
||||||
|
|
||||||
|
callFlake(state, resFlake, *vFlake);
|
||||||
|
|
||||||
|
makeFlakeClosureGCRoot(*state.store, flakeRef, resFlake);
|
||||||
|
|
||||||
auto vProvides = (*vFlake->attrs->get(state.symbols.create("provides")))->value;
|
auto vProvides = (*vFlake->attrs->get(state.symbols.create("provides")))->value;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,10 @@ if [[ -z $(type -p git) ]]; then
|
||||||
exit 99
|
exit 99
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
export _NIX_FORCE_HTTP=1
|
||||||
|
|
||||||
clearStore
|
clearStore
|
||||||
|
rm -rf $TEST_HOME/.cache
|
||||||
|
|
||||||
registry=$TEST_ROOT/registry.json
|
registry=$TEST_ROOT/registry.json
|
||||||
|
|
||||||
|
@ -14,7 +17,7 @@ flake2Dir=$TEST_ROOT/flake2
|
||||||
flake3Dir=$TEST_ROOT/flake3
|
flake3Dir=$TEST_ROOT/flake3
|
||||||
|
|
||||||
for repo in $flake1Dir $flake2Dir $flake3Dir; do
|
for repo in $flake1Dir $flake2Dir $flake3Dir; do
|
||||||
rm -rf $repo
|
rm -rf $repo $repo.tmp
|
||||||
mkdir $repo
|
mkdir $repo
|
||||||
git -C $repo init
|
git -C $repo init
|
||||||
git -C $repo config user.email "foobar@example.com"
|
git -C $repo config user.email "foobar@example.com"
|
||||||
|
@ -142,7 +145,7 @@ nix build -o $TEST_ROOT/result --flake-registry $registry flake2:bar
|
||||||
|
|
||||||
# Or without a registry.
|
# Or without a registry.
|
||||||
# FIXME: shouldn't need '--flake-registry /no-registry'?
|
# FIXME: shouldn't need '--flake-registry /no-registry'?
|
||||||
nix build -o $TEST_ROOT/result --flake-registry /no-registry file://$flake2Dir:bar
|
nix build -o $TEST_ROOT/result --flake-registry /no-registry file://$flake2Dir:bar --tarball-ttl 0
|
||||||
|
|
||||||
# Test whether indirect dependencies work.
|
# Test whether indirect dependencies work.
|
||||||
nix build -o $TEST_ROOT/result --flake-registry $registry $flake3Dir:xyzzy
|
nix build -o $TEST_ROOT/result --flake-registry $registry $flake3Dir:xyzzy
|
||||||
|
@ -184,3 +187,15 @@ nix build -o $TEST_ROOT/result --flake-registry $registry $flake3Dir:sth 2>&1 |
|
||||||
nix flake list --flake-registry file://$registry | grep -q flake3
|
nix flake list --flake-registry file://$registry | grep -q flake3
|
||||||
mv $registry $registry.tmp
|
mv $registry $registry.tmp
|
||||||
nix flake list --flake-registry file://$registry --tarball-ttl 0 | grep -q flake3
|
nix flake list --flake-registry file://$registry --tarball-ttl 0 | grep -q flake3
|
||||||
|
mv $registry.tmp $registry
|
||||||
|
|
||||||
|
# Test whether flakes are registered as GC roots for offline use.
|
||||||
|
rm -rf $TEST_HOME/.cache
|
||||||
|
nix build -o $TEST_ROOT/result --flake-registry file://$registry file://$flake2Dir:bar
|
||||||
|
mv $flake1Dir $flake1Dir.tmp
|
||||||
|
mv $flake2Dir $flake2Dir.tmp
|
||||||
|
nix-store --gc
|
||||||
|
nix build -o $TEST_ROOT/result --flake-registry file://$registry file://$flake2Dir:bar
|
||||||
|
nix build -o $TEST_ROOT/result --flake-registry file://$registry file://$flake2Dir:bar --tarball-ttl 0
|
||||||
|
mv $flake1Dir.tmp $flake1Dir
|
||||||
|
mv $flake2Dir.tmp $flake2Dir
|
||||||
|
|
Loading…
Reference in a new issue