Skip to content

Commit f840b0c

Browse files
bagagearturbosch
authored andcommitted
Add baseline option (#48)
1 parent 819d92d commit f840b0c

File tree

4 files changed

+137
-63
lines changed

4 files changed

+137
-63
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,16 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="io.gitlab.arturbosch.detekt.config.DetektConfigurationForm">
3-
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="8" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
3+
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="9" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
44
<margin top="0" left="0" bottom="0" right="0"/>
55
<constraints>
66
<xy x="20" y="20" width="680" height="400"/>
77
</constraints>
88
<properties/>
99
<border type="none"/>
1010
<children>
11-
<grid id="6b450" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
12-
<margin top="0" left="0" bottom="0" right="0"/>
13-
<constraints>
14-
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
15-
</constraints>
16-
<properties/>
17-
<border type="none"/>
18-
<children>
19-
<component id="26ad6" class="javax.swing.JLabel">
20-
<constraints>
21-
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
22-
</constraints>
23-
<properties>
24-
<text value="Configuration File"/>
25-
</properties>
26-
</component>
27-
<component id="82226" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="configurationFilePath">
28-
<constraints>
29-
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
30-
</constraints>
31-
<properties>
32-
<text value=""/>
33-
<toolTipText value="Selects path to your custom detekt configuration file. A relative path can be used, and will be relative to project directory."/>
34-
</properties>
35-
</component>
36-
</children>
37-
</grid>
3811
<component id="4b496" class="javax.swing.JCheckBox" binding="enableDetekt">
3912
<constraints>
40-
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
13+
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
4114
</constraints>
4215
<properties>
4316
<selected value="true"/>
@@ -47,7 +20,7 @@
4720
</component>
4821
<component id="557e8" class="javax.swing.JCheckBox" binding="buildUponDefaultConfig">
4922
<constraints>
50-
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
23+
<grid row="3" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
5124
</constraints>
5225
<properties>
5326
<text value="Build upon the default configuration"/>
@@ -56,7 +29,7 @@
5629
</component>
5730
<component id="b76c7" class="javax.swing.JCheckBox" binding="treatAsErrors">
5831
<constraints>
59-
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
32+
<grid row="5" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
6033
</constraints>
6134
<properties>
6235
<text value="Treat detekt findings as errors"/>
@@ -65,12 +38,12 @@
6538
</component>
6639
<vspacer id="f22cd">
6740
<constraints>
68-
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
41+
<grid row="8" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
6942
</constraints>
7043
</vspacer>
7144
<component id="4f4cc" class="javax.swing.JCheckBox" binding="enableFormatting">
7245
<constraints>
73-
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
46+
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
7447
</constraints>
7548
<properties>
7649
<text value="Enable Formatting rules"/>
@@ -79,7 +52,7 @@
7952
</component>
8053
<component id="85c28" class="javax.swing.JCheckBox" binding="failFast">
8154
<constraints>
82-
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
55+
<grid row="4" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
8356
</constraints>
8457
<properties>
8558
<text value="Fail fast"/>
@@ -88,13 +61,67 @@
8861
</component>
8962
<component id="8719" class="javax.swing.JCheckBox" binding="autoCorrect">
9063
<constraints>
91-
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
64+
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
9265
</constraints>
9366
<properties>
9467
<text value="Auto correct"/>
9568
<toolTipText value="Corrects automatically in-place rules that are fixable"/>
9669
</properties>
9770
</component>
71+
<grid id="f400d" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
72+
<margin top="0" left="0" bottom="0" right="0"/>
73+
<constraints>
74+
<grid row="7" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
75+
</constraints>
76+
<properties/>
77+
<border type="none"/>
78+
<children>
79+
<component id="2875d" class="javax.swing.JLabel">
80+
<constraints>
81+
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
82+
</constraints>
83+
<properties>
84+
<text value="Baseline File"/>
85+
</properties>
86+
</component>
87+
<component id="bf22a" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="baselineFilePath">
88+
<constraints>
89+
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
90+
</constraints>
91+
<properties>
92+
<text value=""/>
93+
<toolTipText value="Path to detekt baseline file"/>
94+
</properties>
95+
</component>
96+
</children>
97+
</grid>
98+
<grid id="6b450" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
99+
<margin top="0" left="0" bottom="0" right="0"/>
100+
<constraints>
101+
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
102+
</constraints>
103+
<properties/>
104+
<border type="none"/>
105+
<children>
106+
<component id="26ad6" class="javax.swing.JLabel">
107+
<constraints>
108+
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
109+
</constraints>
110+
<properties>
111+
<text value="Configuration File"/>
112+
</properties>
113+
</component>
114+
<component id="82226" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="configurationFilePath">
115+
<constraints>
116+
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
117+
</constraints>
118+
<properties>
119+
<text value=""/>
120+
<toolTipText value="Selects path to your custom detekt configuration file. A relative path can be used, and will be relative to project directory."/>
121+
</properties>
122+
</component>
123+
</children>
124+
</grid>
98125
</children>
99126
</grid>
100127
</form>

Diff for: src/main/java/io/gitlab/arturbosch/detekt/config/DetektConfigurationForm.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class DetektConfigurationForm {
2323
private JCheckBox treatAsErrors;
2424
private JCheckBox enableFormatting;
2525
private JCheckBox autoCorrect;
26+
private TextFieldWithBrowseButton baselineFilePath;
2627

2728
private DetektConfigStorage detektConfigStorage;
2829

@@ -58,6 +59,14 @@ public JComponent createPanel(@NotNull DetektConfigStorage detektConfigStorage)
5859
TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT
5960
);
6061

62+
baselineFilePath.addBrowseFolderListener(
63+
"",
64+
"Detekt baseline file",
65+
null,
66+
fileChooserDescriptor,
67+
TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT
68+
);
69+
6170
return myMainPanel;
6271
}
6372

