Fix GC closure generation
This commit is contained in:
parent
6dbd5c26e6
commit
278114d559
|
@ -50,7 +50,7 @@ void writeRegistry(const FlakeRegistry & registry, const Path & path)
|
||||||
writeFile(path, json.dump(4)); // The '4' is the number of spaces used in the indentation in the json file.
|
writeFile(path, json.dump(4)); // The '4' is the number of spaces used in the indentation in the json file.
|
||||||
}
|
}
|
||||||
|
|
||||||
NonFlakeDep::NonFlakeDep(const nlohmann::json & json)
|
AbstractDep::AbstractDep(const nlohmann::json & json)
|
||||||
: ref(json["uri"])
|
: ref(json["uri"])
|
||||||
, narHash(Hash((std::string) json["narHash"]))
|
, narHash(Hash((std::string) json["narHash"]))
|
||||||
{
|
{
|
||||||
|
@ -58,7 +58,7 @@ NonFlakeDep::NonFlakeDep(const nlohmann::json & json)
|
||||||
throw Error("lockfile contains mutable flakeref '%s'", ref);
|
throw Error("lockfile contains mutable flakeref '%s'", ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json NonFlakeDep::toJson() const
|
nlohmann::json AbstractDep::toJson() const
|
||||||
{
|
{
|
||||||
nlohmann::json json;
|
nlohmann::json json;
|
||||||
json["uri"] = ref.to_string();
|
json["uri"] = ref.to_string();
|
||||||
|
@ -66,22 +66,23 @@ nlohmann::json NonFlakeDep::toJson() const
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Path AbstractDep::computeStorePath(Store & store) const
|
||||||
|
{
|
||||||
|
return store.makeFixedOutputPath(true, narHash, "source");
|
||||||
|
}
|
||||||
|
|
||||||
FlakeDep::FlakeDep(const nlohmann::json & json)
|
FlakeDep::FlakeDep(const nlohmann::json & json)
|
||||||
: FlakeInputs(json)
|
: FlakeInputs(json)
|
||||||
|
, AbstractDep(json)
|
||||||
, id(json["id"])
|
, id(json["id"])
|
||||||
, ref(json["uri"])
|
|
||||||
, narHash(Hash((std::string) json["narHash"]))
|
|
||||||
{
|
{
|
||||||
if (!ref.isImmutable())
|
|
||||||
throw Error("lockfile contains mutable flakeref '%s'", ref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json FlakeDep::toJson() const
|
nlohmann::json FlakeDep::toJson() const
|
||||||
{
|
{
|
||||||
auto json = FlakeInputs::toJson();
|
auto json = FlakeInputs::toJson();
|
||||||
|
json.update(AbstractDep::toJson());
|
||||||
json["id"] = id;
|
json["id"] = id;
|
||||||
json["uri"] = ref.to_string();
|
|
||||||
json["narHash"] = narHash.to_string(SRI);
|
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include "flakeref.hh"
|
#include "flakeref.hh"
|
||||||
|
|
||||||
|
@ -8,6 +10,7 @@ namespace nix {
|
||||||
|
|
||||||
struct Value;
|
struct Value;
|
||||||
class EvalState;
|
class EvalState;
|
||||||
|
class Store;
|
||||||
|
|
||||||
namespace flake {
|
namespace flake {
|
||||||
|
|
||||||
|
@ -37,22 +40,29 @@ enum HandleLockFile : unsigned int
|
||||||
, UseNewLockFile // `RecreateLockFile` without writing to file
|
, UseNewLockFile // `RecreateLockFile` without writing to file
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NonFlakeDep
|
struct AbstractDep
|
||||||
{
|
{
|
||||||
FlakeRef ref;
|
FlakeRef ref;
|
||||||
Hash narHash;
|
Hash narHash;
|
||||||
|
|
||||||
NonFlakeDep(const FlakeRef & flakeRef, const Hash & narHash)
|
AbstractDep(const FlakeRef & flakeRef, const Hash & narHash)
|
||||||
: ref(flakeRef), narHash(narHash) {};
|
: ref(flakeRef), narHash(narHash) {};
|
||||||
|
|
||||||
NonFlakeDep(const nlohmann::json & json);
|
AbstractDep(const nlohmann::json & json);
|
||||||
|
|
||||||
|
nlohmann::json toJson() const;
|
||||||
|
|
||||||
|
Path computeStorePath(Store & store) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NonFlakeDep : AbstractDep
|
||||||
|
{
|
||||||
|
using AbstractDep::AbstractDep;
|
||||||
|
|
||||||
bool operator ==(const NonFlakeDep & other) const
|
bool operator ==(const NonFlakeDep & other) const
|
||||||
{
|
{
|
||||||
return ref == other.ref && narHash == other.narHash;
|
return ref == other.ref && narHash == other.narHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json toJson() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FlakeDep;
|
struct FlakeDep;
|
||||||
|
@ -68,14 +78,12 @@ struct FlakeInputs
|
||||||
nlohmann::json toJson() const;
|
nlohmann::json toJson() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FlakeDep : FlakeInputs
|
struct FlakeDep : FlakeInputs, AbstractDep
|
||||||
{
|
{
|
||||||
FlakeId id;
|
FlakeId id;
|
||||||
FlakeRef ref;
|
|
||||||
Hash narHash;
|
|
||||||
|
|
||||||
FlakeDep(const FlakeId & id, const FlakeRef & flakeRef, const Hash & narHash)
|
FlakeDep(const FlakeId & id, const FlakeRef & flakeRef, const Hash & narHash)
|
||||||
: id(id), ref(flakeRef), narHash(narHash) {};
|
: AbstractDep(flakeRef, narHash), id(id) {};
|
||||||
|
|
||||||
FlakeDep(const nlohmann::json & json);
|
FlakeDep(const nlohmann::json & json);
|
||||||
|
|
||||||
|
|
|
@ -190,23 +190,29 @@ void makeFlakeClosureGCRoot(Store & store,
|
||||||
const FlakeRef & origFlakeRef,
|
const FlakeRef & origFlakeRef,
|
||||||
const flake::ResolvedFlake & resFlake)
|
const flake::ResolvedFlake & resFlake)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if (std::get_if<FlakeRef::IsPath>(&origFlakeRef.data)) return;
|
if (std::get_if<FlakeRef::IsPath>(&origFlakeRef.data)) return;
|
||||||
|
|
||||||
/* Get the store paths of all non-local flakes. */
|
/* Get the store paths of all non-local flakes. */
|
||||||
PathSet closure;
|
PathSet closure;
|
||||||
|
|
||||||
std::queue<std::reference_wrapper<const flake::ResolvedFlake>> queue;
|
assert(store.isValidPath(resFlake.flake.sourceInfo.storePath));
|
||||||
queue.push(resFlake);
|
closure.insert(resFlake.flake.sourceInfo.storePath);
|
||||||
|
|
||||||
|
std::queue<std::reference_wrapper<const flake::FlakeInputs>> queue;
|
||||||
|
queue.push(resFlake.lockFile);
|
||||||
|
|
||||||
while (!queue.empty()) {
|
while (!queue.empty()) {
|
||||||
const flake::ResolvedFlake & flake = queue.front();
|
const flake::FlakeInputs & flake = queue.front();
|
||||||
queue.pop();
|
queue.pop();
|
||||||
if (!std::get_if<FlakeRef::IsPath>(&flake.flake.sourceInfo.resolvedRef.data))
|
/* Note: due to lazy fetching, these paths might not exist
|
||||||
closure.insert(flake.flake.sourceInfo.storePath);
|
yet. */
|
||||||
for (const auto & dep : flake.flakeDeps)
|
for (auto & dep : flake.flakeDeps) {
|
||||||
|
closure.insert(dep.second.computeStorePath(store));
|
||||||
queue.push(dep.second);
|
queue.push(dep.second);
|
||||||
}
|
}
|
||||||
|
for (auto & dep : flake.nonFlakeDeps)
|
||||||
|
closure.insert(dep.second.computeStorePath(store));
|
||||||
|
}
|
||||||
|
|
||||||
if (closure.empty()) return;
|
if (closure.empty()) return;
|
||||||
|
|
||||||
|
@ -225,7 +231,6 @@ void makeFlakeClosureGCRoot(Store & store,
|
||||||
debug("writing GC root '%s' for flake closure of '%s'", symlink, origFlakeRef);
|
debug("writing GC root '%s' for flake closure of '%s'", symlink, origFlakeRef);
|
||||||
replaceSymlink(closurePath, symlink);
|
replaceSymlink(closurePath, symlink);
|
||||||
store.addIndirectRoot(symlink);
|
store.addIndirectRoot(symlink);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InstallableFlake : InstallableValue
|
struct InstallableFlake : InstallableValue
|
||||||
|
|
|
@ -204,6 +204,7 @@ nix flake list --flake-registry file://$registry --tarball-ttl 0 | grep -q flake
|
||||||
mv $registry.tmp $registry
|
mv $registry.tmp $registry
|
||||||
|
|
||||||
# Test whether flakes are registered as GC roots for offline use.
|
# Test whether flakes are registered as GC roots for offline use.
|
||||||
|
# FIXME: use tarballs rather than git.
|
||||||
rm -rf $TEST_HOME/.cache
|
rm -rf $TEST_HOME/.cache
|
||||||
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
|
||||||
mv $flake1Dir $flake1Dir.tmp
|
mv $flake1Dir $flake1Dir.tmp
|
||||||
|
|
Loading…
Reference in a new issue