aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2021-02-24 15:28:19 +0100
committerGitHub <noreply@github.com>2021-02-24 15:28:19 +0100
commit199081ad00e6ee4c704eaac34211b454fe0f310c (patch)
tree0d6d62aaa13ace160111c1c9580a9a7ccc6ba818 /src
parenta878c448d84f087ee1dfdde95a51614187aa170c (diff)
parentf6c5b05488c588964f51ce97ad2c297fbca7ce96 (diff)
Merge pull request #4486 from shlevy/command-plugins-v2
Command plugins
Diffstat (limited to 'src')
-rw-r--r--src/build-remote/build-remote.cc3
-rw-r--r--src/libmain/common-args.cc7
-rw-r--r--src/libmain/common-args.hh6
-rw-r--r--src/libstore/globals.cc12
-rw-r--r--src/libstore/globals.hh19
-rw-r--r--src/libutil/args.cc12
-rw-r--r--src/libutil/args.hh4
-rwxr-xr-xsrc/nix-build/nix-build.cc2
-rwxr-xr-xsrc/nix-channel/nix-channel.cc2
-rw-r--r--src/nix-collect-garbage/nix-collect-garbage.cc2
-rwxr-xr-xsrc/nix-copy-closure/nix-copy-closure.cc2
-rw-r--r--src/nix-env/nix-env.cc2
-rw-r--r--src/nix-instantiate/nix-instantiate.cc2
-rw-r--r--src/nix-store/nix-store.cc2
-rw-r--r--src/nix/daemon.cc2
-rw-r--r--src/nix/main.cc8
-rw-r--r--src/nix/prefetch.cc2
17 files changed, 65 insertions, 24 deletions
diff --git a/src/build-remote/build-remote.cc b/src/build-remote/build-remote.cc
index 5b8ab3387..f784b5160 100644
--- a/src/build-remote/build-remote.cc
+++ b/src/build-remote/build-remote.cc
@@ -53,6 +53,9 @@ static int main_build_remote(int argc, char * * argv)
unsetenv("DISPLAY");
unsetenv("SSH_ASKPASS");
+ /* If we ever use the common args framework, make sure to
+ remove initPlugins below and initialize settings first.
+ */
if (argc != 2)
throw UsageError("called without required arguments");
diff --git a/src/libmain/common-args.cc b/src/libmain/common-args.cc
index ff96ee7d5..c43e9ebd2 100644
--- a/src/libmain/common-args.cc
+++ b/src/libmain/common-args.cc
@@ -79,4 +79,11 @@ MixCommonArgs::MixCommonArgs(const string & programName)
hiddenCategories.insert(cat);
}
+void MixCommonArgs::initialFlagsProcessed()
+{
+ initPlugins();
+ pluginsInited();
+}
+
+
}
diff --git a/src/libmain/common-args.hh b/src/libmain/common-args.hh
index 8e53a7361..31bdf527a 100644
--- a/src/libmain/common-args.hh
+++ b/src/libmain/common-args.hh
@@ -7,10 +7,14 @@ namespace nix {
//static constexpr auto commonArgsCategory = "Miscellaneous common options";
static constexpr auto loggingCategory = "Logging-related options";
-struct MixCommonArgs : virtual Args
+class MixCommonArgs : public virtual Args
{
+ void initialFlagsProcessed() override;
+public:
string programName;
MixCommonArgs(const string & programName);
+protected:
+ virtual void pluginsInited() {}
};
struct MixDryRun : virtual Args
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index df07aee9b..2780e0bf5 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -243,8 +243,17 @@ void MaxBuildJobsSetting::set(const std::string & str, bool append)
}
+void PluginFilesSetting::set(const std::string & str, bool append)
+{
+ if (pluginsLoaded)
+ throw UsageError("plugin-files set after plugins were loaded, you may need to move the flag before the subcommand");
+ BaseSetting<Paths>::set(str, append);
+}
+
+
void initPlugins()
{
+ assert(!settings.pluginFiles.pluginsLoaded);
for (const auto & pluginFile : settings.pluginFiles.get()) {
Paths pluginFiles;
try {
@@ -270,6 +279,9 @@ void initPlugins()
unknown settings. */
globalConfig.reapplyUnknownSettings();
globalConfig.warnUnknownSettings();
+
+ /* Tell the user if they try to set plugin-files after we've already loaded */
+ settings.pluginFiles.pluginsLoaded = true;
}
}
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index 1254698ca..df61d6417 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -28,6 +28,23 @@ struct MaxBuildJobsSetting : public BaseSetting<unsigned int>
void set(const std::string & str, bool append = false) override;
};
+struct PluginFilesSetting : public BaseSetting<Paths>
+{
+ bool pluginsLoaded = false;
+
+ PluginFilesSetting(Config * options,
+ const Paths & def,
+ const std::string & name,
+ const std::string & description,
+ const std::set<std::string> & aliases = {})
+ : BaseSetting<Paths>(def, name, description, aliases)
+ {
+ options->addSetting(this);
+ }
+
+ void set(const std::string & str, bool append = false) override;
+};
+
class Settings : public Config {
unsigned int getDefaultCores();
@@ -819,7 +836,7 @@ public:
Setting<uint64_t> minFreeCheckInterval{this, 5, "min-free-check-interval",
"Number of seconds between checking free disk space."};
- Setting<Paths> pluginFiles{
+ PluginFilesSetting pluginFiles{
this, {}, "plugin-files",
R"(
A list of plugin files to be loaded by Nix. Each of these files will
diff --git a/src/libutil/args.cc b/src/libutil/args.cc
index 9377fe4c0..75eb19d28 100644
--- a/src/libutil/args.cc
+++ b/src/libutil/args.cc
@@ -60,6 +60,7 @@ void Args::parseCmdline(const Strings & _cmdline)
verbosity = lvlError;
}
+ bool argsSeen = false;
for (auto pos = cmdline.begin(); pos != cmdline.end(); ) {
auto arg = *pos;
@@ -88,6 +89,10 @@ void Args::parseCmdline(const Strings & _cmdline)
throw UsageError("unrecognised flag '%1%'", arg);
}
else {
+ if (!argsSeen) {
+ argsSeen = true;
+ initialFlagsProcessed();
+ }
pos = rewriteArgs(cmdline, pos);
pendingArgs.push_back(*pos++);
if (processArgs(pendingArgs, false))
@@ -96,6 +101,9 @@ void Args::parseCmdline(const Strings & _cmdline)
}
processArgs(pendingArgs, true);
+
+ if (!argsSeen)
+ initialFlagsProcessed();
}
bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
@@ -298,8 +306,8 @@ Strings argvToStrings(int argc, char * * argv)
return args;
}
-MultiCommand::MultiCommand(const Commands & commands)
- : commands(commands)
+MultiCommand::MultiCommand(const Commands & commands_)
+ : commands(commands_)
{
expectArgs({
.label = "subcommand",
diff --git a/src/libutil/args.hh b/src/libutil/args.hh
index 88f068087..4721c21df 100644
--- a/src/libutil/args.hh
+++ b/src/libutil/args.hh
@@ -132,6 +132,10 @@ protected:
std::set<std::string> hiddenCategories;
+ /* Called after all command line flags before the first non-flag
+ argument (if any) have been processed. */
+ virtual void initialFlagsProcessed() {}
+
public:
void addFlag(Flag && flag);
diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc
index d975cd16d..7b4a53919 100755
--- a/src/nix-build/nix-build.cc
+++ b/src/nix-build/nix-build.cc
@@ -240,8 +240,6 @@ static void main_nix_build(int argc, char * * argv)
myArgs.parseCmdline(args);
- initPlugins();
-
if (packages && fromArgs)
throw UsageError("'-p' and '-E' are mutually exclusive");
diff --git a/src/nix-channel/nix-channel.cc b/src/nix-channel/nix-channel.cc
index 57189d557..3272c6125 100755
--- a/src/nix-channel/nix-channel.cc
+++ b/src/nix-channel/nix-channel.cc
@@ -196,8 +196,6 @@ static int main_nix_channel(int argc, char ** argv)
return true;
});
- initPlugins();
-
switch (cmd) {
case cNone:
throw UsageError("no command specified");
diff --git a/src/nix-collect-garbage/nix-collect-garbage.cc b/src/nix-collect-garbage/nix-collect-garbage.cc
index c1769790a..4f953fab4 100644
--- a/src/nix-collect-garbage/nix-collect-garbage.cc
+++ b/src/nix-collect-garbage/nix-collect-garbage.cc
@@ -74,8 +74,6 @@ static int main_nix_collect_garbage(int argc, char * * argv)
return true;
});
- initPlugins();
-
auto profilesDir = settings.nixStateDir + "/profiles";
if (removeOld) removeOldGenerations(profilesDir);
diff --git a/src/nix-copy-closure/nix-copy-closure.cc b/src/nix-copy-closure/nix-copy-closure.cc
index ad2e06067..5e8cc515b 100755
--- a/src/nix-copy-closure/nix-copy-closure.cc
+++ b/src/nix-copy-closure/nix-copy-closure.cc
@@ -43,8 +43,6 @@ static int main_nix_copy_closure(int argc, char ** argv)
return true;
});
- initPlugins();
-
if (sshHost.empty())
throw UsageError("no host name specified");
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc
index 106a78fc4..0f10a4cbb 100644
--- a/src/nix-env/nix-env.cc
+++ b/src/nix-env/nix-env.cc
@@ -1420,8 +1420,6 @@ static int main_nix_env(int argc, char * * argv)
myArgs.parseCmdline(argvToStrings(argc, argv));
- initPlugins();
-
if (!op) throw UsageError("no operation specified");
auto store = openStore();
diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc
index ea2e85eb0..95903d882 100644
--- a/src/nix-instantiate/nix-instantiate.cc
+++ b/src/nix-instantiate/nix-instantiate.cc
@@ -149,8 +149,6 @@ static int main_nix_instantiate(int argc, char * * argv)
myArgs.parseCmdline(argvToStrings(argc, argv));
- initPlugins();
-
if (evalOnly && !wantsReadWrite)
settings.readOnlyMode = true;
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index 37191b9e6..e17b38c3c 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -1067,8 +1067,6 @@ static int main_nix_store(int argc, char * * argv)
return true;
});
- initPlugins();
-
if (!op) throw UsageError("no operation specified");
if (op != opDump && op != opRestore) /* !!! hack */
diff --git a/src/nix/daemon.cc b/src/nix/daemon.cc
index 26006167d..2cf2a04c9 100644
--- a/src/nix/daemon.cc
+++ b/src/nix/daemon.cc
@@ -326,8 +326,6 @@ static int main_nix_daemon(int argc, char * * argv)
return true;
});
- initPlugins();
-
runDaemon(stdio);
return 0;
diff --git a/src/nix/main.cc b/src/nix/main.cc
index 1b68cf15b..06e221682 100644
--- a/src/nix/main.cc
+++ b/src/nix/main.cc
@@ -159,6 +159,12 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
#include "nix.md"
;
}
+
+ // Plugins may add new subcommands.
+ void pluginsInited() override
+ {
+ commands = RegisterCommand::getCommandsFor({});
+ }
};
static void showHelp(std::vector<std::string> subcommand)
@@ -283,8 +289,6 @@ void mainWrapped(int argc, char * * argv)
if (completions) return;
- initPlugins();
-
if (args.showVersion) {
printVersion(programName);
return;
diff --git a/src/nix/prefetch.cc b/src/nix/prefetch.cc
index a831dcd15..b7da3ea5a 100644
--- a/src/nix/prefetch.cc
+++ b/src/nix/prefetch.cc
@@ -171,8 +171,6 @@ static int main_nix_prefetch_url(int argc, char * * argv)
myArgs.parseCmdline(argvToStrings(argc, argv));
- initPlugins();
-
if (args.size() > 2)
throw UsageError("too many arguments");