Skip to content

Commit a642040

Browse files
committed
feat: export rich command metadata
1 parent e1ce9cc commit a642040

96 files changed

Lines changed: 1462 additions & 655 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

e2e/analyze.py

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@
2222
import re
2323
import sys
2424
import pathlib
25+
import json
2526

2627
E2E = pathlib.Path(__file__).resolve().parent
2728
SRC = E2E.parent / "paper" / "src" / "main" / "java"
2829
CMDS_FILE = E2E / "commands.txt"
30+
COMMAND_SCHEMA = E2E.parent / "plugin" / "run" / "plugins" / "NotQuests" / "generated" / "commands.json"
2931

3032
EXCLUDE_INTEGRATION = {
3133
"EscortNPC", "JobsRebornReachJobLevel", "SlimefunResearch", "ReachLocation",
@@ -139,10 +141,75 @@ def main():
139141
print(f" {cmd}")
140142
print()
141143

142-
ok = ready and not missing and not real_fails
144+
schema_errors = []
145+
try:
146+
schema = json.loads(COMMAND_SCHEMA.read_text())
147+
exported = schema.get("commands", [])
148+
syntaxes = {entry.get("syntax") for entry in exported}
149+
if not exported:
150+
schema_errors.append("schema contains no commands")
151+
if "/nqa debug exportCommandSchema" not in syntaxes:
152+
schema_errors.append("schema is missing /nqa debug exportCommandSchema")
153+
for entry in exported:
154+
for segment in entry.get("segments", []):
155+
if weak_description(segment.get("description"), segment.get("name"), segment.get("token")):
156+
schema_errors.append(
157+
"weak command-segment description in "
158+
+ str(entry.get("syntax"))
159+
+ ": "
160+
+ str(segment.get("token"))
161+
+ " -> "
162+
+ repr(segment.get("description")))
163+
for flag in entry.get("flags", []):
164+
if weak_description(flag.get("description"), flag.get("name"), flag.get("token")):
165+
schema_errors.append(
166+
"weak flag description in "
167+
+ str(entry.get("syntax"))
168+
+ ": --"
169+
+ str(flag.get("name"))
170+
+ " -> "
171+
+ repr(flag.get("description")))
172+
except FileNotFoundError:
173+
schema_errors.append(f"schema file was not written: {COMMAND_SCHEMA}")
174+
except json.JSONDecodeError as exc:
175+
schema_errors.append(f"schema JSON is invalid: {exc}")
176+
if schema_errors:
177+
print("COMMAND SCHEMA ERROR:")
178+
for error in schema_errors:
179+
print(f" - {error}")
180+
print()
181+
182+
ok = ready and not missing and not real_fails and not schema_errors
143183
print("RESULT:", "PASS" if ok else "FAIL")
144184
sys.exit(0 if ok else 1)
145185

146186

187+
def weak_description(description, name, token):
188+
text = str(description or "").strip()
189+
if not text or text == "Variable Name":
190+
return True
191+
weak_phrases = {
192+
"adds a new entry in this command branch.",
193+
"checks the selected value or condition.",
194+
"creates a new entry.",
195+
"deletes the selected entry.",
196+
"lists matching entries.",
197+
"opens edit commands for the selected entry.",
198+
"optional command flags for this command.",
199+
"removes all entries in this command branch.",
200+
"removes the selected entry or value.",
201+
"sets a new value.",
202+
"shows detailed information about the selected entry.",
203+
"shows or changes the category assigned to this entry.",
204+
"shows the current value.",
205+
"shows, sets, or removes user-facing description text.",
206+
}
207+
if text.lower() in weak_phrases:
208+
return True
209+
token_text = str(token or "").strip().replace("[", "").replace("]", "").replace("<", "").replace(">", "")
210+
candidates = {str(name or "").strip(), token_text}
211+
return text.lower() in {candidate.lower() for candidate in candidates if candidate}
212+
213+
147214
if __name__ == "__main__":
148215
main()

e2e/commands.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ qa variables check RandomNumberBetweenRange 1 10
121121
qa variables check Block world 100 64 100
122122
qa conditions check WorldTime 0 12000
123123
qa edit TestQuest objectives list
124+
qa debug exportCommandSchema
124125
qa list
125126
qa actions
126127
qa conditions

paper/src/main/java/rocks/gravili/notquests/paper/commands/AdminCommands.java

Lines changed: 52 additions & 48 deletions
Large diffs are not rendered by default.

paper/src/main/java/rocks/gravili/notquests/paper/commands/AdminConversationCommands.java

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ public AdminConversationCommands(final NotQuests main,
7272
this.conversationManager = conversationManager;
7373

7474
manager.command(conversationBuilder
75-
.literal("create")
76-
.required("conversation-name", NQArguments.stringArgument(), NQDescription.of("conversation-name"), (context, input) -> {
75+
.literal("create", NQDescription.of("Creates a new conversation file."))
76+
.required("conversation-name", NQArguments.stringArgument(), NQDescription.of("Unique file/name for the new conversation."), (context, input) -> {
7777
List<String> completions = new ArrayList<>();
7878
completions.add("<Enter new conversation-name>");
7979
return completions;
@@ -154,7 +154,7 @@ public AdminConversationCommands(final NotQuests main,
154154

155155
if (main.getConfiguration().debug) {
156156
manager.command(conversationBuilder
157-
.literal("test")
157+
.literal("test", NQDescription.of("Runs a conversation test."))
158158
.senderType(Player.class).commandDescription(NQDescription.of("Starts a test conversation."))
159159
.handler((context) -> {
160160
final Player player = (Player) context.sender();
@@ -164,7 +164,7 @@ public AdminConversationCommands(final NotQuests main,
164164
}
165165

166166
manager.command(conversationBuilder
167-
.literal("list").commandDescription(NQDescription.of("Lists all conversations."))
167+
.literal("list", NQDescription.of("Lists every saved conversation.")).commandDescription(NQDescription.of("Lists all conversations."))
168168
.handler((context) -> {
169169
context.sender().sendMessage(main.parse("<highlight>All conversations:"));
170170
int counter = 1;
@@ -176,7 +176,7 @@ public AdminConversationCommands(final NotQuests main,
176176
}));
177177

178178
manager.command(conversationBuilder
179-
.literal("analyze")
179+
.literal("analyze", NQDescription.of("Runs conversation analysis checks."))
180180
.required("conversation", conversationArgument(main), NQDescription.of("Name of the Conversation."))
181181
.flag(NQFlag.presence("printToConsole", NQDescription.of("Prints the output to the console"))).commandDescription(NQDescription.of("Analyze specific conversations."))
182182
.handler((context) -> {
@@ -195,7 +195,7 @@ public AdminConversationCommands(final NotQuests main,
195195
}));
196196

197197
manager.command(conversationBuilder
198-
.literal("start")
198+
.literal("start", NQDescription.of("Starts the selected conversation."))
199199
.required("conversation", conversationArgument(main), NQDescription.of("Name of the Conversation."))
200200
.senderType(Player.class).commandDescription(NQDescription.of("Starts a conversation."))
201201
.handler((context) -> {
@@ -209,12 +209,12 @@ public AdminConversationCommands(final NotQuests main,
209209
foundConversation, null);
210210
}));
211211

212-
final NQCommandBuilder conversationEditBuilder = conversationBuilder.literal("edit")
212+
final NQCommandBuilder conversationEditBuilder = conversationBuilder.literal("edit", NQDescription.of("Opens subcommands for editing a saved conversation."))
213213
.required("conversation", conversationArgument(main), NQDescription.of("Name of the Conversation."));
214214

215215
manager.command(conversationEditBuilder
216-
.literal("npcs")
217-
.literal("add")
216+
.literal("npcs", NQDescription.of("Manages NPCs attached to this quest or conversation."))
217+
.literal("add", NQDescription.of("Attaches the selected conversation to an NPC or armor stand."))
218218
.required("NPC", nqNPCArgument(main, false, true), NQDescription.of("ID of the NPC which should start the conversation")).commandDescription(NQDescription.of("Add conversation to NPC"))
219219
.handler((context) -> {
220220
final Conversation foundConversation = context.get("conversation");
@@ -260,8 +260,8 @@ public AdminConversationCommands(final NotQuests main,
260260

261261
//TODO: Generalize with an npc remove command
262262
manager.command(conversationEditBuilder
263-
.literal("armorstand")
264-
.literal("remove", "delete")
263+
.literal("armorstand", NQDescription.of("Uses an armor stand selector/removal tool."))
264+
.literal("remove", NQDescription.of("Gives a player the tool used to remove conversations from an armor stand."), "delete")
265265
.senderType(Player.class).commandDescription(NQDescription.of("Gives you an item to remove all conversations from an armorstand"))
266266
.handler((context) -> {
267267
final Player player = (Player) context.sender();
@@ -296,9 +296,9 @@ public AdminConversationCommands(final NotQuests main,
296296
}));
297297

298298
manager.command(conversationEditBuilder
299-
.literal("speakers")
300-
.literal("add", "create")
301-
.required("speaker-name", NQArguments.stringArgument(), NQDescription.of("Speaker Name"), (context, input) -> {
299+
.literal("speakers", NQDescription.of("Manages speakers used by conversation lines."))
300+
.literal("add", NQDescription.of("Creates a new speaker for the selected conversation."), "create")
301+
.required("speaker-name", NQArguments.stringArgument(), NQDescription.of("Unique speaker identifier used by conversation lines and speaker options."), (context, input) -> {
302302
List<String> completions = new ArrayList<>();
303303
completions.add("<Enter new Speaker Name>");
304304
return completions;
@@ -333,8 +333,8 @@ public AdminConversationCommands(final NotQuests main,
333333
}));
334334

335335
manager.command(conversationEditBuilder
336-
.literal("speakers")
337-
.literal("list", "show").commandDescription(NQDescription.of("Adds / creates a new speaker for the conversation."))
336+
.literal("speakers", NQDescription.of("Manages speakers used by conversation lines."))
337+
.literal("list", NQDescription.of("Lists every speaker in the selected conversation."), "show").commandDescription(NQDescription.of("Lists every speaker in the conversation."))
338338
.handler((context) -> {
339339
final Conversation foundConversation = context.get("conversation");
340340

@@ -363,9 +363,11 @@ public AdminConversationCommands(final NotQuests main,
363363
}));
364364

365365
manager.command(conversationEditBuilder
366-
.literal("speakers")
367-
.literal("remove", "delete")
368-
.required("speaker", speakerArgument(main, "conversation")).commandDescription(NQDescription.of("Adds / creates a new speaker for the conversation."))
366+
.literal("speakers", NQDescription.of("Manages speakers used by conversation lines."))
367+
.literal("remove", NQDescription.of("Removes a speaker from the selected conversation."), "delete")
368+
.required("speaker", speakerArgument(main, "conversation"),
369+
NQDescription.of("Speaker identifier to remove from this conversation."))
370+
.commandDescription(NQDescription.of("Removes a speaker from the conversation."))
369371
.handler((context) -> {
370372
final Conversation foundConversation = context.get("conversation");
371373

@@ -390,8 +392,8 @@ public AdminConversationCommands(final NotQuests main,
390392
}));
391393

392394
manager.command(conversationEditBuilder
393-
.literal("category")
394-
.literal("show").commandDescription(NQDescription.of("Shows the current category of this Conversation.."))
395+
.literal("category", NQDescription.of("Shows or changes the category assigned to the selected conversation."))
396+
.literal("show", NQDescription.of("Shows the category currently assigned to the selected conversation.")).commandDescription(NQDescription.of("Shows the current category of this Conversation.."))
395397
.handler((context) -> {
396398
final Conversation conversation = context.get("conversation");
397399
context.sender().sendMessage(main.parse(
@@ -404,8 +406,8 @@ public AdminConversationCommands(final NotQuests main,
404406
}));
405407

406408
manager.command(conversationEditBuilder
407-
.literal("category")
408-
.literal("set")
409+
.literal("category", NQDescription.of("Shows or changes the category assigned to the selected conversation."))
410+
.literal("set", NQDescription.of("Moves the selected conversation into another category."))
409411
.required("category", categoryArgument(main), NQDescription.of("New category for this Conversation.")).commandDescription(NQDescription.of("Changes the current category of this Conversation."))
410412
.handler((context) -> {
411413
final Conversation conversation = context.get("conversation");
@@ -450,10 +452,10 @@ static String formatAttachedNPCs(final List<NQNPC> npcs) {
450452
}
451453

452454
public void handleLinesCommands() {
453-
/*manager.command(conversationBuilder.literal("edit")
455+
/*manager.command(conversationBuilder.literal("edit", NQDescription.of("Opens subcommands for editing a saved conversation."))
454456
.argument(ConversationSelector.of("conversation", main), Description.of("Name of the Conversation."))
455-
.literal("lines")
456-
.literal("add", "create")
457+
.literal("lines", NQDescription.of("Manages conversation lines."))
458+
.literal("add", NQDescription.of("Adds a new line to the selected conversation."), "create")
457459
.meta(CommandMeta.DESCRIPTION, "Creates a line for a conversation.")
458460
.handler((context) -> {
459461
final Audience audience = main.adventure().sender(context.sender());

0 commit comments

Comments
 (0)