Skip to content

Commit 78828b8

Browse files
committed
Added startupt scripts for jshell
1 parent f0a93b5 commit 78828b8

File tree

4 files changed

+70
-27
lines changed

4 files changed

+70
-27
lines changed

application/src/main/java/org/togetherjava/tjbot/features/code/EvalCodeCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public MessageEmbed apply(CodeFence codeFence) {
3131
.build();
3232
}
3333
try {
34-
return jshellEval.evaluateAndRespond(null, codeFence.code(), false);
34+
return jshellEval.evaluateAndRespond(null, codeFence.code(), false, false);
3535
} catch (RequestFailedException e) {
3636
return new EmbedBuilder().setColor(Colors.ERROR_COLOR)
3737
.setDescription("Request failed: " + e.getMessage())

application/src/main/java/org/togetherjava/tjbot/features/jshell/JShellCommand.java

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ public class JShellCommand extends SlashCommandAdapter {
3535
private static final String JSHELL_EVAL_SUBCOMMAND = "eval";
3636
private static final String JSHELL_SNIPPETS_SUBCOMMAND = "snippets";
3737
private static final String JSHELL_CLOSE_SUBCOMMAND = "shutdown";
38+
private static final String JSHELL_STARTUP_SCRIPT_SUBCOMMAND = "startup-script";
39+
private static final String JSHELL_CODE_PARAMETER = "code";
40+
private static final String JSHELL_STARTUP_SCRIPT_PARAMETER = "startup-script";
41+
private static final String JSHELL_USER_PARAMETER = "user";
42+
private static final String JSHELL_INCLUDE_STARTUP_SCRIPT_PARAMETER = "include-startup-script";
43+
3844
private static final int MIN_MESSAGE_INPUT_LENGTH = 0;
3945
private static final int MAX_MESSAGE_INPUT_LENGTH = TextInput.MAX_VALUE_LENGTH;
4046

@@ -52,13 +58,18 @@ public JShellCommand(JShellEval jshellEval) {
5258
new SubcommandData(JSHELL_VERSION_SUBCOMMAND, "Get the version of JShell"),
5359
new SubcommandData(JSHELL_EVAL_SUBCOMMAND,
5460
"Evaluate java code in JShell, don't fill the optional parameter to access a bigger input box.")
55-
.addOption(OptionType.STRING, "code",
56-
"Code to evaluate. If not supplied, open an inout box."),
61+
.addOption(OptionType.STRING, JSHELL_CODE_PARAMETER,
62+
"Code to evaluate. If not supplied, open an inout box.")
63+
.addOption(OptionType.BOOLEAN, JSHELL_STARTUP_SCRIPT_PARAMETER,
64+
"If the startup script should be loaded, true by default."),
5765
new SubcommandData(JSHELL_SNIPPETS_SUBCOMMAND,
5866
"Get the evaluated snippets of the user who sent the command, or the user specified user if any.")
59-
.addOption(OptionType.USER, "user",
60-
"User to get the snippets from. If null, get the snippets of the user who sent the command."),
61-
new SubcommandData(JSHELL_CLOSE_SUBCOMMAND, "Close your session."));
67+
.addOption(OptionType.USER, JSHELL_USER_PARAMETER,
68+
"User to get the snippets from. If null, get the snippets of the user who sent the command.")
69+
.addOption(OptionType.BOOLEAN, JSHELL_INCLUDE_STARTUP_SCRIPT_PARAMETER,
70+
"if the startup script should be included, false by default."),
71+
new SubcommandData(JSHELL_CLOSE_SUBCOMMAND, "Close your session."),
72+
new SubcommandData(JSHELL_STARTUP_SCRIPT_SUBCOMMAND, "Display the startup script."));
6273
}
6374

6475
@Override
@@ -68,16 +79,21 @@ public void onSlashCommand(SlashCommandInteractionEvent event) {
6879
case JSHELL_EVAL_SUBCOMMAND -> handleEvalCommand(event);
6980
case JSHELL_SNIPPETS_SUBCOMMAND -> handleSnippetsCommand(event);
7081
case JSHELL_CLOSE_SUBCOMMAND -> handleCloseCommand(event);
82+
case JSHELL_STARTUP_SCRIPT_SUBCOMMAND -> handleStartupScriptCommand(event);
7183
default -> throw new AssertionError(
7284
"Unexpected Subcommand: " + event.getSubcommandName());
7385
}
7486
}
7587

7688
@Override
7789
public void onModalSubmitted(ModalInteractionEvent event, List<String> args) {
78-
ModalMapping mapping = event.getValue(JSHELL_TEXT_INPUT_ID);
90+
ModalMapping mapping = event.getValue(JSHELL_TEXT_INPUT_ID + "|" + JSHELL_STARTUP_SCRIPT_PARAMETER);
91+
boolean startupScript = mapping != null;
92+
if(mapping == null) {
93+
mapping = event.getValue(JSHELL_TEXT_INPUT_ID);
94+
}
7995
if (mapping != null) {
80-
handleEval(event, event.getUser(), true, mapping.getAsString());
96+
handleEval(event, event.getUser(), true, mapping.getAsString(), startupScript);
8197
}
8298
}
8399

