@sun-asterisk/sunlint 1.3.47 → 1.3.49
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/config/rules/rules-registry-generated.json +1717 -282
- package/core/architecture-integration.js +57 -15
- package/core/cli-action-handler.js +51 -36
- package/core/config-manager.js +6 -0
- package/core/config-merger.js +33 -0
- package/core/config-validator.js +37 -2
- package/core/file-targeting-service.js +148 -15
- package/core/init-command.js +118 -70
- package/core/output-service.js +12 -3
- package/core/project-detector.js +517 -0
- package/core/scoring-service.js +12 -6
- package/core/summary-report-service.js +9 -4
- package/core/tui-select.js +245 -0
- package/engines/arch-detect/rules/layered/l001-presentation-layer.js +7 -15
- package/engines/arch-detect/rules/layered/l002-business-layer.js +7 -15
- package/engines/arch-detect/rules/layered/l003-data-layer.js +7 -15
- package/engines/arch-detect/rules/layered/l004-model-layer.js +7 -15
- package/engines/arch-detect/rules/layered/l005-layer-separation.js +22 -2
- package/engines/arch-detect/rules/layered/l006-dependency-direction.js +8 -5
- package/engines/arch-detect/rules/modular/m005-no-deep-imports.js +67 -29
- package/engines/arch-detect/rules/presentation/pr001-view-layer.js +16 -9
- package/engines/arch-detect/rules/presentation/pr006-router-layer.js +33 -8
- package/engines/arch-detect/rules/presentation/pr007-interactor-layer.js +35 -6
- package/engines/arch-detect/rules/project-scanner/ps003-framework-detection.js +56 -10
- package/engines/impact/cli.js +54 -39
- package/engines/impact/config/default-config.js +105 -5
- package/engines/impact/core/impact-analyzer.js +12 -15
- package/engines/impact/core/utils/gitignore-parser.js +123 -0
- package/engines/impact/core/utils/method-call-graph.js +272 -87
- package/origin-rules/dart-en.md +1 -1
- package/origin-rules/go-en.md +231 -0
- package/origin-rules/php-en.md +107 -0
- package/origin-rules/python-en.md +113 -0
- package/origin-rules/ruby-en.md +607 -0
- package/package.json +1 -1
- package/scripts/copy-arch-detect.js +5 -1
- package/scripts/copy-impact-analyzer.js +5 -1
- package/scripts/generate-rules-registry.js +30 -14
- package/skill-assets/sunlint-code-quality/SKILL.md +3 -2
- package/skill-assets/sunlint-code-quality/rules/dart/C006-verb-noun-functions.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C013-no-dead-code.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C014-dependency-injection.md +92 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C017-no-constructor-logic.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C018-generic-errors.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C019-error-log-level.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C020-no-unused-imports.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C022-no-unused-variables.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C023-no-duplicate-names.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C024-centralize-constants.md +75 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C029-catch-log-root-cause.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C030-custom-error-classes.md +86 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C033-separate-data-access.md +90 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C035-error-context-logging.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C041-no-hardcoded-secrets.md +75 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C042-boolean-naming.md +73 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C052-widget-parsing.md +84 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C060-superclass-logic.md +91 -0
- package/skill-assets/sunlint-code-quality/rules/dart/C067-no-hardcoded-config.md +108 -0
- package/skill-assets/sunlint-code-quality/rules/go/G001-explicit-error-handling.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/go/G002-context-first-argument.md +44 -0
- package/skill-assets/sunlint-code-quality/rules/go/G003-receiver-consistency.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/go/G004-avoid-panic.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/go/G005-goroutine-leak-prevention.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/go/G006-interface-consumer-definition.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/go/GN001-gin-binding-validation.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/go/GN002-gin-error-response.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/go/GN003-graceful-shutdown.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/go/GN004-gin-route-logical-grouping.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/go-gin/AGENTS.md +149 -0
- package/skill-assets/sunlint-code-quality/rules/go-gin/GN001-abort-after-response.md +75 -0
- package/skill-assets/sunlint-code-quality/rules/go-gin/GN002-request-context.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/go-gin/GN003-bind-error-handling.md +70 -0
- package/skill-assets/sunlint-code-quality/rules/go-gin/GN004-dependency-injection.md +78 -0
- package/skill-assets/sunlint-code-quality/rules/go-gin/GN005-route-groups-middleware.md +71 -0
- package/skill-assets/sunlint-code-quality/rules/go-gin/GN006-http-status-codes.md +91 -0
- package/skill-assets/sunlint-code-quality/rules/go-gin/GN007-release-mode.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/go-gin/GN008-struct-validation-tags.md +90 -0
- package/skill-assets/sunlint-code-quality/rules/go-gin/GN009-recovery-middleware.md +68 -0
- package/skill-assets/sunlint-code-quality/rules/go-gin/GN010-context-scope.md +68 -0
- package/skill-assets/sunlint-code-quality/rules/go-gin/GN011-middleware-concerns.md +92 -0
- package/skill-assets/sunlint-code-quality/rules/go-gin/GN012-no-log-sensitive.md +84 -0
- package/skill-assets/sunlint-code-quality/rules/java/J001-try-with-resources.md +86 -0
- package/skill-assets/sunlint-code-quality/rules/java/J002-equals-and-hashcode.md +88 -0
- package/skill-assets/sunlint-code-quality/rules/java/J003-string-comparison.md +72 -0
- package/skill-assets/sunlint-code-quality/rules/java/J004-use-java-time.md +91 -0
- package/skill-assets/sunlint-code-quality/rules/java/J005-no-print-stack-trace.md +80 -0
- package/skill-assets/sunlint-code-quality/rules/java/J006-no-system-println.md +89 -0
- package/skill-assets/sunlint-code-quality/rules/java/J007-proper-logger.md +91 -0
- package/skill-assets/sunlint-code-quality/rules/java/J008-thread-safe-singleton.md +119 -0
- package/skill-assets/sunlint-code-quality/rules/java/J009-utility-class-constructor.md +82 -0
- package/skill-assets/sunlint-code-quality/rules/java/J010-preserve-stack-trace.md +119 -0
- package/skill-assets/sunlint-code-quality/rules/java/J011-null-safe-compare.md +88 -0
- package/skill-assets/sunlint-code-quality/rules/java/J012-use-enum-collections.md +104 -0
- package/skill-assets/sunlint-code-quality/rules/java/J013-return-empty-not-null.md +102 -0
- package/skill-assets/sunlint-code-quality/rules/java/J014-hardcoded-crypto-key.md +108 -0
- package/skill-assets/sunlint-code-quality/rules/java/J015-optional-instead-of-null.md +109 -0
- package/skill-assets/sunlint-code-quality/rules/php-laravel/AGENTS.md +124 -0
- package/skill-assets/sunlint-code-quality/rules/php-laravel/LV001-form-request-validation.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/php-laravel/LV002-eager-load-no-n-plus-1.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/php-laravel/LV003-config-not-env.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/php-laravel/LV004-fillable-mass-assignment.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/php-laravel/LV005-policies-gates-authorization.md +71 -0
- package/skill-assets/sunlint-code-quality/rules/php-laravel/LV006-queue-heavy-tasks.md +68 -0
- package/skill-assets/sunlint-code-quality/rules/php-laravel/LV007-hash-passwords.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/php-laravel/LV008-route-model-binding.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/php-laravel/LV009-api-resources.md +72 -0
- package/skill-assets/sunlint-code-quality/rules/php-laravel/LV010-chunk-large-datasets.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/php-laravel/LV011-db-transactions.md +73 -0
- package/skill-assets/sunlint-code-quality/rules/php-laravel/LV012-service-layer.md +78 -0
- package/skill-assets/sunlint-code-quality/rules/php-laravel/LV013-testing-factories.md +75 -0
- package/skill-assets/sunlint-code-quality/rules/php-laravel/LV014-service-container.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/python/P001-mutable-default-argument.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/python/P002-specify-file-encoding.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/python/P003-context-manager-for-resources.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/python/P004-no-bare-except.md +65 -0
- package/skill-assets/sunlint-code-quality/rules/python/P005-use-isinstance.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/python/P006-timezone-aware-datetime.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/python/P007-use-pathlib.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/python/P008-no-wildcard-import.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/python/P009-logging-lazy-format.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/python/P010-exception-chaining.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/python/P011-subprocess-check.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/python/P012-requests-timeout.md +70 -0
- package/skill-assets/sunlint-code-quality/rules/python/P013-no-global-statement.md +73 -0
- package/skill-assets/sunlint-code-quality/rules/python/P014-no-modify-collection-while-iterating.md +66 -0
- package/skill-assets/sunlint-code-quality/rules/python/P015-prefer-fstrings.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/ruby-rails/AGENTS.md +121 -0
- package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR001-strong-parameters.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR002-eager-load-includes.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR003-service-objects.md +99 -0
- package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR004-active-job-background.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR005-pagination.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR006-find-each-batches.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR007-http-status-codes.md +76 -0
- package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR008-before-action-auth.md +77 -0
- package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR009-rails-credentials.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR010-scopes.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR011-counter-cache.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/ruby-rails/RR012-render-json-status.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C006-verb-noun-functions.md +37 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C013-no-dead-code.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C014-dependency-injection.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C017-no-constructor-logic.md +66 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C018-generic-errors.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C019-error-log-level.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C020-no-unused-imports.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C022-no-unused-variables.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C023-no-duplicate-names.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C024-centralize-constants.md +68 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C029-catch-log-root-cause.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C030-custom-error-classes.md +77 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C033-separate-data-access.md +89 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C035-error-context-logging.md +66 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C041-no-hardcoded-secrets.md +65 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C042-boolean-naming.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C052-controller-parsing.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C060-superclass-logic.md +95 -0
- package/skill-assets/sunlint-code-quality/rules/swift/C067-no-hardcoded-config.md +80 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S003-sql-injection.md +65 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S004-no-log-credentials.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S005-server-authorization.md +73 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S006-default-credentials.md +76 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S007-output-encoding.md +96 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S009-approved-crypto.md +86 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S010-csprng.md +71 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S011-insecure-deserialization.md +74 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S012-secrets-management.md +81 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S013-tls-connections.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S017-parameterized-queries.md +86 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S019-session-management.md +131 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S020-kvc-injection.md +91 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S025-input-validation.md +125 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S029-brute-force-protection.md +120 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S036-path-traversal.md +102 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S039-tls-certificate-validation.md +109 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S041-logout-invalidation.md +103 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S043-password-hashing.md +116 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S044-critical-changes-reauth.md +145 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S045-debug-info-exposure.md +116 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S046-unvalidated-redirect.md +140 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S051-token-expiry.md +134 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S053-jwt-validation.md +139 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S059-background-snapshot-protection.md +113 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S060-data-protection-api.md +106 -0
- package/skill-assets/sunlint-code-quality/rules/swift/S061-jailbreak-detection.md +132 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# 📘 Go Specific Coding Rules
|
|
2
|
+
|
|
3
|
+
### 📘 Rule G001 – Explicitly check ALL errors
|
|
4
|
+
|
|
5
|
+
- **Objective**: Prevent silent failures and ensure robust error recovery.
|
|
6
|
+
- **Details**:
|
|
7
|
+
- In Go, errors are values and must be handled explicitly.
|
|
8
|
+
- Avoid ignoring errors using `_`.
|
|
9
|
+
- Always handle the error before proceeding.
|
|
10
|
+
- **Applies to**: Go
|
|
11
|
+
- **Tool**: errcheck, golangci-lint
|
|
12
|
+
- **Principle**: CODE_QUALITY
|
|
13
|
+
- **Version**: 1.0
|
|
14
|
+
- **Status**: activated
|
|
15
|
+
- **Severity**: critical
|
|
16
|
+
|
|
17
|
+
**Good example**:
|
|
18
|
+
```go
|
|
19
|
+
file, err := os.Open("config.json")
|
|
20
|
+
if err != nil {
|
|
21
|
+
return fmt.Errorf("failed to open config: %w", err)
|
|
22
|
+
}
|
|
23
|
+
defer file.Close()
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Bad example**:
|
|
27
|
+
```go
|
|
28
|
+
file, _ := os.Open("config.json") // Error ignored
|
|
29
|
+
defer file.Close()
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 📘 Rule G002 – Context MUST be the first argument
|
|
33
|
+
|
|
34
|
+
- **Objective**: Follow Go idiomatic patterns for cancellation and timeouts.
|
|
35
|
+
- **Details**:
|
|
36
|
+
- `context.Context` should always be the first parameter of a function, typically named `ctx`.
|
|
37
|
+
- Improving observability and standardizing API signatures.
|
|
38
|
+
- **Applies to**: Go
|
|
39
|
+
- **Tool**: golangci-lint, contextcheck
|
|
40
|
+
- **Principle**: CODE_QUALITY
|
|
41
|
+
- **Version**: 1.0
|
|
42
|
+
- **Status**: activated
|
|
43
|
+
- **Severity**: major
|
|
44
|
+
|
|
45
|
+
**Good example**:
|
|
46
|
+
```go
|
|
47
|
+
func (s *Service) FetchUser(ctx context.Context, userID string) (*User, error) {
|
|
48
|
+
return s.repo.Get(ctx, userID)
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Bad example**:
|
|
53
|
+
```go
|
|
54
|
+
func (s *Service) FetchUser(userID string, ctx context.Context) (*User, error) {
|
|
55
|
+
return s.repo.Get(ctx, userID)
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 📘 Rule G003 – Consistent Receiver Naming
|
|
60
|
+
|
|
61
|
+
- **Objective**: Improve readability and consistency across methods.
|
|
62
|
+
- **Details**:
|
|
63
|
+
- Receiver names should be short (1-2 letters) and consistent across all methods of a type.
|
|
64
|
+
- Avoid generic names like `this`, `self`, or `me`.
|
|
65
|
+
- **Applies to**: Go
|
|
66
|
+
- **Tool**: golangci-lint, stylecheck
|
|
67
|
+
- **Principle**: CODE_QUALITY
|
|
68
|
+
- **Version**: 1.0
|
|
69
|
+
- **Status**: activated
|
|
70
|
+
- **Severity**: minor
|
|
71
|
+
|
|
72
|
+
**Good example**:
|
|
73
|
+
```go
|
|
74
|
+
func (r *UserRepository) Get(id string) (*User, error) { ... }
|
|
75
|
+
func (r *UserRepository) List() ([]*User, error) { ... }
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Bad example**:
|
|
79
|
+
```go
|
|
80
|
+
func (this *UserRepository) Get(id string) (*User, error) { ... }
|
|
81
|
+
func (self *UserRepository) List() ([]*User, error) { ... }
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 📘 Rule G004 – No panic() in production business logic
|
|
85
|
+
|
|
86
|
+
- **Objective**: Prevent application crashes and enable graceful recovery.
|
|
87
|
+
- **Details**:
|
|
88
|
+
- Avoid using `panic()` for normal error handling.
|
|
89
|
+
- Reserve `panic()` for unrecoverable errors during initialization.
|
|
90
|
+
- **Applies to**: Go
|
|
91
|
+
- **Tool**: golangci-lint, staticcheck
|
|
92
|
+
- **Principle**: RELIABILITY
|
|
93
|
+
- **Version**: 1.0
|
|
94
|
+
- **Status**: activated
|
|
95
|
+
- **Severity**: critical
|
|
96
|
+
|
|
97
|
+
**Good example**:
|
|
98
|
+
```go
|
|
99
|
+
func GetUser(id string) (*User, error) {
|
|
100
|
+
user, err := db.Find(id)
|
|
101
|
+
if err != nil {
|
|
102
|
+
return nil, fmt.Errorf("failed to find user: %w", err)
|
|
103
|
+
}
|
|
104
|
+
return user, nil
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Bad example**:
|
|
109
|
+
```go
|
|
110
|
+
func GetUser(id string) *User {
|
|
111
|
+
user, err := db.Find(id)
|
|
112
|
+
if err != nil {
|
|
113
|
+
panic(err) // Crash!
|
|
114
|
+
}
|
|
115
|
+
return user
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### 📘 Rule G005 – Goroutine Leak Prevention
|
|
120
|
+
|
|
121
|
+
- **Objective**: Prevent memory exhaustion and zombie processes.
|
|
122
|
+
- **Details**:
|
|
123
|
+
- Always ensure that a goroutine has a clear termination path.
|
|
124
|
+
- Use `context.Context` or a close channel to stop goroutines.
|
|
125
|
+
- **Applies to**: Go
|
|
126
|
+
- **Tool**: goleak, golangci-lint
|
|
127
|
+
- **Principle**: PERFORMANCE, RELIABILITY
|
|
128
|
+
- **Version**: 1.0
|
|
129
|
+
- **Status**: activated
|
|
130
|
+
- **Severity**: major
|
|
131
|
+
|
|
132
|
+
**Good example**:
|
|
133
|
+
```go
|
|
134
|
+
func StartWatcher(ctx context.Context, ch chan string) {
|
|
135
|
+
go func() {
|
|
136
|
+
for {
|
|
137
|
+
select {
|
|
138
|
+
case <-ctx.Done():
|
|
139
|
+
return
|
|
140
|
+
case msg, ok := <-ch:
|
|
141
|
+
if !ok { return }
|
|
142
|
+
fmt.Println(msg)
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}()
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 📘 Rule G006 – Define interfaces at consumer side
|
|
150
|
+
|
|
151
|
+
- **Objective**: Promote decoupling and simplify testing.
|
|
152
|
+
- **Details**:
|
|
153
|
+
- Define interfaces in the package that requires the dependency (consumer side).
|
|
154
|
+
- Do not define interfaces in the same package where the implementation is defined.
|
|
155
|
+
- **Applies to**: Go
|
|
156
|
+
- **Tool**: Manual Review, Architecture rules
|
|
157
|
+
- **Principle**: MAINTAINABILITY
|
|
158
|
+
- **Version**: 1.0
|
|
159
|
+
- **Status**: activated
|
|
160
|
+
- **Severity**: major
|
|
161
|
+
|
|
162
|
+
**Good example**:
|
|
163
|
+
```go
|
|
164
|
+
// package handler (consumer)
|
|
165
|
+
type AuthProvider interface {
|
|
166
|
+
Login(user, pass string) (string, error)
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### 📘 Rule GN001 – Use Gin binding for validation
|
|
171
|
+
|
|
172
|
+
- **Objective**: Simplify input handling and ensure consistent validation.
|
|
173
|
+
- **Details**:
|
|
174
|
+
- Leverage Gin's `ShouldBindJSON` with struct tags for validation.
|
|
175
|
+
- Avoid manual parsing and validation in handlers.
|
|
176
|
+
- **Applies to**: Go, Gin
|
|
177
|
+
- **Tool**: Gin, validator
|
|
178
|
+
- **Principle**: CODE_QUALITY
|
|
179
|
+
- **Version**: 1.0
|
|
180
|
+
- **Status**: activated
|
|
181
|
+
- **Severity**: major
|
|
182
|
+
|
|
183
|
+
**Good example**:
|
|
184
|
+
```go
|
|
185
|
+
type CreateUserRequest struct {
|
|
186
|
+
Email string `json:"email" binding:"required,email"`
|
|
187
|
+
}
|
|
188
|
+
if err := c.ShouldBindJSON(&req); err != nil {
|
|
189
|
+
c.JSON(400, gin.H{"error": err.Error()})
|
|
190
|
+
return
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### 📘 Rule GN002 – Abort with status for fatal errors
|
|
195
|
+
|
|
196
|
+
- **Objective**: Ensure middleware chain is interrupted and consistent response is sent.
|
|
197
|
+
- **Details**:
|
|
198
|
+
- When a fatal error occurs, use `c.AbortWithStatusJSON` to stop the chain.
|
|
199
|
+
- Prevents security bypasses in middleware.
|
|
200
|
+
- **Applies to**: Go, Gin
|
|
201
|
+
- **Tool**: Gin
|
|
202
|
+
- **Principle**: SECURITY, CODE_QUALITY
|
|
203
|
+
- **Version**: 1.0
|
|
204
|
+
- **Status**: activated
|
|
205
|
+
- **Severity**: major
|
|
206
|
+
|
|
207
|
+
### 📘 Rule GN003 – Implement Graceful Shutdown
|
|
208
|
+
|
|
209
|
+
- **Objective**: Prevent data loss and ensure clean connection handling.
|
|
210
|
+
- **Details**:
|
|
211
|
+
- Handle termination signals (`SIGINT`, `SIGTERM`) to allow inflight requests to finish.
|
|
212
|
+
- Use `http.Server.Shutdown(ctx)` instead of just `r.Run()`.
|
|
213
|
+
- **Applies to**: Go, Gin
|
|
214
|
+
- **Tool**: Go Standard Library, Gin
|
|
215
|
+
- **Principle**: RELIABILITY
|
|
216
|
+
- **Version**: 1.0
|
|
217
|
+
- **Status**: activated
|
|
218
|
+
- **Severity**: major
|
|
219
|
+
|
|
220
|
+
### 📘 Rule GN004 – Logical Route Grouping
|
|
221
|
+
|
|
222
|
+
- **Objective**: Improve code organization and shared middleware management.
|
|
223
|
+
- **Details**:
|
|
224
|
+
- Use `RouterGroup` to organize routes logically (e.g., by version or resource).
|
|
225
|
+
- Apply middleware once to the entire group.
|
|
226
|
+
- **Applies to**: Go, Gin
|
|
227
|
+
- **Tool**: Gin
|
|
228
|
+
- **Principle**: MAINTAINABILITY
|
|
229
|
+
- **Version**: 1.0
|
|
230
|
+
- **Status**: activated
|
|
231
|
+
- **Severity**: major
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# 📘 PHP/Laravel Specific Coding Rules
|
|
2
|
+
|
|
3
|
+
### 📘 Rule P001 – Follow PSR-12 Coding Standard
|
|
4
|
+
|
|
5
|
+
- **Objective**: Maintain consistent code formatting across all PHP projects.
|
|
6
|
+
- **Details**:
|
|
7
|
+
- Use 4 spaces for indentation.
|
|
8
|
+
- Class opening braces on new lines.
|
|
9
|
+
- Method visibility (public/private/protected) must be declared.
|
|
10
|
+
- **Applies to**: PHP
|
|
11
|
+
- **Tool**: PHP_CodeSniffer, Laravel Pint
|
|
12
|
+
- **Principle**: CODE_QUALITY
|
|
13
|
+
- **Version**: 1.0
|
|
14
|
+
- **Status**: activated
|
|
15
|
+
- **Severity**: major
|
|
16
|
+
|
|
17
|
+
### 📘 Rule P002 – Skinny Controllers, Fat Models/Services
|
|
18
|
+
|
|
19
|
+
- **Objective**: Maintain clear separation of concerns and keep controllers easy to read.
|
|
20
|
+
- **Details**:
|
|
21
|
+
- Controllers should only handle request input and response output.
|
|
22
|
+
- Business logic should reside in Service classes or Action classes.
|
|
23
|
+
- Aim for actions under 10 lines of code.
|
|
24
|
+
- **Applies to**: PHP/Laravel
|
|
25
|
+
- **Tool**: Manual Review, Architecture Rules
|
|
26
|
+
- **Principle**: MAINTAINABILITY, SRP
|
|
27
|
+
- **Version**: 1.0
|
|
28
|
+
- **Status**: activated
|
|
29
|
+
- **Severity**: major
|
|
30
|
+
|
|
31
|
+
### 📘 Rule P003 – Use Eloquent over Raw SQL/Query Builder
|
|
32
|
+
|
|
33
|
+
- **Objective**: Improve code readability and leverage Laravel's built-in security features.
|
|
34
|
+
- **Details**:
|
|
35
|
+
- Use Eloquent ORM for most database interactions.
|
|
36
|
+
- Use Query Builder only for complex performance-critical queries.
|
|
37
|
+
- Never use raw SQL unless absolutely necessary and properly parameterized.
|
|
38
|
+
- **Applies to**: PHP/Laravel
|
|
39
|
+
- **Tool**: Manual Review
|
|
40
|
+
- **Principle**: CODE_QUALITY, SECURITY
|
|
41
|
+
- **Version**: 1.0
|
|
42
|
+
- **Status**: activated
|
|
43
|
+
- **Severity**: major
|
|
44
|
+
|
|
45
|
+
### 📘 Rule P004 – Form Requests for Validation
|
|
46
|
+
|
|
47
|
+
- **Objective**: Separate validation logic from business logic.
|
|
48
|
+
- **Details**:
|
|
49
|
+
- Use dediated `FormRequest` classes for request validation.
|
|
50
|
+
- Avoid calling `$request->validate()` inside controller actions.
|
|
51
|
+
- **Applies to**: PHP/Laravel
|
|
52
|
+
- **Tool**: Manual Review, PHPStan
|
|
53
|
+
- **Principle**: MAINTAINABILITY
|
|
54
|
+
- **Version**: 1.0
|
|
55
|
+
- **Status**: activated
|
|
56
|
+
- **Severity**: major
|
|
57
|
+
|
|
58
|
+
### 📘 Rule P005 – Typed Properties and Return Types
|
|
59
|
+
|
|
60
|
+
- **Objective**: Increase code reliability and allow static analysis to catch errors.
|
|
61
|
+
- **Details**:
|
|
62
|
+
- Use type hints for class properties (PHP 7.4+).
|
|
63
|
+
- Always declare return types for methods, including `void`.
|
|
64
|
+
- **Applies to**: PHP 7.4+
|
|
65
|
+
- **Tool**: PHPStan, Psalm
|
|
66
|
+
- **Principle**: CODE_QUALITY, RELIABILITY
|
|
67
|
+
- **Version**: 1.0
|
|
68
|
+
- **Status**: activated
|
|
69
|
+
- **Severity**: major
|
|
70
|
+
|
|
71
|
+
**Good example**:
|
|
72
|
+
```php
|
|
73
|
+
public function updateStatus(int $id, string $status): void
|
|
74
|
+
{
|
|
75
|
+
$item = Item::findOrFail($id);
|
|
76
|
+
$item->status = $status;
|
|
77
|
+
$item->save();
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 📘 Rule P006 – Prevent N+1 with Eager Loading
|
|
82
|
+
|
|
83
|
+
- **Objective**: Optimize performance by reducing the number of database queries.
|
|
84
|
+
- **Details**:
|
|
85
|
+
- Use the `with()` method when accessing associations in a loop.
|
|
86
|
+
- **Applies to**: PHP/Laravel
|
|
87
|
+
- **Tool**: Laravel Telescope, Clockwork, laravel-query-detector
|
|
88
|
+
- **Principle**: PERFORMANCE
|
|
89
|
+
- **Version**: 1.0
|
|
90
|
+
- **Status**: activated
|
|
91
|
+
- **Severity**: critical
|
|
92
|
+
|
|
93
|
+
**Good example**:
|
|
94
|
+
```php
|
|
95
|
+
$posts = Post::with('author')->get();
|
|
96
|
+
foreach ($posts as $post) {
|
|
97
|
+
echo $post->author->name;
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Bad example**:
|
|
102
|
+
```php
|
|
103
|
+
$posts = Post::all();
|
|
104
|
+
foreach ($posts as $post) {
|
|
105
|
+
echo $post->author->name; // Trigger new query for each post
|
|
106
|
+
}
|
|
107
|
+
```
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# 📘 Python Specific Coding Rules
|
|
2
|
+
|
|
3
|
+
### 📘 Rule PY001 – Adhere to PEP 8 Style Guide
|
|
4
|
+
|
|
5
|
+
- **Objective**: Maintain a consistent and readable codebase following Python's official standards.
|
|
6
|
+
- **Details**:
|
|
7
|
+
- Use 4 spaces per indentation level.
|
|
8
|
+
- Limit line length to 79 characters.
|
|
9
|
+
- Use `snake_case` for functions/variables and `PascalCase` for classes.
|
|
10
|
+
- **Applies to**: Python
|
|
11
|
+
- **Tool**: ruff, flake8, black
|
|
12
|
+
- **Principle**: CODE_QUALITY
|
|
13
|
+
- **Version**: 1.0
|
|
14
|
+
- **Status**: activated
|
|
15
|
+
- **Severity**: major
|
|
16
|
+
|
|
17
|
+
### 📘 Rule PY002 – Mandatory Type Hinting
|
|
18
|
+
|
|
19
|
+
- **Objective**: Improve code clarity, enable better IDE support, and catch type-related bugs early.
|
|
20
|
+
- **Details**:
|
|
21
|
+
- Use type annotations for all function parameters and return types.
|
|
22
|
+
- Use `typing` module for complex types (List, Dict, Optional).
|
|
23
|
+
- **Applies to**: Python 3.6+
|
|
24
|
+
- **Tool**: mypy, Pyright
|
|
25
|
+
- **Principle**: CODE_QUALITY, RELIABILITY
|
|
26
|
+
- **Version**: 1.0
|
|
27
|
+
- **Status**: activated
|
|
28
|
+
- **Severity**: major
|
|
29
|
+
|
|
30
|
+
**Good example**:
|
|
31
|
+
```python
|
|
32
|
+
def get_user_name(user_id: int) -> str:
|
|
33
|
+
return db.fetch_name(user_id)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Bad example**:
|
|
37
|
+
```python
|
|
38
|
+
def get_user_name(user_id):
|
|
39
|
+
return db.fetch_name(user_id)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 📘 Rule PY003 – Explicit Error Handling
|
|
43
|
+
|
|
44
|
+
- **Objective**: Prevent catching unexpected errors and ensure specific failure handling.
|
|
45
|
+
- **Details**:
|
|
46
|
+
- Never use bare `except:` blocks.
|
|
47
|
+
- Always catch specific exceptions (e.g., `ValueError`, `KeyError`).
|
|
48
|
+
- **Applies to**: Python
|
|
49
|
+
- **Tool**: pylint, ruff
|
|
50
|
+
- **Principle**: RELIABILITY
|
|
51
|
+
- **Version**: 1.0
|
|
52
|
+
- **Status**: activated
|
|
53
|
+
- **Severity**: critical
|
|
54
|
+
|
|
55
|
+
### 📘 Rule PY004 – Use logging instead of print
|
|
56
|
+
|
|
57
|
+
- **Objective**: Better event tracking, filtering, and production observability.
|
|
58
|
+
- **Details**:
|
|
59
|
+
- Use the `logging` module for any non-ephemeral messaging.
|
|
60
|
+
- Choose appropriate levels: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`.
|
|
61
|
+
- **Applies to**: Python
|
|
62
|
+
- **Tool**: Manual Review, ruff
|
|
63
|
+
- **Principle**: MAINTAINABILITY
|
|
64
|
+
- **Version**: 1.0
|
|
65
|
+
- **Status**: activated
|
|
66
|
+
- **Severity**: major
|
|
67
|
+
|
|
68
|
+
### 📘 Rule PY005 – Context Managers for Resource Handling
|
|
69
|
+
|
|
70
|
+
- **Objective**: Ensure resources like files and network connections are closed properly.
|
|
71
|
+
- **Details**:
|
|
72
|
+
- Use the `with` statement for resource management.
|
|
73
|
+
- **Applies to**: Python
|
|
74
|
+
- **Tool**: pylint, ruff
|
|
75
|
+
- **Principle**: RELIABILITY
|
|
76
|
+
- **Version**: 1.0
|
|
77
|
+
- **Status**: activated
|
|
78
|
+
- **Severity**: major
|
|
79
|
+
|
|
80
|
+
**Good example**:
|
|
81
|
+
```python
|
|
82
|
+
with open("data.txt", "r") as f:
|
|
83
|
+
content = f.read()
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 📘 Rule PY006 – Avoid Mutable Default Arguments
|
|
87
|
+
|
|
88
|
+
- **Objective**: Prevent unexpected state sharing between function calls.
|
|
89
|
+
- **Details**:
|
|
90
|
+
- Never use list or dict as a default value in function signature.
|
|
91
|
+
- Use `None` as default and initialize inside the function.
|
|
92
|
+
- **Applies to**: Python
|
|
93
|
+
- **Tool**: pylint, ruff
|
|
94
|
+
- **Principle**: RELIABILITY
|
|
95
|
+
- **Version**: 1.0
|
|
96
|
+
- **Status**: activated
|
|
97
|
+
- **Severity**: major
|
|
98
|
+
|
|
99
|
+
**Good example**:
|
|
100
|
+
```python
|
|
101
|
+
def add_item(item, items=None):
|
|
102
|
+
if items is None:
|
|
103
|
+
items = []
|
|
104
|
+
items.append(item)
|
|
105
|
+
return items
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Bad example**:
|
|
109
|
+
```python
|
|
110
|
+
def add_item(item, items=[]): # items is shared across calls!
|
|
111
|
+
items.append(item)
|
|
112
|
+
return items
|
|
113
|
+
```
|