Add command flake clone

This commit is contained in:
Nick Van den Broeck 2019-03-21 09:30:16 +01:00
parent 939bee06cd
commit b42ba08fc8
5 changed files with 77 additions and 6 deletions

View file

@ -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())
@ -462,4 +464,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);
}
} }

View file

@ -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 @@ Dependencies resolveFlake(EvalState &, const FlakeRef &, RegistryAccess registry
void updateLockFile(EvalState &, const Path & path); void updateLockFile(EvalState &, const Path & path);
void gitCloneFlake (std::string flakeUri, EvalState &, Registries, Path);
} }

View file

@ -67,6 +67,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)*)?

View file

@ -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());

View file

@ -280,6 +280,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()
@ -291,6 +319,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>()
}) })
{ {
} }