7
7
#include " Rustify/Result.hpp"
8
8
#include " TermColor.hpp"
9
9
10
- #include < cstdlib>
11
- #include < exception>
12
- #include < fmt/core.h>
13
- #include < span>
14
10
#include < string>
15
- #include < string_view>
16
11
#include < utility>
17
- #include < vector>
18
12
19
13
namespace cabin {
20
14
@@ -27,7 +21,10 @@ getCli() noexcept {
27
21
.setShort (" -v" )
28
22
.setDesc (" Use verbose output (-vv very verbose output)" )
29
23
.setGlobal (true ))
24
+ // TODO: assuming -- for long options would be better, also empty
25
+ // long options should be allowed?
30
26
.addOpt (Opt{ " -vv" }
27
+ .setShort (" -vv" )
31
28
.setDesc (" Use very verbose output" )
32
29
.setGlobal (true )
33
30
.setHidden (true ))
@@ -67,66 +64,20 @@ getCli() noexcept {
67
64
return cli;
68
65
}
69
66
70
- static Result<void >
71
- parseArgs (const std::span<char * const > args) noexcept {
72
- // Parse arguments (options should appear before the subcommand, as the help
73
- // message shows intuitively)
74
- // cabin --verbose run --release help --color always --verbose
75
- // ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
76
- // [global] [run] [help (under run)]
77
- for (auto itr = args.begin (); itr != args.end (); ++itr) {
78
- // Global options
79
- const auto control = Try (Cli::handleGlobalOpts (itr, args.end ()));
80
- if (control == Cli::Return) {
81
- return Ok ();
82
- } else if (control == Cli::Continue) {
83
- continue ;
84
- }
85
- // else: Fallthrough: current argument wasn't handled
86
-
87
- // Local options
88
- else if (*itr == " -V" sv || *itr == " --version" sv) {
89
- const std::vector<std::string_view> remArgs (itr + 1 , args.end ());
90
- return versionMain (remArgs);
91
- } else if (*itr == " --list" sv) {
92
- fmt::print (" {}" , getCli ().formatAllSubcmds (true ));
93
- return Ok ();
94
- }
95
-
96
- // Subcommands
97
- else if (getCli ().hasSubcmd (*itr)) {
98
- const std::vector<std::string_view> remArgs (itr + 1 , args.end ());
99
- try {
100
- return getCli ().exec (*itr, remArgs);
101
- } catch (const std::exception& e) {
102
- Bail (e.what ());
103
- }
104
- }
105
-
106
- // Unexpected argument
107
- else {
108
- return getCli ().noSuchArg (*itr);
109
- }
110
- }
111
-
112
- return getCli ().printHelp ({});
113
- }
114
-
115
67
static std::string
116
68
colorizeAnyhowError (std::string s) {
117
- // `Caused by:` leaves a trailing newline
118
69
if (s.find (" Caused by:" ) != std::string::npos) {
119
70
replaceAll (s, " Caused by:" , Yellow (" Caused by:" ).toErrStr ());
71
+ // `Caused by:` leaves a trailing newline, FIXME: upstream this
120
72
replaceAll (s, " \n " , " " );
121
73
}
122
74
return s;
123
75
}
124
76
125
77
Result<void , void >
126
- cliMain (int argc, char * argv[]) noexcept { // NOLINT(*-avoid-c-arrays)
127
- // Drop the first argument (program name)
128
- const std::span<char * const > args (argv + 1 , argv + argc);
129
- return parseArgs (args)
78
+ cabinMain (int argc, char * argv[]) noexcept { // NOLINT(*-avoid-c-arrays)
79
+ return getCli ()
80
+ .parseArgs (argc, argv)
130
81
.map_err ([](const auto & e) { return colorizeAnyhowError (e->what ()); })
131
82
.map_err ([](std::string e) { logger::error (" {}" , std::move (e)); });
132
83
}
0 commit comments