Skip to content

Commit

Permalink
Render problem reports as error markers
Browse files Browse the repository at this point in the history
  • Loading branch information
donat committed Jun 10, 2024
1 parent 754da40 commit 1425085
Show file tree
Hide file tree
Showing 8 changed files with 302 additions and 151 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,7 @@ class GradleErrorMarkerTest extends ProjectSynchronizationSpecification {
def problems = gradleInternal.services.get(Problems)
problems.forNamespace("buildscript").reporting {
it.label("Problem label")
.category('deprecation', 'plugin')
it.id("Problem label", 'deprecation')
.severity(Severity.WARNING)
.solution("Please use 'standard-plugin-2' instead of this plugin")
}
Expand All @@ -152,7 +151,7 @@ class GradleErrorMarkerTest extends ProjectSynchronizationSpecification {
then:
numOfGradleErrorMarkers == 1
gradleErrorMarkers[0].getAttribute(IMarker.MESSAGE) == 'Problem label'
gradleErrorMarkers[0].getAttribute(GradleErrorMarker.ATTRIBUTE_PROBLEM_CATEGORY) == 'buildscript:deprecation:plugin'
gradleErrorMarkers[0].getAttribute(GradleErrorMarker.ATTRIBUTE_ID) == 'deprecation'

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,9 @@ SynchronizationResult run(CancellationTokenSource tokenSource, IProgressMonitor
CorePlugin.operationManager().run(this, tokenSource, monitor);
for (SynchronizationProblem f : this.failures) {
if (f.getSeverity() == IStatus.ERROR) {
GradleErrorMarker.createError(f.getResource(), this.gradleBuild, f.getMessage(), f.getException(), 0);
GradleErrorMarker.createError(f.getResource(), this.gradleBuild, f.getMessage(), f.getException());
} else if (f.getSeverity() == IStatus.WARNING) {
GradleErrorMarker.createWarning(f.getResource(), this.gradleBuild, f.getMessage(), f.getException(), 0);
GradleErrorMarker.createWarning(f.getResource(), this.gradleBuild, f.getMessage(), f.getException());
}
}
result = DefaultSynchronizationResult.from(getFailures());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
package org.eclipse.buildship.core.internal.marker;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;
import java.util.function.Consumer;

import com.google.common.base.Throwables;

Expand All @@ -29,13 +28,14 @@
*/
public class GradleErrorMarker {

public static String ID = CorePlugin.PLUGIN_ID + ".errormarker";
public static String ATTRIBUTE_STACKTRACE = "stacktrace";
public static String ATTRIBUTE_ROOT_DIR = "rootdir";
public static String ATTRIBUTE_PROBLEM_CATEGORY = "problem.category";
public static String ATTRIBUTE_PROBLEM_SOLUTIONS = "problem.solutions";
public static String ATTRIBUTE_DOCUMENTATION_LINK = "problem.documentationlink";

public static final String ID = CorePlugin.PLUGIN_ID + ".errormarker";
public static final String ATTRIBUTE_STACKTRACE = "stacktrace";
public static final String ATTRIBUTE_ROOT_DIR = "rootdir";
public static final String ATTRIBUTE_ID = "problem.id";
public static final String ATTRIBUTE_LABEL = "problem.label";
public static final String ATTRIBUTE_DETAILS = "problem.details";
public static final String ATTRIBUTE_SOLUTIONS = "problem.solutions";
public static final String ATTRIBUTE_DOCUMENTATION_LINK = "problem.documentationlink";

private GradleErrorMarker() {
}
Expand All @@ -45,50 +45,65 @@ public static boolean belongsToBuild(IMarker marker, InternalGradleBuild build)
return build.getBuildConfig().getRootProjectDirectory().getAbsolutePath().equals(rootDir);
}

public static void createError(IResource resource, InternalGradleBuild gradleBuild, String message, Throwable exception) {
createMarker(IMarker.SEVERITY_ERROR, resource, gradleBuild, message, exception, 0);
}

public static void createError(IResource resource, InternalGradleBuild gradleBuild, String message, Throwable exception, int lineNumber) {
createMarker(IMarker.SEVERITY_ERROR, resource, gradleBuild, message, exception, lineNumber);
}

public static void createWarning(IResource resource, InternalGradleBuild gradleBuild, String message, Throwable exception, int lineNumber) {
createMarker(IMarker.SEVERITY_WARNING, resource, gradleBuild, message, exception,lineNumber);
public static void createWarning(IResource resource, InternalGradleBuild gradleBuild, String message, Throwable exception) {
createMarker(IMarker.SEVERITY_WARNING, resource, gradleBuild, message, exception, 0);
}

private static void createMarker(int severity, IResource resource, InternalGradleBuild gradleBuild, String message, Throwable exception, int lineNumber) {
createMarker(severity, resource, gradleBuild, message, exception, lineNumber, null, null, null);
}

public static void createMarker(int severity, IResource resource, InternalGradleBuild gradleBuild, String message, Throwable exception, int lineNumber, String category,
List<String> solutions, String documentationLink) {
try {
IMarker marker = resource.createMarker(GradleErrorMarker.ID);

String stacktrace = exception == null ? null : trimMarkerProperty(Throwables.getStackTraceAsString(exception));
createMarker(resource, severity, gradleBuild, message, stacktrace, marker -> {
if (lineNumber >= 0) {
marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
try {
marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
} catch (CoreException e) {
throw new RuntimeException(e);
}
}
});
}

marker.setAttribute(IMarker.MESSAGE, trimMarkerProperty(message));
marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
marker.setAttribute(IMarker.SEVERITY, severity);
marker.setAttribute(ATTRIBUTE_ROOT_DIR, gradleBuild.getBuildConfig().getRootProjectDirectory().getAbsolutePath());
if (exception != null) {
String stackTrace = Throwables.getStackTraceAsString(exception);
marker.setAttribute(GradleErrorMarker.ATTRIBUTE_STACKTRACE, trimMarkerProperty(stackTrace));
private static void createMarker(IResource resource, int severity, InternalGradleBuild gradleBuild, String message, String exception, Consumer<IMarker> customMarkerConfiguration) {
createMarker(resource, new Consumer<IMarker>() {

@Override
public void accept(IMarker marker) {
try {
marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
marker.setAttribute(IMarker.SEVERITY, severity);
marker.setAttribute(ATTRIBUTE_ROOT_DIR, gradleBuild.getBuildConfig().getRootProjectDirectory().getAbsolutePath());
marker.setAttribute(IMarker.MESSAGE, trimMarkerProperty(message));
if (exception != null) {
marker.setAttribute(GradleErrorMarker.ATTRIBUTE_STACKTRACE, exception);
}
} catch (CoreException e) {
CorePlugin.logger().warn("Cannot create Gradle error marker", e);
throw new RuntimeException(e);
}
}
if (category != null) {
marker.setAttribute(ATTRIBUTE_PROBLEM_CATEGORY, category);
}
if (solutions != null) {
String solutionsString = solutions.stream().collect(Collectors.joining(System.getProperty("line.separator")));
marker.setAttribute(ATTRIBUTE_PROBLEM_SOLUTIONS, solutionsString);
}
if (documentationLink != null) {
marker.setAttribute(ATTRIBUTE_DOCUMENTATION_LINK, documentationLink);
}
} catch (CoreException e) {
}.andThen(customMarkerConfiguration));
}

private static void createMarker(IResource resource, Consumer<IMarker> markerConfiguration) {
try {
IMarker marker = resource.createMarker(GradleErrorMarker.ID);
markerConfiguration.accept(marker);
} catch (Exception e) {
CorePlugin.logger().warn("Cannot create Gradle error marker", e);
}
}

public static void createProblemMarker(int severity, IResource resource, InternalGradleBuild gradleBuild, String message, String exception, Consumer<IMarker> problemPosition, Consumer<IMarker> problemDetails) {
createMarker(resource, severity, gradleBuild, message, exception, problemPosition.andThen(problemDetails));
}

/*
* The Eclipse platform will throw an exception if a marker property is longer than 65535 bytes
* https://github.com/eclipse-platform/eclipse.platform/blob/97d555a8b563dcb3a32bd43ad58ba452fa027a73/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/MarkerInfo.java#L56-L60
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*******************************************************************************
* Copyright (c) 2023 Gradle Inc. and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
package org.eclipse.buildship.core.internal.util.progress;

import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import org.gradle.tooling.events.problems.ProblemGroup;
import org.gradle.tooling.events.problems.SingleProblemEvent;
import org.gradle.tooling.events.problems.Solution;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;

import org.eclipse.buildship.core.internal.marker.GradleErrorMarker;

public class ProblemEventAdapter implements Consumer<IMarker> {

private final SingleProblemEvent problem;

public ProblemEventAdapter(SingleProblemEvent problem) {
this.problem = problem;
}

@Override
public void accept(IMarker marker) {
try {
String idInfo = this.problem.getDefinition().getId().getDisplayName() + " (id: " + fqid() + ")";
marker.setAttribute(GradleErrorMarker.ATTRIBUTE_ID, idInfo);
marker.setAttribute(GradleErrorMarker.ATTRIBUTE_LABEL, this.problem.getContextualLabel().getContextualLabel());
marker.setAttribute(GradleErrorMarker.ATTRIBUTE_DETAILS, this.problem.getDetails().getDetails());
List<Solution> solutions = this.problem.getSolutions();
if (solutions != null) {
String solutionsString = solutions.stream().map(Solution::getSolution).collect(Collectors.joining(System.getProperty("line.separator")));
marker.setAttribute(GradleErrorMarker.ATTRIBUTE_SOLUTIONS, solutionsString);
}
String documentationLink = this.problem.getDefinition().getDocumentationLink().getUrl();
if (documentationLink != null) {
marker.setAttribute(GradleErrorMarker.ATTRIBUTE_DOCUMENTATION_LINK, documentationLink);
}
} catch (CoreException e) {
throw new RuntimeException(e);
}
}

private String fqid() {
return groupFqid(this.problem.getDefinition().getId().getGroup()) + ":" + this.problem.getDefinition().getId().getName();
}

private String groupFqid(ProblemGroup group) {
if (group.getParent() == null) {
return group.getName();
} else {
return groupFqid(group.getParent()) + ":" + group.getName();
}
}
}
Loading

0 comments on commit 1425085

Please sign in to comment.