Skip to content

Commit 0d87c43

Browse files
committed
cufetchpm: args: make it like the git CLI
1 parent abaab30 commit 0d87c43

File tree

1 file changed

+129
-47
lines changed

1 file changed

+129
-47
lines changed

cufetchpm/src/main.cpp

Lines changed: 129 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include <cstring>
1+
#include <cstdlib>
22

33
#include "libcufetch/common.hh"
44
#include "pluginManager.hpp"
@@ -12,20 +12,16 @@
1212

1313
#include "getopt_port/getopt.h"
1414

15-
static int op = 0;
16-
enum
15+
enum Ops
1716
{
17+
NONE,
1818
INSTALL,
19-
REMOVE,
2019
LIST
21-
};
20+
} op = NONE;
2221

23-
static struct operations_install_t
24-
{
25-
std::vector<std::string> args;
26-
} install_op;
22+
static std::vector<std::string> arguments;
2723

28-
static void version()
24+
void version()
2925
{
3026
fmt::print(
3127
"cufetchpm {} built from branch '{}' at {} commit '{}' ({}).\n"
@@ -37,27 +33,106 @@ static void version()
3733
std::exit(EXIT_SUCCESS);
3834
}
3935

40-
static void help(int invalid_opt = false)
36+
void help(int invalid_opt = false)
4137
{
42-
constexpr std::string_view help(
43-
R"(Usage: cufetchpm [OPERATION] [ARGUMENTS] [OPTIONS]...
38+
fmt::print(R"(Usage: cufetchpm <command> [options]
4439
Manage plugins for customfetch.
4540
NOTE: the operations must be the first argument to pass
4641
47-
OPERATIONS:
48-
install - Install a new plugin repository. Takes as an argument the git url to be cloned.
42+
Commands:
43+
install [options] <repo> Install a new plugin repository. Takes as an argument the git url to be cloned.
4944
50-
GENERAL OPTIONS
45+
Global options:
5146
-h, --help Print this help menu.
5247
-V, --version Print version and other infos about the build.
5348
5449
)");
5550

56-
fmt::print("{}", help);
57-
fmt::print("\n");
5851
std::exit(invalid_opt);
5952
}
6053

54+
void help_install(int invalid_opt = false)
55+
{
56+
fmt::print(R"(Usage: cufetchpm install [options] <repo>
57+
58+
Options:
59+
-f, --force Force installation
60+
-h, --help Show help for install
61+
)");
62+
63+
std::exit(invalid_opt);
64+
}
65+
66+
void help_list(int invalid_opt = false)
67+
{
68+
fmt::print(R"(Usage: cufetchpm list [options]
69+
70+
Options:
71+
-v, --verbose Show detailed info
72+
-h, --help Show help for list
73+
)");
74+
75+
std::exit(invalid_opt);
76+
}
77+
78+
bool parse_install_args(int argc, char* argv[])
79+
{
80+
bool force = false;
81+
82+
// clang-format off
83+
const struct option long_opts[] = {
84+
{"force", no_argument, nullptr, 'f'},
85+
{"help", no_argument, nullptr, 'h'},
86+
{0, 0, 0, 0}
87+
};
88+
// clang-format on
89+
90+
int opt;
91+
while ((opt = getopt_long(argc, argv, "-fh", long_opts, nullptr)) != -1)
92+
{
93+
switch (opt)
94+
{
95+
case 'f': force = true; break;
96+
case 'h': help_install(EXIT_SUCCESS); break;
97+
case '?': help_install(EXIT_FAILURE); break;
98+
}
99+
}
100+
101+
for (int i = optind; i < argc; ++i)
102+
arguments.emplace_back(argv[i]);
103+
104+
if (arguments.empty())
105+
die("install: no repositories given");
106+
107+
return true;
108+
}
109+
110+
bool parse_list_args(int argc, char* argv[])
111+
{
112+
bool verbose = false;
113+
114+
// clang-format off
115+
const struct option long_opts[] = {
116+
{"verbose", no_argument, nullptr, 'v'},
117+
{"help", no_argument, nullptr, 'h'},
118+
{0, 0, 0, 0}
119+
};
120+
// clang-format on
121+
122+
int opt;
123+
while ((opt = getopt_long(argc, argv, "-vh", long_opts, nullptr)) != -1)
124+
{
125+
switch (opt)
126+
{
127+
case 'v': verbose = true; break;
128+
case 'h': help_list(EXIT_SUCCESS); break;
129+
case '?': help_list(EXIT_FAILURE); break;
130+
}
131+
}
132+
133+
return true;
134+
}
135+
61136
static bool parseargs(int argc, char* argv[])
62137
{
63138
// clang-format off
@@ -73,28 +148,6 @@ static bool parseargs(int argc, char* argv[])
73148

74149
// clang-format on
75150
optind = 1;
76-
for (int i = 1; i < argc; ++i)
77-
{
78-
if (strncmp(argv[i], "install", 7) == 0 || strncmp(argv[i], "i", 1) == 0)
79-
{
80-
op = INSTALL;
81-
optind++;
82-
break;
83-
}
84-
if (strncmp(argv[i], "list", 4) == 0 || strncmp(argv[i], "l", 1) == 0)
85-
{
86-
op = LIST;
87-
optind++;
88-
break;
89-
}
90-
if (strncmp(argv[i], "remove", 6) == 0 || strncmp(argv[i], "r", 1) == 0)
91-
{
92-
op = REMOVE;
93-
optind++;
94-
break;
95-
}
96-
}
97-
98151
while ((opt = getopt_long(argc, argv, optstring, opts, &option_index)) != -1)
99152
{
100153
switch (opt)
@@ -108,11 +161,40 @@ static bool parseargs(int argc, char* argv[])
108161
}
109162
}
110163

111-
switch (op)
164+
if (optind >= argc)
165+
help(EXIT_FAILURE); // no subcommand
166+
167+
std::string_view cmd = argv[optind];
168+
int sub_argc = argc - optind - 1;
169+
char** sub_argv = argv + optind + 1;
170+
if (cmd == "install" || cmd == "i")
112171
{
113-
case INSTALL:
114-
for (int i = optind; i < argc; ++i)
115-
install_op.args.push_back(argv[i]);
172+
op = INSTALL;
173+
optind = 0;
174+
return parse_install_args(sub_argc, sub_argv);
175+
}
176+
else if (cmd == "list" || cmd == "l")
177+
{
178+
op = LIST;
179+
optind = 0;
180+
return parse_list_args(sub_argc, sub_argv);
181+
}
182+
else if (cmd == "help")
183+
{
184+
if (sub_argc >= 1)
185+
{
186+
std::string_view target = sub_argv[0];
187+
if (target == "install")
188+
help_install();
189+
else if (target == "list")
190+
help_list();
191+
else
192+
die("Unknown subcommand '{}'", cmd);
193+
}
194+
else
195+
{
196+
help(EXIT_FAILURE);
197+
}
116198
}
117199

118200
return true;
@@ -128,14 +210,14 @@ int main(int argc, char* argv[])
128210
{
129211
case INSTALL:
130212
{
131-
if (install_op.args.size() != 1)
213+
if (arguments.size() < 1)
132214
die("Please provide a singular git url repository");
133215
StateManager state;
134216
PluginManager plugin_manager(std::move(state));
135-
plugin_manager.add_repo_plugins(install_op.args[0]);
217+
plugin_manager.add_repo_plugins(arguments[0]);
136218
break;
137219
}
138-
default: warn("Not yet implemented");
220+
default: warn("uh?");
139221
}
140222

141223
return 0;

0 commit comments

Comments
 (0)