Skip to content

Commit 1db5e37

Browse files
refactor: Use detekt.yml for JetBrains compliance rules
Addresses PR feedback to use detekt's built-in rules instead of shell script: - Add comprehensive detekt.yml with JetBrains compliance rules - Use ForbiddenAnnotation for experimental API detection - Use ForbiddenMethodCall for runtime hooks and thread creation - Use ForbiddenImport for bundled library detection - Update GitHub Actions to use detekt for compliance checking - Update documentation to reflect detekt-based approach - Keep shell script as backup for manual verification Benefits: - More precise rule matching with detekt's AST analysis - Better integration with IDE and CI/CD - Detailed HTML reports with exact locations - Configurable severity levels and custom messages Co-authored-by: matifali <[email protected]>
1 parent c4c3d6d commit 1db5e37

File tree

4 files changed

+241
-28
lines changed

4 files changed

+241
-28
lines changed

.github/workflows/jetbrains-compliance.yml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,22 @@ jobs:
3131
restore-keys: |
3232
${{ runner.os }}-gradle-
3333
34-
- name: Make scripts executable
35-
run: chmod +x ./scripts/jetbrains-compliance-check.sh
34+
- name: Make gradlew executable
35+
run: chmod +x ./gradlew
3636

3737
- name: Run JetBrains Compliance Checks
3838
run: |
39-
echo "Running JetBrains auto-approval compliance checks..."
40-
./scripts/jetbrains-compliance-check.sh
39+
echo "Running JetBrains auto-approval compliance checks with detekt..."
40+
./gradlew detekt
41+
42+
- name: Upload detekt reports
43+
uses: actions/upload-artifact@v4
44+
if: always()
45+
with:
46+
name: detekt-reports
47+
path: |
48+
build/reports/detekt/
49+
retention-days: 30
4150

4251
- name: Comment PR with compliance status
4352
if: github.event_name == 'pull_request' && failure()

JETBRAINS_COMPLIANCE.md

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,26 @@ Based on communication with JetBrains team, the following requirements must be m
2525

2626
## Linting Setup
2727

28-
### JetBrains Compliance Check Script
28+
### JetBrains Compliance with Detekt
2929

30-
The primary compliance checking is done via a shell script:
30+
The primary compliance checking is done using Detekt with custom configuration in `detekt.yml`:
3131

3232
```bash
33-
./scripts/jetbrains-compliance-check.sh
33+
./gradlew detekt
3434
```
3535

36-
This script checks for:
37-
- Forbidden experimental API usage
38-
- Manual thread creation patterns
39-
- Java runtime hooks
40-
- Potentially bundled libraries
41-
- Coroutines best practices
36+
This configuration includes JetBrains-specific rules that check for:
37+
- **ForbiddenAnnotation**: Detects forbidden experimental API usage
38+
- **ForbiddenMethodCall**: Detects Java runtime hooks and manual thread creation
39+
- **ForbiddenImport**: Detects potentially bundled libraries
40+
- **Standard code quality rules**: Complexity, naming, performance, etc.
4241

43-
### Standard Code Quality (Detekt)
42+
### Backup Compliance Check Script
4443

45-
Standard Kotlin code quality is checked using Detekt:
44+
A shell script is also available for quick manual checks:
4645

4746
```bash
48-
./gradlew detekt
47+
./scripts/jetbrains-compliance-check.sh
4948
```
5049

5150
## CI/CD Integration
@@ -54,21 +53,21 @@ The GitHub Actions workflow `.github/workflows/jetbrains-compliance.yml` runs co
5453

5554
## Running Locally
5655

57-
### Quick Compliance Check
58-
```bash
59-
# Run JetBrains compliance check
60-
./scripts/jetbrains-compliance-check.sh
61-
```
62-
63-
### Full Code Quality Check
56+
### Primary Compliance Check
6457
```bash
65-
# Run detekt for code quality
58+
# Run JetBrains compliance and code quality check
6659
./gradlew detekt
6760

6861
# View HTML report
6962
open build/reports/detekt/detekt.html
7063
```
7164

65+
### Quick Manual Check
66+
```bash
67+
# Run backup shell script for quick manual verification
68+
./scripts/jetbrains-compliance-check.sh
69+
```
70+
7271
## Understanding Results
7372

7473
### Compliance Check Results

build.gradle.kts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,21 +111,22 @@ tasks.test {
111111
useJUnitPlatform()
112112
}
113113

114-
// Detekt configuration for code quality
114+
// Detekt configuration for JetBrains compliance and code quality
115115
detekt {
116+
config.setFrom("$projectDir/detekt.yml")
116117
buildUponDefaultConfig = true
117118
allRules = false
118119
}
119120

