@sun-asterisk/sunlint 1.0.5
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/CHANGELOG.md +202 -0
- package/LICENSE +21 -0
- package/README.md +490 -0
- package/cli-legacy.js +355 -0
- package/cli.js +35 -0
- package/config/default.json +22 -0
- package/config/presets/beginner.json +36 -0
- package/config/presets/ci.json +46 -0
- package/config/presets/recommended.json +24 -0
- package/config/presets/strict.json +32 -0
- package/config/rules-registry.json +681 -0
- package/config/sunlint-schema.json +166 -0
- package/config/typescript/custom-rules-new.js +0 -0
- package/config/typescript/custom-rules.js +9 -0
- package/config/typescript/eslint.config.js +110 -0
- package/config/typescript/package-lock.json +1585 -0
- package/config/typescript/package.json +13 -0
- package/config/typescript/security-rules/index.js +90 -0
- package/config/typescript/security-rules/s005-no-origin-auth.js +95 -0
- package/config/typescript/security-rules/s006-activation-recovery-secret-not-plaintext.js +69 -0
- package/config/typescript/security-rules/s008-crypto-agility.js +62 -0
- package/config/typescript/security-rules/s009-no-insecure-crypto.js +103 -0
- package/config/typescript/security-rules/s010-no-insecure-random-in-sensitive-context.js +123 -0
- package/config/typescript/security-rules/s011-no-insecure-uuid.js +66 -0
- package/config/typescript/security-rules/s012-hardcode-secret.js +71 -0
- package/config/typescript/security-rules/s014-insecure-tls-version.js +50 -0
- package/config/typescript/security-rules/s015-insecure-tls-certificate.js +43 -0
- package/config/typescript/security-rules/s016-sensitive-query-parameter.js +59 -0
- package/config/typescript/security-rules/s017-no-sql-injection.js +193 -0
- package/config/typescript/security-rules/s018-positive-input-validation.js +56 -0
- package/config/typescript/security-rules/s019-no-raw-user-input-in-email.js +113 -0
- package/config/typescript/security-rules/s020-no-eval-dynamic-execution.js +89 -0
- package/config/typescript/security-rules/s022-output-encoding.js +78 -0
- package/config/typescript/security-rules/s023-no-json-injection.js +300 -0
- package/config/typescript/security-rules/s025-server-side-input-validation.js +217 -0
- package/config/typescript/security-rules/s026-json-schema-validation.js +68 -0
- package/config/typescript/security-rules/s027-no-hardcoded-secrets.js +80 -0
- package/config/typescript/security-rules/s029-require-csrf-protection.js +79 -0
- package/config/typescript/security-rules/s030-no-directory-browsing.js +78 -0
- package/config/typescript/security-rules/s033-require-samesite-cookie.js +80 -0
- package/config/typescript/security-rules/s034-require-host-cookie-prefix.js +77 -0
- package/config/typescript/security-rules/s035-cookie-specific-path.js +74 -0
- package/config/typescript/security-rules/s036-no-unsafe-file-include.js +68 -0
- package/config/typescript/security-rules/s037-require-anti-cache-headers.js +70 -0
- package/config/typescript/security-rules/s038-no-version-disclosure.js +74 -0
- package/config/typescript/security-rules/s039-no-session-token-in-url.js +63 -0
- package/config/typescript/security-rules/s041-require-session-invalidate-on-logout.js +211 -0
- package/config/typescript/security-rules/s042-require-periodic-reauthentication.js +294 -0
- package/config/typescript/security-rules/s043-terminate-sessions-on-password-change.js +254 -0
- package/config/typescript/security-rules/s044-require-full-session-for-sensitive-operations.js +292 -0
- package/config/typescript/security-rules/s045-anti-automation-controls.js +46 -0
- package/config/typescript/security-rules/s046-secure-notification-on-auth-change.js +44 -0
- package/config/typescript/security-rules/s048-password-credential-recovery.js +54 -0
- package/config/typescript/security-rules/s050-session-token-weak-hash.js +94 -0
- package/config/typescript/security-rules/s052-secure-random-authentication-code.js +66 -0
- package/config/typescript/security-rules/s054-verification-default-account.js +109 -0
- package/config/typescript/security-rules/s057-utc-logging.js +54 -0
- package/config/typescript/security-rules/s058-no-ssrf.js +73 -0
- package/config/typescript/test-s005-working.ts +22 -0
- package/config/typescript/tsconfig.json +29 -0
- package/core/ai-analyzer.js +169 -0
- package/core/analysis-orchestrator.js +705 -0
- package/core/cli-action-handler.js +230 -0
- package/core/cli-program.js +106 -0
- package/core/config-manager.js +396 -0
- package/core/config-merger.js +136 -0
- package/core/config-override-processor.js +74 -0
- package/core/config-preset-resolver.js +65 -0
- package/core/config-source-loader.js +152 -0
- package/core/config-validator.js +126 -0
- package/core/dependency-manager.js +105 -0
- package/core/eslint-engine-service.js +312 -0
- package/core/eslint-instance-manager.js +104 -0
- package/core/eslint-integration-service.js +363 -0
- package/core/git-utils.js +170 -0
- package/core/multi-rule-runner.js +239 -0
- package/core/output-service.js +250 -0
- package/core/report-generator.js +320 -0
- package/core/rule-mapping-service.js +309 -0
- package/core/rule-selection-service.js +121 -0
- package/core/sunlint-engine-service.js +23 -0
- package/core/typescript-analyzer.js +262 -0
- package/core/typescript-engine.js +313 -0
- package/docs/AI.md +163 -0
- package/docs/ARCHITECTURE.md +78 -0
- package/docs/CI-CD-GUIDE.md +315 -0
- package/docs/COMMAND-EXAMPLES.md +256 -0
- package/docs/DEBUG.md +86 -0
- package/docs/DISTRIBUTION.md +153 -0
- package/docs/ESLINT-INTEGRATION-STRATEGY.md +392 -0
- package/docs/ESLINT_INTEGRATION.md +238 -0
- package/docs/FOLDER_STRUCTURE.md +59 -0
- package/docs/HEURISTIC_VS_AI.md +113 -0
- package/docs/README.md +32 -0
- package/docs/RELEASE_GUIDE.md +230 -0
- package/docs/RULE-RESPONSIBILITY-MATRIX.md +204 -0
- package/eslint-integration/.eslintrc.js +98 -0
- package/eslint-integration/cli.js +35 -0
- package/eslint-integration/eslint-plugin-custom/c002-no-duplicate-code.js +204 -0
- package/eslint-integration/eslint-plugin-custom/c003-no-vague-abbreviations.js +246 -0
- package/eslint-integration/eslint-plugin-custom/c006-function-name-verb-noun.js +207 -0
- package/eslint-integration/eslint-plugin-custom/c010-limit-block-nesting.js +90 -0
- package/eslint-integration/eslint-plugin-custom/c013-no-dead-code.js +43 -0
- package/eslint-integration/eslint-plugin-custom/c014-abstract-dependency-preferred.js +38 -0
- package/eslint-integration/eslint-plugin-custom/c017-limit-constructor-logic.js +39 -0
- package/eslint-integration/eslint-plugin-custom/c018-no-generic-throw.js +335 -0
- package/eslint-integration/eslint-plugin-custom/c023-no-duplicate-variable-name-in-scope.js +142 -0
- package/eslint-integration/eslint-plugin-custom/c027-limit-function-nesting.js +50 -0
- package/eslint-integration/eslint-plugin-custom/c029-catch-block-logging.js +80 -0
- package/eslint-integration/eslint-plugin-custom/c030-use-custom-error-classes.js +294 -0
- package/eslint-integration/eslint-plugin-custom/c034-no-implicit-return.js +34 -0
- package/eslint-integration/eslint-plugin-custom/c035-no-empty-catch.js +32 -0
- package/eslint-integration/eslint-plugin-custom/c041-no-config-inline.js +64 -0
- package/eslint-integration/eslint-plugin-custom/c042-boolean-name-prefix.js +406 -0
- package/eslint-integration/eslint-plugin-custom/c043-no-console-or-print.js +300 -0
- package/eslint-integration/eslint-plugin-custom/c047-no-duplicate-retry-logic.js +239 -0
- package/eslint-integration/eslint-plugin-custom/c048-no-var-declaration.js +31 -0
- package/eslint-integration/eslint-plugin-custom/c076-one-assert-per-test.js +184 -0
- package/eslint-integration/eslint-plugin-custom/index.js +155 -0
- package/eslint-integration/eslint-plugin-custom/package.json +13 -0
- package/eslint-integration/eslint-plugin-custom/package.json.bak +9 -0
- package/eslint-integration/eslint-plugin-custom/s003-no-unvalidated-redirect.js +86 -0
- package/eslint-integration/eslint-plugin-custom/s005-no-origin-auth.js +95 -0
- package/eslint-integration/eslint-plugin-custom/s006-activation-recovery-secret-not-plaintext.js +69 -0
- package/eslint-integration/eslint-plugin-custom/s008-crypto-agility.js +62 -0
- package/eslint-integration/eslint-plugin-custom/s009-no-insecure-crypto.js +103 -0
- package/eslint-integration/eslint-plugin-custom/s010-no-insecure-random-in-sensitive-context.js +123 -0
- package/eslint-integration/eslint-plugin-custom/s011-no-insecure-uuid.js +66 -0
- package/eslint-integration/eslint-plugin-custom/s012-hardcode-secret.js +71 -0
- package/eslint-integration/eslint-plugin-custom/s014-insecure-tls-version.js +50 -0
- package/eslint-integration/eslint-plugin-custom/s015-insecure-tls-certificate.js +43 -0
- package/eslint-integration/eslint-plugin-custom/s016-sensitive-query-parameter.js +59 -0
- package/eslint-integration/eslint-plugin-custom/s017-no-sql-injection.js +193 -0
- package/eslint-integration/eslint-plugin-custom/s018-positive-input-validation.js +56 -0
- package/eslint-integration/eslint-plugin-custom/s019-no-raw-user-input-in-email.js +113 -0
- package/eslint-integration/eslint-plugin-custom/s020-no-eval-dynamic-execution.js +89 -0
- package/eslint-integration/eslint-plugin-custom/s022-output-encoding.js +78 -0
- package/eslint-integration/eslint-plugin-custom/s023-no-json-injection.js +300 -0
- package/eslint-integration/eslint-plugin-custom/s025-server-side-input-validation.js +217 -0
- package/eslint-integration/eslint-plugin-custom/s026-json-schema-validation.js +68 -0
- package/eslint-integration/eslint-plugin-custom/s027-no-hardcoded-secrets.js +80 -0
- package/eslint-integration/eslint-plugin-custom/s029-require-csrf-protection.js +79 -0
- package/eslint-integration/eslint-plugin-custom/s030-no-directory-browsing.js +78 -0
- package/eslint-integration/eslint-plugin-custom/s033-require-samesite-cookie.js +80 -0
- package/eslint-integration/eslint-plugin-custom/s034-require-host-cookie-prefix.js +77 -0
- package/eslint-integration/eslint-plugin-custom/s035-cookie-specific-path.js +74 -0
- package/eslint-integration/eslint-plugin-custom/s036-no-unsafe-file-include.js +68 -0
- package/eslint-integration/eslint-plugin-custom/s037-require-anti-cache-headers.js +70 -0
- package/eslint-integration/eslint-plugin-custom/s038-no-version-disclosure.js +74 -0
- package/eslint-integration/eslint-plugin-custom/s039-no-session-token-in-url.js +63 -0
- package/eslint-integration/eslint-plugin-custom/s041-require-session-invalidate-on-logout.js +211 -0
- package/eslint-integration/eslint-plugin-custom/s042-require-periodic-reauthentication.js +294 -0
- package/eslint-integration/eslint-plugin-custom/s043-terminate-sessions-on-password-change.js +254 -0
- package/eslint-integration/eslint-plugin-custom/s044-require-full-session-for-sensitive-operations.js +292 -0
- package/eslint-integration/eslint-plugin-custom/s045-anti-automation-controls.js +46 -0
- package/eslint-integration/eslint-plugin-custom/s046-secure-notification-on-auth-change.js +44 -0
- package/eslint-integration/eslint-plugin-custom/s047-secure-random-passwords.js +108 -0
- package/eslint-integration/eslint-plugin-custom/s048-password-credential-recovery.js +54 -0
- package/eslint-integration/eslint-plugin-custom/s050-session-token-weak-hash.js +94 -0
- package/eslint-integration/eslint-plugin-custom/s052-secure-random-authentication-code.js +66 -0
- package/eslint-integration/eslint-plugin-custom/s054-verification-default-account.js +109 -0
- package/eslint-integration/eslint-plugin-custom/s055-verification-rest-check-the-incoming-content-type.js +143 -0
- package/eslint-integration/eslint-plugin-custom/s057-utc-logging.js +54 -0
- package/eslint-integration/eslint-plugin-custom/s058-no-ssrf.js +73 -0
- package/eslint-integration/eslint-plugin-custom/t002-interface-prefix-i.js +42 -0
- package/eslint-integration/eslint-plugin-custom/t003-ts-ignore-reason.js +48 -0
- package/eslint-integration/eslint-plugin-custom/t004-interface-public-only.js +160 -0
- package/eslint-integration/eslint-plugin-custom/t007-no-fn-in-constructor.js +52 -0
- package/eslint-integration/eslint-plugin-custom/t011-no-real-time-dependency.js +175 -0
- package/eslint-integration/eslint-plugin-custom/t019-no-empty-type.js +95 -0
- package/eslint-integration/eslint-plugin-custom/t025-no-nested-union-tuple.js +48 -0
- package/eslint-integration/eslint-plugin-custom/t026-limit-nested-generics.js +377 -0
- package/eslint-integration/eslint.config.js +125 -0
- package/eslint-integration/eslint.config.simple.js +24 -0
- package/eslint-integration/node_modules/eslint-plugin-custom/package.json +0 -0
- package/eslint-integration/package.json +23 -0
- package/eslint-integration/sample.ts +53 -0
- package/eslint-integration/test-s003.js +5 -0
- package/eslint-integration/tsconfig.json +27 -0
- package/examples/.github/workflows/code-quality.yml +111 -0
- package/examples/.sunlint.json +42 -0
- package/examples/README.md +47 -0
- package/examples/package.json +33 -0
- package/package.json +100 -0
- package/rules/C006_function_naming/analyzer.js +338 -0
- package/rules/C006_function_naming/config.json +86 -0
- package/rules/C019_log_level_usage/analyzer.js +359 -0
- package/rules/C019_log_level_usage/config.json +121 -0
- package/rules/C029_catch_block_logging/analyzer.js +339 -0
- package/rules/C029_catch_block_logging/config.json +59 -0
- package/rules/C031_validation_separation/README.md +72 -0
- package/rules/C031_validation_separation/analyzer.js +186 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# 🚀 SunLint Distribution & Installation Guide
|
|
2
|
+
|
|
3
|
+
## 🎯 **Problem:**
|
|
4
|
+
- Cần `cd extensions/sunlint` mỗi lần chạy
|
|
5
|
+
- Muốn cài đặt dễ dàng nhưng giữ tính bảo mật (private)
|
|
6
|
+
- Sử dụng từ bất kỳ directory nào
|
|
7
|
+
|
|
8
|
+
## ✅ **Solutions Ranking:**
|
|
9
|
+
|
|
10
|
+
### **🥇 Option 1: NPM Private Package (RECOMMENDED)**
|
|
11
|
+
|
|
12
|
+
#### **Setup (Company Admin - một lần):**
|
|
13
|
+
```bash
|
|
14
|
+
# 1. Setup package.json for global install
|
|
15
|
+
cd extensions/sunlint
|
|
16
|
+
npm pack # Tạo @sun-sunlint-1.0.0.tgz
|
|
17
|
+
|
|
18
|
+
# 2. Store trong internal file server hoặc private npm registry
|
|
19
|
+
# Hoặc upload lên GitHub Packages (private)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
#### **Installation (Dev - một lần):**
|
|
23
|
+
```bash
|
|
24
|
+
# Cách 1: Từ file
|
|
25
|
+
npm install -g /path/to/@sun-sunlint-1.0.0.tgz
|
|
26
|
+
|
|
27
|
+
# Cách 2: Từ private GitHub (yêu cầu GitHub token)
|
|
28
|
+
npm install -g git+https://github.com/your-company/sunlint.git
|
|
29
|
+
|
|
30
|
+
# Cách 3: Từ GitHub Packages (private npm registry)
|
|
31
|
+
npm login --registry=https://npm.pkg.github.com
|
|
32
|
+
npm install -g @your-company/sunlint --registry=https://npm.pkg.github.com
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
#### **Usage (Dev - hàng ngày):**
|
|
36
|
+
```bash
|
|
37
|
+
# Từ bất kỳ directory nào
|
|
38
|
+
sunlint --typescript --input src --all
|
|
39
|
+
sunlint --typescript --input src --rule C006
|
|
40
|
+
sunlint --typescript --input src --quality --format json
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
### **🥈 Option 2: Shell Script/Alias (SIMPLE)**
|
|
46
|
+
|
|
47
|
+
#### **Setup (Dev - một lần):**
|
|
48
|
+
```bash
|
|
49
|
+
# Tạo global command
|
|
50
|
+
sudo cat > /usr/local/bin/sunlint << 'EOF'
|
|
51
|
+
#!/bin/bash
|
|
52
|
+
SUNLINT_DIR="/Users/bach.ngoc.hoai/Docs/ee/coding-quality/extensions/sunlint"
|
|
53
|
+
cd "$SUNLINT_DIR" && node cli.js "$@"
|
|
54
|
+
EOF
|
|
55
|
+
|
|
56
|
+
sudo chmod +x /usr/local/bin/sunlint
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### **Usage (Dev - hàng ngày):**
|
|
60
|
+
```bash
|
|
61
|
+
# Từ bất kỳ directory nào
|
|
62
|
+
sunlint --typescript --input src --all
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
### **🥉 Option 3: Project-Level NPM Scripts**
|
|
68
|
+
|
|
69
|
+
#### **Setup (Per Project):**
|
|
70
|
+
```json
|
|
71
|
+
// package.json của mỗi project
|
|
72
|
+
{
|
|
73
|
+
"scripts": {
|
|
74
|
+
"lint": "node /path/to/sunlint/cli.js --typescript --input src --all",
|
|
75
|
+
"lint:ci": "node /path/to/sunlint/cli.js --typescript --input src --all --format json",
|
|
76
|
+
"lint:single": "node /path/to/sunlint/cli.js --typescript --input",
|
|
77
|
+
"lint:quality": "node /path/to/sunlint/cli.js --typescript --input src --quality"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
#### **Usage:**
|
|
83
|
+
```bash
|
|
84
|
+
npm run lint
|
|
85
|
+
npm run lint:ci
|
|
86
|
+
npm run lint:single -- src/specific-file.ts
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 🏢 **Enterprise Recommendations:**
|
|
92
|
+
|
|
93
|
+
### **For CI/CD (Production):**
|
|
94
|
+
```yaml
|
|
95
|
+
# GitHub Actions
|
|
96
|
+
- name: Install SunLint
|
|
97
|
+
run: npm install -g /shared/tools/@sun-sunlint-1.0.0.tgz
|
|
98
|
+
|
|
99
|
+
- name: Run Code Quality Check
|
|
100
|
+
run: sunlint --typescript --input src --all --format json
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### **For Development (Local):**
|
|
104
|
+
```bash
|
|
105
|
+
# One-time setup script cho dev team
|
|
106
|
+
#!/bin/bash
|
|
107
|
+
echo "Installing SunLint..."
|
|
108
|
+
npm install -g /shared/tools/@sun-sunlint-1.0.0.tgz
|
|
109
|
+
echo "SunLint installed! Usage: sunlint --help"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### **For VS Code Integration (Future):**
|
|
113
|
+
```json
|
|
114
|
+
// .vscode/settings.json
|
|
115
|
+
{
|
|
116
|
+
"sunlint.executablePath": "sunlint",
|
|
117
|
+
"sunlint.autoRun": "onSave",
|
|
118
|
+
"sunlint.format": "eslint"
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 🎯 **Immediate Action Plan:**
|
|
125
|
+
|
|
126
|
+
### **Phase 1: Quick Fix (This Week)**
|
|
127
|
+
Implement **Option 2 (Shell Script)**:
|
|
128
|
+
1. Tạo shell script cho dev team
|
|
129
|
+
2. Add vào onboarding documentation
|
|
130
|
+
3. Test trên CI environment
|
|
131
|
+
|
|
132
|
+
### **Phase 2: Professional (Next Sprint)**
|
|
133
|
+
Implement **Option 1 (NPM Package)**:
|
|
134
|
+
1. Setup private npm registry hoặc GitHub Packages
|
|
135
|
+
2. Create installation documentation
|
|
136
|
+
3. Migrate existing projects
|
|
137
|
+
|
|
138
|
+
### **Phase 3: IDE Integration (Future)**
|
|
139
|
+
1. VS Code extension
|
|
140
|
+
2. IntelliJ plugin
|
|
141
|
+
3. Auto-formatting on save
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## ✅ **Benefits Matrix:**
|
|
146
|
+
|
|
147
|
+
| Solution | Setup Effort | Usage Simplicity | CI/CD Ready | Maintenance |
|
|
148
|
+
|----------|--------------|------------------|-------------|-------------|
|
|
149
|
+
| NPM Package | High | Excellent | Excellent | Low |
|
|
150
|
+
| Shell Script | Low | Good | Good | Medium |
|
|
151
|
+
| NPM Scripts | Medium | Good | Excellent | High |
|
|
152
|
+
|
|
153
|
+
**Recommendation: Start with Shell Script (quick), then migrate to NPM Package (professional).**
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
# 🎯 SunLint vs ESLint Integration Strategy Analysis
|
|
2
|
+
|
|
3
|
+
## 📊 **Current Situation Assessment**
|
|
4
|
+
|
|
5
|
+
### **Team Assets:**
|
|
6
|
+
- ✅ **29+ mature ESLint custom rules** đã được team phát triển
|
|
7
|
+
- ✅ **Production-ready** codebase với nhiều contributors
|
|
8
|
+
- ✅ **Comprehensive coverage** for TypeScript
|
|
9
|
+
- ✅ **Established workflow** với ESLint integration
|
|
10
|
+
|
|
11
|
+
### **SunLint Unique Value:**
|
|
12
|
+
- ✅ **Multi-language support** (TypeScript, Dart, Kotlin)
|
|
13
|
+
- ✅ **AI-powered analysis** capabilities
|
|
14
|
+
- ✅ **Specialized rules** (C019, C029, C031) không có trong ESLint
|
|
15
|
+
- ✅ **CI/CD optimization** features
|
|
16
|
+
|
|
17
|
+
### **Overlap Analysis:**
|
|
18
|
+
| Rule | ESLint Custom | SunLint | Status |
|
|
19
|
+
|------|---------------|---------|--------|
|
|
20
|
+
| **C003** | ✅ Mature | ❌ Không có | ESLint wins |
|
|
21
|
+
| **C006** | ✅ Mature | ✅ Basic | ESLint better |
|
|
22
|
+
| **C019** | ❌ Không có | ✅ Specialized | SunLint unique |
|
|
23
|
+
| **C029** | ✅ c029, c035 | ✅ Specialized | Both have |
|
|
24
|
+
| **C031** | ❌ Không có | ✅ Specialized | SunLint unique |
|
|
25
|
+
|
|
26
|
+
## 🎯 **SOLUTION ANALYSIS**
|
|
27
|
+
|
|
28
|
+
### **Solution 1: Makefile Integration**
|
|
29
|
+
```bash
|
|
30
|
+
# Makefile approach
|
|
31
|
+
.PHONY: lint
|
|
32
|
+
lint: lint-eslint lint-sunlint
|
|
33
|
+
|
|
34
|
+
lint-eslint:
|
|
35
|
+
cd coding-quality/config/typescript && ./run.sh
|
|
36
|
+
|
|
37
|
+
lint-sunlint:
|
|
38
|
+
cd coding-quality/extensions/sunlint && node cli.js --all --input=src
|
|
39
|
+
|
|
40
|
+
lint-report:
|
|
41
|
+
$(MAKE) lint-eslint --json > eslint-report.json
|
|
42
|
+
$(MAKE) lint-sunlint --format=json > sunlint-report.json
|
|
43
|
+
node merge-reports.js eslint-report.json sunlint-report.json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**✅ Pros:**
|
|
47
|
+
- ✅ **Zero migration cost** - giữ nguyên existing work
|
|
48
|
+
- ✅ **Fast implementation** - 1-2 days setup
|
|
49
|
+
- ✅ **Parallel execution** - có thể chạy concurrent
|
|
50
|
+
- ✅ **Tool independence** - mỗi tool độc lập
|
|
51
|
+
- ✅ **Team harmony** - không ảnh hưởng existing work
|
|
52
|
+
|
|
53
|
+
**❌ Cons:**
|
|
54
|
+
- ❌ **Fragmented results** - cần merge reports
|
|
55
|
+
- ❌ **Duplicated overhead** - chạy 2 tools
|
|
56
|
+
- ❌ **Configuration drift** - 2 sets of configs
|
|
57
|
+
- ❌ **Learning curve** - team cần biết cả 2 tools
|
|
58
|
+
|
|
59
|
+
**🎯 Score: 7/10** - Good short-term solution
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
### **Solution 2: Keep Separate Tools**
|
|
64
|
+
```bash
|
|
65
|
+
# Current approach - no changes
|
|
66
|
+
npm run lint:eslint
|
|
67
|
+
npm run lint:sunlint
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**✅ Pros:**
|
|
71
|
+
- ✅ **No migration cost**
|
|
72
|
+
- ✅ **Maximum flexibility**
|
|
73
|
+
- ✅ **Tool specialization**
|
|
74
|
+
- ✅ **Zero risk**
|
|
75
|
+
|
|
76
|
+
**❌ Cons:**
|
|
77
|
+
- ❌ **Manual coordination**
|
|
78
|
+
- ❌ **Inconsistent adoption**
|
|
79
|
+
- ❌ **Results fragmentation**
|
|
80
|
+
- ❌ **CI/CD complexity**
|
|
81
|
+
|
|
82
|
+
**🎯 Score: 5/10** - Status quo, but not scalable
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
### **Solution 3A: ESLint Plugin for SunLint**
|
|
87
|
+
```bash
|
|
88
|
+
# Embed ESLint rules into SunLint
|
|
89
|
+
node cli.js --all --include-eslint --input=src
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**✅ Pros:**
|
|
93
|
+
- ✅ **Unified command** - single entry point
|
|
94
|
+
- ✅ **Leverage existing rules** - 29+ rules preserved
|
|
95
|
+
- ✅ **Fast to implement** - ESLint integration
|
|
96
|
+
- ✅ **Consistent output** - single report format
|
|
97
|
+
|
|
98
|
+
**❌ Cons:**
|
|
99
|
+
- ❌ **TypeScript only** - hard to extend to Dart/Kotlin
|
|
100
|
+
- ❌ **ESLint dependency** - adds complexity
|
|
101
|
+
- ❌ **Performance overhead** - running ESLint inside SunLint
|
|
102
|
+
- ❌ **Limited AI integration** - ESLint rules can't use AI
|
|
103
|
+
|
|
104
|
+
**🎯 Score: 6/10** - Quick fix but not scalable
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
### **Solution 3B: Migrate ESLint Rules to SunLint**
|
|
109
|
+
```bash
|
|
110
|
+
# Pure SunLint approach
|
|
111
|
+
node cli.js --all --input=src # All rules in SunLint
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**✅ Pros:**
|
|
115
|
+
- ✅ **Unified architecture** - single system
|
|
116
|
+
- ✅ **Multi-language ready** - Dart, Kotlin support
|
|
117
|
+
- ✅ **AI integration** - all rules can use AI
|
|
118
|
+
- ✅ **Performance optimized** - single pass analysis
|
|
119
|
+
- ✅ **Future-proof** - scalable architecture
|
|
120
|
+
|
|
121
|
+
**❌ Cons:**
|
|
122
|
+
- ❌ **High migration cost** - 3-6 months effort
|
|
123
|
+
- ❌ **Team disruption** - major workflow change
|
|
124
|
+
- ❌ **Risk of regression** - might miss edge cases
|
|
125
|
+
- ❌ **Doesn't acknowledge team effort** - feels like "starting over"
|
|
126
|
+
|
|
127
|
+
**🎯 Score: 8/10** - Best long-term but expensive
|
|
128
|
+
|
|
129
|
+
## 🏆 **RECOMMENDED SOLUTION: Hybrid Evolution Strategy**
|
|
130
|
+
|
|
131
|
+
### **Phase 1: Immediate Integration (1-2 weeks)**
|
|
132
|
+
```bash
|
|
133
|
+
# Enhanced Makefile + Report Merger
|
|
134
|
+
make lint-all # Runs both ESLint + SunLint
|
|
135
|
+
make lint-report # Unified JSON report
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Implementation:**
|
|
139
|
+
```makefile
|
|
140
|
+
# Makefile
|
|
141
|
+
.PHONY: lint-all lint-eslint lint-sunlint lint-report
|
|
142
|
+
|
|
143
|
+
lint-all: lint-eslint lint-sunlint
|
|
144
|
+
|
|
145
|
+
lint-eslint:
|
|
146
|
+
@echo "🔍 Running ESLint analysis..."
|
|
147
|
+
cd coding-quality/config/typescript && \
|
|
148
|
+
./run.sh --json --export-json --json-file ../../extensions/sunlint/eslint-results.json $(INPUT)
|
|
149
|
+
|
|
150
|
+
lint-sunlint:
|
|
151
|
+
@echo "☀️ Running SunLint analysis..."
|
|
152
|
+
cd coding-quality/extensions/sunlint && \
|
|
153
|
+
node cli.js --all --input=$(INPUT) --format=json --output=sunlint-results.json --no-ai
|
|
154
|
+
|
|
155
|
+
lint-report: lint-all
|
|
156
|
+
@echo "📊 Generating unified report..."
|
|
157
|
+
cd coding-quality/extensions/sunlint && \
|
|
158
|
+
node scripts/merge-reports.js eslint-results.json sunlint-results.json --output=unified-report.json
|
|
159
|
+
@echo "✅ Unified report: unified-report.json"
|
|
160
|
+
|
|
161
|
+
# Usage
|
|
162
|
+
INPUT ?= src
|
|
163
|
+
lint: lint-all
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### **Phase 2: SunLint ESLint Adapter (1-2 months)**
|
|
167
|
+
```javascript
|
|
168
|
+
// SunLint với ESLint integration
|
|
169
|
+
node cli.js --all --include-eslint --eslint-config=../config/typescript/.eslintrc.cjs --input=src
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Implementation Strategy:**
|
|
173
|
+
1. **ESLint Runner Integration** trong SunLint
|
|
174
|
+
2. **Report normalization** - convert ESLint output to SunLint format
|
|
175
|
+
3. **Unified configuration** - single config controls both
|
|
176
|
+
4. **Gradual migration** - opt-in per rule
|
|
177
|
+
|
|
178
|
+
### **Phase 3: Selective Migration (3-6 months)**
|
|
179
|
+
```javascript
|
|
180
|
+
// Migrate high-value rules only
|
|
181
|
+
const migrationPriority = {
|
|
182
|
+
immediate: ['c003', 'c006'], // High overlap with SunLint
|
|
183
|
+
later: ['c010', 'c013'], // Complex but valuable
|
|
184
|
+
keep_eslint: ['t002', 't003'] // TypeScript-specific
|
|
185
|
+
};
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Migration Strategy:**
|
|
189
|
+
1. **Automated conversion tools** - convert ESLint AST → SunLint patterns
|
|
190
|
+
2. **A/B testing** - run both versions, compare results
|
|
191
|
+
3. **Gradual rollout** - migrate 2-3 rules per sprint
|
|
192
|
+
4. **Team validation** - original authors review migrations
|
|
193
|
+
|
|
194
|
+
## 🎯 **DETAILED IMPLEMENTATION PLAN**
|
|
195
|
+
|
|
196
|
+
### **Week 1-2: Quick Win (Makefile + Report Merger)**
|
|
197
|
+
|
|
198
|
+
#### **Step 1: Enhanced Makefile**
|
|
199
|
+
```makefile
|
|
200
|
+
# coding-quality/Makefile
|
|
201
|
+
include config/typescript/eslint.mk
|
|
202
|
+
include extensions/sunlint/sunlint.mk
|
|
203
|
+
|
|
204
|
+
.PHONY: install lint lint-quick lint-full ci-lint
|
|
205
|
+
|
|
206
|
+
install:
|
|
207
|
+
cd config/typescript && npm install
|
|
208
|
+
cd extensions/sunlint && npm install
|
|
209
|
+
|
|
210
|
+
lint-quick: lint-sunlint-changed
|
|
211
|
+
lint-full: lint-eslint lint-sunlint-all
|
|
212
|
+
lint: lint-full
|
|
213
|
+
|
|
214
|
+
ci-lint:
|
|
215
|
+
$(MAKE) lint-full INPUT=src FORMAT=github
|
|
216
|
+
node scripts/ci-report.js
|
|
217
|
+
|
|
218
|
+
# Development shortcuts
|
|
219
|
+
lint-staged:
|
|
220
|
+
$(MAKE) lint-sunlint-staged
|
|
221
|
+
|
|
222
|
+
lint-pr:
|
|
223
|
+
$(MAKE) lint-sunlint-changed BASE=origin/main
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
#### **Step 2: Report Merger Script**
|
|
227
|
+
```javascript
|
|
228
|
+
// scripts/merge-reports.js
|
|
229
|
+
const fs = require('fs');
|
|
230
|
+
const path = require('path');
|
|
231
|
+
|
|
232
|
+
class ReportMerger {
|
|
233
|
+
mergeReports(eslintReport, sunlintReport) {
|
|
234
|
+
return {
|
|
235
|
+
tools: {
|
|
236
|
+
eslint: this.normalizeESLintReport(eslintReport),
|
|
237
|
+
sunlint: this.normalizeSunLintReport(sunlintReport)
|
|
238
|
+
},
|
|
239
|
+
summary: this.generateSummary(eslintReport, sunlintReport),
|
|
240
|
+
violations: this.mergeViolations(eslintReport, sunlintReport),
|
|
241
|
+
metadata: {
|
|
242
|
+
timestamp: new Date().toISOString(),
|
|
243
|
+
tools_version: {
|
|
244
|
+
eslint: this.getESLintVersion(),
|
|
245
|
+
sunlint: this.getSunLintVersion()
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
generateSummary(eslint, sunlint) {
|
|
252
|
+
return {
|
|
253
|
+
total_files: this.getTotalFiles(eslint, sunlint),
|
|
254
|
+
total_violations: this.getTotalViolations(eslint, sunlint),
|
|
255
|
+
by_severity: this.mergeSeverities(eslint, sunlint),
|
|
256
|
+
by_tool: {
|
|
257
|
+
eslint: this.getToolSummary(eslint),
|
|
258
|
+
sunlint: this.getToolSummary(sunlint)
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### **Month 1-2: ESLint Integration**
|
|
266
|
+
|
|
267
|
+
#### **Step 1: SunLint ESLint Adapter**
|
|
268
|
+
```javascript
|
|
269
|
+
// core/eslint-adapter.js
|
|
270
|
+
class ESLintAdapter {
|
|
271
|
+
constructor(eslintConfigPath) {
|
|
272
|
+
this.eslintConfigPath = eslintConfigPath;
|
|
273
|
+
this.eslint = require('eslint');
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
async runESLintRules(files, options) {
|
|
277
|
+
const engine = new this.eslint.ESLint({
|
|
278
|
+
configFile: this.eslintConfigPath,
|
|
279
|
+
useEslintrc: false
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
const results = await engine.lintFiles(files);
|
|
283
|
+
return this.convertToSunLintFormat(results);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
convertToSunLintFormat(eslintResults) {
|
|
287
|
+
return eslintResults.map(result => ({
|
|
288
|
+
file: result.filePath,
|
|
289
|
+
violations: result.messages.map(msg => ({
|
|
290
|
+
ruleId: `eslint/${msg.ruleId}`,
|
|
291
|
+
line: msg.line,
|
|
292
|
+
column: msg.column,
|
|
293
|
+
message: msg.message,
|
|
294
|
+
severity: this.mapSeverity(msg.severity),
|
|
295
|
+
source: 'eslint'
|
|
296
|
+
}))
|
|
297
|
+
}));
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
#### **Step 2: Enhanced CLI Options**
|
|
303
|
+
```javascript
|
|
304
|
+
// cli.js enhancements
|
|
305
|
+
program
|
|
306
|
+
.option('--include-eslint', 'Include ESLint custom rules')
|
|
307
|
+
.option('--eslint-config <path>', 'ESLint config file path')
|
|
308
|
+
.option('--eslint-only', 'Run only ESLint rules')
|
|
309
|
+
.option('--sunlint-only', 'Run only SunLint rules')
|
|
310
|
+
.option('--tool-comparison', 'Run both tools and compare results');
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### **Month 3-6: Selective Migration**
|
|
314
|
+
|
|
315
|
+
#### **Migration Priority Matrix:**
|
|
316
|
+
```javascript
|
|
317
|
+
const migrationPlan = {
|
|
318
|
+
// High priority - good candidates for migration
|
|
319
|
+
immediate: {
|
|
320
|
+
'c003': {
|
|
321
|
+
reason: 'Variable naming - core feature',
|
|
322
|
+
complexity: 'medium',
|
|
323
|
+
ai_potential: 'high',
|
|
324
|
+
estimated_effort: '1 week'
|
|
325
|
+
},
|
|
326
|
+
'c006': {
|
|
327
|
+
reason: 'Function naming - already exists in SunLint',
|
|
328
|
+
complexity: 'low',
|
|
329
|
+
ai_potential: 'medium',
|
|
330
|
+
estimated_effort: '3 days'
|
|
331
|
+
}
|
|
332
|
+
},
|
|
333
|
+
|
|
334
|
+
// Medium priority - valuable but complex
|
|
335
|
+
later: {
|
|
336
|
+
'c010': {
|
|
337
|
+
reason: 'Block nesting - architectural rule',
|
|
338
|
+
complexity: 'high',
|
|
339
|
+
ai_potential: 'high',
|
|
340
|
+
estimated_effort: '2 weeks'
|
|
341
|
+
},
|
|
342
|
+
'c013': {
|
|
343
|
+
reason: 'Dead code - useful across languages',
|
|
344
|
+
complexity: 'high',
|
|
345
|
+
ai_potential: 'very_high',
|
|
346
|
+
estimated_effort: '3 weeks'
|
|
347
|
+
}
|
|
348
|
+
},
|
|
349
|
+
|
|
350
|
+
// Keep in ESLint - TypeScript specific
|
|
351
|
+
keep_eslint: {
|
|
352
|
+
't002': { reason: 'Interface prefix - TS specific syntax' },
|
|
353
|
+
't003': { reason: 'TS ignore reason - TS compiler specific' },
|
|
354
|
+
't004': { reason: 'Interface public only - TS type system' }
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
## 📊 **COST-BENEFIT ANALYSIS**
|
|
360
|
+
|
|
361
|
+
| Solution | Implementation Time | Maintenance Cost | Team Disruption | Long-term Value |
|
|
362
|
+
|----------|-------------------|------------------|-----------------|-----------------|
|
|
363
|
+
| **Makefile** | 1-2 weeks | Low | Minimal | Medium |
|
|
364
|
+
| **ESLint Integration** | 1-2 months | Medium | Low | High |
|
|
365
|
+
| **Full Migration** | 3-6 months | Low | High | Very High |
|
|
366
|
+
| **Hybrid Evolution** | 3-4 months total | Medium | Gradual | Very High |
|
|
367
|
+
|
|
368
|
+
## 🎯 **FINAL RECOMMENDATION**
|
|
369
|
+
|
|
370
|
+
### **🏆 Choose: Hybrid Evolution Strategy**
|
|
371
|
+
|
|
372
|
+
**Rationale:**
|
|
373
|
+
1. **Preserves team effort** - ESLint rules remain valuable
|
|
374
|
+
2. **Immediate benefits** - unified reporting in weeks
|
|
375
|
+
3. **Future flexibility** - gradual migration path
|
|
376
|
+
4. **Risk mitigation** - incremental changes
|
|
377
|
+
5. **Team buy-in** - respects existing work
|
|
378
|
+
|
|
379
|
+
**Success Metrics:**
|
|
380
|
+
- ✅ **Week 2**: Unified report generation
|
|
381
|
+
- ✅ **Month 1**: Single command execution
|
|
382
|
+
- ✅ **Month 2**: ESLint integration in SunLint
|
|
383
|
+
- ✅ **Month 6**: 50% rules migrated to SunLint
|
|
384
|
+
- ✅ **Year 1**: Multi-language support with migrated rules
|
|
385
|
+
|
|
386
|
+
**Key Decision Factors:**
|
|
387
|
+
- ✅ **Team productivity** > tool purity
|
|
388
|
+
- ✅ **Incremental value** > big bang approach
|
|
389
|
+
- ✅ **Respect existing work** > reinvent everything
|
|
390
|
+
- ✅ **Multi-language future** > TypeScript-only optimization
|
|
391
|
+
|
|
392
|
+
This strategy acknowledges your team's investment while building toward a unified, scalable future! 🚀
|