Add path flakeref variant
Unlike file://<path>, this allows the path to be a dirty Git tree, so nix build /path/to/flake:attr is a convenient way to test building a local flake.
This commit is contained in:
parent
a9ceeeb4b0
commit
6a4c7fb975
|
@ -170,7 +170,7 @@ GitInfo exportGit(ref<Store> store, const std::string & uri,
|
||||||
json["uri"] = uri;
|
json["uri"] = uri;
|
||||||
json["name"] = name;
|
json["name"] = name;
|
||||||
json["rev"] = gitInfo.rev;
|
json["rev"] = gitInfo.rev;
|
||||||
json["revCount"] = gitInfo.revCount;
|
json["revCount"] = *gitInfo.revCount;
|
||||||
|
|
||||||
writeFile(storeLink, json.dump());
|
writeFile(storeLink, json.dump());
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ static void prim_fetchGit(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
mkString(*state.allocAttr(v, state.sOutPath), gitInfo.storePath, PathSet({gitInfo.storePath}));
|
mkString(*state.allocAttr(v, state.sOutPath), gitInfo.storePath, PathSet({gitInfo.storePath}));
|
||||||
mkString(*state.allocAttr(v, state.symbols.create("rev")), gitInfo.rev);
|
mkString(*state.allocAttr(v, state.symbols.create("rev")), gitInfo.rev);
|
||||||
mkString(*state.allocAttr(v, state.symbols.create("shortRev")), gitInfo.shortRev);
|
mkString(*state.allocAttr(v, state.symbols.create("shortRev")), gitInfo.shortRev);
|
||||||
mkInt(*state.allocAttr(v, state.symbols.create("revCount")), gitInfo.revCount);
|
mkInt(*state.allocAttr(v, state.symbols.create("revCount")), gitInfo.revCount.value_or(0));
|
||||||
v.attrs->sort();
|
v.attrs->sort();
|
||||||
|
|
||||||
if (state.allowedPaths)
|
if (state.allowedPaths)
|
||||||
|
|
|
@ -11,7 +11,7 @@ struct GitInfo
|
||||||
Path storePath;
|
Path storePath;
|
||||||
std::string rev;
|
std::string rev;
|
||||||
std::string shortRev;
|
std::string shortRev;
|
||||||
uint64_t revCount = 0;
|
std::optional<uint64_t> revCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
GitInfo exportGit(ref<Store> store, const std::string & uri,
|
GitInfo exportGit(ref<Store> store, const std::string & uri,
|
||||||
|
|
|
@ -129,6 +129,7 @@ struct FlakeSourceInfo
|
||||||
{
|
{
|
||||||
Path storePath;
|
Path storePath;
|
||||||
std::optional<Hash> rev;
|
std::optional<Hash> rev;
|
||||||
|
std::optional<uint64_t> revCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
static FlakeSourceInfo fetchFlake(EvalState & state, const FlakeRef & flakeRef)
|
static FlakeSourceInfo fetchFlake(EvalState & state, const FlakeRef & flakeRef)
|
||||||
|
@ -178,6 +179,18 @@ static FlakeSourceInfo fetchFlake(EvalState & state, const FlakeRef & flakeRef)
|
||||||
FlakeSourceInfo info;
|
FlakeSourceInfo info;
|
||||||
info.storePath = gitInfo.storePath;
|
info.storePath = gitInfo.storePath;
|
||||||
info.rev = Hash(gitInfo.rev, htSHA1);
|
info.rev = Hash(gitInfo.rev, htSHA1);
|
||||||
|
info.revCount = gitInfo.revCount;
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (auto refData = std::get_if<FlakeRef::IsPath>(&directFlakeRef.data)) {
|
||||||
|
if (!pathExists(refData->path + "/.git"))
|
||||||
|
throw Error("flake '%s' does not reference a Git repository", refData->path);
|
||||||
|
auto gitInfo = exportGit(state.store, refData->path, {}, "", "source");
|
||||||
|
FlakeSourceInfo info;
|
||||||
|
info.storePath = gitInfo.storePath;
|
||||||
|
info.rev = Hash(gitInfo.rev, htSHA1);
|
||||||
|
info.revCount = gitInfo.revCount;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,6 +219,8 @@ Flake getFlake(EvalState & state, const FlakeRef & flakeRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
Flake flake(newFlakeRef);
|
Flake flake(newFlakeRef);
|
||||||
|
flake.path = flakePath;
|
||||||
|
flake.revCount = sourceInfo.revCount;
|
||||||
|
|
||||||
Value vInfo;
|
Value vInfo;
|
||||||
state.evalFile(flakePath + "/flake.nix", vInfo); // FIXME: symlink attack
|
state.evalFile(flakePath + "/flake.nix", vInfo); // FIXME: symlink attack
|
||||||
|
@ -349,10 +364,20 @@ Value * makeFlakeValue(EvalState & state, const FlakeRef & flakeRef, bool impure
|
||||||
for (auto & flake : flakes) {
|
for (auto & flake : flakes) {
|
||||||
auto vFlake = state.allocAttr(*vResult, flake.second.id);
|
auto vFlake = state.allocAttr(*vResult, flake.second.id);
|
||||||
if (topFlakeId == flake.second.id) vTop = vFlake;
|
if (topFlakeId == flake.second.id) vTop = vFlake;
|
||||||
state.mkAttrs(*vFlake, 2);
|
|
||||||
|
state.mkAttrs(*vFlake, 4);
|
||||||
|
|
||||||
mkString(*state.allocAttr(*vFlake, state.sDescription), flake.second.description);
|
mkString(*state.allocAttr(*vFlake, state.sDescription), flake.second.description);
|
||||||
|
|
||||||
|
state.store->assertStorePath(flake.second.path);
|
||||||
|
mkString(*state.allocAttr(*vFlake, state.sOutPath), flake.second.path, {flake.second.path});
|
||||||
|
|
||||||
|
if (flake.second.revCount)
|
||||||
|
mkInt(*state.allocAttr(*vFlake, state.symbols.create("revCount")), *flake.second.revCount);
|
||||||
|
|
||||||
auto vProvides = state.allocAttr(*vFlake, state.symbols.create("provides"));
|
auto vProvides = state.allocAttr(*vFlake, state.symbols.create("provides"));
|
||||||
mkApp(*vProvides, *flake.second.vProvides, *vResult);
|
mkApp(*vProvides, *flake.second.vProvides, *vResult);
|
||||||
|
|
||||||
vFlake->attrs->sort();
|
vFlake->attrs->sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ struct Flake
|
||||||
FlakeRef ref;
|
FlakeRef ref;
|
||||||
std::string description;
|
std::string description;
|
||||||
Path path;
|
Path path;
|
||||||
|
std::optional<uint64_t> revCount;
|
||||||
std::vector<FlakeRef> requires;
|
std::vector<FlakeRef> requires;
|
||||||
std::shared_ptr<FlakeRegistry> lockFile;
|
std::shared_ptr<FlakeRegistry> lockFile;
|
||||||
Value * vProvides; // FIXME: gc
|
Value * vProvides; // FIXME: gc
|
||||||
|
|
|
@ -106,6 +106,12 @@ FlakeRef::FlakeRef(const std::string & uri)
|
||||||
data = d;
|
data = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (hasPrefix(uri, "/")) {
|
||||||
|
IsPath d;
|
||||||
|
d.path = canonPath(uri);
|
||||||
|
data = d;
|
||||||
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
throw Error("'%s' is not a valid flake reference", uri);
|
throw Error("'%s' is not a valid flake reference", uri);
|
||||||
}
|
}
|
||||||
|
@ -135,6 +141,10 @@ std::string FlakeRef::to_string() const
|
||||||
(refData->rev ? "&rev=" + refData->rev->to_string(Base16, false) : "");
|
(refData->rev ? "&rev=" + refData->rev->to_string(Base16, false) : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (auto refData = std::get_if<FlakeRef::IsPath>(&data)) {
|
||||||
|
return refData->path;
|
||||||
|
}
|
||||||
|
|
||||||
else abort();
|
else abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,6 +159,9 @@ bool FlakeRef::isImmutable() const
|
||||||
else if (auto refData = std::get_if<FlakeRef::IsGit>(&data))
|
else if (auto refData = std::get_if<FlakeRef::IsGit>(&data))
|
||||||
return (bool) refData->rev;
|
return (bool) refData->rev;
|
||||||
|
|
||||||
|
else if (std::get_if<FlakeRef::IsPath>(&data))
|
||||||
|
return false;
|
||||||
|
|
||||||
else abort();
|
else abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,9 +122,14 @@ struct FlakeRef
|
||||||
std::optional<Hash> rev;
|
std::optional<Hash> rev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct IsPath
|
||||||
|
{
|
||||||
|
Path path;
|
||||||
|
};
|
||||||
|
|
||||||
// Git, Tarball
|
// Git, Tarball
|
||||||
|
|
||||||
std::variant<IsFlakeId, IsGitHub, IsGit> data;
|
std::variant<IsFlakeId, IsGitHub, IsGit, IsPath> data;
|
||||||
|
|
||||||
// Parse a flake URI.
|
// Parse a flake URI.
|
||||||
FlakeRef(const std::string & uri);
|
FlakeRef(const std::string & uri);
|
||||||
|
|
Loading…
Reference in a new issue