Add completion for --update-input

This commit is contained in:
Eelco Dolstra 2020-06-08 16:20:00 +02:00
parent 9ef6048d78
commit 6470450ab4
7 changed files with 45 additions and 7 deletions

View file

@ -198,7 +198,7 @@ InputPath parseInputPath(std::string_view s)
for (auto & elem : tokenizeString<std::vector<std::string>>(s, "/")) { for (auto & elem : tokenizeString<std::vector<std::string>>(s, "/")) {
if (!std::regex_match(elem, flakeIdRegex)) if (!std::regex_match(elem, flakeIdRegex))
throw Error("invalid flake input path element '%s'", elem); throw UsageError("invalid flake input path element '%s'", elem);
path.push_back(elem); path.push_back(elem);
} }

View file

@ -72,4 +72,3 @@ InputPath parseInputPath(std::string_view s);
std::string diffLockFiles(const LockFile & oldLocks, const LockFile & newLocks); std::string diffLockFiles(const LockFile & oldLocks, const LockFile & newLocks);
} }

View file

@ -8,8 +8,6 @@
namespace nix { namespace nix {
MakeError(UsageError, Error);
enum HashType : char; enum HashType : char;
class Args class Args

View file

@ -131,6 +131,7 @@ public:
} }
MakeError(Error, BaseError); MakeError(Error, BaseError);
MakeError(UsageError, Error);
class SysError : public Error class SysError : public Error
{ {

View file

@ -40,14 +40,17 @@ struct EvalCommand : virtual StoreCommand, MixEvalArgs
std::shared_ptr<EvalState> evalState; std::shared_ptr<EvalState> evalState;
}; };
struct MixFlakeOptions : virtual Args struct MixFlakeOptions : virtual Args, EvalCommand
{ {
flake::LockFlags lockFlags; flake::LockFlags lockFlags;
MixFlakeOptions(); MixFlakeOptions();
virtual std::optional<FlakeRef> getFlakeRefForCompletion()
{ return {}; }
}; };
struct SourceExprCommand : virtual Args, EvalCommand, MixFlakeOptions struct SourceExprCommand : virtual Args, MixFlakeOptions
{ {
std::optional<Path> file; std::optional<Path> file;
std::optional<std::string> expr; std::optional<std::string> expr;
@ -81,6 +84,8 @@ struct InstallablesCommand : virtual Args, SourceExprCommand
virtual bool useDefaultInstallables() { return true; } virtual bool useDefaultInstallables() { return true; }
std::optional<FlakeRef> getFlakeRefForCompletion() override;
private: private:
std::vector<std::string> _installables; std::vector<std::string> _installables;
@ -95,6 +100,11 @@ struct InstallableCommand : virtual Args, SourceExprCommand
void prepare() override; void prepare() override;
std::optional<FlakeRef> getFlakeRefForCompletion() override
{
return parseFlakeRef(_installable, absPath("."));
}
private: private:
std::string _installable{"."}; std::string _installable{"."};

View file

@ -20,7 +20,7 @@
using namespace nix; using namespace nix;
using namespace nix::flake; using namespace nix::flake;
class FlakeCommand : virtual Args, public EvalCommand, public MixFlakeOptions class FlakeCommand : virtual Args, public MixFlakeOptions
{ {
std::string flakeUrl = "."; std::string flakeUrl = ".";
@ -53,6 +53,11 @@ public:
{ {
return flake::lockFlake(*getEvalState(), getFlakeRef(), lockFlags); return flake::lockFlake(*getEvalState(), getFlakeRef(), lockFlags);
} }
std::optional<FlakeRef> getFlakeRefForCompletion() override
{
return getFlakeRef();
}
}; };
static void printFlakeInfo(const Store & store, const Flake & flake) static void printFlakeInfo(const Store & store, const Flake & flake)

View file

@ -18,6 +18,17 @@
namespace nix { namespace nix {
void completeFlakeInputPath(
ref<EvalState> evalState,
const FlakeRef & flakeRef,
std::string_view prefix)
{
auto flake = flake::getFlake(*evalState, flakeRef, true);
for (auto & input : flake.inputs)
if (hasPrefix(input.first, prefix))
completions->insert(input.first);
}
MixFlakeOptions::MixFlakeOptions() MixFlakeOptions::MixFlakeOptions()
{ {
addFlag({ addFlag({
@ -56,6 +67,10 @@ MixFlakeOptions::MixFlakeOptions()
.labels = {"input-path"}, .labels = {"input-path"},
.handler = {[&](std::string s) { .handler = {[&](std::string s) {
lockFlags.inputUpdates.insert(flake::parseInputPath(s)); lockFlags.inputUpdates.insert(flake::parseInputPath(s));
}},
.completer = {[&](size_t, std::string_view prefix) {
if (auto flakeRef = getFlakeRefForCompletion())
completeFlakeInputPath(getEvalState(), *flakeRef, prefix);
}} }}
}); });
@ -707,6 +722,16 @@ void InstallablesCommand::prepare()
installables = parseInstallables(getStore(), _installables); installables = parseInstallables(getStore(), _installables);
} }
std::optional<FlakeRef> InstallablesCommand::getFlakeRefForCompletion()
{
if (_installables.empty()) {
if (useDefaultInstallables())
return parseFlakeRef(".", absPath("."));
return {};
}
return parseFlakeRef(_installables.front(), absPath("."));
}
InstallableCommand::InstallableCommand() InstallableCommand::InstallableCommand()
{ {
expectArgs({ expectArgs({