aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/args.hh
AgeCommit message (Collapse)Author
2024-08-28tree-wide: shuffle headers around for about 30s compile timeJade Lovelace
This didn't really feel so worth it afterwards, but I did untangle a bunch of stuff that should not have been tangled. The general gist of this change is that variant bullshit was causing a bunch of compile time, and it seems like the only way to deal with variant induced compile time is to keep variant types out of headers. Explicit template instantiation seems to do nothing for them. I also seem to have gotten some back-end time improvement from explicitly instantiating regex, but I don't know why. There is no corresponding front-end time improvement from it: regex is still at the top of the sinners list. **** Templates that took longest to instantiate: 15231 ms: std::basic_regex<char>::_M_compile (28 times, avg 543 ms) 15066 ms: std::__detail::_Compiler<std::regex_traits<char>>::_Compiler (28 times, avg 538 ms) 12571 ms: std::__detail::_Compiler<std::regex_traits<char>>::_M_disjunction (28 times, avg 448 ms) 12454 ms: std::__detail::_Compiler<std::regex_traits<char>>::_M_alternative (28 times, avg 444 ms) 12225 ms: std::__detail::_Compiler<std::regex_traits<char>>::_M_term (28 times, avg 436 ms) 11363 ms: nlohmann::basic_json<>::parse<const char *> (21 times, avg 541 ms) 10628 ms: nlohmann::basic_json<>::basic_json (109 times, avg 97 ms) 10134 ms: std::__detail::_Compiler<std::regex_traits<char>>::_M_atom (28 times, avg 361 ms) Back-end time before messing with the regex: **** Function sets that took longest to compile / optimize: 8076 ms: void boost::io::detail::put<$>(boost::io::detail::put_holder<$> cons... (177 times, avg 45 ms) 4382 ms: std::_Rb_tree<$>::_M_erase(std::_Rb_tree_node<$>*) (1247 times, avg 3 ms) 3137 ms: boost::stacktrace::detail::to_string_impl_base<boost::stacktrace::de... (137 times, avg 22 ms) 2896 ms: void boost::io::detail::mk_str<$>(std::__cxx11::basic_string<$>&, ch... (177 times, avg 16 ms) 2304 ms: std::_Rb_tree<$>::_M_get_insert_hint_unique_pos(std::_Rb_tree_const_... (210 times, avg 10 ms) 2116 ms: bool std::__detail::_Compiler<$>::_M_expression_term<$>(std::__detai... (112 times, avg 18 ms) 2051 ms: std::_Rb_tree_iterator<$> std::_Rb_tree<$>::_M_emplace_hint_unique<$... (244 times, avg 8 ms) 2037 ms: toml::result<$> toml::detail::sequence<$>::invoke<$>(toml::detail::l... (93 times, avg 21 ms) 1928 ms: std::__detail::_Compiler<$>::_M_quantifier() (28 times, avg 68 ms) 1859 ms: nlohmann::json_abi_v3_11_3::detail::serializer<$>::dump(nlohmann::js... (41 times, avg 45 ms) 1824 ms: std::_Function_handler<$>::_M_manager(std::_Any_data&, std::_Any_dat... (973 times, avg 1 ms) 1810 ms: std::__detail::_BracketMatcher<$>::_BracketMatcher(std::__detail::_B... (112 times, avg 16 ms) 1793 ms: nix::fetchers::GitInputScheme::fetch(nix::ref<$>, nix::fetchers::Inp... (1 times, avg 1793 ms) 1759 ms: std::_Rb_tree<$>::_M_get_insert_unique_pos(std::__cxx11::basic_strin... (281 times, avg 6 ms) 1722 ms: bool nlohmann::json_abi_v3_11_3::detail::parser<$>::sax_parse_intern... (19 times, avg 90 ms) 1677 ms: boost::io::basic_altstringbuf<$>::overflow(int) (194 times, avg 8 ms) 1674 ms: std::__cxx11::basic_string<$>::_M_mutate(unsigned long, unsigned lon... (249 times, avg 6 ms) 1660 ms: std::_Rb_tree_node<$>* std::_Rb_tree<$>::_M_copy<$>(std::_Rb_tree_no... (304 times, avg 5 ms) 1599 ms: bool nlohmann::json_abi_v3_11_3::detail::parser<$>::sax_parse_intern... (19 times, avg 84 ms) 1568 ms: void std::__detail::_Compiler<$>::_M_insert_bracket_matcher<$>(bool) (112 times, avg 14 ms) 1541 ms: std::__shared_ptr<$>::~__shared_ptr() (531 times, avg 2 ms) 1539 ms: nlohmann::json_abi_v3_11_3::detail::serializer<$>::dump_escaped(std:... (41 times, avg 37 ms) 1471 ms: void std::__detail::_Compiler<$>::_M_insert_character_class_matcher<... (112 times, avg 13 ms) After messing with the regex (notice std::__detail::_Compiler vanishes here, but I don't know why): **** Function sets that took longest to compile / optimize: 8054 ms: void boost::io::detail::put<$>(boost::io::detail::put_holder<$> cons... (177 times, avg 45 ms) 4313 ms: std::_Rb_tree<$>::_M_erase(std::_Rb_tree_node<$>*) (1217 times, avg 3 ms) 3259 ms: boost::stacktrace::detail::to_string_impl_base<boost::stacktrace::de... (137 times, avg 23 ms) 3045 ms: void boost::io::detail::mk_str<$>(std::__cxx11::basic_string<$>&, ch... (177 times, avg 17 ms) 2314 ms: std::_Rb_tree<$>::_M_get_insert_hint_unique_pos(std::_Rb_tree_const_... (207 times, avg 11 ms) 1923 ms: std::_Rb_tree_iterator<$> std::_Rb_tree<$>::_M_emplace_hint_unique<$... (216 times, avg 8 ms) 1817 ms: bool nlohmann::json_abi_v3_11_3::detail::parser<$>::sax_parse_intern... (18 times, avg 100 ms) 1816 ms: toml::result<$> toml::detail::sequence<$>::invoke<$>(toml::detail::l... (93 times, avg 19 ms) 1788 ms: nlohmann::json_abi_v3_11_3::detail::serializer<$>::dump(nlohmann::js... (40 times, avg 44 ms) 1749 ms: std::_Rb_tree<$>::_M_get_insert_unique_pos(std::__cxx11::basic_strin... (278 times, avg 6 ms) 1724 ms: std::__cxx11::basic_string<$>::_M_mutate(unsigned long, unsigned lon... (248 times, avg 6 ms) 1697 ms: boost::io::basic_altstringbuf<$>::overflow(int) (194 times, avg 8 ms) 1684 ms: nix::fetchers::GitInputScheme::fetch(nix::ref<$>, nix::fetchers::Inp... (1 times, avg 1684 ms) 1680 ms: std::_Rb_tree_node<$>* std::_Rb_tree<$>::_M_copy<$>(std::_Rb_tree_no... (303 times, avg 5 ms) 1589 ms: bool nlohmann::json_abi_v3_11_3::detail::parser<$>::sax_parse_intern... (18 times, avg 88 ms) 1483 ms: non-virtual thunk to boost::wrapexcept<$>::~wrapexcept() (181 times, avg 8 ms) 1447 ms: nlohmann::json_abi_v3_11_3::detail::serializer<$>::dump_escaped(std:... (40 times, avg 36 ms) 1441 ms: std::__shared_ptr<$>::~__shared_ptr() (496 times, avg 2 ms) 1420 ms: boost::stacktrace::basic_stacktrace<$>::init(unsigned long, unsigned... (137 times, avg 10 ms) 1396 ms: boost::basic_format<$>::~basic_format() (194 times, avg 7 ms) 1290 ms: std::__cxx11::basic_string<$>::_M_replace_cold(char*, unsigned long,... (231 times, avg 5 ms) 1258 ms: std::vector<$>::~vector() (354 times, avg 3 ms) 1222 ms: std::__cxx11::basic_string<$>::_M_replace(unsigned long, unsigned lo... (231 times, avg 5 ms) 1194 ms: std::_Rb_tree<$>::_M_get_insert_hint_unique_pos(std::_Rb_tree_const_... (49 times, avg 24 ms) 1186 ms: bool tao::pegtl::internal::sor<$>::match<$>(std::integer_sequence<$>... (1 times, avg 1186 ms) 1149 ms: std::__detail::_Executor<$>::_M_dfs(std::__detail::_Executor<$>::_Ma... (70 times, avg 16 ms) 1123 ms: toml::detail::sequence<$>::invoke(toml::detail::location&) (69 times, avg 16 ms) 1110 ms: nlohmann::json_abi_v3_11_3::basic_json<$>::json_value::destroy(nlohm... (55 times, avg 20 ms) 1079 ms: std::_Function_handler<$>::_M_manager(std::_Any_data&, std::_Any_dat... (541 times, avg 1 ms) 1033 ms: nlohmann::json_abi_v3_11_3::detail::lexer<$>::scan_number() (20 times, avg 51 ms) Change-Id: I10af282bcd4fc39c2d3caae3453e599e4639c70b
2024-08-08refactor: make HashType and Base enum classes for type safetyJade Lovelace
Change-Id: I9fbd55a9d50464a56fe11cb42a06a206914150d8
2024-05-31libutil: fix args assert being thrown on Darwin in nix-eval-jobsJade Lovelace
This is because a dynamic_cast<nix::RootArgs *> of a (n-e-j) MyArgs returns nullptr even though MyArgs has virtual nix::RootArgs as a parent. class MyArgs : virtual public nix::MixEvalArgs, virtual public nix::MixCommonArgs, virtual nix::RootArgs { ... }; So this should work right?? But it does not. We found out that it's caused by -fvisibility=hidden in n-e-j, but honestly this code was bad anyway. The trivial solution is to simply stop relying on RTTI working properly here, which is probably better OO architecture anyway. However, I am not 100% confident *this* is sound, since we have this horrible hierarchy: Args (defines getRoot) / | \ RootArgs MixCommonArgs MixEvalArgs (overrides) I am not confident that this is guaranteed to resolve from Args always in the case of this override. Assertion failed: (res), function getRoot, file src/libutil/args.cc, line 67. 6MyArgsProcess 60503 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = hit program assert frame #4: 0x0000000100b1a41c liblixutil.dylib`nix::Args::processArgs(std::__1::list<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>> const&, bool) [inlined] nix::Args::getRoot(this=0x00000001000d0688) at args.cc:67:5 [opt] 64 std::cout << typeid(*p).name(); 65 66 auto * res = dynamic_cast<RootArgs *>(p); -> 67 assert(res); 68 return *res; 69 } 70 Target 0: (nix-eval-jobs) stopped. (lldb) p this (MyArgs *) 0x00000001000d0688 (lldb) p *this (nix::Args) { longFlags = size=180 { ... } shortFlags = size=4 { ... } expectedArgs = size=1 { ... } processedArgs = size=0 {} hiddenCategories = size=1 { [0] = "Options to override configuration settings" } parent = nullptr } We also found that if we did this: class [[gnu::visibility("default")]] RootArgs : virtual public Args it would work properly (???!). This is of course, very strange, because objdump -Ct output on liblixexpr.dylib is identical both with and without it. Possibly related: https://www.qt.io/blog/quality-assurance/one-way-dynamic_cast-across-library-boundaries-can-fail-and-how-to-fix-it Fixes: https://git.lix.systems/lix-project/nix-eval-jobs/issues/2 Change-Id: I6b9ed968ed56420a9c4d2dffd18999d78c2761bd
2024-05-29util.hh: Delete remaining file and clean up headersTom Hubrecht
Change-Id: Ic1f68e6af658e94ef7922841dd3ad4c69551ef56
2024-03-25Merge pull request #8817 from iFreilicht/flake-update-lock-overhaulThéophane Hufschmitt
Overhaul `nix flake update` and `nix flake lock` UX (cherry picked from commit 12a0ae73dbb37becefa5a442eb4532ff0de9ce65) Change-Id: Iff3b4f4235ebb1948ec612036b39ab29e4ca22b2
2024-03-25Overhaul completions, redo #6693 (#8131)John Ericson
As I complained in https://github.com/NixOS/nix/pull/6784#issuecomment-1421777030 (a comment on the wrong PR, sorry again!), #6693 introduced a second completions mechanism to fix a bug. Having two completion mechanisms isn't so nice. As @thufschmitt also pointed out, it was a bummer to go from `FlakeRef` to `std::string` when collecting flake refs. Now it is `FlakeRefs` again. The underlying issue that sought to work around was that completion of arguments not at the end can still benefit from the information from latter arguments. To fix this better, we rip out that change and simply defer all completion processing until after all the (regular, already-complete) arguments have been passed. In addition, I noticed the original completion logic used some global variables. I do not like global variables, because even if they save lines of code, they also obfuscate the architecture of the code. I got rid of them moved them to a new `RootArgs` class, which now has `parseCmdline` instead of `Args`. The idea is that we have many argument parsers from subcommands and what-not, but only one root args that owns the other per actual parsing invocation. The state that was global is now part of the root args instead. This did, admittedly, add a bunch of new code. And I do feel bad about that. So I went and added a lot of API docs to try to at least make the current state of things clear to the next person. -- This is needed for RFC 134 (tracking issue #7868). It was very hard to modularize `Installable` parsing when there were two completion arguments. I wouldn't go as far as to say it is *easy* now, but at least it is less hard (and the completions test finally passed). Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io> Change-Id: If18cd5be78da4a70635e3fdcac6326dbfeea71a5 (cherry picked from commit 67eb37c1d0de28160cd25376e51d1ec1b1c8305b)
2024-03-04Merge pull request #9167 from obsidiansystems/pre-overhaul-completionseldritch horrors
Improve tests and docs prior to refactoring completions (cherry picked from commit 5442d9b47298389918d1f38d20f768a80ffc2369) Change-Id: Ief99ac2cd9c92981a9a522d15b9c3daf99182c9d
2023-04-03Stuctured command stabilityJohn Ericson
Prior to this, there was an ad-hoc whitelist in `main.cc`. Now, every command states its stability. In a future PR, we will adjust the manual to take advantage of this new information in the JSON. (It will be easier to do that once we have some experimental feature docs to link too; see #5930 and #7798.)
2023-03-31Ensure all headers have `#pragma once` and are in API docsJohn Ericson
`///@file` makes them show up in the internal API dos. A tiny few were missing `#pragma once`.
2023-03-31Extend internal API docs, part 2John Ericson
Picking up from #8111. Co-authored-by: Eelco Dolstra <edolstra@gmail.com>
2023-03-20Fix handling of experimental features mid-parseJohn Ericson
If we conditionally "declare" the argument, as we did before, based upon weather the feature is enabled, commands like nix --experimental-features=foo ... --thing-gated-on-foo won't work, because the experimental feature isn't enabled until *after* we start parsing. Instead, allow arguments to also be associated with experimental features (just as we did for builtins and settings), and then the command line parser will filter out the experimental ones. Since the effects of arguments (handler functions) are performed right away, we get the required behavior: earlier arguments can enable later arguments enabled! There is just one catch: we want to keep non-positional flags...non-positional. So if nix --experimental-features=foo ... --thing-gated-on-foo works, then nix --thing-gated-on-foo --experimental-features=foo ... should also work. This is not my favorite long-term solution, but for now this is implemented by delaying the requirement of needed experimental features until *after* all the arguments have been parsed.
2023-03-15Make command infra less stateful and more regularJohn Ericson
Already, we had classes like `BuiltPathsCommand` and `StorePathsCommand` which provided alternative `run` virtual functions providing the implementation with more arguments. This was a very nice and easy way to make writing command; just fill in the virtual functions and it is fairly clear what to do. However, exception to this pattern were `Installable{,s}Command`. These two classes instead just had a field where the installables would be stored, and various side-effecting `prepare` and `load` machinery too fill them in. Command would wish out those fields. This isn't so clear to use. What this commit does is make those command classes like the others, with richer `run` functions. Not only does this restore the pattern making commands easier to write, it has a number of other benefits: - `prepare` and `load` are gone entirely! One command just hands just hands off to the next. - `useDefaultInstallables` because `defaultInstallables`. This takes over `prepare` for the one case that needs it, and provides enough flexiblity to handle `nix repl`'s idiosyncratic migration. - We can use `ref` instead of `std::shared_ptr`. The former must be initialized (so it is like Rust's `Box` rather than `Option<Box>`, This expresses the invariant that the installable are in fact initialized much better. This is possible because since we just have local variables not fields, we can stop worrying about the not-yet-initialized case. - Fewer lines of code! (Finally I have a large refactor that makes the number go down not up...) - `nix repl` is now implemented in a clearer way. The last item deserves further mention. `nix repl` is not like the other installable commands because instead working from once-loaded installables, it needs to be able to load them again and again. To properly support this, we make a new superclass `RawInstallablesCommand`. This class has the argument parsing and completion logic, but does *not* hand off parsed installables but instead just the raw string arguments. This is exactly what `nix repl` needs, and allows us to instead of having the logic awkwardly split between `prepare`, `useDefaultInstallables,` and `load`, have everything right next to each other. I think this will enable future simplifications of that argument defaulting logic, but I am saving those for a future PR --- best to keep code motion and more complicated boolean expression rewriting separate steps. The "diagnostic ignored `-Woverloaded-virtual`" pragma helps because C++ doesn't like our many `run` methods. In our case, we don't mind the shadowing it all --- it is *intentional* that the derived class only provides a `run` method, and doesn't call any of the overridden `run` methods. Helps with https://github.com/NixOS/rfcs/pull/134
2022-07-11Fix flake input completion for `InstallablesCommand`sNaïm Favier
Defers completion of flake inputs until the whole command line is parsed so that we know what flakes we need to complete the inputs of. Previously, `nix build flake --update-input <Tab>` always behaved like `nix build . --update-input <Tab>`.
2022-05-31repl: `--option pure-eval true` actually enables pure eval modeMaximilian Bosch
To quote Eelco in #5867: > Unfortunately we can't do > > evalSettings.pureEval.setDefault(false); > > because then we have to do the same in main.cc (where > pureEval is set to true), and that would allow pure-eval > to be disabled globally from nix.conf. Instead, a command should specify that it should be impure by default. Then, `evalSettings.pureEval` will be set to `false;` unless it's overridden by e.g. a CLI flag. In that case it's IMHO OK to be (theoretically) able to override `pure-eval` via `nix.conf` because it doesn't have an effect on commands where `forceImpureByDefault` returns `false` (i.e. everything where pure eval actually matters). Closes #5867
2022-02-25Remove std::string alias (for real this time)Eelco Dolstra
Also use std::string_view in a few more places.
2021-12-22Don't insert spaces when completing attribute pathsNaïm Favier
2021-09-14Add "nix profile rollback" commandEelco Dolstra
2021-09-13nix --help: Display help using lowdown instead of manEelco Dolstra
Fixes #4476. Fixes #5231.
2021-02-26nix flake update: Recreate the lock fileEelco Dolstra
This is probably what most people expect it to do. Fixes #3781. There is a new command 'nix flake lock' that has the old behaviour of 'nix flake update', i.e. it just adds missing lock file entries unless overriden using --update-input.
2021-02-24Initialize plugins after handling initial command line flagsShea Levy
This is technically a breaking change, since attempting to set plugin files after the first non-flag argument will now throw an error. This is acceptable given the relative lack of stability in a plugin interface and the need to tie the knot somewhere once plugins can actually define new subcommands.
2021-02-07Support --no-net for backwards compatibilityEelco Dolstra
2021-01-27Remove mkFlag()Eelco Dolstra
2021-01-25Group common optionsEelco Dolstra
2021-01-25Make '--help' do the same as 'help' (i.e. show a manpage)Eelco Dolstra
2021-01-08Support binary unit prefixes in command line argumentsEelco Dolstra
2021-01-08string2Int(): Return std::optionalEelco Dolstra
2021-01-08Remove unused mkFlag1Eelco Dolstra
2021-01-08Remove mkFlag integer specialisationEelco Dolstra
2021-01-08Remove mkIntFlagEelco Dolstra
2020-12-23Command: Remove examples()Eelco Dolstra
2020-12-21Move doc() to ArgsEelco Dolstra
2020-12-03Add deprecated aliases for renamed commandsEelco Dolstra
2020-10-09Add a description in the completion outputsregnat
Make nix output completions in the form `completion\tdescription`. This can't be used by bash (afaik), but other shells like zsh or fish can display it along the completion choices
2020-09-25expectArg(): Respect the 'optional' flagEelco Dolstra
2020-08-20Allow 'nix' subcommands to provide docs in Markdown formatEelco Dolstra
2020-08-17Add 'nix dump-args' to dump all commands/flags for manpage generationEelco Dolstra
2020-06-26Merge remote-tracking branch 'origin/master' into flakesEelco Dolstra
2020-06-18Revert the `enum struct` changeJohn Ericson
Not a regular git revert as there have been many merges and things.
2020-06-18Merge branch 'enum-class' into no-hash-type-unknownJohn Ericson
2020-06-18Merge remote-tracking branch 'upstream/master' into enum-classJohn Ericson
2020-06-08Add completion for --update-inputEelco Dolstra
2020-06-04Merge remote-tracking branch 'origin/master' into flakesEelco Dolstra
2020-06-04Make 'nix dev-shell' a deprecated alias for 'nix develop'Eelco Dolstra
2020-06-02Fix to-base --type handler to correctly set std::optional flagJohn Ericson
Now that we have a separate flag function, also describe why it is optional.
2020-05-28Merge branch 'master' of github.com:NixOS/nix into enum-classCarlo Nucera
2020-05-11When completing flakerefs, only return directoriesEelco Dolstra
2020-05-11CleanupEelco Dolstra
2020-05-10Add completion for pathsEelco Dolstra
2020-05-10nix: Implement basic bash completionEelco Dolstra
2020-05-05nix --help: Group commandsEelco Dolstra