Nix 2.26.3
Nix, the purely functional package manager; unstable internal interfaces
 
Loading...
Searching...
No Matches
args.hh
Go to the documentation of this file.
1#pragma once
3
4#include <functional>
5#include <filesystem>
6#include <map>
7#include <memory>
8#include <optional>
9
10#include <nlohmann/json_fwd.hpp>
11
12#include "types.hh"
14#include "ref.hh"
15
16namespace nix {
17
18enum struct HashAlgorithm : char;
19enum struct HashFormat : int;
20
21class MultiCommand;
22
23class RootArgs;
24
25class AddCompletions;
26
27class Args
28{
29
30public:
31
35 virtual std::string description() { return ""; }
36
37 virtual bool forceImpureByDefault() { return false; }
38
42 virtual std::string doc() { return ""; }
43
52 virtual Path getCommandBaseDir() const;
53
54protected:
55
61 static const size_t ArityAny = std::numeric_limits<size_t>::max();
62
71 struct Handler
72 {
73 std::function<void(std::vector<std::string>)> fun;
74 size_t arity;
75
76 Handler() = default;
77
78 Handler(std::function<void(std::vector<std::string>)> && fun)
79 : fun(std::move(fun))
80 , arity(ArityAny)
81 { }
82
83 Handler(std::function<void()> && handler)
84 : fun([handler{std::move(handler)}](std::vector<std::string>) { handler(); })
85 , arity(0)
86 { }
87
88 Handler(std::function<void(std::string)> && handler)
89 : fun([handler{std::move(handler)}](std::vector<std::string> ss) {
90 handler(std::move(ss[0]));
91 })
92 , arity(1)
93 { }
94
95 Handler(std::function<void(std::string, std::string)> && handler)
96 : fun([handler{std::move(handler)}](std::vector<std::string> ss) {
97 handler(std::move(ss[0]), std::move(ss[1]));
98 })
99 , arity(2)
100 { }
101
102 Handler(std::vector<std::string> * dest)
103 : fun([dest](std::vector<std::string> ss) { *dest = ss; })
104 , arity(ArityAny)
105 { }
106
107 Handler(std::string * dest)
108 : fun([dest](std::vector<std::string> ss) { *dest = ss[0]; })
109 , arity(1)
110 { }
111
112 Handler(std::optional<std::string> * dest)
113 : fun([dest](std::vector<std::string> ss) { *dest = ss[0]; })
114 , arity(1)
115 { }
116
117 Handler(std::filesystem::path * dest)
118 : fun([dest](std::vector<std::string> ss) { *dest = ss[0]; })
119 , arity(1)
120 { }
121
122 Handler(std::optional<std::filesystem::path> * dest)
123 : fun([dest](std::vector<std::string> ss) { *dest = ss[0]; })
124 , arity(1)
125 { }
126
127 template<class T>
128 Handler(T * dest, const T & val)
129 : fun([dest, val](std::vector<std::string> ss) { *dest = val; })
130 , arity(0)
131 { }
132
133 template<class I>
134 Handler(I * dest)
135 : fun([dest](std::vector<std::string> ss) {
136 *dest = string2IntWithUnitPrefix<I>(ss[0]);
137 })
138 , arity(1)
139 { }
140
141 template<class I>
142 Handler(std::optional<I> * dest)
143 : fun([dest](std::vector<std::string> ss) {
144 *dest = string2IntWithUnitPrefix<I>(ss[0]);
145 })
146 , arity(1)
147 { }
148 };
149
159 using CompleterFun = void(AddCompletions &, size_t, std::string_view);
160
167 using CompleterClosure = std::function<CompleterFun>;
168
169public:
170
177 struct Flag
178 {
179 using ptr = std::shared_ptr<Flag>;
180
181 std::string longName;
182 std::set<std::string> aliases;
183 char shortName = 0;
184 std::string description;
185 std::string category;
186 Strings labels;
187 Handler handler;
188 CompleterClosure completer;
189
190 std::optional<ExperimentalFeature> experimentalFeature;
191 };
192
193protected:
194
199 std::map<std::string, Flag::ptr> longFlags;
200
205 std::map<char, Flag::ptr> shortFlags;
206
211 virtual bool processFlag(Strings::iterator & pos, Strings::iterator end);
212
213public:
214
222 {
223 std::string label;
224 bool optional = false;
225 Handler handler;
226 CompleterClosure completer;
227 };
228
229protected:
230
240 std::list<ExpectedArg> expectedArgs;
252 std::list<ExpectedArg> processedArgs;
253
261 virtual bool processArgs(const Strings & args, bool finish);
262
263 virtual Strings::iterator rewriteArgs(Strings & args, Strings::iterator pos)
264 { return pos; }
265
266 std::set<std::string> hiddenCategories;
267
272 virtual void initialFlagsProcessed() {}
273
274public:
275
276 void addFlag(Flag && flag);
277
278 void removeFlag(const std::string & longName);
279
280 void expectArgs(ExpectedArg && arg)
281 {
282 expectedArgs.emplace_back(std::move(arg));
283 }
284
288 void expectArg(const std::string & label, std::string * dest, bool optional = false)
289 {
290 expectArgs({
291 .label = label,
292 .optional = optional,
293 .handler = {dest}
294 });
295 }
296
300 void expectArg(const std::string & label, std::filesystem::path * dest, bool optional = false)
301 {
302 expectArgs({
303 .label = label,
304 .optional = optional,
305 .handler = {dest}
306 });
307 }
308
312 void expectArgs(const std::string & label, std::vector<std::string> * dest)
313 {
314 expectArgs({
315 .label = label,
316 .handler = {dest}
317 });
318 }
319
320 static CompleterFun completePath;
321
322 static CompleterFun completeDir;
323
324 virtual nlohmann::json toJSON();
325
326 friend class MultiCommand;
327
337 MultiCommand * parent = nullptr;
338
343 RootArgs & getRoot();
344};
345
350struct Command : virtual public Args
351{
352 friend class MultiCommand;
353
354 virtual ~Command() = default;
355
359 virtual void run() = 0;
360
361 using Category = int;
362
363 static constexpr Category catDefault = 0;
364
365 virtual std::optional<ExperimentalFeature> experimentalFeature();
366
367 virtual Category category() { return catDefault; }
368};
369
370using Commands = std::map<std::string, std::function<ref<Command>()>>;
371
376class MultiCommand : virtual public Args
377{
378public:
379 Commands commands;
380
381 std::map<Command::Category, std::string> categories;
382
386 std::optional<std::pair<std::string, ref<Command>>> command;
387
388 MultiCommand(std::string_view commandName, const Commands & commands);
389
390 bool processFlag(Strings::iterator & pos, Strings::iterator end) override;
391
392 bool processArgs(const Strings & args, bool finish) override;
393
394 nlohmann::json toJSON() override;
395
396protected:
397 std::string commandName = "";
398};
399
400Strings argvToStrings(int argc, char * * argv);
401
403 std::string completion;
404 std::string description;
405
406 auto operator<=>(const Completion & other) const noexcept;
407};
408
419{
420public:
421
425 enum class Type {
426 Normal,
427 Filenames,
428 Attrs,
429 };
430
436 virtual void setType(Type type) = 0;
437
441 virtual void add(std::string completion, std::string description = "") = 0;
442};
443
444Strings parseShebangContent(std::string_view s);
445
446}
Definition args.hh:419
virtual void setType(Type type)=0
virtual void add(std::string completion, std::string description="")=0
Type
Definition args.hh:425
Definition args.hh:28
virtual Path getCommandBaseDir() const
Get the base directory for the command.
Definition args.cc:355
MultiCommand * parent
Definition args.hh:337
virtual bool processFlag(Strings::iterator &pos, Strings::iterator end)
Definition args.cc:366
std::list< ExpectedArg > expectedArgs
Definition args.hh:240
std::function< CompleterFun > CompleterClosure
Definition args.hh:167
std::list< ExpectedArg > processedArgs
Definition args.hh:252
virtual std::string description()
Definition args.hh:35
RootArgs & getRoot()
Definition args.cc:64
void expectArgs(const std::string &label, std::vector< std::string > *dest)
Definition args.hh:312
virtual std::string doc()
Definition args.hh:42
void expectArg(const std::string &label, std::filesystem::path *dest, bool optional=false)
Definition args.hh:300
void(AddCompletions &, size_t, std::string_view) CompleterFun
Definition args.hh:159
virtual void initialFlagsProcessed()
Definition args.hh:272
std::map< char, Flag::ptr > shortFlags
Definition args.hh:205
virtual bool processArgs(const Strings &args, bool finish)
Definition args.cc:441
std::map< std::string, Flag::ptr > longFlags
Definition args.hh:199
void expectArg(const std::string &label, std::string *dest, bool optional=false)
Definition args.hh:288
static const size_t ArityAny
Definition args.hh:61
Definition args.hh:377
bool processFlag(Strings::iterator &pos, Strings::iterator end) override
Definition args.cc:615
std::optional< std::pair< std::string, ref< Command > > > command
Definition args.hh:386
bool processArgs(const Strings &args, bool finish) override
Definition args.cc:622
Definition root.hh:31
PosIdx end
Definition lexer.l:5814
char
Definition lexer.l:3739
return s
Definition lexer.l:459
int
Definition lexer.l:2928
ValueType type
Definition lexer.l:7098
virtual nlohmann::json toJSON()=0
std::optional< ExperimentalFeature > experimentalFeature
Definition lexer.l:1937
std::vector< Expr * > args
Definition lexer.l:6126
HashFormat
Enumeration representing the hash formats.
Definition hash.hh:29
Definition args.hh:222
Definition args.hh:178
Definition args.hh:72
Definition args.hh:351
virtual void run()=0
Definition args.hh:402
std::string Path
Definition types.hh:22
N string2IntWithUnitPrefix(std::string_view s)
Definition util.hh:88