Skip to content

Commit 1c08685

Browse files
committed
breaking change how (sub)project command initialization works
Subprojects have to now explicitly define an initCommands function that registers the projects commands with registerCommands. This allows for subprojects to exist on multiple levels, e.g. to make a sub-project of Foldseek. your_tool.cpp needs to include now something as follows: std::vector<Command> yourToolCommands = { ... }; extern std::vector<Command> baseCommands; void init() { registerCommands(&baseCommands); registerCommands(&yourToolCommands); } void (*initCommands)(void) = init; instead of: std::vector<Command> commands = { ... }
1 parent 9b9383a commit 1c08685

File tree

5 files changed

+88
-97
lines changed

5 files changed

+88
-97
lines changed

cmake/MMseqsSetupDerivedTarget.cmake

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
include(AppendTargetProperty)
22

33
function (mmseqs_setup_derived_target TARGET)
4-
get_target_property(COMPILE_TMP mmseqs-framework COMPILE_FLAGS)
5-
get_target_property(LINK_TMP mmseqs-framework LINK_FLAGS)
6-
get_target_property(DEF_TMP mmseqs-framework COMPILE_DEFINITIONS)
7-
get_target_property(INCL_TMP mmseqs-framework INCLUDE_DIRECTORIES)
4+
set(SOURCE "${ARGN}")
5+
if(NOT SOURCE)
6+
set(SOURCE "mmseqs-framework")
7+
endif()
8+
get_target_property(COMPILE_TMP ${SOURCE} COMPILE_FLAGS)
9+
get_target_property(LINK_TMP ${SOURCE} LINK_FLAGS)
10+
get_target_property(DEF_TMP ${SOURCE} COMPILE_DEFINITIONS)
11+
get_target_property(INCL_TMP ${SOURCE} INCLUDE_DIRECTORIES)
812

9-
target_link_libraries(${TARGET} mmseqs-framework)
13+
target_link_libraries(${TARGET} ${SOURCE})
1014
append_target_property(${TARGET} COMPILE_FLAGS ${COMPILE_TMP})
1115
append_target_property(${TARGET} LINK_FLAGS ${LINK_TMP})
1216
set_property(TARGET ${TARGET} APPEND PROPERTY COMPILE_DEFINITIONS ${DEF_TMP})

src/commons/Application.cpp

Lines changed: 65 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,30 @@ extern const char *show_extended_help;
1616
extern const char *show_bash_info;
1717
extern bool hide_base_commands;
1818

19-
extern std::vector<Command> commands;
20-
extern std::vector<Command> baseCommands;
19+
extern std::vector<std::vector<Command>*> commands;
2120
extern std::vector<Categories> categories;
2221
extern void (*validatorUpdate)(void);
22+
extern void (*initCommands)(void);
2323

