@archznn/xavva 1.6.5 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -48
- package/package.json +1 -1
- package/src/commands/AuditCommand.ts +6 -10
- package/src/commands/BuildCommand.ts +3 -3
- package/src/commands/Command.ts +2 -2
- package/src/commands/CommandRegistry.ts +36 -0
- package/src/commands/DeployCommand.ts +181 -105
- package/src/commands/DocsCommand.ts +11 -11
- package/src/commands/DoctorCommand.ts +331 -68
- package/src/commands/HelpCommand.ts +2 -1
- package/src/commands/RunCommand.ts +108 -31
- package/src/commands/StartCommand.ts +4 -2
- package/src/index.ts +43 -115
- package/src/services/AuditService.ts +7 -7
- package/src/services/BrowserService.ts +41 -0
- package/src/services/BuildCacheService.ts +75 -0
- package/src/services/BuildService.ts +96 -88
- package/src/services/EndpointService.ts +17 -3
- package/src/services/ProjectService.ts +126 -0
- package/src/services/TomcatService.ts +125 -18
- package/src/services/WatcherService.ts +78 -0
- package/src/types/config.ts +30 -1
- package/src/utils/config.ts +22 -18
- package/src/utils/ui.ts +198 -102
|
@@ -49,12 +49,12 @@ export class DocsCommand implements Command {
|
|
|
49
49
|
|
|
50
50
|
private renderEndpoint(ep: ApiEndpoint, port: number) {
|
|
51
51
|
const methodColors: Record<string, string> = {
|
|
52
|
-
GET: "\x1b[32m",
|
|
53
|
-
POST: "\x1b[33m",
|
|
54
|
-
PUT: "\x1b[34m",
|
|
55
|
-
DELETE: "\x1b[31m",
|
|
56
|
-
PATCH: "\x1b[35m",
|
|
57
|
-
ALL: "\x1b[37m"
|
|
52
|
+
GET: "\x1b[32m",
|
|
53
|
+
POST: "\x1b[33m",
|
|
54
|
+
PUT: "\x1b[34m",
|
|
55
|
+
DELETE: "\x1b[31m",
|
|
56
|
+
PATCH: "\x1b[35m",
|
|
57
|
+
ALL: "\x1b[37m"
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
const color = methodColors[ep.method] || "\x1b[37m";
|
|
@@ -75,11 +75,11 @@ export class DocsCommand implements Command {
|
|
|
75
75
|
|
|
76
76
|
private renderParameter(param: ApiParam) {
|
|
77
77
|
const sourceColors: Record<string, string> = {
|
|
78
|
-
PATH: "\x1b[35m",
|
|
79
|
-
QUERY: "\x1b[36m",
|
|
80
|
-
BODY: "\x1b[33m",
|
|
81
|
-
HEADER: "\x1b[32m",
|
|
82
|
-
FORM: "\x1b[34m"
|
|
78
|
+
PATH: "\x1b[35m",
|
|
79
|
+
QUERY: "\x1b[36m",
|
|
80
|
+
BODY: "\x1b[33m",
|
|
81
|
+
HEADER: "\x1b[32m",
|
|
82
|
+
FORM: "\x1b[34m"
|
|
83
83
|
};
|
|
84
84
|
|
|
85
85
|
const color = sourceColors[param.source] || "\x1b[37m";
|
|
@@ -5,85 +5,348 @@ import fs from "fs";
|
|
|
5
5
|
import path from "path";
|
|
6
6
|
|
|
7
7
|
export class DoctorCommand implements Command {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
async execute(config: AppConfig, values: any = {}): Promise<void> {
|
|
9
|
+
Logger.section("Xavva Doctor - Ambiente");
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (tomcatOk) {
|
|
17
|
-
const binOk = fs.existsSync(path.join(config.tomcat.path, "bin", "catalina.bat"));
|
|
18
|
-
this.check("Tomcat Bin", binOk, binOk ? "OK" : "catalina.bat não encontrado");
|
|
19
|
-
}
|
|
11
|
+
this.check(
|
|
12
|
+
"JAVA_HOME",
|
|
13
|
+
!!process.env.JAVA_HOME,
|
|
14
|
+
process.env.JAVA_HOME || "Não definido",
|
|
15
|
+
);
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
const jvmInfo = this.checkJVM();
|
|
18
|
+
this.check(
|
|
19
|
+
"JVM Type",
|
|
20
|
+
jvmInfo.dcevm,
|
|
21
|
+
jvmInfo.name +
|
|
22
|
+
(jvmInfo.dcevm ? " (Advanced Hot Reload OK)" : " (Standard)"),
|
|
23
|
+
);
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
if (!jvmInfo.dcevm) {
|
|
26
|
+
Logger.log(
|
|
27
|
+
` ${Logger.C.yellow}💡 Dica: Sua JVM não suporta mudanças estruturais (novos métodos/campos).${Logger.C.reset}`,
|
|
28
|
+
);
|
|
29
|
+
if (values.fix) {
|
|
30
|
+
await this.installDCEVM();
|
|
31
|
+
} else {
|
|
32
|
+
Logger.log(
|
|
33
|
+
` ${Logger.C.cyan}Use 'xavva doctor --fix' para baixar uma JDK com DCEVM integrado.${Logger.C.reset}`,
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
26
37
|
|
|
27
|
-
|
|
28
|
-
|
|
38
|
+
const tomcatOk = fs.existsSync(config.tomcat.path);
|
|
39
|
+
this.check("Tomcat Path", tomcatOk, config.tomcat.path);
|
|
29
40
|
|
|
30
|
-
|
|
31
|
-
|
|
41
|
+
if (tomcatOk) {
|
|
42
|
+
const binOk = fs.existsSync(
|
|
43
|
+
path.join(config.tomcat.path, "bin", "catalina.bat"),
|
|
44
|
+
);
|
|
45
|
+
this.check(
|
|
46
|
+
"Tomcat Bin",
|
|
47
|
+
binOk,
|
|
48
|
+
binOk ? "OK" : "catalina.bat não encontrado",
|
|
49
|
+
);
|
|
50
|
+
}
|
|
32
51
|
|
|
33
|
-
|
|
34
|
-
|
|
52
|
+
const mvnOk = this.checkBinary("mvn");
|
|
53
|
+
this.check("Maven", mvnOk, mvnOk ? "Disponível" : "Não encontrado no PATH");
|
|
35
54
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const list = fs.readdirSync(dir, { withFileTypes: true });
|
|
43
|
-
for (const item of list) {
|
|
44
|
-
const res = path.resolve(dir, item.name);
|
|
45
|
-
if (item.isDirectory()) {
|
|
46
|
-
scan(res);
|
|
47
|
-
} else if (item.name.endsWith(".java")) {
|
|
48
|
-
const buffer = fs.readFileSync(res);
|
|
49
|
-
if (buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
|
|
50
|
-
filesWithBOM.push(res);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
scan(srcPath);
|
|
57
|
-
|
|
58
|
-
if (filesWithBOM.length > 0) {
|
|
59
|
-
this.check("Encoding BOM", false, `${filesWithBOM.length} arquivos com BOM (UTF-8 com assinatura)`);
|
|
60
|
-
if (fix) {
|
|
61
|
-
for (const file of filesWithBOM) {
|
|
62
|
-
const buffer = fs.readFileSync(file);
|
|
63
|
-
const cleanBuffer = buffer.subarray(3);
|
|
64
|
-
fs.writeFileSync(file, cleanBuffer);
|
|
65
|
-
console.log(` \x1b[32m✔\x1b[0m Corrigido: ${path.basename(file)}`);
|
|
66
|
-
}
|
|
67
|
-
Logger.success("BOM removido de todos os arquivos!");
|
|
68
|
-
} else {
|
|
69
|
-
Logger.warn("Use 'xavva doctor --fix' para remover o BOM automaticamente.");
|
|
70
|
-
}
|
|
71
|
-
} else {
|
|
72
|
-
this.check("Encoding BOM", true, "Nenhum arquivo com BOM detectado.");
|
|
73
|
-
}
|
|
74
|
-
}
|
|
55
|
+
const gradleOk = this.checkBinary("gradle") || this.checkBinary("gradlew");
|
|
56
|
+
this.check(
|
|
57
|
+
"Gradle",
|
|
58
|
+
gradleOk,
|
|
59
|
+
gradleOk ? "Disponível" : "Não encontrado no PATH",
|
|
60
|
+
);
|
|
75
61
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
62
|
+
const gitOk = this.checkBinary("git");
|
|
63
|
+
this.check("Git", gitOk, gitOk ? "Disponível" : "Não encontrado no PATH");
|
|
64
|
+
|
|
65
|
+
Logger.section("Xavva Doctor - Integridade de Arquivos");
|
|
66
|
+
await this.checkJarIntegrity(values.fix, config);
|
|
67
|
+
await this.checkBOM(values.fix);
|
|
68
|
+
|
|
69
|
+
console.log("");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private async checkJarIntegrity(fix: boolean, config: AppConfig) {
|
|
73
|
+
const searchPaths = [
|
|
74
|
+
path.join(process.cwd(), "target"),
|
|
75
|
+
path.join(process.cwd(), "build"),
|
|
76
|
+
path.join(config.tomcat.path, "webapps")
|
|
77
|
+
].filter(p => fs.existsSync(p));
|
|
78
|
+
|
|
79
|
+
const corruptedJars: string[] = [];
|
|
80
|
+
const zipEndSignature = Buffer.from([0x50, 0x4b, 0x05, 0x06]);
|
|
81
|
+
|
|
82
|
+
const scan = (dir: string) => {
|
|
83
|
+
try {
|
|
84
|
+
const list = fs.readdirSync(dir, { withFileTypes: true });
|
|
85
|
+
for (const item of list) {
|
|
86
|
+
const res = path.resolve(dir, item.name);
|
|
87
|
+
if (item.isDirectory()) {
|
|
88
|
+
if (item.name === "node_modules" || item.name === ".git") continue;
|
|
89
|
+
scan(res);
|
|
90
|
+
} else if (item.name.endsWith(".jar")) {
|
|
91
|
+
try {
|
|
92
|
+
const stats = fs.statSync(res);
|
|
93
|
+
if (stats.size < 22) {
|
|
94
|
+
corruptedJars.push(res);
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Lê os últimos 1024 bytes para encontrar a assinatura EOCD do ZIP
|
|
99
|
+
const readSize = Math.min(stats.size, 1024);
|
|
100
|
+
const buffer = Buffer.alloc(readSize);
|
|
101
|
+
const fd = fs.openSync(res, "r");
|
|
102
|
+
fs.readSync(fd, buffer, 0, readSize, stats.size - readSize);
|
|
103
|
+
fs.closeSync(fd);
|
|
104
|
+
|
|
105
|
+
if (!buffer.includes(zipEndSignature)) {
|
|
106
|
+
corruptedJars.push(res);
|
|
107
|
+
}
|
|
108
|
+
} catch (e) {
|
|
109
|
+
corruptedJars.push(res);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
} catch (e) {}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
for (const p of searchPaths) {
|
|
117
|
+
scan(p);
|
|
118
|
+
}
|
|
80
119
|
|
|
81
|
-
|
|
120
|
+
if (corruptedJars.length > 0) {
|
|
121
|
+
this.check(
|
|
122
|
+
"Integridade JAR",
|
|
123
|
+
false,
|
|
124
|
+
`${corruptedJars.length} arquivos corrompidos detectados.`,
|
|
125
|
+
);
|
|
126
|
+
if (fix) {
|
|
127
|
+
for (const file of corruptedJars) {
|
|
128
|
+
try {
|
|
129
|
+
fs.unlinkSync(file);
|
|
130
|
+
console.log(` \x1b[32m✔\x1b[0m Removido: ${path.basename(file)}`);
|
|
131
|
+
} catch (e) {}
|
|
132
|
+
}
|
|
133
|
+
Logger.success("JARs corrompidos removidos! Eles serão reconstruídos no próximo build.");
|
|
134
|
+
|
|
135
|
+
// Limpar cache do Tomcat
|
|
136
|
+
Logger.process("Limpando cache do Tomcat (work/temp)...");
|
|
137
|
+
const tomcatWork = path.join(config.tomcat.path, "work");
|
|
138
|
+
const tomcatTemp = path.join(config.tomcat.path, "temp");
|
|
139
|
+
[tomcatWork, tomcatTemp].forEach(p => {
|
|
140
|
+
try {
|
|
141
|
+
if (fs.existsSync(p)) {
|
|
142
|
+
fs.rmSync(p, { recursive: true, force: true });
|
|
143
|
+
fs.mkdirSync(p);
|
|
144
|
+
}
|
|
145
|
+
} catch (e) {}
|
|
146
|
+
});
|
|
147
|
+
Logger.success("Cache do Tomcat limpo com sucesso.");
|
|
148
|
+
} else {
|
|
149
|
+
Logger.warn(
|
|
150
|
+
"Use 'xavva doctor --fix' para remover os JARs corrompidos e limpar o cache.",
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
this.check("Integridade JAR", true, "Todos os arquivos JAR parecem íntegros.");
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
private async checkBOM(fix: boolean) {
|
|
159
|
+
const srcPath = path.join(process.cwd(), "src");
|
|
160
|
+
if (!fs.existsSync(srcPath)) return;
|
|
161
|
+
|
|
162
|
+
const filesWithBOM: string[] = [];
|
|
163
|
+
const scan = (dir: string) => {
|
|
164
|
+
const list = fs.readdirSync(dir, { withFileTypes: true });
|
|
165
|
+
for (const item of list) {
|
|
166
|
+
const res = path.resolve(dir, item.name);
|
|
167
|
+
if (item.isDirectory()) {
|
|
168
|
+
scan(res);
|
|
169
|
+
} else if (item.name.endsWith(".java")) {
|
|
170
|
+
const buffer = fs.readFileSync(res);
|
|
171
|
+
if (buffer[0] === 0xef && buffer[1] === 0xbb && buffer[2] === 0xbf) {
|
|
172
|
+
filesWithBOM.push(res);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
scan(srcPath);
|
|
179
|
+
|
|
180
|
+
if (filesWithBOM.length > 0) {
|
|
181
|
+
this.check(
|
|
182
|
+
"Encoding BOM",
|
|
183
|
+
false,
|
|
184
|
+
`${filesWithBOM.length} arquivos com BOM (UTF-8 com assinatura)`,
|
|
185
|
+
);
|
|
186
|
+
if (fix) {
|
|
187
|
+
for (const file of filesWithBOM) {
|
|
188
|
+
const buffer = fs.readFileSync(file);
|
|
189
|
+
const cleanBuffer = buffer.subarray(3);
|
|
190
|
+
fs.writeFileSync(file, cleanBuffer);
|
|
191
|
+
console.log(
|
|
192
|
+
` \x1b[32m✔\x1b[0m Corrigido: ${path.basename(file)}`,
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
Logger.success("BOM removido de todos os arquivos!");
|
|
196
|
+
} else {
|
|
197
|
+
Logger.warn(
|
|
198
|
+
"Use 'xavva doctor --fix' para remover o BOM automaticamente.",
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
} else {
|
|
202
|
+
this.check("Encoding BOM", true, "Nenhum arquivo com BOM detectado.");
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
private check(label: string, ok: boolean, detail: string) {
|
|
207
|
+
const icon = ok ? "\x1b[32m✔\x1b[0m" : "\x1b[31m✘\x1b[0m";
|
|
208
|
+
console.log(` ${icon} ${label.padEnd(15)} ${detail}`);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private checkBinary(name: string): boolean {
|
|
212
|
+
try {
|
|
213
|
+
const proc = Bun.spawnSync([
|
|
214
|
+
process.platform === "win32" ? "where" : "which",
|
|
215
|
+
name,
|
|
216
|
+
]);
|
|
217
|
+
return proc.exitCode === 0;
|
|
218
|
+
} catch {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
private checkJVM(): { name: string, dcevm: boolean } {
|
|
82
224
|
try {
|
|
83
|
-
|
|
84
|
-
|
|
225
|
+
// Tentar primeiro o binário do JAVA_HOME para evitar cache do Path
|
|
226
|
+
let javaBin = "java";
|
|
227
|
+
if (process.env.JAVA_HOME) {
|
|
228
|
+
const homeBin = path.join(process.env.JAVA_HOME, "bin", "java.exe");
|
|
229
|
+
if (fs.existsSync(homeBin)) javaBin = homeBin;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const proc = Bun.spawnSync([javaBin, "-version"]);
|
|
233
|
+
const output = (proc.stderr.toString() + proc.stdout.toString()).toLowerCase();
|
|
234
|
+
const isDcevm = output.includes("dcevm") ||
|
|
235
|
+
output.includes("jetbrains") ||
|
|
236
|
+
output.includes("trava") ||
|
|
237
|
+
output.includes("jbr");
|
|
238
|
+
|
|
239
|
+
const versionMatch = output.match(/version "(.*?)"/);
|
|
240
|
+
return {
|
|
241
|
+
name: versionMatch ? `Java ${versionMatch[1]}` : "Java Desconhecido",
|
|
242
|
+
dcevm: isDcevm
|
|
243
|
+
};
|
|
85
244
|
} catch {
|
|
86
|
-
return false;
|
|
245
|
+
return { name: "Não encontrada", dcevm: false };
|
|
87
246
|
}
|
|
88
247
|
}
|
|
248
|
+
|
|
249
|
+
private async installDCEVM() {
|
|
250
|
+
Logger.section("Instalação do JetBrains Runtime (JBR 21)");
|
|
251
|
+
Logger.log("Baixando JDK moderna com DCEVM nativo (JBR 21 SDK)...");
|
|
252
|
+
|
|
253
|
+
// URL para o JetBrains Runtime 21 SDK Windows x64
|
|
254
|
+
const url = "https://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-21.0.6-windows-x64-b895.97.tar.gz";
|
|
255
|
+
const installDir = path.join(require("os").homedir(), ".xavva", "jdk-dcevm");
|
|
256
|
+
|
|
257
|
+
// Limpar instalação anterior se existir
|
|
258
|
+
if (fs.existsSync(installDir)) {
|
|
259
|
+
try {
|
|
260
|
+
fs.rmSync(installDir, { recursive: true, force: true });
|
|
261
|
+
} catch (e) {}
|
|
262
|
+
}
|
|
263
|
+
fs.mkdirSync(installDir, { recursive: true });
|
|
264
|
+
|
|
265
|
+
try {
|
|
266
|
+
const response = await fetch(url);
|
|
267
|
+
if (!response.ok) throw new Error("Erro ao baixar JBR (verifique sua conexão)");
|
|
268
|
+
const buffer = await response.arrayBuffer();
|
|
269
|
+
const tarPath = path.join(installDir, "jbr.tar.gz");
|
|
270
|
+
fs.writeFileSync(tarPath, Buffer.from(buffer));
|
|
271
|
+
|
|
272
|
+
Logger.success("Download concluído. Extraindo binários...");
|
|
273
|
+
|
|
274
|
+
// Usar PowerShell para extrair .tar.gz (nativo no Windows 10/11)
|
|
275
|
+
const extractCmd = `tar -xzf $env:TAR_PATH -C $env:INSTALL_DIR`;
|
|
276
|
+
Bun.spawnSync(["powershell", "-command", extractCmd], {
|
|
277
|
+
env: {
|
|
278
|
+
...process.env,
|
|
279
|
+
TAR_PATH: tarPath,
|
|
280
|
+
INSTALL_DIR: installDir
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
fs.rmSync(tarPath);
|
|
285
|
+
|
|
286
|
+
// Busca recursiva para encontrar onde está o bin/java.exe
|
|
287
|
+
const findJdkRoot = (dir: string): string | null => {
|
|
288
|
+
if (fs.existsSync(path.join(dir, "bin", "java.exe"))) return dir;
|
|
289
|
+
const subdirs = fs.readdirSync(dir, { withFileTypes: true })
|
|
290
|
+
.filter(d => d.isDirectory())
|
|
291
|
+
.map(d => path.join(dir, d.name));
|
|
292
|
+
for (const subdir of subdirs) {
|
|
293
|
+
const found = findJdkRoot(subdir);
|
|
294
|
+
if (found) return found;
|
|
295
|
+
}
|
|
296
|
+
return null;
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
const jdkPath = findJdkRoot(installDir) || installDir;
|
|
300
|
+
const binPath = path.join(jdkPath, "bin");
|
|
301
|
+
|
|
302
|
+
Logger.process("Configurando variáveis de ambiente do SISTEMA...");
|
|
303
|
+
|
|
304
|
+
const setEnvCmd = `
|
|
305
|
+
$jdk = $env:JDK_PATH;
|
|
306
|
+
$bin = $env:BIN_PATH;
|
|
307
|
+
try {
|
|
308
|
+
[Environment]::SetEnvironmentVariable('JAVA_HOME', $jdk, 'Machine');
|
|
309
|
+
$pathVar = [Environment]::GetEnvironmentVariable('Path', 'Machine');
|
|
310
|
+
$paths = $pathVar -split ';' | Where-Object { $_ -ne '' };
|
|
311
|
+
$normalizedBin = $bin.TrimEnd('\\').ToLower();
|
|
312
|
+
|
|
313
|
+
$exists = $false;
|
|
314
|
+
foreach ($p in $paths) {
|
|
315
|
+
if ($p.TrimEnd('\\').ToLower() -eq $normalizedBin) { $exists = $true; break; }
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (-not $exists) {
|
|
319
|
+
$newPath = "$bin;" + $pathVar;
|
|
320
|
+
[Environment]::SetEnvironmentVariable('Path', $newPath, 'Machine');
|
|
321
|
+
}
|
|
322
|
+
Write-Output "OK";
|
|
323
|
+
} catch {
|
|
324
|
+
Write-Error $_.Exception.Message;
|
|
325
|
+
}
|
|
326
|
+
`.replace(/\n/g, ' ');
|
|
327
|
+
const result = Bun.spawnSync(["powershell", "-command", setEnvCmd], {
|
|
328
|
+
env: {
|
|
329
|
+
...process.env,
|
|
330
|
+
JDK_PATH: jdkPath,
|
|
331
|
+
BIN_PATH: binPath
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
const output = result.stdout.toString() + result.stderr.toString();
|
|
335
|
+
|
|
336
|
+
if (output.includes("ACCESS_DENIED")) {
|
|
337
|
+
Logger.error("Falha ao configurar variáveis do SISTEMA (Acesso Negado).");
|
|
338
|
+
Logger.warn("Dica: Execute o terminal como ADMINISTRADOR para permitir esta alteração.");
|
|
339
|
+
Logger.info("JAVA_HOME manual", jdkPath);
|
|
340
|
+
} else {
|
|
341
|
+
Logger.success(`DCEVM configurado no SISTEMA com sucesso!`);
|
|
342
|
+
Logger.info("JAVA_HOME", jdkPath);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
Logger.newline();
|
|
346
|
+
Logger.warn("IMPORTANTE: Reinicie seu terminal (ou o VS Code) para as mudanças surtirem efeito.");
|
|
347
|
+
} catch (e: any) {
|
|
348
|
+
|
|
349
|
+
Logger.error(`Falha na instalação: ${e.message}`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
89
352
|
}
|
|
@@ -24,7 +24,8 @@ Comandos principais:
|
|
|
24
24
|
|
|
25
25
|
Opções:
|
|
26
26
|
-w, --watch 👀 Hot Reload: monitora arquivos e redeploya automaticamente.
|
|
27
|
-
-d, --debug 🐞 Habilita debug Java (JPDA)
|
|
27
|
+
-d, --debug 🐞 Habilita debug Java (JPDA).
|
|
28
|
+
--dp [porta] 🔌 Porta do Debugger (padrão: 5005).
|
|
28
29
|
-c, --clean 🧹 Logs coloridos e simplificados (recomendado).
|
|
29
30
|
-q, --quiet 🤫 Mostra apenas mensagens essenciais nos logs.
|
|
30
31
|
-V, --verbose 📣 Mostra logs completos do Maven/Gradle.
|