RUBY-19094 Reworked existed Kubernetes-Yaml inspection

IDEA-CR-33445
This commit is contained in:
Alexey Merkulov
2018-06-13 17:29:08 +03:00
parent c88e90984a
commit 717174e1c2
9 changed files with 218 additions and 20 deletions
@@ -44,6 +44,11 @@
key="inspections.recursive.alias.name" level="ERROR"
groupKey="inspections.group.name" enabledByDefault="true"
implementationClass="org.jetbrains.yaml.inspections.YAMLRecursiveAliasInspection"/>
<localInspection language="yaml" bundle="messages.YAMLBundle"
shortName="YAMLDuplicatedKeys" level="ERROR"
key="inspections.duplicated.keys.name"
groupKey="inspections.group.name" enabledByDefault="true"
implementationClass="org.jetbrains.yaml.inspections.YAMLDuplicatedKeysInspection"/>
</extensions>
@@ -0,0 +1,6 @@
<html>
<body>
This inspection detects duplicated keys in YAML files and highlights them in the editor.
<br>
</body>
</html>
@@ -23,8 +23,8 @@ YamlMissingKeysInspectionBase.add.missing.keys.quickfix.name=Add missing keys
YamlNonEditableKeysInspectionBase.noneditable.key=Key ''{0}'' is not modifiable by user
YamlDeprecatedKeysInspectionBase.deprecated.key=Key ''{0}'' is deprecated
YamlDuplicatedKeysInspectionBase.duplicated.key=Key ''{0}'' is duplicated
YamlDuplicatedKeysInspectionBase.remove.key.quickfix.name=Remove key
YAMLDuplicatedKeysInspection.duplicated.key=Key ''{0}'' is duplicated
YAMLDuplicatedKeysInspection.remove.key.quickfix.name=Remove key
YamlNonEditableKeyInspectionBase.strip.noneditable.keys.quickfix.name=Remove all non-editable keys from the file
YamlUnknownValuesInspectionBase.error.value.is.required=Value is required
@@ -69,3 +69,4 @@ inspections.unresolved.alias.name=Unresolved alias
inspections.unresolved.alias.message=Can''t resolve alias {0}
inspections.recursive.alias.name=Recursive alias
inspections.recursive.alias.message=Alias can't be recursive
inspections.duplicated.keys.name=Duplicated YAML keys
@@ -1,43 +1,37 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.yaml.meta.impl;
package org.jetbrains.yaml.inspections;
import com.intellij.codeInspection.*;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.SmartPointerManager;
import com.intellij.psi.SmartPsiElementPointer;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.yaml.YAMLBundle;
import org.jetbrains.yaml.psi.YAMLKeyValue;
import org.jetbrains.yaml.psi.YAMLMapping;
import org.jetbrains.yaml.psi.YamlPsiElementVisitor;
import java.util.Collection;
import java.util.Map;
@ApiStatus.Experimental
public abstract class YamlDuplicatedKeysInspectionBase extends LocalInspectionTool {
public class YAMLDuplicatedKeysInspection extends LocalInspectionTool {
@NotNull
@Override
public final PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
return new PsiElementVisitor() {
return new YamlPsiElementVisitor() {
@Override
public void visitElement(PsiElement element) {
ProgressIndicatorProvider.checkCanceled();
if (!(element instanceof YAMLMapping)) {
return;
}
public void visitMapping(@NotNull YAMLMapping mapping) {
MultiMap<String, YAMLKeyValue> occurrences = new MultiMap<>();
for (YAMLKeyValue keyValue : ((YAMLMapping)element).getKeyValues()) {
for (YAMLKeyValue keyValue : mapping.getKeyValues()) {
final String keyName = keyValue.getKeyText().trim();
// http://yaml.org/type/merge.html
if (keyName.equals("<<")) {
continue;
}
if (!keyName.isEmpty()) {
occurrences.putValue(keyName, keyValue);
}
@@ -48,7 +42,7 @@ public abstract class YamlDuplicatedKeysInspectionBase extends LocalInspectionTo
entry.getValue().forEach((duplicatedKey) -> {
assert duplicatedKey.getKey() != null;
holder.registerProblem(duplicatedKey.getKey(),
YAMLBundle.message("YamlDuplicatedKeysInspectionBase.duplicated.key", entry.getKey()),
YAMLBundle.message("YAMLDuplicatedKeysInspection.duplicated.key", entry.getKey()),
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new RemoveDuplicatedKeyQuickFix(duplicatedKey));
});
}
@@ -68,7 +62,7 @@ public abstract class YamlDuplicatedKeysInspectionBase extends LocalInspectionTo
@NotNull
@Override
public String getFamilyName() {
return YAMLBundle.message("YamlDuplicatedKeysInspectionBase.remove.key.quickfix.name");
return YAMLBundle.message("YAMLDuplicatedKeysInspection.remove.key.quickfix.name");
}
@Override
@@ -3,6 +3,7 @@ package org.jetbrains.yaml.highlighting;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
import org.jetbrains.yaml.inspections.YAMLDuplicatedKeysInspection;
import org.jetbrains.yaml.inspections.YAMLRecursiveAliasInspection;
import org.jetbrains.yaml.inspections.YAMLUnresolvedAliasInspection;
@@ -34,6 +35,11 @@ public class YAMLHighlightingTest extends LightPlatformCodeInsightFixtureTestCas
doTest();
}
public void testDuplicatedKeys() {
myFixture.enableInspections(YAMLDuplicatedKeysInspection.class);
doTest();
}
private void doTest() {
myFixture.testHighlighting(true, false, false, getTestName(true) + ".yml");
}
@@ -0,0 +1,10 @@
map1: &an1
<error descr="Key 'testKey' is duplicated">testKey</error>: hello
anotherKey: world
<error descr="Key 'testKey' is duplicated">testKey</error>: duplicate
map2: &an2
someKey: some value from map 2
map3:
<<: *an1
<<: *an2
ownKey: some value from map 3
@@ -0,0 +1,41 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.yaml.intention;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.yaml.inspections.YAMLDuplicatedKeysInspection;
import java.util.List;
import java.util.Optional;
public class YAMLIntentionTest extends LightPlatformCodeInsightFixtureTestCase {
@Override
protected String getTestDataPath() {
return PathManagerEx.getCommunityHomePath() + "/plugins/yaml/testSrc/org/jetbrains/yaml/intention/data/";
}
public void testDeleteDuplicatedKey() {
myFixture.enableInspections(YAMLDuplicatedKeysInspection.class);
doTest("Remove key");
}
@SuppressWarnings("SameParameterValue")
private void doTest(@NotNull String intentionName) {
String testName = getTestName(true);
myFixture.configureByFile(testName + ".yml");
IntentionAction quickFix = findIntention(intentionName);
myFixture.launchAction(quickFix);
myFixture.checkResultByFile(testName + ".txt");
}
@NotNull
private IntentionAction findIntention(@NotNull String name) {
List<IntentionAction> intentions = myFixture.getAvailableIntentions();
Optional<IntentionAction> intention =
intentions.stream().filter(it -> it.getText().contains(name)).findFirst();
assert intention.isPresent();
return intention.get();
}
}
@@ -0,0 +1,67 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
labels:
app: psi-agent
version: 2017.2.2057
name: psi-agent
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: psi-agent
version: 2017.2.2057
strategy:
rollingUpdate:
maxSurge: abc
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
app: psi-agent
version: 2017.2.2057
name: psi-agent
spec:
containers:
- image: jetbrains/upsource-psi-agent:2017.2.2057
imagePullPolicy: IfNotPresent
name: psi-agent
resources: {}
securityContext:
privileged: false
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
env:
- name: HUB_URL
value: http://hub-service:8088/hub
- name: UPSOURCE_SERVICE_ID
value: d574afce-a315-4bb2-b2a7-6c726b3e1080
- name: UPSOURCE_SERVICE_SECRET
value: lxnbMouMvGId
- name: UPSOURCE_URL
value: http://35.195.40.139
- name: UPSOURCE_SERVICE_PORT
value: "10061"
- name: UPSOURCE_STATISTICS_UPLOAD
value: "false"
- name: CASSANDRA_HOSTS
value: cassandra
- name: CASSANDRA_PORT
value: "9042"
- name: UPSOURCE_DATABASE
value: datastax
- name: UPSOURCE_SUBNET
value: 10.60.0.0/16
- name: UPSOURCE_PSI_BROKER_PORT
value: "11111"
- name: UPSOURCE_PSI_BROKER_HOST
value: psi-broker
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
@@ -0,0 +1,68 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
labels:
app: psi-agent
version: 2017.2.2057
name: psi-agent
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: psi-agent
version: 2017.2.2057
strategy:
rollingUpdate:
maxSurge: abc
maxUnavailable: 1
type: RollingUpdate
re<caret>plicas : 2
template:
metadata:
labels:
app: psi-agent
version: 2017.2.2057
name: psi-agent
spec:
containers:
- image: jetbrains/upsource-psi-agent:2017.2.2057
imagePullPolicy: IfNotPresent
name: psi-agent
resources: {}
securityContext:
privileged: false
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
env:
- name: HUB_URL
value: http://hub-service:8088/hub
- name: UPSOURCE_SERVICE_ID
value: d574afce-a315-4bb2-b2a7-6c726b3e1080
- name: UPSOURCE_SERVICE_SECRET
value: lxnbMouMvGId
- name: UPSOURCE_URL
value: http://35.195.40.139
- name: UPSOURCE_SERVICE_PORT
value: "10061"
- name: UPSOURCE_STATISTICS_UPLOAD
value: "false"
- name: CASSANDRA_HOSTS
value: cassandra
- name: CASSANDRA_PORT
value: "9042"
- name: UPSOURCE_DATABASE
value: datastax
- name: UPSOURCE_SUBNET
value: 10.60.0.0/16
- name: UPSOURCE_PSI_BROKER_PORT
value: "11111"
- name: UPSOURCE_PSI_BROKER_HOST
value: psi-broker
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30