24-
Command *getCommandByName(const char *s) {
25-
for (size_t i = 0; i < commands.size(); i++) {
26-
Command &p = commands[i];
27-
if (!strcmp(s, p.cmd))
28-
return &p;
29-
}
30-
24+
const Command* getCommandByName(const char *s) {
3125
// allow base commands also to be called with a prefix, e.g. "mmseqs base:createdb"
3226
// this allows inheriting programs to find shadowed base modules
3327
const char *prefix = "base:";
3428
const char *check = strncmp(s, prefix, strlen(prefix)) == 0 ? s + strlen(prefix) : s;
35-
for (size_t i = 0; i < baseCommands.size(); i++) {
36-
Command &p = baseCommands[i];
37-
if (!strcmp(check, p.cmd))
38-
return &p;
29+
30+
for (size_t i = 0; i < commands.size(); i++) {
31+
for (size_t j = 0; j < commands[i]->size(); j++) {
32+
const Command &p = (*commands[i])[j];
33+
if (!strcmp(s, p.cmd))
34+
return &p;
35+
if (i == 0 && !strcmp(check, p.cmd))
36+
return &p;
37+
}
3938
}
4039
return NULL;
4140
}
4241

43-
int runCommand(Command *p, int argc, const char **argv) {
42+
int runCommand(const Command *p, int argc, const char **argv) {
4443
Timer timer;
4544
int status = p->commandFunction(argc, argv, *p);
4645
Debug(Debug::INFO) << "Time for processing: " << timer.lap() << "\n";
@@ -57,21 +56,17 @@ void printUsage(bool showExtended) {
5756

5857
std::vector<int> showCategoryHeader(categories.size(), 0);
5958
for (size_t i = 0; i < categories.size(); ++i) {
60-
for (size_t j = 0; j < commands.size(); j++) {
61-
Command &p = commands[j];
62-
if (p.mode & categories[i].mode) {
63-
showCategoryHeader[i] = 1;
64-
break;
65-
}
66-
}
59+
size_t start = 0;
6760
if (hide_base_commands) {
68-
continue;
69-
}
70-
for (size_t j = 0; j < baseCommands.size(); j++) {
71-
Command &p = baseCommands[j];
72-
if (p.mode & categories[i].mode) {
73-
showCategoryHeader[i] = 1;
74-
break;
61+
start = commands.size() - 1;
62+
}
63+
for (size_t j = start; j < commands.size(); j++) {
64+
for (size_t k = 0; k < commands[j]->size(); k++) {
65+
const Command &p = (*commands[j])[k];
66+
if (p.mode & categories[i].mode) {
67+
showCategoryHeader[i] = 1;
68+
break;
69+
}
7570
}
7671
}
7772
}
@@ -93,24 +88,18 @@ void printUsage(bool showExtended) {
9388

9489
usage << "\n" << std::setw(20) << categories[i].title << "\n";
9590
for (size_t j = 0; j < commands.size(); j++) {
96-
struct Command &p = commands[j];
97-
if (showExtended == false && (p.mode & COMMAND_EXPERT) != 0) {
98-
continue;
99-
}
100-
if (p.mode & categories[i].mode) {
101-
usage << std::left << std::setw(20) << " " + std::string(p.cmd) << "\t" << p.description << "\n";
91+
size_t start = 0;
92+
if (hide_base_commands) {
93+
start = commands.size() - 1;
10294
}
103-
}
104-
if (hide_base_commands) {
105-
continue;
106-
}
107-
for (size_t j = 0; j < baseCommands.size(); j++) {
108-
struct Command &p = baseCommands[j];
109-
if (showExtended == false && (p.mode & COMMAND_EXPERT) != 0) {
110-
continue;
111-
}
112-
if (p.mode & categories[i].mode) {
113-
usage << std::left << std::setw(20) << " " + std::string(p.cmd) << "\t" << p.description << "\n";
95+
for (size_t k = start; k < commands[j]->size(); k++) {
96+
const Command &p = (*commands[j])[k];
97+
if (showExtended == false && (p.mode & COMMAND_EXPERT) != 0) {
98+
continue;
99+
}
100+
if (p.mode & categories[i].mode) {
101+
usage << std::left << std::setw(20) << " " + std::string(p.cmd) << "\t" << p.description << "\n";
102+
}
114103
}
115104
}
116105
}
@@ -130,14 +119,12 @@ int shellcompletion(int argc, const char **argv) {
130119
// mmseqs programs
131120
if (argc == 0) {
132121
for (size_t i = 0; i < commands.size(); i++) {
133-
struct Command &p = commands[i];
134-
if (p.mode & COMMAND_HIDDEN)
135-
continue;
136-
Debug(Debug::INFO) << p.cmd << " ";
137-
}
138-
if (hide_base_commands == false) {
139-
for (size_t i = 0; i < baseCommands.size(); i++) {
140-
struct Command &p = baseCommands[i];
122+
size_t start = 0;
123+
if (hide_base_commands) {
124+
start = commands.size() - 1;
125+
}
126+
for (size_t j = start; j < commands[i]->size(); j++) {
127+
const Command &p = (*commands[i])[j];
141128
if (p.mode & COMMAND_HIDDEN)
142129
continue;
143130
Debug(Debug::INFO) << p.cmd << " ";
@@ -149,30 +136,19 @@ int shellcompletion(int argc, const char **argv) {
149136
// mmseqs parameters for given program
150137
if (argc == 1) {
151138
for (size_t i = 0; i < commands.size(); i++) {
152-
struct Command &p = commands[i];
153-
if (strcmp(p.cmd, argv[0]) != 0) {
154-
continue;
155-
}
156-
if (p.params == NULL) {
157-
continue;
139+
size_t start = 0;
140+
if (hide_base_commands) {
141+
start = commands.size() - 1;
158142
}
159-
for (std::vector<MMseqsParameter *>::const_iterator it = p.params->begin(); it != p.params->end(); ++it) {
160-
Debug(Debug::INFO) << (*it)->name << " ";
161-
}
162-
Debug(Debug::INFO) << "\n";
163-
break;
164-
}
165-
if (hide_base_commands == false) {
166-
for (size_t i = 0; i < baseCommands.size(); i++) {
167-
struct Command &p = baseCommands[i];
143+
for (size_t j = start; j < commands[i]->size(); j++) {
144+
const Command &p = (*commands[i])[j];
168145
if (strcmp(p.cmd, argv[0]) != 0) {
169146
continue;
170147
}
171148
if (p.params == NULL) {
172149
continue;
173150
}
174-
for (std::vector<MMseqsParameter *>::const_iterator it = p.params->begin();
175-
it != p.params->end(); ++it) {
151+
for (std::vector<MMseqsParameter *>::const_iterator it = p.params->begin(); it != p.params->end(); ++it) {
176152
Debug(Debug::INFO) << (*it)->name << " ";
177153
}
178154
Debug(Debug::INFO) << "\n";
@@ -185,6 +161,10 @@ int shellcompletion(int argc, const char **argv) {
185161
}
186162

187163
int main(int argc, const char **argv) {
164+
if (initCommands != NULL) {
165+
initCommands();
166+
}
167+
188168
if (argc < 2) {
189169
printUsage(false);
190170
return EXIT_SUCCESS;
@@ -201,7 +181,7 @@ int main(int argc, const char **argv) {
201181
FileUtil::fixRlimitNoFile();
202182

203183
setenv("MMSEQS", argv[0], true);
204-
Command *c = NULL;
184+
const Command *c = NULL;
205185
if (strncmp(argv[1], "shellcompletion", strlen("shellcompletion")) == 0) {
206186
return shellcompletion(argc - 2, argv + 2);
207187
} else if ((c = getCommandByName(argv[1])) != NULL) {
@@ -211,37 +191,31 @@ int main(int argc, const char **argv) {
211191
Debug(Debug::INFO) << "\nInvalid Command: " << argv[1] << "\n";
212192

213193
// Suggest some command that the user might have meant
214-
size_t index = SIZE_MAX;
194+
size_t indexI = SIZE_MAX;
195+
size_t indexJ = SIZE_MAX;
215196
int maxDistance = 0;
216-
for (size_t i = 0; i < commands.size(); ++i) {
217-
struct Command &p = commands[i];
218-
if (p.mode & COMMAND_HIDDEN) {
219-
continue;
220-
}
221-
222-
int distance = DistanceCalculator::localLevenshteinDistance(argv[1], p.cmd);
223-
if (distance > maxDistance) {
224-
maxDistance = distance;
225-
index = i;
197+
for (size_t i = 0; i < commands.size(); i++) {
198+
size_t start = 0;
199+
if (hide_base_commands) {
200+
start = commands.size() - 1;
226201
}
227-
}
228-
229-
if (hide_base_commands == false) {
230-
for (size_t i = 0; i < baseCommands.size(); ++i) {
231-
struct Command &p = baseCommands[i];
232-
if (p.mode & COMMAND_HIDDEN)
202+
for (size_t j = start; j < commands[i]->size(); j++) {
203+
const Command &p = (*commands[i])[j];
204+
if (p.mode & COMMAND_HIDDEN) {
233205
continue;
206+
}
234207

235208
int distance = DistanceCalculator::localLevenshteinDistance(argv[1], p.cmd);
236209
if (distance > maxDistance) {
237210
maxDistance = distance;
238-
index = i;
211+
indexI = i;
212+
indexJ = j;
239213
}
240214
}
241215
}
242216

243-
if (index != SIZE_MAX) {
244-
Debug(Debug::WARNING) << "Did you mean \"" << argv[0] << " " << baseCommands[index].cmd << "\"?\n";
217+
if (indexI != SIZE_MAX && indexJ != SIZE_MAX) {
218+
Debug(Debug::WARNING) << "Did you mean \"" << argv[0] << " " << (*commands[indexI])[indexJ].cmd << "\"?\n";
245219
}
246220

247221
return EXIT_FAILURE;

src/commons/Command.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#include "Command.h"
22
#include "Parameters.h"
33

4+
std::vector<std::vector<Command>*> commands;
5+
void registerCommands(std::vector<Command>* cmd) {
6+
commands.emplace_back(cmd);
7+
}
8+
49
std::vector<Categories> categories = {
510
{"Easy workflows for plain text input/output", COMMAND_EASY},
611
{"Main workflows for database input/output", COMMAND_MAIN},

src/commons/Command.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,6 @@ struct Categories {
108108
CommandMode mode;
109109
};
110110

111+
void registerCommands(std::vector<Command>* cmd);
112+
111113
#endif

src/mmseqs.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ extern const char* MMSEQS_CURRENT_INDEX_VERSION;
1212
const char* index_version_compatible = MMSEQS_CURRENT_INDEX_VERSION;
1313
bool hide_base_commands = false;
1414
void (*validatorUpdate)(void) = 0;
15-
std::vector<Command> commands = {};
15+
16+
extern std::vector<Command> baseCommands;
17+
void init() {
18+
registerCommands(&baseCommands);
19+
}
20+
void (*initCommands)(void) = init;
21+
1622
std::vector<DatabaseDownload> externalDownloads = {};
1723
std::vector<KmerThreshold> externalThreshold = {};
1824

0 commit comments

Comments
 (0)