diff --git a/src/libutil/args.cc b/src/libutil/args.cc index 8bd9c8aeb..61f9503ec 100644 --- a/src/libutil/args.cc +++ b/src/libutil/args.cc @@ -86,6 +86,7 @@ void Args::parseCmdline(const Strings & _cmdline) throw UsageError("unrecognised flag '%1%'", arg); } else { + pos = rewriteArgs(cmdline, pos); pendingArgs.push_back(*pos++); if (processArgs(pendingArgs, false)) pendingArgs.clear(); @@ -390,10 +391,6 @@ MultiCommand::MultiCommand(const Commands & commands) .optional = true, .handler = {[=](std::string s) { assert(!command); - if (auto alias = get(deprecatedAliases, s)) { - warn("'%s' is a deprecated alias for '%s'", s, *alias); - s = *alias; - } if (auto prefix = needsCompletion(s)) { for (auto & [name, command] : commands) if (hasPrefix(name, *prefix)) diff --git a/src/libutil/args.hh b/src/libutil/args.hh index 26f1bc11b..8069fd70f 100644 --- a/src/libutil/args.hh +++ b/src/libutil/args.hh @@ -115,6 +115,9 @@ protected: virtual bool processArgs(const Strings & args, bool finish); + virtual Strings::iterator rewriteArgs(Strings & args, Strings::iterator pos) + { return pos; } + std::set hiddenCategories; public: @@ -257,8 +260,6 @@ public: std::map categories; - std::map deprecatedAliases; - // Selected command, if any. std::optional>> command; diff --git a/src/nix/main.cc b/src/nix/main.cc index 6d8c66406..94f4cad3c 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -112,8 +112,36 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs .description = "consider all previously downloaded files out-of-date", .handler = {[&]() { refresh = true; }}, }); + } - deprecatedAliases.insert({"dev-shell", "develop"}); + std::map> aliases = { + {"dev-shell", {"develop"}}, + {"hash-file", {"hash", "file"}}, + {"hash-path", {"hash", "path"}}, + {"to-base16", {"hash", "to-base16"}}, + {"to-base32", {"hash", "to-base32"}}, + {"to-base64", {"hash", "to-base64"}}, + {"ls-nar", {"nar", "ls"}}, + {"ls-store", {"store", "ls"}}, + {"cat-nar", {"nar", "cat"}}, + {"cat-store", {"store", "cat"}}, + }; + + bool aliasUsed = false; + + Strings::iterator rewriteArgs(Strings & args, Strings::iterator pos) override + { + if (aliasUsed || command || pos == args.end()) return pos; + auto arg = *pos; + auto i = aliases.find(arg); + if (i == aliases.end()) return pos; + warn("'%s' is a deprecated alias for '%s'", + arg, concatStringsSep(" ", i->second)); + pos = args.erase(pos); + for (auto j = i->second.rbegin(); j != i->second.rend(); ++j) + pos = args.insert(pos, *j); + aliasUsed = true; + return pos; } void printFlags(std::ostream & out) override