vg-coder-cli 1.0.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 +179 -0
- package/bin/vg-coder.js +11 -0
- package/package.json +64 -0
- package/src/detectors/project-detector.js +333 -0
- package/src/exporter/html-exporter.js +1026 -0
- package/src/ignore/ignore-manager.js +298 -0
- package/src/index.js +282 -0
- package/src/scanner/file-scanner.js +592 -0
- package/src/tokenizer/token-manager.js +389 -0
- package/src/utils/helpers.js +128 -0
- package/test-project/package.json +21 -0
- package/test-project/src/controllers/userController.js +129 -0
- package/test-project/src/index.js +46 -0
- package/test-project/src/middleware/auth.js +142 -0
- package/test-project/styles/main.css +287 -0
- package/vg-coder-cli-1.0.0.tgz +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# VG Coder CLI
|
|
2
|
+
|
|
3
|
+
🚀 **CLI tool để phân tích dự án, nối file mã nguồn, đếm token và xuất HTML** với syntax highlighting và copy functionality.
|
|
4
|
+
|
|
5
|
+
## ✨ Tính năng
|
|
6
|
+
|
|
7
|
+
- 🔍 **Phát hiện loại dự án**: Tự động nhận diện Angular, Spring Boot, React, Vue, Node.js, Python, Java, .NET
|
|
8
|
+
- 📁 **Xử lý .gitignore**: Tuân thủ chuẩn Git với multi-level ignore rules
|
|
9
|
+
- 📄 **Scan và nối file**: Quét toàn bộ dự án và nối file mã nguồn
|
|
10
|
+
- 🧮 **Đếm token**: Sử dụng tiktoken để đếm token chính xác cho AI models
|
|
11
|
+
- ✂️ **Chia nhỏ nội dung**: Smart chunking với preserve structure
|
|
12
|
+
- 🌐 **Xuất HTML**: Tạo HTML với syntax highlighting và copy buttons
|
|
13
|
+
- 🎨 **Syntax Highlighting**: Hỗ trợ nhiều ngôn ngữ lập trình
|
|
14
|
+
- 📋 **Copy to Clipboard**: Dễ dàng copy code với một click
|
|
15
|
+
|
|
16
|
+
## 📦 Cài đặt
|
|
17
|
+
|
|
18
|
+
### Cài đặt từ NPM (Recommended)
|
|
19
|
+
```bash
|
|
20
|
+
# Cài đặt global
|
|
21
|
+
npm install -g vg-coder-cli
|
|
22
|
+
|
|
23
|
+
# Hoặc cài đặt local
|
|
24
|
+
npm install vg-coder-cli
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Cài đặt từ source
|
|
28
|
+
```bash
|
|
29
|
+
# Clone repository
|
|
30
|
+
git clone <repository-url>
|
|
31
|
+
cd vg-coder-cli
|
|
32
|
+
|
|
33
|
+
# Cài đặt dependencies
|
|
34
|
+
npm install
|
|
35
|
+
|
|
36
|
+
# Cấp quyền thực thi (nếu cần)
|
|
37
|
+
chmod +x bin/vg-coder.js
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 🚀 Sử dụng
|
|
41
|
+
|
|
42
|
+
### Phân tích dự án
|
|
43
|
+
```bash
|
|
44
|
+
# Nếu cài global
|
|
45
|
+
vg-coder analyze
|
|
46
|
+
|
|
47
|
+
# Nếu cài local
|
|
48
|
+
npx vg-coder analyze
|
|
49
|
+
|
|
50
|
+
# Phân tích dự án khác
|
|
51
|
+
vg-coder analyze /path/to/project
|
|
52
|
+
|
|
53
|
+
# Với options tùy chỉnh
|
|
54
|
+
vg-coder analyze /path/to/project --max-tokens 8192 --output ./my-output --theme monokai
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Xem thông tin dự án
|
|
58
|
+
```bash
|
|
59
|
+
# Thông tin dự án hiện tại
|
|
60
|
+
vg-coder info
|
|
61
|
+
|
|
62
|
+
# Thông tin dự án khác
|
|
63
|
+
vg-coder info /path/to/project
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Xóa output
|
|
67
|
+
```bash
|
|
68
|
+
# Xóa output mặc định
|
|
69
|
+
node src/index.js clean
|
|
70
|
+
|
|
71
|
+
# Xóa output tùy chỉnh
|
|
72
|
+
node src/index.js clean --output ./my-output
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## ⚙️ Options
|
|
76
|
+
|
|
77
|
+
| Option | Mô tả | Default |
|
|
78
|
+
|--------|-------|---------|
|
|
79
|
+
| `--max-tokens <number>` | Số token tối đa mỗi chunk | 8000 |
|
|
80
|
+
| `--model <model>` | Model AI để đếm token | gpt-4 |
|
|
81
|
+
| `--output <path>` | Thư mục output | ./vg-output |
|
|
82
|
+
| `--extensions <list>` | Danh sách extensions (comma-separated) | Auto-detect |
|
|
83
|
+
| `--include-hidden` | Bao gồm file ẩn | false |
|
|
84
|
+
| `--no-structure` | Không ưu tiên giữ cấu trúc file | false |
|
|
85
|
+
| `--theme <theme>` | Theme cho syntax highlighting | github |
|
|
86
|
+
|
|
87
|
+
## 📋 Ví dụ chi tiết
|
|
88
|
+
|
|
89
|
+
### Phân tích dự án Angular
|
|
90
|
+
```bash
|
|
91
|
+
node src/index.js analyze ./my-angular-app --max-tokens 6000 --theme monokai
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Phân tích với extensions tùy chỉnh
|
|
95
|
+
```bash
|
|
96
|
+
node src/index.js analyze ./my-project --extensions "js,ts,vue,css" --include-hidden
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Xem thông tin chi tiết
|
|
100
|
+
```bash
|
|
101
|
+
node src/index.js info ./my-project
|
|
102
|
+
# Output:
|
|
103
|
+
# 📁 Project Information:
|
|
104
|
+
# Path: /path/to/my-project
|
|
105
|
+
# Primary Type: nodejs
|
|
106
|
+
#
|
|
107
|
+
# Detected Technologies:
|
|
108
|
+
# nodejs: high confidence
|
|
109
|
+
#
|
|
110
|
+
# 📊 File Statistics:
|
|
111
|
+
# Total Files: 25
|
|
112
|
+
# Total Size: 156.7 KB
|
|
113
|
+
# Total Lines: 4,523
|
|
114
|
+
# Extensions: js, ts, json, md
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## 🧪 Testing
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Chạy tất cả tests
|
|
121
|
+
npm test
|
|
122
|
+
|
|
123
|
+
# Chạy tests với coverage
|
|
124
|
+
npm run test:coverage
|
|
125
|
+
|
|
126
|
+
# Chạy specific test
|
|
127
|
+
npm test -- --testNamePattern="project detection"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 📁 Cấu trúc Output
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
vg-output/
|
|
134
|
+
├── index.html # Trang chính với navigation
|
|
135
|
+
├── combined.html # Tất cả code trong một file
|
|
136
|
+
├── chunks/ # Các chunk riêng biệt
|
|
137
|
+
│ ├── chunk-1.html
|
|
138
|
+
│ ├── chunk-2.html
|
|
139
|
+
│ └── ...
|
|
140
|
+
└── assets/ # CSS, JS, themes
|
|
141
|
+
├── styles.css
|
|
142
|
+
├── scripts.js
|
|
143
|
+
└── highlight.css
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## 🎯 Các loại dự án được hỗ trợ
|
|
147
|
+
|
|
148
|
+
- **Frontend**: Angular, React, Vue.js, Svelte
|
|
149
|
+
- **Backend**: Node.js, Spring Boot, Python, .NET
|
|
150
|
+
- **Mobile**: React Native, Flutter
|
|
151
|
+
- **Languages**: JavaScript, TypeScript, Java, Python, C#, Go, Rust
|
|
152
|
+
- **Config**: JSON, YAML, XML, TOML
|
|
153
|
+
|
|
154
|
+
## 🔧 Tùy chỉnh
|
|
155
|
+
|
|
156
|
+
### Extensions mặc định
|
|
157
|
+
Tool tự động detect extensions phù hợp với loại dự án:
|
|
158
|
+
- **Web**: .js, .jsx, .ts, .tsx, .vue, .html, .css, .scss
|
|
159
|
+
- **Backend**: .java, .py, .cs, .go, .rs, .php
|
|
160
|
+
- **Config**: .json, .yaml, .xml, .toml, .env
|
|
161
|
+
|
|
162
|
+
### Themes có sẵn
|
|
163
|
+
- github (default)
|
|
164
|
+
- monokai
|
|
165
|
+
- atom-one-dark
|
|
166
|
+
- vs2015
|
|
167
|
+
- rainbow
|
|
168
|
+
|
|
169
|
+
## 🤝 Đóng góp
|
|
170
|
+
|
|
171
|
+
1. Fork repository
|
|
172
|
+
2. Tạo feature branch (`git checkout -b feature/amazing-feature`)
|
|
173
|
+
3. Commit changes (`git commit -m 'Add amazing feature'`)
|
|
174
|
+
4. Push to branch (`git push origin feature/amazing-feature`)
|
|
175
|
+
5. Tạo Pull Request
|
|
176
|
+
|
|
177
|
+
## 📄 License
|
|
178
|
+
|
|
179
|
+
MIT License - xem file [LICENSE](LICENSE) để biết thêm chi tiết.
|
package/bin/vg-coder.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vg-coder-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "🚀 CLI tool to analyze projects, concatenate source files, count tokens, and export HTML with syntax highlighting and copy functionality",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"vg-coder": "./bin/vg-coder.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node src/index.js",
|
|
11
|
+
"test": "jest",
|
|
12
|
+
"test:analyze": "node src/index.js analyze hdb-signature-service --max-tokens 8192 --theme monokai",
|
|
13
|
+
"test:watch": "jest --watch",
|
|
14
|
+
"dev": "nodemon src/index.js"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"cli",
|
|
18
|
+
"code-analysis",
|
|
19
|
+
"token-counter",
|
|
20
|
+
"ai-helper",
|
|
21
|
+
"gitignore",
|
|
22
|
+
"html-export",
|
|
23
|
+
"syntax-highlighting",
|
|
24
|
+
"project-analyzer",
|
|
25
|
+
"source-code",
|
|
26
|
+
"tiktoken",
|
|
27
|
+
"spring-boot",
|
|
28
|
+
"angular",
|
|
29
|
+
"react",
|
|
30
|
+
"vue",
|
|
31
|
+
"java",
|
|
32
|
+
"javascript",
|
|
33
|
+
"typescript"
|
|
34
|
+
],
|
|
35
|
+
"author": "VG Coder",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/vg-coder/vg-coder-cli.git"
|
|
40
|
+
},
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/vg-coder/vg-coder-cli/issues"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://github.com/vg-coder/vg-coder-cli#readme",
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"commander": "^11.1.0",
|
|
47
|
+
"directory-tree": "^3.5.1",
|
|
48
|
+
"tiktoken": "^1.0.10",
|
|
49
|
+
"highlight.js": "^11.9.0",
|
|
50
|
+
"ignore": "^5.3.0",
|
|
51
|
+
"fs-extra": "^11.2.0",
|
|
52
|
+
"path": "^0.12.7",
|
|
53
|
+
"chalk": "^4.1.2",
|
|
54
|
+
"ora": "^5.4.1"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"jest": "^29.7.0",
|
|
58
|
+
"nodemon": "^3.0.2",
|
|
59
|
+
"@types/jest": "^29.5.8"
|
|
60
|
+
},
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=16.0.0"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Phát hiện loại dự án dựa trên các file cấu hình
|
|
6
|
+
*/
|
|
7
|
+
class ProjectDetector {
|
|
8
|
+
constructor(projectPath) {
|
|
9
|
+
this.projectPath = projectPath;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Phát hiện tất cả loại dự án có thể
|
|
14
|
+
* @returns {Object} Object chứa thông tin các loại dự án được phát hiện
|
|
15
|
+
*/
|
|
16
|
+
async detectAll() {
|
|
17
|
+
const results = {
|
|
18
|
+
angular: await this.detectAngular(),
|
|
19
|
+
springBoot: await this.detectSpringBoot(),
|
|
20
|
+
react: await this.detectReact(),
|
|
21
|
+
vue: await this.detectVue(),
|
|
22
|
+
nodejs: await this.detectNodeJS(),
|
|
23
|
+
java: await this.detectJava(),
|
|
24
|
+
python: await this.detectPython(),
|
|
25
|
+
dotnet: await this.detectDotNet()
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Lọc ra các loại dự án được phát hiện
|
|
29
|
+
const detected = Object.entries(results)
|
|
30
|
+
.filter(([_, info]) => info.detected)
|
|
31
|
+
.reduce((acc, [type, info]) => {
|
|
32
|
+
acc[type] = info;
|
|
33
|
+
return acc;
|
|
34
|
+
}, {});
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
detected,
|
|
38
|
+
primary: this.determinePrimaryType(detected),
|
|
39
|
+
all: results
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Phát hiện Angular project
|
|
45
|
+
*/
|
|
46
|
+
async detectAngular() {
|
|
47
|
+
try {
|
|
48
|
+
const packageJsonPath = path.join(this.projectPath, 'package.json');
|
|
49
|
+
const angularJsonPath = path.join(this.projectPath, 'angular.json');
|
|
50
|
+
|
|
51
|
+
if (await fs.pathExists(packageJsonPath)) {
|
|
52
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
53
|
+
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
54
|
+
|
|
55
|
+
const hasAngularCore = deps['@angular/core'];
|
|
56
|
+
const hasAngularCli = deps['@angular/cli'];
|
|
57
|
+
const hasAngularJson = await fs.pathExists(angularJsonPath);
|
|
58
|
+
|
|
59
|
+
if (hasAngularCore || hasAngularCli || hasAngularJson) {
|
|
60
|
+
return {
|
|
61
|
+
detected: true,
|
|
62
|
+
confidence: hasAngularCore && hasAngularJson ? 'high' : 'medium',
|
|
63
|
+
version: hasAngularCore || 'unknown',
|
|
64
|
+
indicators: {
|
|
65
|
+
packageJson: !!hasAngularCore || !!hasAngularCli,
|
|
66
|
+
angularJson: hasAngularJson,
|
|
67
|
+
dependencies: Object.keys(deps).filter(dep => dep.startsWith('@angular/'))
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
} catch (error) {
|
|
73
|
+
// Ignore errors
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return { detected: false };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Phát hiện Spring Boot project
|
|
81
|
+
*/
|
|
82
|
+
async detectSpringBoot() {
|
|
83
|
+
try {
|
|
84
|
+
const pomPath = path.join(this.projectPath, 'pom.xml');
|
|
85
|
+
const gradlePath = path.join(this.projectPath, 'build.gradle');
|
|
86
|
+
const gradleKtsPath = path.join(this.projectPath, 'build.gradle.kts');
|
|
87
|
+
|
|
88
|
+
// Kiểm tra Maven (pom.xml)
|
|
89
|
+
if (await fs.pathExists(pomPath)) {
|
|
90
|
+
const pomContent = await fs.readFile(pomPath, 'utf8');
|
|
91
|
+
if (pomContent.includes('spring-boot-starter') || pomContent.includes('org.springframework.boot')) {
|
|
92
|
+
return {
|
|
93
|
+
detected: true,
|
|
94
|
+
confidence: 'high',
|
|
95
|
+
buildTool: 'maven',
|
|
96
|
+
indicators: {
|
|
97
|
+
pomXml: true,
|
|
98
|
+
springBootStarter: pomContent.includes('spring-boot-starter')
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Kiểm tra Gradle
|
|
105
|
+
for (const gradleFile of [gradlePath, gradleKtsPath]) {
|
|
106
|
+
if (await fs.pathExists(gradleFile)) {
|
|
107
|
+
const gradleContent = await fs.readFile(gradleFile, 'utf8');
|
|
108
|
+
if (gradleContent.includes('spring-boot') || gradleContent.includes('org.springframework.boot')) {
|
|
109
|
+
return {
|
|
110
|
+
detected: true,
|
|
111
|
+
confidence: 'high',
|
|
112
|
+
buildTool: gradleFile.endsWith('.kts') ? 'gradle-kotlin' : 'gradle',
|
|
113
|
+
indicators: {
|
|
114
|
+
buildGradle: true,
|
|
115
|
+
springBootPlugin: gradleContent.includes('org.springframework.boot')
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
} catch (error) {
|
|
122
|
+
// Ignore errors
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return { detected: false };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Phát hiện React project
|
|
130
|
+
*/
|
|
131
|
+
async detectReact() {
|
|
132
|
+
try {
|
|
133
|
+
const packageJsonPath = path.join(this.projectPath, 'package.json');
|
|
134
|
+
if (await fs.pathExists(packageJsonPath)) {
|
|
135
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
136
|
+
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
137
|
+
|
|
138
|
+
if (deps.react) {
|
|
139
|
+
return {
|
|
140
|
+
detected: true,
|
|
141
|
+
confidence: 'high',
|
|
142
|
+
version: deps.react,
|
|
143
|
+
indicators: {
|
|
144
|
+
react: true,
|
|
145
|
+
reactDom: !!deps['react-dom'],
|
|
146
|
+
nextJs: !!deps.next,
|
|
147
|
+
createReactApp: !!deps['react-scripts']
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
} catch (error) {
|
|
153
|
+
// Ignore errors
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return { detected: false };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Phát hiện Vue project
|
|
161
|
+
*/
|
|
162
|
+
async detectVue() {
|
|
163
|
+
try {
|
|
164
|
+
const packageJsonPath = path.join(this.projectPath, 'package.json');
|
|
165
|
+
if (await fs.pathExists(packageJsonPath)) {
|
|
166
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
167
|
+
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
168
|
+
|
|
169
|
+
if (deps.vue) {
|
|
170
|
+
return {
|
|
171
|
+
detected: true,
|
|
172
|
+
confidence: 'high',
|
|
173
|
+
version: deps.vue,
|
|
174
|
+
indicators: {
|
|
175
|
+
vue: true,
|
|
176
|
+
vueRouter: !!deps['vue-router'],
|
|
177
|
+
vuex: !!deps.vuex,
|
|
178
|
+
nuxt: !!deps.nuxt
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
} catch (error) {
|
|
184
|
+
// Ignore errors
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return { detected: false };
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Phát hiện Node.js project
|
|
192
|
+
*/
|
|
193
|
+
async detectNodeJS() {
|
|
194
|
+
try {
|
|
195
|
+
const packageJsonPath = path.join(this.projectPath, 'package.json');
|
|
196
|
+
return {
|
|
197
|
+
detected: await fs.pathExists(packageJsonPath),
|
|
198
|
+
confidence: 'high',
|
|
199
|
+
indicators: {
|
|
200
|
+
packageJson: await fs.pathExists(packageJsonPath)
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
} catch (error) {
|
|
204
|
+
return { detected: false };
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Phát hiện Java project
|
|
210
|
+
*/
|
|
211
|
+
async detectJava() {
|
|
212
|
+
try {
|
|
213
|
+
const pomPath = path.join(this.projectPath, 'pom.xml');
|
|
214
|
+
const gradlePath = path.join(this.projectPath, 'build.gradle');
|
|
215
|
+
const gradleKtsPath = path.join(this.projectPath, 'build.gradle.kts');
|
|
216
|
+
|
|
217
|
+
const hasPom = await fs.pathExists(pomPath);
|
|
218
|
+
const hasGradle = await fs.pathExists(gradlePath) || await fs.pathExists(gradleKtsPath);
|
|
219
|
+
|
|
220
|
+
if (hasPom || hasGradle) {
|
|
221
|
+
return {
|
|
222
|
+
detected: true,
|
|
223
|
+
confidence: 'high',
|
|
224
|
+
buildTool: hasPom ? 'maven' : 'gradle',
|
|
225
|
+
indicators: {
|
|
226
|
+
maven: hasPom,
|
|
227
|
+
gradle: hasGradle
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
} catch (error) {
|
|
232
|
+
// Ignore errors
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return { detected: false };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Phát hiện Python project
|
|
240
|
+
*/
|
|
241
|
+
async detectPython() {
|
|
242
|
+
try {
|
|
243
|
+
const requirementsPath = path.join(this.projectPath, 'requirements.txt');
|
|
244
|
+
const pipfilePath = path.join(this.projectPath, 'Pipfile');
|
|
245
|
+
const pyprojectPath = path.join(this.projectPath, 'pyproject.toml');
|
|
246
|
+
const setupPyPath = path.join(this.projectPath, 'setup.py');
|
|
247
|
+
|
|
248
|
+
const hasRequirements = await fs.pathExists(requirementsPath);
|
|
249
|
+
const hasPipfile = await fs.pathExists(pipfilePath);
|
|
250
|
+
const hasPyproject = await fs.pathExists(pyprojectPath);
|
|
251
|
+
const hasSetupPy = await fs.pathExists(setupPyPath);
|
|
252
|
+
|
|
253
|
+
if (hasRequirements || hasPipfile || hasPyproject || hasSetupPy) {
|
|
254
|
+
return {
|
|
255
|
+
detected: true,
|
|
256
|
+
confidence: 'high',
|
|
257
|
+
indicators: {
|
|
258
|
+
requirements: hasRequirements,
|
|
259
|
+
pipfile: hasPipfile,
|
|
260
|
+
pyproject: hasPyproject,
|
|
261
|
+
setupPy: hasSetupPy
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
} catch (error) {
|
|
266
|
+
// Ignore errors
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return { detected: false };
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Phát hiện .NET project
|
|
274
|
+
*/
|
|
275
|
+
async detectDotNet() {
|
|
276
|
+
try {
|
|
277
|
+
const csprojFiles = await this.findFilesByExtension('.csproj');
|
|
278
|
+
const vbprojFiles = await this.findFilesByExtension('.vbproj');
|
|
279
|
+
const fsprojFiles = await this.findFilesByExtension('.fsproj');
|
|
280
|
+
const slnFiles = await this.findFilesByExtension('.sln');
|
|
281
|
+
|
|
282
|
+
const hasProjectFiles = csprojFiles.length > 0 || vbprojFiles.length > 0 || fsprojFiles.length > 0;
|
|
283
|
+
const hasSolution = slnFiles.length > 0;
|
|
284
|
+
|
|
285
|
+
if (hasProjectFiles || hasSolution) {
|
|
286
|
+
return {
|
|
287
|
+
detected: true,
|
|
288
|
+
confidence: 'high',
|
|
289
|
+
indicators: {
|
|
290
|
+
csproj: csprojFiles.length,
|
|
291
|
+
vbproj: vbprojFiles.length,
|
|
292
|
+
fsproj: fsprojFiles.length,
|
|
293
|
+
solution: slnFiles.length
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
} catch (error) {
|
|
298
|
+
// Ignore errors
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return { detected: false };
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Tìm files theo extension
|
|
306
|
+
*/
|
|
307
|
+
async findFilesByExtension(extension) {
|
|
308
|
+
try {
|
|
309
|
+
const files = await fs.readdir(this.projectPath);
|
|
310
|
+
return files.filter(file => file.endsWith(extension));
|
|
311
|
+
} catch (error) {
|
|
312
|
+
return [];
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Xác định loại dự án chính
|
|
318
|
+
*/
|
|
319
|
+
determinePrimaryType(detected) {
|
|
320
|
+
const priorities = ['angular', 'springBoot', 'react', 'vue', 'nodejs', 'java', 'python', 'dotnet'];
|
|
321
|
+
|
|
322
|
+
for (const type of priorities) {
|
|
323
|
+
if (detected[type] && detected[type].confidence === 'high') {
|
|
324
|
+
return type;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Fallback to first detected
|
|
329
|
+
return Object.keys(detected)[0] || 'unknown';
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
module.exports = ProjectDetector;
|