forked from lix-project/lix
Merge remote-tracking branch 'tweag/flake-clone' into flakes
This commit is contained in:
commit
21d5abfc14
|
@ -146,17 +146,19 @@ std::shared_ptr<FlakeRegistry> getFlagRegistry()
|
||||||
return std::make_shared<FlakeRegistry>();
|
return std::make_shared<FlakeRegistry>();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::shared_ptr<FlakeRegistry>> EvalState::getFlakeRegistries()
|
// This always returns a vector with globalReg, userReg, localReg, flakeReg.
|
||||||
|
// If one of them doesn't exist, the registry is left empty but does exist.
|
||||||
|
const Registries EvalState::getFlakeRegistries()
|
||||||
{
|
{
|
||||||
std::vector<std::shared_ptr<FlakeRegistry>> registries;
|
Registries registries;
|
||||||
registries.push_back(getGlobalRegistry());
|
registries.push_back(getGlobalRegistry()); // TODO (Nick): Doesn't this break immutability?
|
||||||
registries.push_back(getUserRegistry());
|
registries.push_back(getUserRegistry());
|
||||||
|
registries.push_back(std::make_shared<FlakeRegistry>()); // local
|
||||||
registries.push_back(getFlagRegistry());
|
registries.push_back(getFlagRegistry());
|
||||||
return registries;
|
return registries;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FlakeRef lookupFlake(EvalState & state, const FlakeRef & flakeRef,
|
static FlakeRef lookupFlake(EvalState & state, const FlakeRef & flakeRef, const Registries & registries,
|
||||||
const std::vector<std::shared_ptr<FlakeRegistry>> & registries,
|
|
||||||
std::vector<FlakeRef> pastSearches = {})
|
std::vector<FlakeRef> pastSearches = {})
|
||||||
{
|
{
|
||||||
if (registries.empty() && !flakeRef.isDirect())
|
if (registries.empty() && !flakeRef.isDirect())
|
||||||
|
@ -467,4 +469,35 @@ static void prim_getFlake(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
|
|
||||||
static RegisterPrimOp r2("getFlake", 1, prim_getFlake);
|
static RegisterPrimOp r2("getFlake", 1, prim_getFlake);
|
||||||
|
|
||||||
|
void gitCloneFlake (std::string flakeUri, EvalState & state, Registries registries,
|
||||||
|
Path endDirectory)
|
||||||
|
{
|
||||||
|
FlakeRef flakeRef(flakeUri);
|
||||||
|
flakeRef = lookupFlake(state, flakeRef, registries);
|
||||||
|
|
||||||
|
std::string uri;
|
||||||
|
|
||||||
|
Strings args = {"clone"};
|
||||||
|
|
||||||
|
if (auto refData = std::get_if<FlakeRef::IsGitHub>(&flakeRef.data)) {
|
||||||
|
uri = "git@github.com:" + refData->owner + "/" + refData->repo + ".git";
|
||||||
|
args.push_back(uri);
|
||||||
|
if (flakeRef.ref) {
|
||||||
|
args.push_back("--branch");
|
||||||
|
args.push_back(*flakeRef.ref);
|
||||||
|
}
|
||||||
|
} else if (auto refData = std::get_if<FlakeRef::IsGit>(&flakeRef.data)) {
|
||||||
|
args.push_back(refData->uri);
|
||||||
|
if (flakeRef.ref) {
|
||||||
|
args.push_back("--branch");
|
||||||
|
args.push_back(*flakeRef.ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endDirectory != "")
|
||||||
|
args.push_back(endDirectory);
|
||||||
|
|
||||||
|
runProgram("git", true, args);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@ struct LockFile
|
||||||
std::map<FlakeId, FlakeRef> nonFlakeEntries;
|
std::map<FlakeId, FlakeRef> nonFlakeEntries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::vector<std::shared_ptr<FlakeRegistry>> Registries;
|
||||||
|
|
||||||
Path getUserRegistryPath();
|
Path getUserRegistryPath();
|
||||||
|
|
||||||
enum RegistryAccess { DisallowRegistry, AllowRegistry, AllowRegistryAtTop };
|
enum RegistryAccess { DisallowRegistry, AllowRegistry, AllowRegistryAtTop };
|
||||||
|
@ -86,4 +88,5 @@ ResolvedFlake resolveFlake(EvalState &, const FlakeRef &, RegistryAccess registr
|
||||||
|
|
||||||
void updateLockFile(EvalState &, const Path & path);
|
void updateLockFile(EvalState &, const Path & path);
|
||||||
|
|
||||||
|
void gitCloneFlake (std::string flakeUri, EvalState &, Registries, Path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ namespace nix {
|
||||||
https://example.org/my/repo.git
|
https://example.org/my/repo.git
|
||||||
https://example.org/my/repo.git?ref=release-1.2.3
|
https://example.org/my/repo.git?ref=release-1.2.3
|
||||||
https://example.org/my/repo.git?rev=e72daba8250068216d79d2aeef40d4d95aff6666
|
https://example.org/my/repo.git?rev=e72daba8250068216d79d2aeef40d4d95aff6666
|
||||||
|
git://github.com/edolstra/dwarffs.git\?ref=flake\&rev=2efca4bc9da70fb001b26c3dc858c6397d3c4817
|
||||||
|
|
||||||
* /path.git(\?attr(&attr)*)?
|
* /path.git(\?attr(&attr)*)?
|
||||||
|
|
||||||
|
|
|
@ -962,12 +962,14 @@ std::vector<char *> stringsToCharPtrs(const Strings & ss)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Output = "standard out" output stream
|
||||||
string runProgram(Path program, bool searchPath, const Strings & args,
|
string runProgram(Path program, bool searchPath, const Strings & args,
|
||||||
const std::optional<std::string> & input)
|
const std::optional<std::string> & input)
|
||||||
{
|
{
|
||||||
RunOptions opts(program, args);
|
RunOptions opts(program, args);
|
||||||
opts.searchPath = searchPath;
|
opts.searchPath = searchPath;
|
||||||
|
// This allows you to refer to a program with a pathname relative to the
|
||||||
|
// PATH variable.
|
||||||
opts.input = input;
|
opts.input = input;
|
||||||
|
|
||||||
auto res = runProgram(opts);
|
auto res = runProgram(opts);
|
||||||
|
@ -978,6 +980,7 @@ string runProgram(Path program, bool searchPath, const Strings & args,
|
||||||
return res.second;
|
return res.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Output = error code + "standard out" output stream
|
||||||
std::pair<int, std::string> runProgram(const RunOptions & options_)
|
std::pair<int, std::string> runProgram(const RunOptions & options_)
|
||||||
{
|
{
|
||||||
RunOptions options(options_);
|
RunOptions options(options_);
|
||||||
|
@ -1028,6 +1031,8 @@ void runProgram2(const RunOptions & options)
|
||||||
|
|
||||||
if (options.searchPath)
|
if (options.searchPath)
|
||||||
execvp(options.program.c_str(), stringsToCharPtrs(args_).data());
|
execvp(options.program.c_str(), stringsToCharPtrs(args_).data());
|
||||||
|
// This allows you to refer to a program with a pathname relative
|
||||||
|
// to the PATH variable.
|
||||||
else
|
else
|
||||||
execv(options.program.c_str(), stringsToCharPtrs(args_).data());
|
execv(options.program.c_str(), stringsToCharPtrs(args_).data());
|
||||||
|
|
||||||
|
|
|
@ -284,6 +284,34 @@ struct CmdFlakeInit : virtual Args, Command
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CmdFlakeClone : StoreCommand, FlakeCommand, MixEvalArgs
|
||||||
|
{
|
||||||
|
Path endDirectory = "";
|
||||||
|
|
||||||
|
std::string name() override
|
||||||
|
{
|
||||||
|
return "clone";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string description() override
|
||||||
|
{
|
||||||
|
return "clone flake repository";
|
||||||
|
}
|
||||||
|
|
||||||
|
CmdFlakeClone()
|
||||||
|
{
|
||||||
|
expectArg("end-dir", &endDirectory, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void run(nix::ref<nix::Store> store) override
|
||||||
|
{
|
||||||
|
auto evalState = std::make_shared<EvalState>(searchPath, store);
|
||||||
|
|
||||||
|
Registries registries = evalState->getFlakeRegistries();
|
||||||
|
gitCloneFlake(flakeUri, *evalState, registries, endDirectory);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct CmdFlake : virtual MultiCommand, virtual Command
|
struct CmdFlake : virtual MultiCommand, virtual Command
|
||||||
{
|
{
|
||||||
CmdFlake()
|
CmdFlake()
|
||||||
|
@ -295,6 +323,7 @@ struct CmdFlake : virtual MultiCommand, virtual Command
|
||||||
, make_ref<CmdFlakeRemove>()
|
, make_ref<CmdFlakeRemove>()
|
||||||
, make_ref<CmdFlakePin>()
|
, make_ref<CmdFlakePin>()
|
||||||
, make_ref<CmdFlakeInit>()
|
, make_ref<CmdFlakeInit>()
|
||||||
|
, make_ref<CmdFlakeClone>()
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue