@sun-asterisk/sunlint 1.0.7 β 1.1.4
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/.sunlint.json +35 -0
- package/CHANGELOG.md +30 -3
- package/CONTRIBUTING.md +235 -0
- package/PROJECT_STRUCTURE.md +60 -0
- package/README.md +146 -58
- package/cli.js +1 -0
- package/config/README.md +88 -0
- package/config/defaults/ai-rules-context.json +231 -0
- package/config/engines/engines.json +49 -0
- package/config/engines/eslint-rule-mapping.json +74 -0
- package/config/eslint-rule-mapping.json +126 -0
- package/config/integrations/eslint/base.config.js +125 -0
- package/config/integrations/eslint/simple.config.js +24 -0
- package/config/presets/strict.json +0 -1
- package/config/rule-analysis-strategies.js +74 -0
- package/config/{rules-registry.json β rules/rules-registry.json} +30 -7
- package/core/analysis-orchestrator.js +383 -591
- package/core/ast-modules/README.md +103 -0
- package/core/ast-modules/base-parser.js +90 -0
- package/core/ast-modules/index.js +97 -0
- package/core/ast-modules/package.json +37 -0
- package/core/ast-modules/parsers/eslint-js-parser.js +153 -0
- package/core/ast-modules/parsers/eslint-ts-parser.js +98 -0
- package/core/ast-modules/parsers/javascript-parser.js +187 -0
- package/core/ast-modules/parsers/typescript-parser.js +187 -0
- package/core/cli-action-handler.js +271 -255
- package/core/cli-program.js +18 -4
- package/core/config-manager.js +9 -3
- package/core/config-merger.js +40 -1
- package/core/config-validator.js +2 -2
- package/core/dependency-checker.js +125 -0
- package/core/enhanced-rules-registry.js +331 -0
- package/core/file-targeting-service.js +92 -23
- package/core/interfaces/analysis-engine.interface.js +100 -0
- package/core/multi-rule-runner.js +0 -221
- package/core/output-service.js +1 -1
- package/core/rule-mapping-service.js +1 -1
- package/core/rule-selection-service.js +10 -2
- package/core/smart-installer.js +164 -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/CONFIGURATION.md +414 -0
- package/docs/DEBUG.md +86 -0
- package/docs/DEPENDENCIES.md +90 -0
- package/docs/DEPLOYMENT-STRATEGIES.md +270 -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/FUTURE_PACKAGES.md +83 -0
- package/docs/HEURISTIC_VS_AI.md +113 -0
- package/docs/PRODUCTION_DEPLOYMENT_ANALYSIS.md +112 -0
- package/docs/PRODUCTION_SIZE_IMPACT.md +183 -0
- package/docs/README.md +32 -0
- package/docs/RELEASE_GUIDE.md +230 -0
- package/engines/eslint-engine.js +610 -0
- package/engines/heuristic-engine.js +864 -0
- package/engines/openai-engine.js +374 -0
- package/engines/tree-sitter-parser.js +0 -0
- package/engines/universal-ast-engine.js +0 -0
- package/integrations/eslint/README.md +99 -0
- package/integrations/eslint/configs/.eslintrc.js +98 -0
- package/integrations/eslint/configs/eslint.config.js +133 -0
- package/integrations/eslint/configs/eslint.config.simple.js +24 -0
- package/integrations/eslint/package.json +23 -0
- package/integrations/eslint/plugin/index.js +164 -0
- package/integrations/eslint/plugin/package.json +13 -0
- package/integrations/eslint/plugin/rules/common/c002-no-duplicate-code.js +204 -0
- package/integrations/eslint/plugin/rules/common/c003-no-vague-abbreviations.js +246 -0
- package/integrations/eslint/plugin/rules/common/c006-function-name-verb-noun.js +216 -0
- package/integrations/eslint/plugin/rules/common/c010-limit-block-nesting.js +90 -0
- package/integrations/eslint/plugin/rules/common/c013-no-dead-code.js +78 -0
- package/integrations/eslint/plugin/rules/common/c014-abstract-dependency-preferred.js +38 -0
- package/integrations/eslint/plugin/rules/common/c017-limit-constructor-logic.js +146 -0
- package/integrations/eslint/plugin/rules/common/c018-no-generic-throw.js +335 -0
- package/integrations/eslint/plugin/rules/common/c023-no-duplicate-variable-name-in-scope.js +142 -0
- package/integrations/eslint/plugin/rules/common/c029-catch-block-logging.js +115 -0
- package/integrations/eslint/plugin/rules/common/c030-use-custom-error-classes.js +294 -0
- package/integrations/eslint/plugin/rules/common/c035-no-empty-catch.js +162 -0
- package/integrations/eslint/plugin/rules/common/c041-no-config-inline.js +122 -0
- package/integrations/eslint/plugin/rules/common/c042-boolean-name-prefix.js +406 -0
- package/integrations/eslint/plugin/rules/common/c043-no-console-or-print.js +300 -0
- package/integrations/eslint/plugin/rules/common/c047-no-duplicate-retry-logic.js +239 -0
- package/integrations/eslint/plugin/rules/common/c072-one-assert-per-test.js +184 -0
- package/integrations/eslint/plugin/rules/common/c075-explicit-function-return-types.js +168 -0
- package/integrations/eslint/plugin/rules/common/c076-single-behavior-per-test.js +254 -0
- package/integrations/eslint/plugin/rules/security/s001-fail-securely.js +381 -0
- package/integrations/eslint/plugin/rules/security/s002-idor-check.js +945 -0
- package/integrations/eslint/plugin/rules/security/s003-no-unvalidated-redirect.js +86 -0
- package/integrations/eslint/plugin/rules/security/s007-no-plaintext-otp.js +74 -0
- package/integrations/eslint/plugin/rules/security/s013-verify-tls-connection.js +47 -0
- package/integrations/eslint/plugin/rules/security/s047-secure-random-passwords.js +108 -0
- package/integrations/eslint/plugin/rules/security/s055-verification-rest-check-the-incoming-content-type.js +143 -0
- package/integrations/eslint/plugin/rules/typescript/t002-interface-prefix-i.js +42 -0
- package/integrations/eslint/plugin/rules/typescript/t003-ts-ignore-reason.js +48 -0
- package/integrations/eslint/plugin/rules/typescript/t004-no-empty-type.js +95 -0
- package/integrations/eslint/plugin/rules/typescript/t007-no-fn-in-constructor.js +52 -0
- package/integrations/eslint/plugin/rules/typescript/t010-no-nested-union-tuple.js +48 -0
- package/integrations/eslint/plugin/rules/typescript/t019-no-this-assign.js +81 -0
- package/integrations/eslint/plugin/rules/typescript/t020-no-default-multi-export.js +127 -0
- package/integrations/eslint/plugin/rules/typescript/t021-limit-nested-generics.js +150 -0
- package/integrations/eslint/tsconfig.json +27 -0
- package/package.json +61 -21
- package/rules/README.md +252 -0
- package/rules/common/C002_no_duplicate_code/analyzer.js +65 -0
- package/rules/common/C002_no_duplicate_code/config.json +23 -0
- package/rules/common/C003_no_vague_abbreviations/analyzer.js +418 -0
- package/rules/common/C003_no_vague_abbreviations/config.json +35 -0
- package/rules/{C006_function_naming β common/C006_function_naming}/analyzer.js +13 -2
- package/rules/common/C010_limit_block_nesting/analyzer.js +389 -0
- package/rules/common/C013_no_dead_code/analyzer.js +206 -0
- package/rules/common/C014_dependency_injection/analyzer.js +338 -0
- package/rules/common/C017_constructor_logic/analyzer.js +314 -0
- package/rules/{C019_log_level_usage β common/C019_log_level_usage}/analyzer.js +5 -2
- package/rules/{C029_catch_block_logging β common/C029_catch_block_logging}/analyzer.js +49 -15
- package/rules/common/C041_no_sensitive_hardcode/analyzer.js +292 -0
- package/rules/common/C042_boolean_name_prefix/analyzer.js +300 -0
- package/rules/common/C043_no_console_or_print/analyzer.js +304 -0
- package/rules/common/C047_no_duplicate_retry_logic/analyzer.js +351 -0
- package/rules/common/C075_explicit_return_types/analyzer.js +103 -0
- package/rules/common/C076_single_test_behavior/analyzer.js +121 -0
- package/rules/docs/C002_no_duplicate_code.md +57 -0
- package/rules/index.js +149 -0
- package/rules/migration/converter.js +385 -0
- package/rules/migration/mapping.json +164 -0
- package/rules/security/S026_json_schema_validation/analyzer.js +251 -0
- package/rules/security/S026_json_schema_validation/config.json +27 -0
- package/rules/security/S027_no_hardcoded_secrets/analyzer.js +263 -0
- package/rules/security/S027_no_hardcoded_secrets/config.json +29 -0
- package/rules/security/S029_csrf_protection/analyzer.js +264 -0
- package/rules/tests/C002_no_duplicate_code.test.js +50 -0
- package/rules/universal/C010/generic.js +0 -0
- package/rules/universal/C010/tree-sitter-analyzer.js +0 -0
- package/rules/utils/ast-utils.js +191 -0
- package/rules/utils/base-analyzer.js +98 -0
- package/rules/utils/pattern-matchers.js +239 -0
- package/rules/utils/rule-helpers.js +264 -0
- package/rules/utils/severity-constants.js +93 -0
- package/scripts/build-release.sh +117 -0
- package/scripts/ci-report.js +179 -0
- package/scripts/install.sh +196 -0
- package/scripts/manual-release.sh +338 -0
- package/scripts/merge-reports.js +424 -0
- package/scripts/pre-release-test.sh +175 -0
- package/scripts/prepare-release.sh +202 -0
- package/scripts/setup-github-registry.sh +42 -0
- package/scripts/test-scripts/README.md +22 -0
- package/scripts/test-scripts/test-c041-comparison.js +114 -0
- package/scripts/test-scripts/test-c041-eslint.js +67 -0
- package/scripts/test-scripts/test-eslint-rules.js +146 -0
- package/scripts/test-scripts/test-real-world.js +44 -0
- package/scripts/test-scripts/test-rules-on-real-projects.js +86 -0
- package/scripts/trigger-release.sh +285 -0
- package/scripts/validate-rule-structure.js +148 -0
- package/scripts/verify-install.sh +82 -0
- package/config/sunlint-schema.json +0 -159
- package/config/typescript/custom-rules.js +0 -9
- package/config/typescript/package-lock.json +0 -1585
- package/config/typescript/package.json +0 -13
- package/config/typescript/security-rules/index.js +0 -90
- package/config/typescript/tsconfig.json +0 -29
- package/core/ai-analyzer.js +0 -169
- package/core/eslint-engine-service.js +0 -312
- package/core/eslint-instance-manager.js +0 -104
- package/core/eslint-integration-service.js +0 -363
- package/core/sunlint-engine-service.js +0 -23
- package/core/typescript-analyzer.js +0 -262
- package/core/typescript-engine.js +0 -313
- /package/config/{default.json β defaults/default.json} +0 -0
- /package/config/{typescript/eslint.config.js β integrations/eslint/typescript.config.js} +0 -0
- /package/config/{typescript/custom-rules-new.js β schemas/sunlint-schema.json} +0 -0
- /package/config/{typescript β testing}/test-s005-working.ts +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s005-no-origin-auth.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s006-activation-recovery-secret-not-plaintext.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s008-crypto-agility.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s009-no-insecure-crypto.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s010-no-insecure-random-in-sensitive-context.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s011-no-insecure-uuid.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s012-hardcode-secret.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s014-insecure-tls-version.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s015-insecure-tls-certificate.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s016-sensitive-query-parameter.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s017-no-sql-injection.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s018-positive-input-validation.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s019-no-raw-user-input-in-email.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s020-no-eval-dynamic-execution.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s022-output-encoding.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s023-no-json-injection.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s025-server-side-input-validation.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s026-json-schema-validation.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s027-no-hardcoded-secrets.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s029-require-csrf-protection.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s030-no-directory-browsing.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s033-require-samesite-cookie.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s034-require-host-cookie-prefix.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s035-cookie-specific-path.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s036-no-unsafe-file-include.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s037-require-anti-cache-headers.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s038-no-version-disclosure.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s039-no-session-token-in-url.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s041-require-session-invalidate-on-logout.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s042-require-periodic-reauthentication.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s043-terminate-sessions-on-password-change.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s044-require-full-session-for-sensitive-operations.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s045-anti-automation-controls.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s046-secure-notification-on-auth-change.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s048-password-credential-recovery.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s050-session-token-weak-hash.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s052-secure-random-authentication-code.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s054-verification-default-account.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s057-utc-logging.js +0 -0
- /package/{config/typescript/security-rules β integrations/eslint/plugin/rules/security}/s058-no-ssrf.js +0 -0
- /package/rules/{C006_function_naming β common/C006_function_naming}/config.json +0 -0
- /package/rules/{C019_log_level_usage β common/C019_log_level_usage}/config.json +0 -0
- /package/rules/{C029_catch_block_logging β common/C029_catch_block_logging}/config.json +0 -0
- /package/rules/{C031_validation_separation β common/C031_validation_separation}/analyzer.js +0 -0
- /package/rules/{C031_validation_separation/README.md β docs/C031_validation_separation.md} +0 -0
|
@@ -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! π
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# ESLint Integration Feature
|
|
2
|
+
|
|
3
|
+
## π― **Overview**
|
|
4
|
+
|
|
5
|
+
SunLint ESLint Integration cho phΓ©p teams **merge** existing ESLint configuration vα»i SunLint rules trong **single execution pipeline**. Thay vΓ¬ chαΊ‘y parallel, SunLint sαΊ½ **orchestrate** vΓ **combine** cαΊ£ 2 rule sets.
|
|
6
|
+
|
|
7
|
+
### **Problem Solved**
|
|
8
|
+
- β
Teams cΓ³ existing ESLint (20 rules) + muα»n add SunLint (93 rules) = **113 rules total**
|
|
9
|
+
- β
Single command execution thay vì multiple tool chains
|
|
10
|
+
- β
No degradation cα»§a existing ESLint workflow
|
|
11
|
+
- β
Combined reporting cho easier debugging
|
|
12
|
+
|
|
13
|
+
## π **Configuration**
|
|
14
|
+
|
|
15
|
+
### **Method 1: package.json Configuration**
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"scripts": {
|
|
19
|
+
"lint:integrated": "sunlint --all --eslint-integration --input=src"
|
|
20
|
+
},
|
|
21
|
+
"sunlint": {
|
|
22
|
+
"eslintIntegration": {
|
|
23
|
+
"enabled": true,
|
|
24
|
+
"mergeRules": true,
|
|
25
|
+
"preserveUserConfig": true
|
|
26
|
+
},
|
|
27
|
+
"rules": {
|
|
28
|
+
"C006": "warn",
|
|
29
|
+
"C019": "error"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### **Method 2: .sunlint.json Configuration**
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"eslintIntegration": {
|
|
39
|
+
"enabled": true,
|
|
40
|
+
"mergeRules": true,
|
|
41
|
+
"preserveUserConfig": true,
|
|
42
|
+
"runAfterSunLint": false
|
|
43
|
+
},
|
|
44
|
+
"rules": {
|
|
45
|
+
"C006": "warn",
|
|
46
|
+
"C019": "error",
|
|
47
|
+
"S047": "warn"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### **Method 3: CLI Flags**
|
|
53
|
+
```bash
|
|
54
|
+
# Enable integration
|
|
55
|
+
sunlint --all --eslint-integration --input=src
|
|
56
|
+
|
|
57
|
+
# Merge rules (default: true)
|
|
58
|
+
sunlint --all --eslint-integration --eslint-merge-rules --input=src
|
|
59
|
+
|
|
60
|
+
# Preserve user config (default: true)
|
|
61
|
+
sunlint --all --eslint-integration --eslint-preserve-config --input=src
|
|
62
|
+
|
|
63
|
+
# Run ESLint after SunLint (alternative to merge)
|
|
64
|
+
sunlint --all --eslint-integration --eslint-run-after --input=src
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## π§ **Integration Modes**
|
|
68
|
+
|
|
69
|
+
### **Mode 1: Merged Execution (Default)**
|
|
70
|
+
```bash
|
|
71
|
+
sunlint --all --eslint-integration --input=src
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**How it works:**
|
|
75
|
+
1. SunLint discovers existing `.eslintrc.json`
|
|
76
|
+
2. Merges SunLint rules + User ESLint rules
|
|
77
|
+
3. Creates combined ESLint configuration
|
|
78
|
+
4. Runs single ESLint execution with **merged ruleset**
|
|
79
|
+
5. Categorizes results by rule source (SunLint vs User)
|
|
80
|
+
|
|
81
|
+
**Output:**
|
|
82
|
+
```
|
|
83
|
+
π ESLint Integration Summary:
|
|
84
|
+
π SunLint violations: 4
|
|
85
|
+
π§ User ESLint violations: 6
|
|
86
|
+
π Total combined violations: 10
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### **Mode 2: Sequential Execution**
|
|
90
|
+
```bash
|
|
91
|
+
sunlint --all --eslint-integration --eslint-run-after --input=src
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**How it works:**
|
|
95
|
+
1. Run SunLint rules first
|
|
96
|
+
2. Run user ESLint rules after
|
|
97
|
+
3. Combine results for reporting
|
|
98
|
+
4. Maintain separation of concerns
|
|
99
|
+
|
|
100
|
+
## π **Usage Examples**
|
|
101
|
+
|
|
102
|
+
### **Basic Integration**
|
|
103
|
+
```bash
|
|
104
|
+
# Analyze with both SunLint + existing ESLint rules
|
|
105
|
+
sunlint --typescript --eslint-integration --input=src
|
|
106
|
+
|
|
107
|
+
# Git integration + ESLint integration
|
|
108
|
+
sunlint --all --eslint-integration --changed-files
|
|
109
|
+
|
|
110
|
+
# CI pipeline
|
|
111
|
+
sunlint --all --eslint-integration --changed-files --format=summary --fail-on-new-violations
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### **Team Migration Scripts**
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"scripts": {
|
|
118
|
+
"lint": "npm run lint:integrated",
|
|
119
|
+
"lint:integrated": "sunlint --all --eslint-integration --input=src",
|
|
120
|
+
"lint:changed": "sunlint --all --eslint-integration --changed-files",
|
|
121
|
+
"lint:staged": "sunlint --all --eslint-integration --staged-files",
|
|
122
|
+
"ci:lint": "sunlint --all --eslint-integration --changed-files --format=summary"
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### **GitHub Actions Integration**
|
|
128
|
+
```yaml
|
|
129
|
+
name: Code Quality Check
|
|
130
|
+
on: [pull_request]
|
|
131
|
+
|
|
132
|
+
jobs:
|
|
133
|
+
lint:
|
|
134
|
+
runs-on: ubuntu-latest
|
|
135
|
+
steps:
|
|
136
|
+
- uses: actions/checkout@v3
|
|
137
|
+
- uses: actions/setup-node@v3
|
|
138
|
+
- run: npm ci
|
|
139
|
+
- name: Run Integrated Linting
|
|
140
|
+
run: |
|
|
141
|
+
sunlint --all --eslint-integration --changed-files \
|
|
142
|
+
--diff-base=origin/main \
|
|
143
|
+
--format=summary \
|
|
144
|
+
--fail-on-new-violations
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## ποΈ **Architecture**
|
|
148
|
+
|
|
149
|
+
### **ESLintIntegrationService**
|
|
150
|
+
- **Responsibility**: Detect, load, and merge ESLint configurations
|
|
151
|
+
- **Methods**:
|
|
152
|
+
- `hasExistingESLintConfig()`: Auto-detect existing ESLint setup
|
|
153
|
+
- `loadExistingESLintConfig()`: Load user's ESLint configuration
|
|
154
|
+
- `createMergedConfig()`: Merge SunLint + User rules
|
|
155
|
+
- `runIntegratedAnalysis()`: Execute combined analysis
|
|
156
|
+
|
|
157
|
+
### **Configuration Merging Strategy**
|
|
158
|
+
```javascript
|
|
159
|
+
mergedConfig = {
|
|
160
|
+
extends: [...sunlintExtends, ...userExtends],
|
|
161
|
+
plugins: [...sunlintPlugins, ...userPlugins],
|
|
162
|
+
rules: {
|
|
163
|
+
...sunlintRules,
|
|
164
|
+
...userRules // User rules override SunLint in case of conflicts
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### **Result Categorization**
|
|
170
|
+
```javascript
|
|
171
|
+
{
|
|
172
|
+
results: [...],
|
|
173
|
+
categorized: {
|
|
174
|
+
sunlint: [/* SunLint violations */],
|
|
175
|
+
user: [/* User ESLint violations */],
|
|
176
|
+
combined: [/* All violations */]
|
|
177
|
+
},
|
|
178
|
+
integration: {
|
|
179
|
+
totalRules: 113,
|
|
180
|
+
sunlintRules: 93,
|
|
181
|
+
userRules: 20
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## π― **Benefits**
|
|
187
|
+
|
|
188
|
+
### **For Development Teams**
|
|
189
|
+
- β
**No workflow disruption**: Existing ESLint continues working
|
|
190
|
+
- β
**Single command**: One execution for all quality checks
|
|
191
|
+
- β
**Incremental adoption**: Can enable/disable integration easily
|
|
192
|
+
- β
**Conflict resolution**: User rules take precedence over SunLint
|
|
193
|
+
|
|
194
|
+
### **For CI/CD Pipelines**
|
|
195
|
+
- β
**Faster execution**: Single tool execution vs multiple tools
|
|
196
|
+
- β
**Unified reporting**: Combined results, easier to track
|
|
197
|
+
- β
**Git integration**: Works with `--changed-files`, `--staged-files`
|
|
198
|
+
- β
**Baseline comparison**: `--fail-on-new-violations`
|
|
199
|
+
|
|
200
|
+
### **For Enterprise Adoption**
|
|
201
|
+
- β
**Backward compatibility**: No existing config changes required
|
|
202
|
+
- β
**Gradual migration**: Teams can test integration without commitment
|
|
203
|
+
- β
**Centralized enforcement**: SunLint rules + team-specific ESLint rules
|
|
204
|
+
- β
**Compliance reporting**: Combined violation tracking
|
|
205
|
+
|
|
206
|
+
## π **Example Scenario**
|
|
207
|
+
|
|
208
|
+
**Before Integration:**
|
|
209
|
+
```bash
|
|
210
|
+
# Team workflow (2 separate commands)
|
|
211
|
+
npm run lint:eslint # 20 rules, 6 violations
|
|
212
|
+
npm run lint:sunlint # 93 rules, 4 violations
|
|
213
|
+
# Total: 10 violations, 2 command executions
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**After Integration:**
|
|
217
|
+
```bash
|
|
218
|
+
# Single integrated command
|
|
219
|
+
npm run lint:integrated # 113 rules, 10 violations
|
|
220
|
+
# Total: 10 violations, 1 command execution
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## π **Demo**
|
|
224
|
+
|
|
225
|
+
Run the integration demo:
|
|
226
|
+
```bash
|
|
227
|
+
./demo-eslint-integration.sh
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
This demonstrates:
|
|
231
|
+
1. Existing ESLint workflow (20 rules)
|
|
232
|
+
2. SunLint-only analysis (93 rules)
|
|
233
|
+
3. **Integrated analysis (113 rules total)**
|
|
234
|
+
4. Available npm scripts for team adoption
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
**π Result**: Teams can now run **113 total rules** (93 SunLint + 20 existing ESLint) in **single command execution** without disrupting existing workflows!
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Sunlint Folder Structure
|
|
2
|
+
|
|
3
|
+
## Rules Directory Naming Convention
|
|
4
|
+
|
|
5
|
+
All rule folders follow the consistent pattern: `C{ID}_{descriptive_name}`
|
|
6
|
+
|
|
7
|
+
### Current Rules Structure
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
rules/
|
|
11
|
+
βββ C006_function_naming/ # Function naming conventions
|
|
12
|
+
β βββ analyzer.js # Rule implementation
|
|
13
|
+
β βββ config.json # Rule configuration
|
|
14
|
+
βββ C019_log_level_usage/ # Log level usage validation
|
|
15
|
+
β βββ analyzer.js
|
|
16
|
+
β βββ config.json
|
|
17
|
+
βββ C029_catch_block_logging/ # Catch block error logging
|
|
18
|
+
β βββ analyzer.js
|
|
19
|
+
β βββ config.json
|
|
20
|
+
βββ C031_validation_separation/ # Validation logic separation (planned)
|
|
21
|
+
βββ analyzer.js
|
|
22
|
+
βββ config.json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Benefits of This Naming Convention
|
|
26
|
+
|
|
27
|
+
1. **Consistency** - All folders follow the same pattern
|
|
28
|
+
2. **Resilience** - If rule IDs change, descriptive names provide context
|
|
29
|
+
3. **Readability** - Easy to understand rule purpose from folder name
|
|
30
|
+
4. **Maintainability** - Clear organization for developers
|
|
31
|
+
|
|
32
|
+
### Adding New Rules
|
|
33
|
+
|
|
34
|
+
When adding a new rule, follow this pattern:
|
|
35
|
+
|
|
36
|
+
1. Create folder: `C{ID}_{snake_case_description}/`
|
|
37
|
+
2. Add `analyzer.js` with rule implementation
|
|
38
|
+
3. Add `config.json` with rule configuration
|
|
39
|
+
4. Update `rules-registry.json` with correct paths
|
|
40
|
+
5. Add tests in `test/fixtures/`
|
|
41
|
+
|
|
42
|
+
### Example
|
|
43
|
+
|
|
44
|
+
For a new rule C040 about "API Response Format":
|
|
45
|
+
```
|
|
46
|
+
rules/C040_api_response_format/
|
|
47
|
+
βββ analyzer.js
|
|
48
|
+
βββ config.json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Registry entry:
|
|
52
|
+
```json
|
|
53
|
+
"C040": {
|
|
54
|
+
"name": "API Response Format",
|
|
55
|
+
"description": "HΓ m xα» lΓ½ API nΓͺn return response object chuαΊ©n",
|
|
56
|
+
"analyzer": "./rules/C040_api_response_format/analyzer.js",
|
|
57
|
+
"config": "./rules/C040_api_response_format/config.json"
|
|
58
|
+
}
|
|
59
|
+
```
|