forked from lix-project/lix
Fix lock file generation
Before: "requires": { "nixpkgs": { "uri": "nixpkgs" } }, After: "requires": { "nixpkgs": { "uri": "github:edolstra/nixpkgs/f10e8a02eb7fa2b4a070f30cf87f4efcc7f3186d" } },
This commit is contained in:
parent
8c4e759efd
commit
3d0e81051f
|
@ -188,13 +188,6 @@ static FlakeRef lookupFlake(EvalState & state, const FlakeRef & flakeRef,
|
||||||
return flakeRef;
|
return flakeRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FlakeSourceInfo
|
|
||||||
{
|
|
||||||
Path storePath;
|
|
||||||
std::optional<Hash> rev;
|
|
||||||
std::optional<uint64_t> revCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
static FlakeSourceInfo fetchFlake(EvalState & state, const FlakeRef flakeRef, bool impureIsAllowed = false)
|
static FlakeSourceInfo fetchFlake(EvalState & state, const FlakeRef flakeRef, bool impureIsAllowed = false)
|
||||||
{
|
{
|
||||||
FlakeRef fRef = lookupFlake(state, flakeRef,
|
FlakeRef fRef = lookupFlake(state, flakeRef,
|
||||||
|
@ -226,9 +219,11 @@ static FlakeSourceInfo fetchFlake(EvalState & state, const FlakeRef flakeRef, bo
|
||||||
if (result.etag->size() != 42 || (*result.etag)[0] != '"' || (*result.etag)[41] != '"')
|
if (result.etag->size() != 42 || (*result.etag)[0] != '"' || (*result.etag)[41] != '"')
|
||||||
throw Error("ETag header '%s' from '%s' is not a Git revision", *result.etag, url);
|
throw Error("ETag header '%s' from '%s' is not a Git revision", *result.etag, url);
|
||||||
|
|
||||||
FlakeSourceInfo info;
|
FlakeSourceInfo info(fRef);
|
||||||
info.storePath = result.path;
|
info.storePath = result.path;
|
||||||
info.rev = Hash(std::string(*result.etag, 1, result.etag->size() - 2), htSHA1);
|
info.rev = Hash(std::string(*result.etag, 1, result.etag->size() - 2), htSHA1);
|
||||||
|
info.flakeRef.rev = info.rev;
|
||||||
|
info.flakeRef.ref = {};
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
@ -237,10 +232,12 @@ static FlakeSourceInfo fetchFlake(EvalState & state, const FlakeRef flakeRef, bo
|
||||||
else if (auto refData = std::get_if<FlakeRef::IsGit>(&fRef.data)) {
|
else if (auto refData = std::get_if<FlakeRef::IsGit>(&fRef.data)) {
|
||||||
auto gitInfo = exportGit(state.store, refData->uri, fRef.ref,
|
auto gitInfo = exportGit(state.store, refData->uri, fRef.ref,
|
||||||
fRef.rev ? fRef.rev->to_string(Base16, false) : "", "source");
|
fRef.rev ? fRef.rev->to_string(Base16, false) : "", "source");
|
||||||
FlakeSourceInfo info;
|
FlakeSourceInfo info(fRef);
|
||||||
info.storePath = gitInfo.storePath;
|
info.storePath = gitInfo.storePath;
|
||||||
info.rev = Hash(gitInfo.rev, htSHA1);
|
info.rev = Hash(gitInfo.rev, htSHA1);
|
||||||
info.revCount = gitInfo.revCount;
|
info.revCount = gitInfo.revCount;
|
||||||
|
info.flakeRef.rev = info.rev;
|
||||||
|
// FIXME: ensure info.flakeRef.ref is set.
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,10 +245,11 @@ static FlakeSourceInfo fetchFlake(EvalState & state, const FlakeRef flakeRef, bo
|
||||||
if (!pathExists(refData->path + "/.git"))
|
if (!pathExists(refData->path + "/.git"))
|
||||||
throw Error("flake '%s' does not reference a Git repository", refData->path);
|
throw Error("flake '%s' does not reference a Git repository", refData->path);
|
||||||
auto gitInfo = exportGit(state.store, refData->path, {}, "", "source");
|
auto gitInfo = exportGit(state.store, refData->path, {}, "", "source");
|
||||||
FlakeSourceInfo info;
|
FlakeSourceInfo info(fRef);
|
||||||
info.storePath = gitInfo.storePath;
|
info.storePath = gitInfo.storePath;
|
||||||
info.rev = Hash(gitInfo.rev, htSHA1);
|
info.rev = Hash(gitInfo.rev, htSHA1);
|
||||||
info.revCount = gitInfo.revCount;
|
info.revCount = gitInfo.revCount;
|
||||||
|
info.flakeRef.rev = info.rev;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,24 +263,21 @@ Flake getFlake(EvalState & state, const FlakeRef & flakeRef, bool impureIsAllowe
|
||||||
debug("got flake source '%s' with revision %s",
|
debug("got flake source '%s' with revision %s",
|
||||||
sourceInfo.storePath, sourceInfo.rev.value_or(Hash(htSHA1)).to_string(Base16, false));
|
sourceInfo.storePath, sourceInfo.rev.value_or(Hash(htSHA1)).to_string(Base16, false));
|
||||||
|
|
||||||
auto flakePath = sourceInfo.storePath;
|
state.store->assertStorePath(sourceInfo.storePath);
|
||||||
state.store->assertStorePath(flakePath);
|
|
||||||
|
|
||||||
if (state.allowedPaths)
|
if (state.allowedPaths)
|
||||||
state.allowedPaths->insert(flakePath);
|
state.allowedPaths->insert(sourceInfo.storePath);
|
||||||
|
|
||||||
Flake flake(flakeRef);
|
Flake flake(flakeRef, std::move(sourceInfo));
|
||||||
if (std::get_if<FlakeRef::IsGitHub>(&flakeRef.data)) {
|
if (std::get_if<FlakeRef::IsGitHub>(&flakeRef.data)) {
|
||||||
if (sourceInfo.rev)
|
// FIXME: ehm?
|
||||||
|
if (flake.sourceInfo.rev)
|
||||||
flake.ref = FlakeRef(flakeRef.baseRef().to_string()
|
flake.ref = FlakeRef(flakeRef.baseRef().to_string()
|
||||||
+ "/" + sourceInfo.rev->to_string(Base16, false));
|
+ "/" + flake.sourceInfo.rev->to_string(Base16, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
flake.path = flakePath;
|
|
||||||
flake.revCount = sourceInfo.revCount;
|
|
||||||
|
|
||||||
Value vInfo;
|
Value vInfo;
|
||||||
state.evalFile(flakePath + "/flake.nix", vInfo); // FIXME: symlink attack
|
state.evalFile(sourceInfo.storePath + "/flake.nix", vInfo); // FIXME: symlink attack
|
||||||
|
|
||||||
state.forceAttrs(vInfo);
|
state.forceAttrs(vInfo);
|
||||||
|
|
||||||
|
@ -317,7 +312,7 @@ Flake getFlake(EvalState & state, const FlakeRef & flakeRef, bool impureIsAllowe
|
||||||
} else
|
} else
|
||||||
throw Error("flake lacks attribute 'provides'");
|
throw Error("flake lacks attribute 'provides'");
|
||||||
|
|
||||||
const Path lockFile = flakePath + "/flake.lock"; // FIXME: symlink attack
|
Path lockFile = sourceInfo.storePath + "/flake.lock"; // FIXME: symlink attack
|
||||||
|
|
||||||
flake.lockFile = readLockFile(lockFile);
|
flake.lockFile = readLockFile(lockFile);
|
||||||
|
|
||||||
|
@ -373,7 +368,7 @@ Dependencies resolveFlake(EvalState & state, const FlakeRef & topRef,
|
||||||
|
|
||||||
LockFile::FlakeEntry dependenciesToFlakeEntry(const Dependencies & deps)
|
LockFile::FlakeEntry dependenciesToFlakeEntry(const Dependencies & deps)
|
||||||
{
|
{
|
||||||
LockFile::FlakeEntry entry(deps.flake.ref);
|
LockFile::FlakeEntry entry(deps.flake.sourceInfo.flakeRef);
|
||||||
|
|
||||||
for (auto & deps : deps.flakeDeps)
|
for (auto & deps : deps.flakeDeps)
|
||||||
entry.flakeEntries.insert_or_assign(deps.flake.id, dependenciesToFlakeEntry(deps));
|
entry.flakeEntries.insert_or_assign(deps.flake.id, dependenciesToFlakeEntry(deps));
|
||||||
|
@ -396,7 +391,10 @@ static LockFile makeLockFile(EvalState & evalState, FlakeRef & flakeRef)
|
||||||
|
|
||||||
void updateLockFile(EvalState & state, const Path & path)
|
void updateLockFile(EvalState & state, const Path & path)
|
||||||
{
|
{
|
||||||
FlakeRef flakeRef = FlakeRef("file://" + path); // FIXME: ugly
|
// FIXME: don't copy 'path' to the store (especially since we
|
||||||
|
// dirty it immediately afterwards).
|
||||||
|
|
||||||
|
FlakeRef flakeRef = FlakeRef(path); // FIXME: ugly
|
||||||
auto lockFile = makeLockFile(state, flakeRef);
|
auto lockFile = makeLockFile(state, flakeRef);
|
||||||
writeLockFile(lockFile, path + "/flake.lock");
|
writeLockFile(lockFile, path + "/flake.lock");
|
||||||
|
|
||||||
|
@ -427,11 +425,12 @@ void callFlake(EvalState & state, const Dependencies & flake, Value & v)
|
||||||
|
|
||||||
mkString(*state.allocAttr(v, state.sDescription), flake.flake.description);
|
mkString(*state.allocAttr(v, state.sDescription), flake.flake.description);
|
||||||
|
|
||||||
state.store->isValidPath(flake.flake.path);
|
auto & path = flake.flake.sourceInfo.storePath;
|
||||||
mkString(*state.allocAttr(v, state.sOutPath), flake.flake.path, {flake.flake.path});
|
state.store->isValidPath(path);
|
||||||
|
mkString(*state.allocAttr(v, state.sOutPath), path, {path});
|
||||||
|
|
||||||
if (flake.flake.revCount)
|
if (flake.flake.sourceInfo.revCount)
|
||||||
mkInt(*state.allocAttr(v, state.symbols.create("revCount")), *flake.flake.revCount);
|
mkInt(*state.allocAttr(v, state.symbols.create("revCount")), *flake.flake.sourceInfo.revCount);
|
||||||
|
|
||||||
auto vProvides = state.allocAttr(v, state.symbols.create("provides"));
|
auto vProvides = state.allocAttr(v, state.symbols.create("provides"));
|
||||||
mkApp(*vProvides, *flake.flake.vProvides, v);
|
mkApp(*vProvides, *flake.flake.vProvides, v);
|
||||||
|
|
|
@ -37,20 +37,28 @@ std::shared_ptr<FlakeRegistry> readRegistry(const Path &);
|
||||||
|
|
||||||
void writeRegistry(const FlakeRegistry &, const Path &);
|
void writeRegistry(const FlakeRegistry &, const Path &);
|
||||||
|
|
||||||
|
struct FlakeSourceInfo
|
||||||
|
{
|
||||||
|
FlakeRef flakeRef;
|
||||||
|
Path storePath;
|
||||||
|
std::optional<Hash> rev;
|
||||||
|
std::optional<uint64_t> revCount;
|
||||||
|
// date
|
||||||
|
FlakeSourceInfo(const FlakeRef & flakeRef) : flakeRef(flakeRef) { }
|
||||||
|
};
|
||||||
|
|
||||||
struct Flake
|
struct Flake
|
||||||
{
|
{
|
||||||
FlakeId id;
|
FlakeId id;
|
||||||
FlakeRef ref;
|
FlakeRef ref;
|
||||||
std::string description;
|
std::string description;
|
||||||
Path path;
|
FlakeSourceInfo sourceInfo;
|
||||||
std::optional<uint64_t> revCount;
|
|
||||||
std::vector<FlakeRef> requires;
|
std::vector<FlakeRef> requires;
|
||||||
LockFile lockFile;
|
LockFile lockFile;
|
||||||
std::map<FlakeAlias, FlakeRef> nonFlakeRequires;
|
std::map<FlakeAlias, FlakeRef> nonFlakeRequires;
|
||||||
Value * vProvides; // FIXME: gc
|
Value * vProvides; // FIXME: gc
|
||||||
// date
|
Flake(const FlakeRef & flakeRef, FlakeSourceInfo && sourceInfo)
|
||||||
// content hash
|
: ref(flakeRef), sourceInfo(sourceInfo) {};
|
||||||
Flake(const FlakeRef flakeRef) : ref(flakeRef) {};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NonFlake
|
struct NonFlake
|
||||||
|
|
|
@ -123,7 +123,7 @@ std::string FlakeRef::to_string() const
|
||||||
string = refData->alias;
|
string = refData->alias;
|
||||||
|
|
||||||
else if (auto refData = std::get_if<FlakeRef::IsGitHub>(&data)) {
|
else if (auto refData = std::get_if<FlakeRef::IsGitHub>(&data)) {
|
||||||
assert(!ref || !rev);
|
assert(!(ref && rev));
|
||||||
string = "github:" + refData->owner + "/" + refData->repo;
|
string = "github:" + refData->owner + "/" + refData->repo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,13 +40,13 @@ void printFlakeInfo(Flake & flake, bool json) {
|
||||||
if (json) {
|
if (json) {
|
||||||
nlohmann::json j;
|
nlohmann::json j;
|
||||||
j["id"] = flake.id;
|
j["id"] = flake.id;
|
||||||
j["location"] = flake.path;
|
j["location"] = flake.sourceInfo.storePath;
|
||||||
j["description"] = flake.description;
|
j["description"] = flake.description;
|
||||||
std::cout << j.dump(4) << std::endl;
|
std::cout << j.dump(4) << std::endl;
|
||||||
} else {
|
} else {
|
||||||
std::cout << "ID: " << flake.id << "\n";
|
std::cout << "ID: " << flake.id << "\n";
|
||||||
std::cout << "Description: " << flake.description << "\n";
|
std::cout << "Description: " << flake.description << "\n";
|
||||||
std::cout << "Location: " << flake.path << "\n";
|
std::cout << "Location: " << flake.sourceInfo.storePath << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue