-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathQuarkusEdit.java
executable file
·214 lines (182 loc) · 8.68 KB
/
QuarkusEdit.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS info.picocli:picocli:4.6.3
//DEPS dev.jbang:jbang-cli:RELEASE
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Parameters;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
import dev.jbang.cli.Edit;
import dev.jbang.cli.ExitException;
import dev.jbang.net.*;
import dev.jbang.util.CommandBuffer;
import dev.jbang.util.Util;
import dev.jbang.util.Util.Shell;
import static dev.jbang.util.Util.infoMsg;
import static dev.jbang.util.Util.pathToString;
import static dev.jbang.util.Util.verboseMsg;
/**
* most of this code copied from jbang. intent is to make this available in a reusable utility API
*/
@Command(name = "QuarkusEdit", mixinStandardHelpOptions = true, version = "QuarkusEdit 0.1",
description = "Experimental Quarkus Edit that download and setup vscode IDE for you with proper Quarkus/Java features installed")
class QuarkusEdit implements Callable<Integer> {
@CommandLine.Option(names = {
"--editor", "-e" }, arity = "0..1")
public Optional<String> editor;
@CommandLine.Parameters(index = "0", arity = "0..N")
List<Path> additionalFiles = new ArrayList<>();
private boolean openEditor(String projectPathString, List<String> additionalFiles) throws IOException {
if (!editor.isPresent() || editor.get().isEmpty()) {
editor = askEditor();
if (!editor.isPresent()) {
return false;
}
} else {
showStartingMsg(editor.get(), false);
}
if ("gitpod".equals(editor.get()) && System.getenv("GITPOD_WORKSPACE_URL") != null) {
infoMsg("Open this url to edit the project in your gitpod session:\n\n"
+ System.getenv("GITPOD_WORKSPACE_URL") + "#" + projectPathString + "\n\n");
} else {
List<String> optionList = new ArrayList<>();
optionList.add(editor.get());
optionList.add(projectPathString);
optionList.addAll(additionalFiles);
String[] cmd;
if (Util.getShell() == Shell.bash) {
final String editorCommand = CommandBuffer.of(optionList).asCommandLine(Shell.bash);
cmd = new String[] { "sh", "-c", editorCommand };
} else {
final String editorCommand = CommandBuffer.of(optionList).asCommandLine(Shell.cmd);
cmd = new String[] { "cmd", "/c", editorCommand };
}
verboseMsg("Running `" + String.join(" ", cmd) + "`");
new ProcessBuilder(cmd).start();
}
return true;
}
static String[] knownEditors = { "codium", "code", "cursor", "eclipse", "idea", "netbeans" };
private static List<String> findEditorsOnPath() {
return Arrays.stream(knownEditors).filter(e -> Util.searchPath(e) != null).collect(Collectors.toList());
}
private static Optional<String> askEditor() throws IOException {
Path editorBinPath = EditorManager.getVSCodiumBinPath();
Path dataPath = EditorManager.getVSCodiumDataPath();
if (!Files.exists(editorBinPath)) {
String question = "You requested to open default editor but no default editor configured.\n" +
"\n" +
"Quarkus can download and configure a visual studio code (VSCodium) with Java support to use\n" +
"See https://vscodium.com for details\n" +
"\n" +
"Do you want to";
List<String> options = new ArrayList<>();
options.add("Download and run VSCodium");
List<String> pathEditors = findEditorsOnPath();
for (String ed : pathEditors) {
options.add("Use '" + ed + "'");
}
int result = Util.askInput(question, 30, 0, options.toArray(new String[] {}));
if (result == 0) {
return Optional.empty();
} else if (result == 1) {
setupEditor(editorBinPath, dataPath);
} else if (result > 1) {
String ed = pathEditors.get(result - 2);
showStartingMsg(ed, true);
return Optional.of(ed);
} else {
throw new ExitException(22,
"No default editor configured and no other option accepted.\n Please try again making a correct choice or use an explicit editor, i.e. `jbang edit --open=eclipse xyz.java`");
}
}
return Optional.of(editorBinPath.toAbsolutePath().toString());
}
private static void showStartingMsg(String ed, boolean showConfig) {
String msg = "Starting '" + ed + "'.";
// if (showConfig) {
// msg += "If you want to make this the default, run 'jbang config set edit.open " + ed + "'";
// }
Util.infoMsg(msg);
}
// copied from jbang until its available via proper api/dependency
private static void setupEditor(Path editorBinPath, Path dataPath) throws IOException {
EditorManager.downloadAndInstallEditor();
if (!Files.exists(dataPath)) {
verboseMsg("Making portable data path " + dataPath.toString());
Files.createDirectories(dataPath);
}
Path settingsjson = dataPath.resolve("user-data/User/settings.json");
if (!Files.exists(settingsjson)) {
verboseMsg("Setting up some good default settings at " + settingsjson);
Files.createDirectories(settingsjson.getParent());
String vscodeSettings = "{\n" +
// better than breadcrumbs
" \"editor.experimental.stickyScroll.enabled\": true,\n" +
// autosave because vscode has it default and it just makes things work smoother
" \"files.autoSave\": \"onFocusChange\",\n" +
// use modern java
" \"java.codeGeneration.hashCodeEquals.useJava7Objects\": true,\n" +
// instead of `out.println(x);` you get
// `out.println(argClosestWithMatchingType)`
" \"java.completion.guessMethodArguments\": true,\n" +
// when editing html/xml editing tags updates the matching pair
" \"editor.linkedEditing\": true,\n" +
// looks cooler - doesn't hurt
" \"editor.cursorBlinking\": \"phase\",\n" +
// making easy to zoom for presentations
" \"editor.mouseWheelZoom\": true\n" +
"}";
Util.writeString(settingsjson, vscodeSettings);
}
verboseMsg("Installing Java + Quarkus extensions...");
ProcessBuilder pb = new ProcessBuilder(editorBinPath.toAbsolutePath().toString(),
"--install-extension", "redhat.java",
"--install-extension", "vscjava.vscode-java-debug",
"--install-extension", "vscjava.vscode-java-test",
"--install-extension", "vscjava.vscode-java-dependency",
"--install-extension", "jbangdev.jbang-vscode",
"--install-extension", "redhat.vscode-quarkus");
pb.inheritIO();
Process process = pb.start();
try {
int exit = process.waitFor();
if (exit > 0) {
throw new ExitException(22,
"Could not install and setup extensions into VSCodium. Aborting.");
}
} catch (InterruptedException e) {
Util.errorMsg("Problems installing VSCodium extensions", e);
}
}
public static void main(String... args) {
int exitCode = new CommandLine(new QuarkusEdit()).execute(args);
System.exit(exitCode);
}
@Override
public Integer call() throws Exception { // your business logic goes here...
Path path = null;
Path location = null;
if(additionalFiles.size() > 0) {
location = additionalFiles.get(0);
}
if (location == null) {
path = Edit.locateProjectDir(Paths.get("."));
} else {
path = Edit.locateProjectDir(location);
}
if (path != null && ((location != null) && !path.equals(location))) {
additionalFiles.add(0, location);
}
openEditor(pathToString(path), additionalFiles.stream().map(p -> pathToString(p)).collect(Collectors.toList()));
return 0;
}
}