120-
// Configure detekt for code quality reporting
121+
// Configure detekt for JetBrains compliance and code quality
121122
tasks.withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach {
122123
jvmTarget = "21"
123124
reports {
124125
html.required.set(true)
125126
xml.required.set(true)
126127
}
127-
// Don't fail build on detekt issues - just report them
128-
ignoreFailures = true
128+
// Fail build on detekt issues for JetBrains compliance
129+
ignoreFailures = false
129130
}
130131

131132

detekt.yml

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
# Detekt configuration for JetBrains Toolbox Plugin Auto-Approval Compliance
2+
# Based on clarified requirements from JetBrains team
3+
4+
build:
5+
maxIssues: 1000 # Allow many issues for code quality reporting
6+
excludeCorrectable: false
7+
8+
config:
9+
validation: true
10+
warningsAsErrors: false # Don't treat warnings as errors
11+
checkExhaustiveness: false
12+
13+
# CRITICAL: JetBrains Compliance Rules using detekt built-in rules
14+
style:
15+
active: true
16+
17+
# JetBrains Auto-Approval Compliance: Forbidden experimental annotations
18+
ForbiddenAnnotation:
19+
active: true
20+
annotations:
21+
- reason: 'Forbidden for JetBrains auto-approval: Core Kotlin experimental APIs are not allowed'
22+
value: 'kotlin.ExperimentalStdlibApi'
23+
- reason: 'Forbidden for JetBrains auto-approval: Core Kotlin experimental APIs are not allowed'
24+
value: 'kotlin.ExperimentalUnsignedTypes'
25+
- reason: 'Forbidden for JetBrains auto-approval: Core Kotlin experimental APIs are not allowed'
26+
value: 'kotlin.contracts.ExperimentalContracts'
27+
- reason: 'Forbidden for JetBrains auto-approval: Core Kotlin experimental APIs are not allowed'
28+
value: 'kotlin.experimental.ExperimentalTypeInference'
29+
- reason: 'Forbidden for JetBrains auto-approval: Internal coroutines APIs should be avoided'
30+
value: 'kotlinx.coroutines.InternalCoroutinesApi'
31+
- reason: 'Forbidden for JetBrains auto-approval: Experimental time APIs are not allowed'
32+
value: 'kotlin.time.ExperimentalTime'
33+
# Note: ExperimentalCoroutinesApi, DelicateCoroutinesApi, FlowPreview are acceptable
34+
# based on JetBrains feedback about select/onTimeout being OK
35+
36+
# JetBrains Auto-Approval Compliance: Forbidden method calls
37+
ForbiddenMethodCall:
38+
active: true
39+
methods:
40+
# Java runtime hooks - forbidden
41+
- reason: 'Forbidden for JetBrains auto-approval: Java runtime hooks are not allowed'
42+
value: 'java.lang.Runtime.addShutdownHook'
43+
- reason: 'Forbidden for JetBrains auto-approval: Java runtime hooks are not allowed'
44+
value: 'java.lang.System.setSecurityManager'
45+
- reason: 'Forbidden for JetBrains auto-approval: Java runtime hooks are not allowed'
46+
value: 'java.lang.Thread.setUncaughtExceptionHandler'
47+
- reason: 'Forbidden for JetBrains auto-approval: Java runtime hooks are not allowed'
48+
value: 'java.lang.Thread.setDefaultUncaughtExceptionHandler'
49+
# Manual thread creation - warnings (allowed with proper cleanup)
50+
- reason: 'Warning for JetBrains auto-approval: Manual thread creation detected. Consider using coroutineScope.launch or ensure proper cleanup in CoderRemoteProvider#close()'
51+
value: 'java.lang.Thread.<init>'
52+
- reason: 'Warning for JetBrains auto-approval: Manual thread creation detected. Consider using coroutineScope.launch or ensure proper cleanup in CoderRemoteProvider#close()'
53+
value: 'java.util.concurrent.Executors.newFixedThreadPool'
54+
- reason: 'Warning for JetBrains auto-approval: Manual thread creation detected. Consider using coroutineScope.launch or ensure proper cleanup in CoderRemoteProvider#close()'
55+
value: 'java.util.concurrent.Executors.newCachedThreadPool'
56+
- reason: 'Warning for JetBrains auto-approval: Manual thread creation detected. Consider using coroutineScope.launch or ensure proper cleanup in CoderRemoteProvider#close()'
57+
value: 'java.util.concurrent.Executors.newSingleThreadExecutor'
58+
- reason: 'Warning for JetBrains auto-approval: Manual thread creation detected. Consider using coroutineScope.launch or ensure proper cleanup in CoderRemoteProvider#close()'
59+
value: 'java.util.concurrent.CompletableFuture.runAsync'
60+
- reason: 'Warning for JetBrains auto-approval: Manual thread creation detected. Consider using coroutineScope.launch or ensure proper cleanup in CoderRemoteProvider#close()'
61+
value: 'java.util.concurrent.CompletableFuture.supplyAsync'
62+
63+
# JetBrains Auto-Approval Compliance: Forbidden imports
64+
ForbiddenImport:
65+
active: true
66+
imports:
67+
# Potentially bundled libraries - warnings
68+
- reason: 'Warning for JetBrains auto-approval: Ensure slf4j is not bundled - it is provided by Toolbox'
69+
value: 'org.slf4j.*'
70+
- reason: 'Warning for JetBrains auto-approval: Ensure annotations library is not bundled - it is provided by Toolbox'
71+
value: 'org.jetbrains.annotations.*'
72+
# Runtime hook classes - forbidden
73+
- reason: 'Forbidden for JetBrains auto-approval: Runtime hook classes are not allowed'
74+
value: 'java.lang.Runtime'
75+
- reason: 'Forbidden for JetBrains auto-approval: Security manager modifications are not allowed'
76+
value: 'java.security.SecurityManager'
77+
78+
# Other important style rules
79+
MagicNumber:
80+
active: true
81+
ignoreNumbers:
82+
- '-1'
83+
- '0'
84+
- '1'
85+
- '2'
86+
ignoreHashCodeFunction: true
87+
ignorePropertyDeclaration: false
88+
ignoreLocalVariableDeclaration: false
89+
ignoreConstantDeclaration: true
90+
ignoreCompanionObjectPropertyDeclaration: true
91+
ignoreAnnotation: false
92+
ignoreNamedArgument: true
93+
ignoreEnums: false
94+
ignoreRanges: false
95+
ignoreExtensionFunctions: true
96+
97+
MaxLineLength:
98+
active: true
99+
maxLineLength: 120
100+
excludePackageStatements: true
101+
excludeImportStatements: true
102+
excludeCommentStatements: false
103+
104+
NewLineAtEndOfFile:
105+
active: true
106+
107+
WildcardImport:
108+
active: true
109+
110+
# Essential built-in rules for basic code quality
111+
complexity:
112+
active: true
113+
CyclomaticComplexMethod:
114+
active: true
115+
threshold: 15
116+
LongMethod:
117+
active: true
118+
threshold: 60
119+
LongParameterList:
120+
active: true
121+
functionThreshold: 6
122+
constructorThreshold: 7
123+
NestedBlockDepth:
124+
active: true
125+
threshold: 4
126+
127+
coroutines:
128+
active: true
129+
GlobalCoroutineUsage:
130+
active: true
131+
RedundantSuspendModifier:
132+
active: true
133+
SleepInsteadOfDelay:
134+
active: true
135+
136+
exceptions:
137+
active: true
138+
ExceptionRaisedInUnexpectedLocation:
139+
active: true
140+
ObjectExtendsThrowable:
141+
active: true
142+
PrintStackTrace:
143+
active: true
144+
ReturnFromFinally:
145+
active: true
146+
SwallowedException:
147+
active: true
148+
ThrowingExceptionFromFinally:
149+
active: true
150+
ThrowingExceptionsWithoutMessageOrCause:
151+
active: true
152+
TooGenericExceptionCaught:
153+
active: true
154+
TooGenericExceptionThrown:
155+
active: true
156+
157+
naming:
158+
active: true
159+
ClassNaming:
160+
active: true
161+
classPattern: '[A-Z][a-zA-Z0-9]*'
162+
FunctionNaming:
163+
active: true
164+
functionPattern: '[a-z][a-zA-Z0-9]*'
165+
PackageNaming:
166+
active: true
167+
packagePattern: '[a-z]+(\.?[a-z][A-Za-z0-9]*)*'
168+
VariableNaming:
169+
active: true
170+
variablePattern: '[a-z][A-Za-z0-9]*'
171+
172+
performance:
173+
active: true
174+
ArrayPrimitive:
175+
active: true
176+
ForEachOnRange:
177+
active: true
178+
SpreadOperator:
179+
active: true
180+
UnnecessaryTemporaryInstantiation:
181+
active: true
182+
183+
potential-bugs:
184+
active: true
185+
EqualsAlwaysReturnsTrueOrFalse:
186+
active: true
187+
EqualsWithHashCodeExist:
188+
active: true
189+
ExplicitGarbageCollectionCall:
190+
active: true
191+
HasPlatformType:
192+
active: true
193+
InvalidRange:
194+
active: true
195+
UnreachableCatchBlock:
196+
active: true
197+
UnreachableCode:
198+
active: true
199+
UnsafeCallOnNullableType:
200+
active: true
201+
UnsafeCast:
202+
active: true
203+
WrongEqualsTypeParameter:
204+
active: true

0 commit comments

Comments
 (0)