@@ -69,6 +78,7 @@ public void apply() {
6978
detektConfigStorage.setFailFast(failFast.isSelected());
7079
detektConfigStorage.setTreatAsError(treatAsErrors.isSelected());
7180
detektConfigStorage.setRulesPath(configurationFilePath.getText());
81+
detektConfigStorage.setBaselinePath(baselineFilePath.getText());
7282
}
7383

7484
public void reset() {
@@ -79,6 +89,7 @@ public void reset() {
7989
failFast.setSelected(detektConfigStorage.getFailFast());
8090
treatAsErrors.setSelected(detektConfigStorage.getTreatAsError());
8191
configurationFilePath.setText(detektConfigStorage.getRulesPath());
92+
baselineFilePath.setText(detektConfigStorage.getBaselinePath());
8293
}
8394

8495
public boolean isModified() {
@@ -88,6 +99,7 @@ public boolean isModified() {
8899
|| !Comparing.equal(detektConfigStorage.getBuildUponDefaultConfig(), buildUponDefaultConfig.isSelected())
89100
|| !Comparing.equal(detektConfigStorage.getFailFast(), failFast.isSelected())
90101
|| !Comparing.equal(detektConfigStorage.getTreatAsError(), treatAsErrors.isSelected())
91-
|| !Comparing.equal(detektConfigStorage.getRulesPath(), configurationFilePath.getText());
102+
|| !Comparing.equal(detektConfigStorage.getRulesPath(), configurationFilePath.getText())
103+
|| !Comparing.equal(detektConfigStorage.getBaselinePath(), baselineFilePath.getText());
92104
}
93105
}

Diff for: src/main/kotlin/io/gitlab/arturbosch/detekt/DetektAnnotator.kt

+57-19
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import com.intellij.psi.PsiFile
1818
import io.gitlab.arturbosch.detekt.api.Finding
1919
import io.gitlab.arturbosch.detekt.api.TextLocation
2020
import io.gitlab.arturbosch.detekt.cli.CliArgs
21+
import io.gitlab.arturbosch.detekt.cli.FilteredDetectionResult
22+
import io.gitlab.arturbosch.detekt.cli.baseline.BaselineFacade
2123
import io.gitlab.arturbosch.detekt.cli.loadConfiguration
2224
import io.gitlab.arturbosch.detekt.config.DetektConfig
2325
import io.gitlab.arturbosch.detekt.config.DetektConfigStorage
@@ -64,7 +66,13 @@ class DetektAnnotator : ExternalAnnotator<PsiFile, List<Finding>>() {
6466
val settings = processingSettings(collectedInfo.project, virtualFile, configuration)
6567

6668
return settings?.let {
67-
val result = createFacade(settings, configuration).run()
69+
val detektion = createFacade(settings, configuration).run()
70+
71+
val result = if (configuration.baselinePath.isNotBlank()) {
72+
FilteredDetectionResult(detektion, BaselineFacade(File(absolutePath(collectedInfo.project, configuration.baselinePath)).toPath()))
73+
} else {
74+
detektion
75+
}
6876

6977
if (settings.autoCorrect) {
7078
virtualFile.refresh(false, false)
@@ -98,40 +106,70 @@ class DetektAnnotator : ExternalAnnotator<PsiFile, List<Finding>>() {
98106
virtualFile: VirtualFile,
99107
configStorage: DetektConfigStorage
100108
): ProcessingSettings? {
101-
if (configStorage.rulesPath.isNotEmpty()) {
102-
val path = File(configStorage.rulesPath)
103-
if (!path.exists()) {
104-
val n = Notification(
105-
"Detekt",
106-
"Configuration file not found",
107-
"The provided detekt configuration file <b>${path.absolutePath}</b> does not exist. Skipping detekt run.",
108-
NotificationType.WARNING
109+
val rulesPath = absolutePath(project, configStorage.rulesPath)
110+
val baselinePath = absolutePath(project, configStorage.baselinePath)
111+
112+
if (baselinePath.isNotEmpty()) {
113+
if (!ensureFileExists(
114+
baselinePath,
115+
project,
116+
"Baseline file not found",
117+
"The provided detekt baseline file <b>${baselinePath}</b> does not exist. Skipping detekt run."
109118
)
110-
n.addAction(object : AnAction("Open Detekt projects settings") {
111-
override fun actionPerformed(e: AnActionEvent) {
112-
val dialog = SettingsDialog(project, "Detekt project settings", DetektConfig(project), true, true)
113-
ApplicationManager.getApplication().invokeLater(dialog::show);
114-
}
115-
})
116-
n.notify(project)
119+
)
117120
return null
118-
}
119121
}
120122

121-
123+
if (rulesPath.isNotEmpty()) {
124+
if (!ensureFileExists(
125+
rulesPath,
126+
project,
127+
"Configuration file not found",
128+
"The provided detekt configuration file <b>${rulesPath}</b> does not exist. Skipping detekt run."
129+
)
130+
)
131+
return null
132+
}
122133

123134
return ProcessingSettings(
124135
inputPath = Paths.get(virtualFile.path),
125136
autoCorrect = configStorage.autoCorrect,
126137
config = NoAutoCorrectConfig(CliArgs().apply {
127-
config = configStorage.rulesPath
138+
config = rulesPath
128139
failFast = configStorage.failFast
129140
buildUponDefaultConfig = configStorage.buildUponDefaultConfig
130141
}.loadConfiguration(), configStorage.autoCorrect),
131142
executorService = ForkJoinPool.commonPool()
132143
)
133144
}
134145

146+
private fun absolutePath(project: Project, path: String): String {
147+
return if (path.isBlank() || File(path).isAbsolute)
148+
path
149+
else
150+
project.basePath + "/" + path
151+
}
152+
153+
private fun ensureFileExists(path: String, project: Project, title: String, content: String): Boolean {
154+
if (!File(path).exists()) {
155+
val n = Notification(
156+
"Detekt",
157+
title,
158+
content,
159+
NotificationType.WARNING
160+
)
161+
n.addAction(object : AnAction("Open Detekt projects settings") {
162+
override fun actionPerformed(e: AnActionEvent) {
163+
val dialog = SettingsDialog(project, "Detekt project settings", DetektConfig(project), true, true)
164+
ApplicationManager.getApplication().invokeLater(dialog::show);
165+
}
166+
})
167+
n.notify(project)
168+
return false
169+
}
170+
return true
171+
}
172+
135173
private fun createFacade(settings: ProcessingSettings, configuration: DetektConfigStorage): DetektFacade {
136174
var providers = RuleSetLocator(settings).load()
137175
if (!configuration.enableFormatting) {

Diff for: src/main/kotlin/io/gitlab/arturbosch/detekt/config/DetektConfigStorage.kt

+5-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import com.intellij.openapi.components.PersistentStateComponent
44
import com.intellij.openapi.components.ServiceManager
55
import com.intellij.openapi.components.State
66
import com.intellij.openapi.components.Storage
7-
import com.intellij.openapi.components.StoragePathMacros
87
import com.intellij.openapi.project.Project
98
import com.intellij.util.xmlb.annotations.Tag
109
import java.io.File
@@ -16,7 +15,7 @@ import java.io.File
1615
name = "DetektProjectConfiguration",
1716
storages = [Storage("detekt.xml")]
1817
)
19-
class DetektConfigStorage(val project: Project) : PersistentStateComponent<DetektConfigStorage> {
18+
class DetektConfigStorage : PersistentStateComponent<DetektConfigStorage> {
2019

2120
@Tag
2221
var enableDetekt: Boolean = false
@@ -38,12 +37,9 @@ class DetektConfigStorage(val project: Project) : PersistentStateComponent<Detek
3837

3938
@Tag
4039
var rulesPath: String = ""
41-
set(value) {
42-
field = if (value.isBlank() || File(value).isAbsolute)
43-
value
44-
else
45-
project.basePath + "/" + value
46-
}
40+
41+
@Tag
42+
var baselinePath: String = ""
4743

4844
override fun getState(): DetektConfigStorage? = this
4945

@@ -54,6 +50,7 @@ class DetektConfigStorage(val project: Project) : PersistentStateComponent<Detek
5450
this.buildUponDefaultConfig = state.buildUponDefaultConfig
5551
this.failFast = state.failFast
5652
this.rulesPath = state.rulesPath
53+
this.baselinePath = state.baselinePath
5754
this.treatAsError = state.treatAsError
5855
}
5956

0 commit comments

Comments
 (0)