@archznn/xavva 2.0.2 → 2.1.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 +165 -39
- package/package.json +1 -1
- package/src/commands/AuditCommand.ts +3 -2
- package/src/commands/BuildCommand.ts +5 -3
- package/src/commands/CommandRegistry.ts +9 -5
- package/src/commands/DeployCommand.ts +4 -2
- package/src/commands/DepsCommand.ts +123 -0
- package/src/commands/DoctorCommand.ts +5 -4
- package/src/commands/HelpCommand.ts +94 -39
- package/src/commands/ProfilesCommand.ts +32 -0
- package/src/commands/RunCommand.ts +13 -12
- package/src/commands/StartCommand.ts +5 -3
- package/src/index.ts +17 -5
- package/src/services/AuditService.ts +30 -4
- package/src/services/BuildCacheService.ts +2 -1
- package/src/services/BuildService.ts +8 -1
- package/src/services/DashboardService.ts +31 -12
- package/src/services/DependencyAnalyzerService.ts +538 -0
- package/src/services/ProjectService.ts +39 -1
- package/src/services/TomcatService.ts +11 -11
- package/src/services/WatcherService.ts +3 -2
- package/src/types/config.ts +4 -0
- package/src/utils/config.ts +7 -2
- package/src/utils/constants.ts +54 -0
- package/src/utils/processManager.ts +145 -0
- package/src/utils/ui.ts +7 -4
package/README.md
CHANGED
|
@@ -1,78 +1,204 @@
|
|
|
1
|
-
# XAVVA 🚀
|
|
1
|
+
# XAVVA CLI 🚀
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Ultra-fast development toolkit for Java Enterprise (Tomcat) on Windows
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://github.com/leorsousa05/Xavva)
|
|
6
|
+
[](LICENSE)
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
Xavva is a high-performance CLI built with **Bun** that transforms the Java/Tomcat development experience. It brings modern development workflows (like Node.js/Vite) to the Java Enterprise ecosystem with hot-reload, smart logging, and automated deployment.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
---
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
## ✨ Features
|
|
12
13
|
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
19
|
-
- **Auto-Healing
|
|
14
|
+
- ⚡ **Hot Reload** — Incremental compilation and class injection without server restart
|
|
15
|
+
- 📊 **Interactive Dashboard** — Real-time TUI with system metrics and shortcuts
|
|
16
|
+
- 🧠 **Smart Log Analyzer** — Stack trace folding and root cause highlighting
|
|
17
|
+
- 🔒 **Security Audit** — Automated vulnerability scanning via OSV.dev
|
|
18
|
+
- 📦 **Dependency Analysis** — Detect conflicts and outdated dependencies
|
|
19
|
+
- 🎯 **Maven & Gradle** — Native support for both build tools
|
|
20
|
+
- 🔧 **Auto-Healing** — Automatic diagnosis and repair of common issues
|
|
20
21
|
|
|
21
22
|
---
|
|
22
23
|
|
|
23
|
-
##
|
|
24
|
+
## 📦 Installation
|
|
24
25
|
|
|
25
|
-
### Instalação
|
|
26
26
|
```powershell
|
|
27
|
-
#
|
|
27
|
+
# Via NPM
|
|
28
28
|
npm install -g @archznn/xavva
|
|
29
29
|
|
|
30
|
-
#
|
|
30
|
+
# Or run directly with Bun
|
|
31
|
+
bunx @archznn/xavva dev
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 🚀 Quick Start
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Start development mode with dashboard
|
|
31
40
|
xavva dev --tui
|
|
41
|
+
|
|
42
|
+
# Deploy to Tomcat
|
|
43
|
+
xavva deploy
|
|
44
|
+
|
|
45
|
+
# Analyze dependencies for issues
|
|
46
|
+
xavva deps
|
|
47
|
+
|
|
48
|
+
# Check for security vulnerabilities
|
|
49
|
+
xavva audit
|
|
32
50
|
```
|
|
33
51
|
|
|
34
52
|
---
|
|
35
53
|
|
|
36
|
-
## 📖
|
|
54
|
+
## 📖 Commands
|
|
55
|
+
|
|
56
|
+
### Core Development
|
|
57
|
+
|
|
58
|
+
| Command | Description |
|
|
59
|
+
|---------|-------------|
|
|
60
|
+
| `xavva dev` | Full development mode (build + deploy + watch + debug) |
|
|
61
|
+
| `xavva deploy` | Build and deploy application to Tomcat |
|
|
62
|
+
| `xavva build` | Compile project only |
|
|
63
|
+
| `xavva start` | Start Tomcat server only |
|
|
64
|
+
|
|
65
|
+
### Code Execution
|
|
66
|
+
|
|
67
|
+
| Command | Description |
|
|
68
|
+
|---------|-------------|
|
|
69
|
+
| `xavva run <class>` | Execute a Java class with automatic classpath |
|
|
70
|
+
| `xavva debug <class>` | Debug a Java class (port 5005) |
|
|
71
|
+
|
|
72
|
+
### Analysis & Monitoring
|
|
73
|
+
|
|
74
|
+
| Command | Description |
|
|
75
|
+
|---------|-------------|
|
|
76
|
+
| `xavva logs` | Stream and analyze Tomcat logs in real-time |
|
|
77
|
+
| `xavva deps` | **Analyze dependencies** — detect conflicts, find updates |
|
|
78
|
+
| `xavva audit` | Security audit of JAR files via OSV.dev |
|
|
79
|
+
| `xavva doctor` | Diagnose environment issues (JAVA_HOME, DCEVM) |
|
|
80
|
+
| `xavva profiles` | List available Maven/Gradle profiles |
|
|
81
|
+
| `xavva docs` | Generate endpoint documentation |
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 🔍 Dependency Analysis
|
|
86
|
+
|
|
87
|
+
The `xavva deps` command provides comprehensive dependency analysis:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Basic analysis
|
|
91
|
+
xavva deps
|
|
37
92
|
|
|
38
|
-
|
|
93
|
+
# With verbose output for debugging
|
|
94
|
+
xavva deps --verbose
|
|
39
95
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
96
|
+
# Show fix suggestions for conflicts
|
|
97
|
+
xavva deps --fix
|
|
98
|
+
|
|
99
|
+
# Export report as JSON
|
|
100
|
+
xavva deps --output report.json
|
|
101
|
+
|
|
102
|
+
# Fail on critical conflicts (useful in CI/CD)
|
|
103
|
+
xavva deps --strict
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### What it detects:
|
|
107
|
+
|
|
108
|
+
- ⚠️ **Version Conflicts** — Same dependency with different versions
|
|
109
|
+
- ⬆️ **Available Updates** — Newer versions in Maven Central
|
|
110
|
+
- 🔴 **Major Updates** — Breaking changes that need attention
|
|
111
|
+
- 📊 **Statistics** — Direct vs transitive dependencies
|
|
112
|
+
|
|
113
|
+
### Sample output:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
══════════════════════════════════════════════════════════
|
|
117
|
+
📊 DEPENDENCY ANALYSIS
|
|
118
|
+
══════════════════════════════════════════════════════════
|
|
119
|
+
|
|
120
|
+
Statistics:
|
|
121
|
+
Total: 183 dependencies
|
|
122
|
+
Direct: 45 | Transitive: 138
|
|
123
|
+
|
|
124
|
+
⚠️ VERSION CONFLICTS (2)
|
|
125
|
+
✖ com.fasterxml.jackson.core:jackson-databind
|
|
126
|
+
Versions: 2.13.0, 2.12.6
|
|
127
|
+
|
|
128
|
+
⬆️ UPDATES AVAILABLE (5)
|
|
129
|
+
↑ org.postgresql:postgresql
|
|
130
|
+
42.2.5 → 42.7.1
|
|
131
|
+
|
|
132
|
+
⚠️ MAJOR UPDATES (1)
|
|
133
|
+
! org.springframework.boot:spring-boot-starter
|
|
134
|
+
2.5.0 → 3.1.0
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## ⚙️ Configuration
|
|
140
|
+
|
|
141
|
+
Create `xavva.json` in your project root:
|
|
47
142
|
|
|
48
|
-
### 2. Configuração de Projeto (`xavva.json`)
|
|
49
|
-
Crie um arquivo `xavva.json` na raiz do seu projeto para salvar suas configurações:
|
|
50
143
|
```json
|
|
51
144
|
{
|
|
52
145
|
"project": {
|
|
53
|
-
"appName": "
|
|
146
|
+
"appName": "my-application",
|
|
54
147
|
"buildTool": "maven",
|
|
55
|
-
"
|
|
148
|
+
"profile": "dev",
|
|
149
|
+
"tui": false
|
|
56
150
|
},
|
|
57
151
|
"tomcat": {
|
|
152
|
+
"path": "C:/apache-tomcat",
|
|
58
153
|
"port": 8080
|
|
59
154
|
}
|
|
60
155
|
}
|
|
61
156
|
```
|
|
62
157
|
|
|
63
|
-
###
|
|
64
|
-
|
|
158
|
+
### CLI Options
|
|
159
|
+
|
|
160
|
+
| Option | Description |
|
|
161
|
+
|--------|-------------|
|
|
162
|
+
| `-p, --path <path>` | Tomcat installation path |
|
|
163
|
+
| `-t, --tool <tool>` | Build tool: `maven` or `gradle` |
|
|
164
|
+
| `-n, --name <name>` | Application name (WAR context) |
|
|
165
|
+
| `--port <port>` | Tomcat port (default: 8080) |
|
|
166
|
+
| `-P, --profile <prof>` | Maven/Gradle profile |
|
|
167
|
+
| `-e, --encoding <enc>` | Source encoding (utf8, cp1252) |
|
|
168
|
+
| `-w, --watch` | Enable file watching |
|
|
169
|
+
| `--tui` | Interactive dashboard mode |
|
|
170
|
+
| `-d, --debug` | Enable JPDA debugger |
|
|
171
|
+
| `-c, --clean` | Clean logs before start |
|
|
172
|
+
| `-s, --no-build` | Skip initial build |
|
|
173
|
+
| `-V, --verbose` | Detailed output |
|
|
65
174
|
|
|
66
175
|
---
|
|
67
176
|
|
|
68
|
-
## 🏗️
|
|
177
|
+
## 🏗️ Architecture
|
|
178
|
+
|
|
179
|
+
Xavva uses a modular service-oriented architecture:
|
|
180
|
+
|
|
181
|
+
- **DashboardService** — TUI management and interactivity
|
|
182
|
+
- **LogAnalyzer** — Intelligent log processing
|
|
183
|
+
- **DependencyAnalyzerService** — Dependency conflict detection
|
|
184
|
+
- **ProjectService** — Project structure discovery
|
|
185
|
+
- **BuildService** — Maven/Gradle integration
|
|
186
|
+
- **TomcatService** — Server lifecycle management
|
|
187
|
+
|
|
188
|
+
---
|
|
69
189
|
|
|
70
|
-
|
|
190
|
+
## 🤝 Contributing
|
|
71
191
|
|
|
72
|
-
|
|
73
|
-
- **LogAnalyzer**: Processamento inteligente de logs e stack traces.
|
|
74
|
-
- **ProjectService**: Inteligência centralizada para descoberta de diretórios e artefatos.
|
|
75
|
-
- **CommandRegistry**: Despacho modular de comandos.
|
|
192
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
76
193
|
|
|
77
194
|
---
|
|
78
|
-
|
|
195
|
+
|
|
196
|
+
## 📄 License
|
|
197
|
+
|
|
198
|
+
MIT License — see [LICENSE](LICENSE) for details.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
<p align="center">
|
|
203
|
+
<sub>Built with ❤️ for Java developers who miss modern tooling</sub>
|
|
204
|
+
</p>
|
package/package.json
CHANGED
|
@@ -60,8 +60,9 @@ export class AuditCommand implements Command {
|
|
|
60
60
|
Logger.info("Total de Falhas", totalVulns);
|
|
61
61
|
Logger.info("Relatório gerado via", "OSV.dev (Open Source Vulnerability Database)");
|
|
62
62
|
|
|
63
|
-
} catch (e
|
|
64
|
-
|
|
63
|
+
} catch (e) {
|
|
64
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
65
|
+
Logger.error(message);
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
|
|
@@ -2,6 +2,7 @@ import type { Command } from "./Command";
|
|
|
2
2
|
import type { AppConfig } from "../types/config";
|
|
3
3
|
import { BuildService } from "../services/BuildService";
|
|
4
4
|
import { Logger } from "../utils/ui";
|
|
5
|
+
import { ProcessManager } from "../utils/processManager";
|
|
5
6
|
|
|
6
7
|
export class BuildCommand implements Command {
|
|
7
8
|
constructor(private buildService: BuildService) {}
|
|
@@ -14,9 +15,10 @@ export class BuildCommand implements Command {
|
|
|
14
15
|
try {
|
|
15
16
|
await this.buildService.runBuild();
|
|
16
17
|
Logger.success("Build completed successfully!");
|
|
17
|
-
} catch (error
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
} catch (error) {
|
|
19
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
20
|
+
Logger.error(message);
|
|
21
|
+
await ProcessManager.getInstance().shutdown(1);
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
}
|
|
@@ -2,6 +2,7 @@ import type { AppConfig, CLIArguments } from "../types/config";
|
|
|
2
2
|
import type { Command } from "./Command";
|
|
3
3
|
import { Logger } from "../utils/ui";
|
|
4
4
|
import { HelpCommand } from "./HelpCommand";
|
|
5
|
+
import { ProcessManager } from "../utils/processManager";
|
|
5
6
|
|
|
6
7
|
export class CommandRegistry {
|
|
7
8
|
private commands = new Map<string, Command>();
|
|
@@ -18,19 +19,22 @@ export class CommandRegistry {
|
|
|
18
19
|
return this.commands.get(name);
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
async execute(name: string, config: AppConfig, args: CLIArguments) {
|
|
22
|
+
async execute(name: string, config: AppConfig, args: CLIArguments): Promise<void> {
|
|
22
23
|
const command = this.commands.get(name);
|
|
24
|
+
const processManager = ProcessManager.getInstance();
|
|
25
|
+
|
|
23
26
|
if (!command) {
|
|
24
27
|
Logger.error(`Comando desconhecido: ${name}`);
|
|
25
28
|
await new HelpCommand().execute(config);
|
|
26
|
-
|
|
29
|
+
await processManager.shutdown(2);
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
try {
|
|
30
33
|
await command.execute(config, args);
|
|
31
|
-
} catch (error
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
} catch (error) {
|
|
35
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
36
|
+
Logger.error(`Erro ao executar comando '${name}': ${message}`);
|
|
37
|
+
await processManager.shutdown(1);
|
|
34
38
|
}
|
|
35
39
|
}
|
|
36
40
|
}
|
|
@@ -102,14 +102,16 @@ export class DeployCommand implements Command {
|
|
|
102
102
|
};
|
|
103
103
|
|
|
104
104
|
tomcat.start(config, isWatching);
|
|
105
|
-
} catch (error
|
|
106
|
-
|
|
105
|
+
} catch (error) {
|
|
106
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
107
|
+
Logger.error(message);
|
|
107
108
|
throw error;
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
private logConfiguration(config: AppConfig, isWatching: boolean) {
|
|
112
113
|
Logger.config("Runtime", config.project.buildTool.toUpperCase());
|
|
114
|
+
if (config.project.profile) Logger.config("Profile", config.project.profile.toUpperCase());
|
|
113
115
|
Logger.config("Watch Mode", isWatching ? "ON" : "OFF");
|
|
114
116
|
Logger.config("Debug", config.project.debug ? `ON (Port ${config.project.debugPort})` : "OFF");
|
|
115
117
|
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { Command } from "./Command";
|
|
2
|
+
import type { AppConfig, CLIArguments } from "../types/config";
|
|
3
|
+
import type { DependencyAnalysisResult } from "../services/DependencyAnalyzerService";
|
|
4
|
+
import { DependencyAnalyzerService } from "../services/DependencyAnalyzerService";
|
|
5
|
+
import { AuditService } from "../services/AuditService";
|
|
6
|
+
import { Logger } from "../utils/ui";
|
|
7
|
+
import { ProcessManager } from "../utils/processManager";
|
|
8
|
+
import fs from "fs";
|
|
9
|
+
|
|
10
|
+
export class DepsCommand implements Command {
|
|
11
|
+
private config!: AppConfig;
|
|
12
|
+
|
|
13
|
+
async execute(config: AppConfig, args?: CLIArguments): Promise<void> {
|
|
14
|
+
this.config = config;
|
|
15
|
+
const analyzer = new DependencyAnalyzerService(config.project);
|
|
16
|
+
analyzer.setVerbose(!!args?.verbose);
|
|
17
|
+
|
|
18
|
+
Logger.section("Análise de Dependências");
|
|
19
|
+
Logger.info("Ferramenta", config.project.buildTool.toUpperCase());
|
|
20
|
+
Logger.info("Diretório", process.cwd());
|
|
21
|
+
|
|
22
|
+
const spinner = Logger.spinner("Analisando dependências...");
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const result = await analyzer.analyze();
|
|
26
|
+
spinner();
|
|
27
|
+
|
|
28
|
+
// Se não encontrou dependências, mostrar ajuda
|
|
29
|
+
if (result.dependencies.length === 0) {
|
|
30
|
+
Logger.warn("Nenhuma dependência encontrada!");
|
|
31
|
+
Logger.info("Possíveis causas:", "");
|
|
32
|
+
Logger.log(" • Projeto não foi compilado ainda (execute: mvn compile)");
|
|
33
|
+
Logger.log(" • Maven não está no PATH");
|
|
34
|
+
Logger.log(" • Arquivo pom.xml/build.gradle não encontrado");
|
|
35
|
+
Logger.log(" • Erro de parsing no arquivo de configuração");
|
|
36
|
+
Logger.newline();
|
|
37
|
+
Logger.log(`${Logger.C.cyan}Dica:${Logger.C.reset} Execute com --verbose para mais detalhes`);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Verificar vulnerabilidades se solicitado
|
|
42
|
+
if (args?.["scan"] !== false) {
|
|
43
|
+
Logger.step("Verificando vulnerabilidades");
|
|
44
|
+
// Integração com AuditService para check de vulnerabilidades
|
|
45
|
+
// nas dependências do projeto
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Exibir relatório
|
|
49
|
+
const report = analyzer.generateReport(result);
|
|
50
|
+
console.log(report);
|
|
51
|
+
|
|
52
|
+
// Ações adicionais baseadas em flags
|
|
53
|
+
if (args?.["fix"]) {
|
|
54
|
+
await this.suggestFixes(result, config.project.buildTool);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Exportar resultado se solicitado
|
|
58
|
+
if (args?.["output"]) {
|
|
59
|
+
this.exportReport(result, args["output"] as string);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Sair com erro se houver conflitos críticos
|
|
63
|
+
const hasErrors = result.conflicts.some(c => c.severity === "error");
|
|
64
|
+
if (hasErrors && args?.["strict"]) {
|
|
65
|
+
await ProcessManager.getInstance().shutdown(1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
} catch (error) {
|
|
69
|
+
spinner(false);
|
|
70
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
71
|
+
Logger.error(`Falha na análise: ${message}`);
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private async suggestFixes(result: DependencyAnalysisResult, buildTool: string): Promise<void> {
|
|
77
|
+
if (result.conflicts.length === 0) {
|
|
78
|
+
Logger.success("Nenhum conflito para resolver!");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
Logger.newline();
|
|
83
|
+
Logger.section("Sugestões de Correção");
|
|
84
|
+
|
|
85
|
+
for (const conflict of result.conflicts) {
|
|
86
|
+
Logger.log(`\n${Logger.C.cyan}${conflict.groupId}:${conflict.artifactId}${Logger.C.reset}`);
|
|
87
|
+
|
|
88
|
+
if (buildTool === "maven") {
|
|
89
|
+
Logger.log(" Adicione ao pom.xml:");
|
|
90
|
+
Logger.log(` ${Logger.C.dim}<dependencyManagement>${Logger.C.reset}`);
|
|
91
|
+
Logger.log(` ${Logger.C.dim} <dependencies>${Logger.C.reset}`);
|
|
92
|
+
Logger.log(` ${Logger.C.dim} <dependency>${Logger.C.reset}`);
|
|
93
|
+
Logger.log(` ${Logger.C.dim} <groupId>${conflict.groupId}</groupId>${Logger.C.reset}`);
|
|
94
|
+
Logger.log(` ${Logger.C.dim} <artifactId>${conflict.artifactId}</artifactId>${Logger.C.reset}`);
|
|
95
|
+
Logger.log(` ${Logger.C.dim} <version>${conflict.versions[conflict.versions.length - 1]}</version>${Logger.C.reset}`);
|
|
96
|
+
Logger.log(` ${Logger.C.dim} </dependency>${Logger.C.reset}`);
|
|
97
|
+
Logger.log(` ${Logger.C.dim} </dependencies>${Logger.C.reset}`);
|
|
98
|
+
Logger.log(` ${Logger.C.dim}</dependencyManagement>${Logger.C.reset}`);
|
|
99
|
+
} else {
|
|
100
|
+
Logger.log(" Adicione ao build.gradle:");
|
|
101
|
+
Logger.log(` ${Logger.C.dim}implementation("${conflict.groupId}:${conflict.artifactId}:${conflict.versions[conflict.versions.length - 1]}")${Logger.C.reset}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private exportReport(
|
|
107
|
+
result: DependencyAnalysisResult,
|
|
108
|
+
outputPath: string
|
|
109
|
+
): void {
|
|
110
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "../../package.json"), "utf-8"));
|
|
111
|
+
const data = {
|
|
112
|
+
timestamp: new Date().toISOString(),
|
|
113
|
+
tool: "xavva",
|
|
114
|
+
version: pkg.version,
|
|
115
|
+
result
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
fs.writeFileSync(outputPath, JSON.stringify(data, null, 2));
|
|
119
|
+
Logger.success(`Relatório exportado para: ${outputPath}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
import path from "path";
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { Command } from "./Command";
|
|
2
|
-
import type { AppConfig } from "../types/config";
|
|
2
|
+
import type { AppConfig, CLIArguments } from "../types/config";
|
|
3
3
|
import { Logger } from "../utils/ui";
|
|
4
4
|
import fs from "fs";
|
|
5
5
|
import path from "path";
|
|
6
|
+
import os from "os";
|
|
6
7
|
|
|
7
8
|
export class DoctorCommand implements Command {
|
|
8
|
-
async execute(config: AppConfig, values:
|
|
9
|
+
async execute(config: AppConfig, values: CLIArguments = {}): Promise<void> {
|
|
9
10
|
Logger.section("Xavva Doctor - Ambiente");
|
|
10
11
|
|
|
11
12
|
this.check(
|
|
@@ -252,7 +253,7 @@ export class DoctorCommand implements Command {
|
|
|
252
253
|
|
|
253
254
|
// URL para o JetBrains Runtime 21 SDK Windows x64
|
|
254
255
|
const url = "https://cache-redirector.jetbrains.com/intellij-jbr/jbrsdk-21.0.6-windows-x64-b895.97.tar.gz";
|
|
255
|
-
const installDir = path.join(
|
|
256
|
+
const installDir = path.join(os.homedir(), ".xavva", "jdk-dcevm");
|
|
256
257
|
|
|
257
258
|
// Limpar instalação anterior se existir
|
|
258
259
|
if (fs.existsSync(installDir)) {
|
|
@@ -344,7 +345,7 @@ export class DoctorCommand implements Command {
|
|
|
344
345
|
|
|
345
346
|
Logger.newline();
|
|
346
347
|
Logger.warn("IMPORTANTE: Reinicie seu terminal (ou o VS Code) para as mudanças surtirem efeito.");
|
|
347
|
-
} catch (e
|
|
348
|
+
} catch (e) {
|
|
348
349
|
|
|
349
350
|
Logger.error(`Falha na instalação: ${e.message}`);
|
|
350
351
|
}
|
|
@@ -4,45 +4,100 @@ import pkg from "../../package.json";
|
|
|
4
4
|
|
|
5
5
|
export class HelpCommand implements Command {
|
|
6
6
|
async execute(_config: AppConfig, _args?: CLIArguments): Promise<void> {
|
|
7
|
+
const version = pkg.version;
|
|
8
|
+
|
|
7
9
|
console.log(`
|
|
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
|
-
|
|
10
|
+
${this.c("cyan", "▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓")}
|
|
11
|
+
${this.c("cyan", "▓")} ${this.c("cyan", "▓")}
|
|
12
|
+
${this.c("cyan", "▓")} ${this.c("bold", "XAVVA")} ${this.c("dim", `v${version}`)} ${this.c("gray", "— Java/Tomcat Dev CLI")} ${this.c("cyan", "▓")}
|
|
13
|
+
${this.c("cyan", "▓")} ${this.c("cyan", "▓")}
|
|
14
|
+
${this.c("cyan", "▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓")}
|
|
15
|
+
|
|
16
|
+
${this.c("yellow", "USAGE")}
|
|
17
|
+
xavva <command> [options]
|
|
18
|
+
|
|
19
|
+
${this.c("yellow", "COMMANDS")}
|
|
20
|
+
${this.c("green", "dev")} Start development mode (build + deploy + watch)
|
|
21
|
+
${this.c("green", "deploy")} Build and deploy to Tomcat (default)
|
|
22
|
+
${this.c("green", "build")} Compile project only
|
|
23
|
+
${this.c("green", "start")} Start Tomcat server only
|
|
24
|
+
${this.c("green", "run")} <class> Run a Java class with automatic classpath
|
|
25
|
+
${this.c("green", "debug")} <class> Debug a Java class (port 5005)
|
|
26
|
+
${this.c("green", "logs")} Stream and analyze Tomcat logs
|
|
27
|
+
${this.c("green", "deps")} Analyze dependencies (conflicts, updates)
|
|
28
|
+
${this.c("green", "audit")} Security audit of JAR files
|
|
29
|
+
${this.c("green", "doctor")} Diagnose and fix environment issues
|
|
30
|
+
${this.c("green", "profiles")} List available Maven/Gradle profiles
|
|
31
|
+
${this.c("green", "docs")} Generate endpoint documentation
|
|
32
|
+
|
|
33
|
+
${this.c("yellow", "OPTIONS")}
|
|
34
|
+
${this.c("cyan", "-p, --path")} <path> Tomcat installation path
|
|
35
|
+
${this.c("cyan", "-t, --tool")} <tool> Build tool: maven | gradle
|
|
36
|
+
${this.c("cyan", "-n, --name")} <name> Application name (WAR context)
|
|
37
|
+
${this.c("cyan", "--port")} <port> Tomcat port (default: 8080)
|
|
38
|
+
${this.c("cyan", "-P, --profile")} <prof> Maven/Gradle profile
|
|
39
|
+
${this.c("cyan", "-e, --encoding")} <enc> Source encoding (utf8, cp1252)
|
|
40
|
+
|
|
41
|
+
${this.c("cyan", "-w, --watch")} Enable file watching (hot reload)
|
|
42
|
+
${this.c("cyan", "--tui")} Interactive dashboard mode
|
|
43
|
+
${this.c("cyan", "-d, --debug")} Enable JPDA debugger
|
|
44
|
+
${this.c("cyan", "--dp")} <port> Debugger port (default: 5005)
|
|
45
|
+
|
|
46
|
+
${this.c("cyan", "-c, --clean")} Clean logs before start
|
|
47
|
+
${this.c("cyan", "-s, --no-build")} Skip initial build
|
|
48
|
+
${this.c("cyan", "-q, --quiet")} Minimal output
|
|
49
|
+
${this.c("cyan", "-V, --verbose")} Detailed output
|
|
50
|
+
${this.c("cyan", "-h, --help")} Show this help
|
|
51
|
+
${this.c("cyan", "-v, --version")} Show version
|
|
52
|
+
|
|
53
|
+
${this.c("yellow", "EXAMPLES")}
|
|
54
|
+
${this.c("dim", "# Development with hot reload and dashboard")}
|
|
55
|
+
xavva dev --tui --watch
|
|
56
|
+
|
|
57
|
+
${this.c("dim", "# Quick deploy to specific Tomcat")}
|
|
58
|
+
xavva deploy -p /opt/tomcat --port 8081
|
|
59
|
+
|
|
60
|
+
${this.c("dim", "# Run a class with debugging")}
|
|
61
|
+
xavva debug com.example.MyClass
|
|
62
|
+
|
|
63
|
+
${this.c("dim", "# Analyze dependencies for conflicts")}
|
|
64
|
+
xavva deps --verbose
|
|
65
|
+
|
|
66
|
+
${this.c("dim", "# Security audit with auto-fix suggestions")}
|
|
67
|
+
xavva audit --fix
|
|
68
|
+
|
|
69
|
+
${this.c("yellow", "CONFIGURATION")}
|
|
70
|
+
Settings are loaded from ${this.c("cyan", "xavva.json")} in the project root:
|
|
71
|
+
|
|
72
|
+
${this.c("dim", `{
|
|
73
|
+
"project": {
|
|
74
|
+
"appName": "my-app",
|
|
75
|
+
"buildTool": "maven",
|
|
76
|
+
"tui": true
|
|
77
|
+
},
|
|
78
|
+
"tomcat": {
|
|
79
|
+
"path": "C:/apache-tomcat",
|
|
80
|
+
"port": 8080
|
|
81
|
+
}
|
|
82
|
+
}`)}
|
|
83
|
+
|
|
84
|
+
${this.c("gray", "────────────────────────────────────────────────────────────")}
|
|
85
|
+
${this.c("gray", "Docs: github.com/leorsousa05/Xavva | License: MIT")}
|
|
86
|
+
`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private c(color: string, text: string): string {
|
|
90
|
+
const colors: Record<string, string> = {
|
|
91
|
+
reset: "\x1b[0m",
|
|
92
|
+
bold: "\x1b[1m",
|
|
93
|
+
dim: "\x1b[2m",
|
|
94
|
+
gray: "\x1b[90m",
|
|
95
|
+
red: "\x1b[31m",
|
|
96
|
+
green: "\x1b[32m",
|
|
97
|
+
yellow: "\x1b[33m",
|
|
98
|
+
blue: "\x1b[34m",
|
|
99
|
+
cyan: "\x1b[36m",
|
|
100
|
+
};
|
|
101
|
+
return `${colors[color] || ""}${text}\x1b[0m`;
|
|
47
102
|
}
|
|
48
103
|
}
|