@@ -89,21 +105,22 @@ private void handleVersionCommand(SlashCommandInteractionEvent event) {
89105
System.out.println("OS: " + System.getProperty("os.name"));
90106
System.out.println("Arch: " + System.getProperty("os.arch"));
91107
System.out.println("```");""";
92-
handleEval(event, null, false, code);
108+
handleEval(event, null, false, code, false);
93109
}
94110

95111
private void handleEvalCommand(SlashCommandInteractionEvent event) {
96-
OptionMapping code = event.getOption("code");
112+
OptionMapping code = event.getOption(JSHELL_CODE_PARAMETER);
113+
boolean startupScript = event.getOption(JSHELL_STARTUP_SCRIPT_PARAMETER) == null || Objects.requireNonNull(event.getOption(JSHELL_STARTUP_SCRIPT_PARAMETER)).getAsBoolean();
97114
if (code == null) {
98-
sendEvalModal(event);
115+
sendEvalModal(event, startupScript);
99116
} else {
100-
handleEval(event, event.getUser(), true, code.getAsString());
117+
handleEval(event, event.getUser(), true, code.getAsString(), startupScript);
101118
}
102119
}
103120

104-
private void sendEvalModal(SlashCommandInteractionEvent event) {
121+
private void sendEvalModal(SlashCommandInteractionEvent event, boolean startupScript) {
105122
TextInput body = TextInput
106-
.create(JSHELL_TEXT_INPUT_ID, "Enter code to evaluate.", TextInputStyle.PARAGRAPH)
123+
.create(JSHELL_TEXT_INPUT_ID + (startupScript ? "|" + JSHELL_STARTUP_SCRIPT_PARAMETER : ""), "Enter code to evaluate.", TextInputStyle.PARAGRAPH)
107124
.setPlaceholder("Put your code here.")
108125
.setRequiredRange(MIN_MESSAGE_INPUT_LENGTH, MAX_MESSAGE_INPUT_LENGTH)
109126
.build();
@@ -118,14 +135,15 @@ private void sendEvalModal(SlashCommandInteractionEvent event) {
118135
* @param replyCallback the callback to reply to
119136
* @param user the user, if null, will create a single use session
120137
* @param showCode if the embed should contain the original code
138+
* @param startupScript if the startup script should be used or not
121139
* @param code the code
122140
*/
123141
private void handleEval(IReplyCallback replyCallback, @Nullable User user, boolean showCode,
124-
String code) {
142+
String code, boolean startupScript) {
125143
replyCallback.deferReply().queue(interactionHook -> {
126144
try {
127145
interactionHook
128-
.editOriginalEmbeds(jshellEval.evaluateAndRespond(user, code, showCode))
146+
.editOriginalEmbeds(jshellEval.evaluateAndRespond(user, code, showCode, startupScript))
129147
.queue();
130148
} catch (RequestFailedException e) {
131149
interactionHook.editOriginalEmbeds(createUnexpectedErrorEmbed(user, e)).queue();
@@ -135,11 +153,13 @@ private void handleEval(IReplyCallback replyCallback, @Nullable User user, boole
135153

136154
private void handleSnippetsCommand(SlashCommandInteractionEvent event) {
137155
event.deferReply().queue(interactionHook -> {
138-
OptionMapping userOption = event.getOption("user");
156+
OptionMapping userOption = event.getOption(JSHELL_USER_PARAMETER);
139157
User user = userOption == null ? event.getUser() : userOption.getAsUser();
158+
OptionMapping includeStartupScriptOption = event.getOption(JSHELL_INCLUDE_STARTUP_SCRIPT_PARAMETER);
159+
boolean includeStartupScript = includeStartupScriptOption != null && includeStartupScriptOption.getAsBoolean();
140160
List<String> snippets;
141161
try {
142-
snippets = jshellEval.getApi().snippetsSession(user.getId()).snippets();
162+
snippets = jshellEval.getApi().snippetsSession(user.getId(), includeStartupScript).snippets();
143163
} catch (RequestFailedException e) {
144164
if (e.getStatus() == JShellApi.SESSION_NOT_FOUND) {
145165
interactionHook.editOriginalEmbeds(createSessionNotFoundErrorEmbed(user))
@@ -232,6 +252,23 @@ private void handleCloseCommand(SlashCommandInteractionEvent event) {
232252
.queue();
233253
}
234254

255+
private void handleStartupScriptCommand(SlashCommandInteractionEvent event) {
256+
event.deferReply().queue(interactionHook -> {
257+
try {
258+
String startupScript = jshellEval.getApi().startupScript();
259+
interactionHook
260+
.editOriginalEmbeds(new EmbedBuilder().setColor(Colors.SUCCESS_COLOR)
261+
.setAuthor(event.getUser().getName())
262+
.setTitle("Startup script")
263+
.setDescription("```java\n" + startupScript + "```")
264+
.build())
265+
.queue();
266+
} catch (RequestFailedException e) {
267+
event.replyEmbeds(createUnexpectedErrorEmbed(event.getUser(), e)).queue();
268+
}
269+
});
270+
}
271+
235272
private MessageEmbed createSessionNotFoundErrorEmbed(User user) {
236273
return new EmbedBuilder().setAuthor(user.getName() + "'s result")
237274
.setColor(Colors.ERROR_COLOR)

application/src/main/java/org/togetherjava/tjbot/features/jshell/JShellEval.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,21 @@ public JShellApi getApi() {
4343
* @param user the user, if null, will create a single use session
4444
* @param code the code
4545
* @param showCode if the original code should be displayed
46+
* @param startupScript if the startup script should be used or not
4647
* @return the response
4748
* @throws RequestFailedException if a http error happens
4849
*/
49-
public MessageEmbed evaluateAndRespond(@Nullable User user, String code, boolean showCode)
50+
public MessageEmbed evaluateAndRespond(@Nullable User user, String code, boolean showCode, boolean startupScript)
5051
throws RequestFailedException {
5152
MessageEmbed rateLimitedMessage = wasRateLimited(user, Instant.now());
5253
if (rateLimitedMessage != null) {
5354
return rateLimitedMessage;
5455
}
5556
JShellResult result;
5657
if (user == null) {
57-
result = api.evalOnce(code);
58+
result = api.evalOnce(code, startupScript);
5859
} else {
59-
result = api.evalSession(code, user.getId());
60+
result = api.evalSession(code, user.getId(), startupScript);
6061
}
6162

6263
return renderer

application/src/main/java/org/togetherjava/tjbot/features/jshell/backend/JShellApi.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
public class JShellApi {
2323
public static final int SESSION_NOT_FOUND = 404;
24+
private static final String STARTUP_SCRIPT_ID = "CUSTOM_DEFAULT";
2425

2526
private final ObjectMapper objectMapper;
2627
private final HttpClient httpClient;
@@ -33,27 +34,31 @@ public JShellApi(ObjectMapper objectMapper, String baseUrl) {
3334
this.httpClient = HttpClient.newBuilder().build();
3435
}
3536

36-
public JShellResult evalOnce(String code) throws RequestFailedException {
37-
return send(baseUrl + "single-eval",
37+
public JShellResult evalOnce(String code, boolean startupScript) throws RequestFailedException {
38+
return send(baseUrl + "single-eval" + (startupScript ? "?startupScriptId=" + STARTUP_SCRIPT_ID : ""),
3839
HttpRequest.newBuilder().POST(BodyPublishers.ofString(code)),
3940
ResponseUtils.ofJson(JShellResult.class, objectMapper)).body();
4041
}
4142

42-
public JShellResult evalSession(String code, String sessionId) throws RequestFailedException {
43-
return send(baseUrl + "eval/" + sessionId,
43+
public JShellResult evalSession(String code, String sessionId, boolean startupScript) throws RequestFailedException {
44+
return send(baseUrl + "eval/" + sessionId + (startupScript ? "?startupScriptId=" + STARTUP_SCRIPT_ID : ""),
4445
HttpRequest.newBuilder().POST(BodyPublishers.ofString(code)),
4546
ResponseUtils.ofJson(JShellResult.class, objectMapper)).body();
4647
}
4748

48-
public SnippetList snippetsSession(String sessionId) throws RequestFailedException {
49-
return send(baseUrl + "snippets/" + sessionId, HttpRequest.newBuilder().GET(),
49+
public SnippetList snippetsSession(String sessionId, boolean includeStartupScript) throws RequestFailedException {
50+
return send(baseUrl + "snippets/" + sessionId + "?includeStartupScript=" + includeStartupScript, HttpRequest.newBuilder().GET(),
5051
ResponseUtils.ofJson(SnippetList.class, objectMapper)).body();
5152
}
5253

5354
public void closeSession(String sessionId) throws RequestFailedException {
5455
send(baseUrl + sessionId, HttpRequest.newBuilder().DELETE(), BodyHandlers.discarding())
5556
.body();
5657
}
58+
public String startupScript() throws RequestFailedException {
59+
return send(baseUrl + "startup_script/" + STARTUP_SCRIPT_ID, HttpRequest.newBuilder().GET(),
60+
BodyHandlers.ofString()).body();
61+
}
5762

5863
private <T> HttpResponse<T> send(String url, HttpRequest.Builder builder, BodyHandler<T> body)
5964
throws RequestFailedException {

0 commit comments

Comments
 (0)