@archznn/xavva 3.1.2 → 3.2.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 +221 -12
- package/package.json +3 -2
- package/src/commands/AuditCommand.ts +12 -10
- package/src/commands/BuildCommand.ts +9 -7
- package/src/commands/ChangelogCommand.ts +5 -5
- package/src/commands/CleanCommand.ts +242 -0
- package/src/commands/CompletionCommand.ts +7 -7
- package/src/commands/DbCommand.ts +43 -14
- package/src/commands/DeployCommand.ts +252 -229
- package/src/commands/DepsCommand.ts +174 -174
- package/src/commands/DockerCommand.ts +35 -4
- package/src/commands/DoctorCommand.ts +252 -239
- package/src/commands/EncodingCommand.ts +26 -19
- package/src/commands/HealthCommand.ts +7 -7
- package/src/commands/HelpCommand.ts +34 -14
- package/src/commands/HistoryCommand.ts +5 -5
- package/src/commands/HttpCommand.ts +27 -1
- package/src/commands/IdeCommand.ts +313 -0
- package/src/commands/InitCommand.ts +26 -25
- package/src/commands/LogsCommand.ts +8 -6
- package/src/commands/ProfilesCommand.ts +6 -6
- package/src/commands/RedoCommand.ts +2 -2
- package/src/commands/RunCommand.ts +64 -24
- package/src/commands/StartCommand.ts +9 -7
- package/src/commands/TestCommand.ts +25 -1
- package/src/commands/TomcatCommand.ts +232 -88
- package/src/config/versions.ts +111 -9
- package/src/di/container.ts +239 -105
- package/src/errors/ErrorHandler.ts +23 -19
- package/src/errors/errorMessages.ts +235 -0
- package/src/index.ts +20 -6
- package/src/logging/FileLogger.ts +235 -0
- package/src/logging/Logger.ts +545 -0
- package/src/logging/OperationLogger.ts +296 -0
- package/src/logging/ProgressLogger.ts +187 -0
- package/src/logging/TableLogger.ts +246 -0
- package/src/logging/colors.ts +167 -0
- package/src/logging/constants.ts +176 -0
- package/src/logging/formatters.ts +337 -0
- package/src/logging/index.ts +93 -0
- package/src/logging/types.ts +64 -0
- package/src/plugins/PluginManager.ts +325 -0
- package/src/plugins/types.ts +82 -0
- package/src/services/AuditService.ts +5 -3
- package/src/services/BuildService.ts +15 -17
- package/src/services/DashboardService.ts +14 -3
- package/src/services/DbService.ts +35 -34
- package/src/services/DependencyAnalyzerService.ts +18 -18
- package/src/services/DependencyCacheService.ts +303 -0
- package/src/services/DeployWatcher.ts +127 -23
- package/src/services/DockerService.ts +3 -3
- package/src/services/EmbeddedTomcatService.ts +13 -12
- package/src/services/FileWatcher.ts +15 -7
- package/src/services/HttpService.ts +5 -5
- package/src/services/LogAnalyzer.ts +26 -22
- package/src/services/PerformanceProfiler.ts +267 -0
- package/src/services/ProjectService.ts +3 -0
- package/src/services/TestService.ts +3 -3
- package/src/services/TomcatService.ts +46 -25
- package/src/services/tomcat/TomcatBackupManager.ts +330 -0
- package/src/services/tomcat/TomcatChecksumVerifier.ts +211 -0
- package/src/services/tomcat/TomcatCompatibilityChecker.ts +298 -0
- package/src/services/tomcat/TomcatDownloadCache.ts +250 -0
- package/src/services/tomcat/TomcatDownloadService.ts +335 -0
- package/src/services/tomcat/TomcatInstallerService.ts +474 -0
- package/src/services/tomcat/TomcatMirrorManager.ts +181 -0
- package/src/services/tomcat/index.ts +36 -0
- package/src/services/tomcat/types.ts +120 -0
- package/src/types/args.ts +68 -1
- package/src/types/configSchema.ts +174 -0
- package/src/utils/ChangelogGenerator.ts +11 -11
- package/src/utils/LoggerLevel.ts +44 -20
- package/src/utils/ProgressBar.ts +87 -46
- package/src/utils/argsParser.ts +260 -0
- package/src/utils/config.ts +340 -189
- package/src/utils/constants.ts +87 -9
- package/src/utils/dryRun.ts +192 -0
- package/src/utils/processManager.ts +23 -7
- package/src/utils/security.ts +293 -0
- package/src/utils/ui.ts +299 -428
|
@@ -4,14 +4,15 @@ import { join } from "path";
|
|
|
4
4
|
import { constants, existsSync } from "fs";
|
|
5
5
|
import type { Command } from "./Command";
|
|
6
6
|
import type { AppConfig, CLIArguments } from "../types/config";
|
|
7
|
-
import { Logger } from "../
|
|
7
|
+
import { Logger } from "../logging";
|
|
8
8
|
|
|
9
9
|
export class InitCommand implements Command {
|
|
10
|
+
private logger = Logger.getInstance();
|
|
11
|
+
|
|
10
12
|
async execute(_config: AppConfig, _args?: CLIArguments): Promise<void> {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Logger.newline();
|
|
13
|
+
this.logger.section("Project Setup Wizard");
|
|
14
|
+
this.logger.info("Vamos configurar seu projeto Xavva");
|
|
15
|
+
this.logger.newline();
|
|
15
16
|
|
|
16
17
|
// Detect build tool and available profiles
|
|
17
18
|
const buildTool = await this.detectBuildTool();
|
|
@@ -25,9 +26,9 @@ export class InitCommand implements Command {
|
|
|
25
26
|
});
|
|
26
27
|
|
|
27
28
|
// Profile selection with explanation
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
this.logger.newline();
|
|
30
|
+
console.log("The profile is used to activate Maven/Gradle build configurations");
|
|
31
|
+
console.log("(e.g., 'dev' for development, 'prod' for production)");
|
|
31
32
|
|
|
32
33
|
let profile: string;
|
|
33
34
|
|
|
@@ -76,8 +77,8 @@ export class InitCommand implements Command {
|
|
|
76
77
|
}) || 8080;
|
|
77
78
|
|
|
78
79
|
// Optional settings
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
this.logger.newline();
|
|
81
|
+
console.log("Advanced settings:");
|
|
81
82
|
|
|
82
83
|
const useEmbedded = await confirm({
|
|
83
84
|
message: "Use embedded Tomcat (auto-download)?",
|
|
@@ -150,8 +151,8 @@ export class InitCommand implements Command {
|
|
|
150
151
|
|
|
151
152
|
// Add environments if enabled
|
|
152
153
|
if (enableMultiEnv) {
|
|
153
|
-
|
|
154
|
-
|
|
154
|
+
this.logger.newline();
|
|
155
|
+
console.log("Environment Configuration:");
|
|
155
156
|
|
|
156
157
|
const environments: Record<string, unknown> = {};
|
|
157
158
|
|
|
@@ -213,20 +214,20 @@ export class InitCommand implements Command {
|
|
|
213
214
|
}
|
|
214
215
|
|
|
215
216
|
// Save file
|
|
216
|
-
|
|
217
|
-
|
|
217
|
+
this.logger.newline();
|
|
218
|
+
this.logger.step("Saving configuration...");
|
|
218
219
|
|
|
219
220
|
const configPath = join(process.cwd(), "xavva.json");
|
|
220
221
|
await writeFile(configPath, JSON.stringify(config, null, 2));
|
|
221
222
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
223
|
+
this.logger.success(`Configuration saved to ${configPath}`);
|
|
224
|
+
this.logger.newline();
|
|
225
|
+
this.logger.ready("Project configured!");
|
|
226
|
+
this.logger.info("Next steps:");
|
|
227
|
+
console.log(` │ xavva build - Compile project`);
|
|
228
|
+
console.log(` │ xavva deploy - Build + deploy`);
|
|
229
|
+
console.log(` │ xavva health - Check environment`);
|
|
230
|
+
this.logger.newline();
|
|
230
231
|
}
|
|
231
232
|
|
|
232
233
|
private async detectBuildTool(): Promise<"maven" | "gradle"> {
|
|
@@ -235,17 +236,17 @@ export class InitCommand implements Command {
|
|
|
235
236
|
existsSync(join(process.cwd(), "build.gradle.kts"));
|
|
236
237
|
|
|
237
238
|
if (hasPom && !hasGradle) {
|
|
238
|
-
|
|
239
|
+
this.logger.info("Detected: Maven project");
|
|
239
240
|
return "maven";
|
|
240
241
|
}
|
|
241
242
|
|
|
242
243
|
if (hasGradle && !hasPom) {
|
|
243
|
-
|
|
244
|
+
this.logger.info("Detected: Gradle project");
|
|
244
245
|
return "gradle";
|
|
245
246
|
}
|
|
246
247
|
|
|
247
248
|
if (hasPom && hasGradle) {
|
|
248
|
-
|
|
249
|
+
this.logger.warn("Both pom.xml and build.gradle found");
|
|
249
250
|
const choice = await select({
|
|
250
251
|
message: "Select build tool:",
|
|
251
252
|
choices: [
|
|
@@ -2,11 +2,13 @@ import type { Command } from "./Command";
|
|
|
2
2
|
import type { AppConfig, CLIArguments } from "../types/config";
|
|
3
3
|
import { DashboardService } from "../services/DashboardService";
|
|
4
4
|
import { LogAnalyzer } from "../services/LogAnalyzer";
|
|
5
|
-
import { Logger } from "../
|
|
5
|
+
import { Logger } from "../logging";
|
|
6
6
|
import path from "path";
|
|
7
7
|
import fs from "fs";
|
|
8
8
|
|
|
9
9
|
export class LogsCommand implements Command {
|
|
10
|
+
private logger = Logger.getInstance();
|
|
11
|
+
|
|
10
12
|
constructor(private dashboard?: DashboardService, private logAnalyzer?: LogAnalyzer) {}
|
|
11
13
|
|
|
12
14
|
async execute(config: AppConfig, args?: CLIArguments): Promise<void> {
|
|
@@ -14,18 +16,18 @@ export class LogsCommand implements Command {
|
|
|
14
16
|
|
|
15
17
|
if (!fs.existsSync(logPath)) {
|
|
16
18
|
const errorMsg = `Arquivo de log não encontrado: ${logPath}`;
|
|
17
|
-
if (this.dashboard) this.dashboard.log(
|
|
18
|
-
else
|
|
19
|
+
if (this.dashboard) this.dashboard.log(errorMsg);
|
|
20
|
+
else this.logger.error(errorMsg);
|
|
19
21
|
return;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
const analyzer = this.logAnalyzer || new LogAnalyzer(config.project);
|
|
23
25
|
const dashboard = this.dashboard || new DashboardService(config);
|
|
24
26
|
|
|
25
|
-
dashboard.setStatus("LOGGING",
|
|
27
|
+
dashboard.setStatus("LOGGING", "running");
|
|
26
28
|
|
|
27
29
|
if (args?.grep) {
|
|
28
|
-
dashboard.log(
|
|
30
|
+
dashboard.log(`Filter: ${args.grep}`);
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
const stats = fs.statSync(logPath);
|
|
@@ -60,7 +62,7 @@ export class LogsCommand implements Command {
|
|
|
60
62
|
currentSize = newStats.size;
|
|
61
63
|
} else if (newStats.size < currentSize) {
|
|
62
64
|
currentSize = newStats.size;
|
|
63
|
-
dashboard.log(
|
|
65
|
+
dashboard.log("Arquivo de log foi resetado/rotacionado.");
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
68
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Command } from "./Command";
|
|
2
2
|
import type { AppConfig, CLIArguments } from "../types/config";
|
|
3
3
|
import { ProjectService } from "../services/ProjectService";
|
|
4
|
-
import { Logger } from "../utils/ui";
|
|
4
|
+
import { Logger, C } from "../utils/ui";
|
|
5
5
|
|
|
6
6
|
export class ProfilesCommand implements Command {
|
|
7
7
|
constructor(private projectService: ProjectService) {}
|
|
@@ -15,18 +15,18 @@ export class ProfilesCommand implements Command {
|
|
|
15
15
|
|
|
16
16
|
if (profiles.length === 0) {
|
|
17
17
|
Logger.warn("Nenhum perfil específico encontrado no arquivo de configuração.");
|
|
18
|
-
Logger.log(` ${
|
|
18
|
+
Logger.log(` ${C.dim}Dica: Perfis Maven são definidos em <profiles> no pom.xml.${C.reset}`);
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
Logger.log(`
|
|
23
|
-
${
|
|
23
|
+
${C.primary}Perfis detectados:${C.reset}`);
|
|
24
24
|
profiles.forEach(p => {
|
|
25
|
-
const active = config.project.profile === p ? ` ${
|
|
26
|
-
Logger.log(` ${
|
|
25
|
+
const active = config.project.profile === p ? ` ${C.success}(Ativo)${C.reset}` : "";
|
|
26
|
+
Logger.log(` ${C.bold}➜${C.reset} ${p}${active}`);
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
Logger.newline();
|
|
30
|
-
Logger.log(` ${
|
|
30
|
+
Logger.log(` ${C.dim}Para usar um perfil: xavva build -P nome-do-perfil${C.reset}`);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Command } from "./Command";
|
|
2
2
|
import type { AppConfig, CLIArguments } from "../types/config";
|
|
3
3
|
import { HistoryService } from "../services/HistoryService";
|
|
4
|
-
import { Logger } from "../utils/ui";
|
|
4
|
+
import { Logger, C } from "../utils/ui";
|
|
5
5
|
import { ProcessManager } from "../utils/processManager";
|
|
6
6
|
|
|
7
7
|
export class RedoCommand implements Command {
|
|
@@ -17,7 +17,7 @@ export class RedoCommand implements Command {
|
|
|
17
17
|
|
|
18
18
|
const args = lastEntry.args.length > 0 ? lastEntry.args.join(" ") : "";
|
|
19
19
|
Logger.banner("redo");
|
|
20
|
-
Logger.info(`Repetindo: ${
|
|
20
|
+
Logger.info(`Repetindo: ${C.white}xavva ${lastEntry.command}${C.reset} ${C.gray}${args}${C.reset}`);
|
|
21
21
|
Logger.newline();
|
|
22
22
|
|
|
23
23
|
// Re-executar o comando
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import type { Command } from "./Command";
|
|
2
2
|
import type { AppConfig, CLIArguments } from "../types/config";
|
|
3
|
-
import { Logger } from "../
|
|
3
|
+
import { Logger } from "../logging";
|
|
4
4
|
import path from "path";
|
|
5
5
|
import fs from "fs";
|
|
6
6
|
import { glob } from "glob";
|
|
7
7
|
import readline from "readline";
|
|
8
|
+
import { BuildService } from "../services/BuildService";
|
|
8
9
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
getJavaPath,
|
|
11
|
+
getMavenCommand,
|
|
12
|
+
getGradleCommand,
|
|
13
|
+
getClasspathSeparator,
|
|
14
|
+
normalizeClasspathPath,
|
|
15
|
+
isWindows,
|
|
15
16
|
} from "../utils/platform";
|
|
16
17
|
|
|
17
18
|
export class RunCommand implements Command {
|
|
19
|
+
private logger = Logger.getInstance();
|
|
20
|
+
|
|
21
|
+
constructor(private buildService?: BuildService) {}
|
|
22
|
+
|
|
18
23
|
async execute(config: AppConfig, args?: CLIArguments): Promise<void> {
|
|
19
24
|
const isDebug = args?.debug !== false; // Default to true if not specified, matching previous behavior
|
|
20
25
|
let className = config.project.grep;
|
|
@@ -22,7 +27,7 @@ export class RunCommand implements Command {
|
|
|
22
27
|
if (!className) {
|
|
23
28
|
className = await this.loadFromHistory();
|
|
24
29
|
if (!className) {
|
|
25
|
-
|
|
30
|
+
this.logger.error(`Uso: xavva ${isDebug ? "debug" : "run"} NomeDaClasse`);
|
|
26
31
|
return;
|
|
27
32
|
}
|
|
28
33
|
}
|
|
@@ -36,11 +41,14 @@ export class RunCommand implements Command {
|
|
|
36
41
|
this.saveToHistory(className);
|
|
37
42
|
|
|
38
43
|
if (isDebug) {
|
|
39
|
-
|
|
44
|
+
this.logger.section(`Interactive Debug: ${className}`);
|
|
40
45
|
} else {
|
|
41
|
-
|
|
46
|
+
this.logger.section(`Running: ${className}`);
|
|
42
47
|
}
|
|
43
48
|
|
|
49
|
+
// Verifica se as classes estão compiladas, se não, compila
|
|
50
|
+
await this.ensureCompiled(config);
|
|
51
|
+
|
|
44
52
|
const { localCp, dependencyCp } = await this.getClasspath(config);
|
|
45
53
|
const pathingJar = await this.createPathingJar(dependencyCp);
|
|
46
54
|
|
|
@@ -62,11 +70,11 @@ export class RunCommand implements Command {
|
|
|
62
70
|
javaArgs.push(className);
|
|
63
71
|
|
|
64
72
|
if (isDebug) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
73
|
+
this.logger.warn(`🚀 Aguardando debugger na porta 5005 para ${className}...`);
|
|
74
|
+
console.log(`Dica: No VS Code ou IntelliJ, use 'Attach to Remote JVM' na porta 5005.`);
|
|
75
|
+
this.logger.newline();
|
|
68
76
|
} else {
|
|
69
|
-
|
|
77
|
+
this.logger.warn(`🚀 Executando ${className}...`);
|
|
70
78
|
}
|
|
71
79
|
|
|
72
80
|
const bin = getJavaPath();
|
|
@@ -82,7 +90,7 @@ export class RunCommand implements Command {
|
|
|
82
90
|
});
|
|
83
91
|
|
|
84
92
|
await proc.exited;
|
|
85
|
-
|
|
93
|
+
this.logger.info(`Sessão de ${isDebug ? "debug" : "execução"} encerrada.`);
|
|
86
94
|
}
|
|
87
95
|
|
|
88
96
|
private async discoverClass(simpleName: string): Promise<string | null> {
|
|
@@ -124,7 +132,7 @@ export class RunCommand implements Command {
|
|
|
124
132
|
}
|
|
125
133
|
}
|
|
126
134
|
if (files.length === 0) {
|
|
127
|
-
|
|
135
|
+
this.logger.error(`Classe "${simpleName}" não encontrada nos diretórios de código (src/main/java, src/test/java, src).`);
|
|
128
136
|
return null;
|
|
129
137
|
}
|
|
130
138
|
}
|
|
@@ -143,9 +151,9 @@ export class RunCommand implements Command {
|
|
|
143
151
|
return uniqueClasses[0];
|
|
144
152
|
}
|
|
145
153
|
|
|
146
|
-
|
|
154
|
+
this.logger.warn(`Múltiplas classes encontradas para "${simpleName}":`);
|
|
147
155
|
uniqueClasses.forEach((c, i) => {
|
|
148
|
-
|
|
156
|
+
console.log(` [${i + 1}] ${c}`);
|
|
149
157
|
});
|
|
150
158
|
|
|
151
159
|
const rl = readline.createInterface({
|
|
@@ -160,7 +168,7 @@ export class RunCommand implements Command {
|
|
|
160
168
|
if (!isNaN(idx) && uniqueClasses[idx]) {
|
|
161
169
|
resolve(uniqueClasses[idx]);
|
|
162
170
|
} else {
|
|
163
|
-
|
|
171
|
+
this.logger.error("Operação cancelada.");
|
|
164
172
|
resolve(null);
|
|
165
173
|
}
|
|
166
174
|
});
|
|
@@ -177,9 +185,9 @@ export class RunCommand implements Command {
|
|
|
177
185
|
const history: string[] = JSON.parse(fs.readFileSync(historyFile, "utf8"));
|
|
178
186
|
if (history.length === 0) return null;
|
|
179
187
|
|
|
180
|
-
|
|
188
|
+
this.logger.warn(`Classes executadas recentemente:`);
|
|
181
189
|
history.slice(0, 5).forEach((c, i) => {
|
|
182
|
-
|
|
190
|
+
console.log(` [${i + 1}] ${c}${i === 0 ? " (Enter)" : ""}`);
|
|
183
191
|
});
|
|
184
192
|
|
|
185
193
|
const rl = readline.createInterface({
|
|
@@ -296,6 +304,38 @@ export class RunCommand implements Command {
|
|
|
296
304
|
return jarPath;
|
|
297
305
|
}
|
|
298
306
|
|
|
307
|
+
/**
|
|
308
|
+
* Verifica se as classes compiladas existem, se não, executa o build
|
|
309
|
+
* Usa build incremental (apenas compile, sem clean) para evitar conflitos
|
|
310
|
+
* com o Tomcat que pode estar rodando e usando arquivos em target/
|
|
311
|
+
*/
|
|
312
|
+
private async ensureCompiled(config: AppConfig): Promise<void> {
|
|
313
|
+
// Usa build incremental (sem clean) para evitar problemas quando Tomcat está rodando
|
|
314
|
+
if (this.buildService) {
|
|
315
|
+
this.logger.step("Compilando projeto...");
|
|
316
|
+
await this.buildService.runBuild(true); // true = incremental, sem clean
|
|
317
|
+
} else {
|
|
318
|
+
// Fallback: executa build via comando direto (apenas compile, sem clean)
|
|
319
|
+
this.logger.step("Compilando projeto (fallback)...");
|
|
320
|
+
const buildCmd = config.project.buildTool === "maven"
|
|
321
|
+
? [getMavenCommand(), "compile", "-DskipTests"]
|
|
322
|
+
: [getGradleCommand(), "classes", "-x", "test"];
|
|
323
|
+
|
|
324
|
+
const spinner = this.logger.spinner("Compilando");
|
|
325
|
+
const proc = Bun.spawn(buildCmd, {
|
|
326
|
+
stdout: "pipe",
|
|
327
|
+
stderr: "pipe",
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
await proc.exited;
|
|
331
|
+
spinner.stop();
|
|
332
|
+
|
|
333
|
+
if (proc.exitCode !== 0) {
|
|
334
|
+
throw new Error("Falha ao compilar o projeto. Verifique os erros acima.");
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
299
339
|
private async getClasspath(config: AppConfig): Promise<{ localCp: string, dependencyCp: string }> {
|
|
300
340
|
const xavvaDir = path.join(process.cwd(), ".xavva");
|
|
301
341
|
const cpFile = path.join(xavvaDir, "classpath.txt");
|
|
@@ -303,7 +343,7 @@ export class RunCommand implements Command {
|
|
|
303
343
|
if (!fs.existsSync(xavvaDir)) fs.mkdirSync(xavvaDir);
|
|
304
344
|
|
|
305
345
|
if (!fs.existsSync(cpFile)) {
|
|
306
|
-
const
|
|
346
|
+
const spinner = this.logger.spinner("Generating project classpath");
|
|
307
347
|
try {
|
|
308
348
|
if (config.project.buildTool === "maven") {
|
|
309
349
|
Bun.spawnSync([getMavenCommand(), "dependency:build-classpath", `-Dmdep.outputFile=${cpFile}`]);
|
|
@@ -337,9 +377,9 @@ export class RunCommand implements Command {
|
|
|
337
377
|
fs.writeFileSync(cpFile, ".");
|
|
338
378
|
}
|
|
339
379
|
} catch (e) {
|
|
340
|
-
|
|
380
|
+
this.logger.error(`Falha ao gerar classpath: ${e}`);
|
|
341
381
|
}
|
|
342
|
-
|
|
382
|
+
spinner.stop();
|
|
343
383
|
}
|
|
344
384
|
|
|
345
385
|
let dependencyCp = fs.existsSync(cpFile) ? fs.readFileSync(cpFile, "utf8").trim() : "";
|
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
import type { Command } from "./Command";
|
|
2
2
|
import type { AppConfig } from "../types/config";
|
|
3
3
|
import { TomcatService } from "../services/TomcatService";
|
|
4
|
-
import { Logger } from "../
|
|
4
|
+
import { Logger } from "../logging";
|
|
5
5
|
import { ProcessManager } from "../utils/processManager";
|
|
6
6
|
|
|
7
7
|
export class StartCommand implements Command {
|
|
8
|
+
private logger = Logger.getInstance();
|
|
9
|
+
|
|
8
10
|
constructor(private tomcat: TomcatService) {}
|
|
9
11
|
|
|
10
12
|
async execute(config: AppConfig): Promise<void> {
|
|
11
13
|
const tomcat = this.tomcat;
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (config.project.debug)
|
|
15
|
+
this.logger.section("Start Only");
|
|
16
|
+
this.logger.config("Port", config.tomcat.port);
|
|
17
|
+
if (config.project.debug) this.logger.config("Debugger", "Active (5005)");
|
|
16
18
|
|
|
17
19
|
try {
|
|
18
|
-
|
|
20
|
+
this.logger.step("Checking ports");
|
|
19
21
|
await tomcat.killConflict();
|
|
20
|
-
|
|
22
|
+
this.logger.step("Starting Tomcat");
|
|
21
23
|
tomcat.start(config, false);
|
|
22
24
|
|
|
23
25
|
await new Promise(() => {});
|
|
24
26
|
} catch (error) {
|
|
25
27
|
const message = error instanceof Error ? error.message : String(error);
|
|
26
|
-
|
|
28
|
+
this.logger.error(message);
|
|
27
29
|
await ProcessManager.getInstance().shutdown(1);
|
|
28
30
|
}
|
|
29
31
|
}
|
|
@@ -6,14 +6,38 @@
|
|
|
6
6
|
import type { Command } from "./Command";
|
|
7
7
|
import type { AppConfig, CLIArguments } from "../types/config";
|
|
8
8
|
import { TestService } from "../services/TestService";
|
|
9
|
-
import { Logger } from "../utils/ui";
|
|
9
|
+
import { Logger, C } from "../utils/ui";
|
|
10
10
|
import { ProcessManager } from "../utils/processManager";
|
|
11
11
|
|
|
12
12
|
export class TestCommand implements Command {
|
|
13
13
|
private service: TestService | null = null;
|
|
14
14
|
|
|
15
|
+
private showHelp(): void {
|
|
16
|
+
Logger.section("Test Runner");
|
|
17
|
+
Logger.log(`${C.bold}Usage:${C.reset} xavva test [options] [filter]`);
|
|
18
|
+
Logger.newline();
|
|
19
|
+
Logger.log(`${C.bold}Options:${C.reset}`);
|
|
20
|
+
Logger.log(` -w, --watch Watch mode (run on file change)`);
|
|
21
|
+
Logger.log(` --coverage Generate JaCoCo coverage report`);
|
|
22
|
+
Logger.log(` --fail-fast Stop on first failure`);
|
|
23
|
+
Logger.log(` --parallel Run tests in parallel`);
|
|
24
|
+
Logger.log(` -V, --verbose Verbose output`);
|
|
25
|
+
Logger.newline();
|
|
26
|
+
Logger.log(`${C.bold}Examples:${C.reset}`);
|
|
27
|
+
Logger.log(` xavva test # Run all tests`);
|
|
28
|
+
Logger.log(` xavva test --watch # Watch mode`);
|
|
29
|
+
Logger.log(` xavva test --coverage # With coverage`);
|
|
30
|
+
Logger.log(` xavva test UserServiceTest # Run specific test`);
|
|
31
|
+
}
|
|
32
|
+
|
|
15
33
|
async execute(config: AppConfig, args?: CLIArguments, positionals?: string[]): Promise<void> {
|
|
16
34
|
const processManager = ProcessManager.getInstance();
|
|
35
|
+
|
|
36
|
+
// Mostra help se solicitado
|
|
37
|
+
if (args?.help) {
|
|
38
|
+
this.showHelp();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
17
41
|
|
|
18
42
|
// Extrai filtros de teste dos positionals (após o comando "test")
|
|
19
43
|
const filter = positionals?.slice(1).join(" ") || undefined;
|