Skip to content
This repository has been archived by the owner on Jan 7, 2021. It is now read-only.

Commit

Permalink
implement resetting of overview comments
Browse files Browse the repository at this point in the history
  • Loading branch information
t-8ch committed Nov 2, 2017
1 parent ab72441 commit c3fa85a
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 53 deletions.
6 changes: 6 additions & 0 deletions src/main/java/org/sonar/plugins/stash/StashPluginUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import com.google.common.base.CharMatcher;
import java.io.IOException;
import java.util.Collection;
import java.util.Optional;
import java.util.Properties;
import java.util.stream.Stream;
import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.postjob.issue.PostJobIssue;
Expand Down Expand Up @@ -72,4 +74,8 @@ public static String removeEnd(String s, String suffix) {
}
return s;
}

public static <T> Stream<T> removeEmpty(Optional<T> v) {
return v.map(Stream::of).orElse(Stream.empty());
}
}
57 changes: 32 additions & 25 deletions src/main/java/org/sonar/plugins/stash/StashRequestFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -398,39 +398,46 @@ public void resetComments(PullRequestRef pr,
StashUser sonarUser,
StashClient stashClient) {
try {
// Let's call this "diffRep_loop"
for (StashComment comment : diffReport.getComments()) {

// delete comment only if published by the current SQ user
if (sonarUser.getId() != comment.getAuthor().getId()) {
continue;
// Next element in "diffRep_loop"

// comment contains tasks which cannot be deleted => do nothing
} else if (comment.containsPermanentTasks()) {
LOGGER.debug("Comment \"{}\" (path:\"{}\", line:\"{}\")"
+ "CANNOT be deleted because one of its tasks is not deletable.", comment.getId(),
comment.getPath(),
comment.getLine());
continue; // Next element in "diffRep_loop"
}

// delete tasks linked to the current comment
for (StashTask task : comment.getTasks()) {
stashClient.deleteTaskOnComment(task);
}

stashClient.deletePullRequestComment(pr, comment);
}
// FIXME delete tasks on file-wide comments
// resetComments(diffReport.getComments(), pr, sonarUser, stashClient);
resetComments(stashClient.getPullRequestOverviewComments(pr), pr, sonarUser, stashClient);

LOGGER.info("SonarQube issues reported to Stash by user \"{}\" have been reset",
sonarUser.getName());

} catch (StashClientException e) {
LOGGER.error("Unable to reset comment list", e);
}
}

private void resetComments(Collection<StashComment> comments, PullRequestRef pr, StashUser sonarUser, StashClient stashClient)
throws StashClientException {
for (StashComment comment : comments) {
if (comment.getId() == 2079776) {
LOGGER.warn(comment.toString());
LOGGER.warn(comment.getTasks().toString());
}

if (sonarUser.getId() != comment.getAuthor().getId()) {
continue;
}

if (comment.containsPermanentTasks()) {
LOGGER.debug("Comment \"{}\" (path:\"{}\", line:\"{}\")"
+ "CANNOT be deleted because one of its tasks is not deletable.", comment.getId(),
comment.getPath(),
comment.getLine());
continue; // Next element in "diffRep_loop"
}

// delete tasks linked to the current comment
for (StashTask task : comment.getTasks()) {
stashClient.deleteTaskOnComment(task);
}

stashClient.deletePullRequestComment(pr, comment);
}
}

@Override
public String getIssuePath(PostJobIssue issue) {
InputComponent ip = issue.inputComponent();
Expand Down
159 changes: 136 additions & 23 deletions src/main/java/org/sonar/plugins/stash/client/StashClient.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package org.sonar.plugins.stash.client;

import java.util.Collection;
import java.util.Optional;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.asynchttpclient.AsyncHttpClient;
import org.asynchttpclient.BoundRequestBuilder;
import org.asynchttpclient.DefaultAsyncHttpClient;
Expand All @@ -19,7 +25,6 @@
import org.sonar.plugins.stash.PeekableInputStream;
import org.sonar.plugins.stash.PluginInfo;
import org.sonar.plugins.stash.PullRequestRef;
import org.sonar.plugins.stash.StashPlugin;
import org.sonar.plugins.stash.StashPlugin.IssueType;
import org.sonar.plugins.stash.StashPluginUtils;
import org.sonar.plugins.stash.exceptions.StashClientException;
Expand Down Expand Up @@ -64,7 +69,7 @@ public class StashClient implements AutoCloseable {
private static final String API_ONE_PR_ALL_COMMENTS = API_ONE_PR + "/comments";
private static final String API_ONE_PR_DIFF = API_ONE_PR + "/diff?withComments=true";
private static final String API_ONE_PR_APPROVAL = API_ONE_PR + "/approve";
private static final String API_ONE_PR_COMMENT_PATH = API_ONE_PR + "/comments?path={4}&start={5,number,#}";
private static final String API_ONE_PR_COMMENT_PATH = API_ONE_PR + "/comments?path={4}";

private static final String API_ONE_PR_ONE_COMMENT = API_ONE_PR_ALL_COMMENTS + "/{4}?version={5}";

Expand Down Expand Up @@ -111,35 +116,33 @@ public void postCommentOnPullRequest(PullRequestRef pr, String report)
postCreate(request, json, MessageFormat.format(COMMENT_POST_ERROR_MESSAGE, pr.repository(), pr.pullRequestId()));
}

public Collection<StashComment> getPullRequestOverviewComments(PullRequestRef pr) throws StashClientException {
return getPaged(
MessageFormat.format(API_ONE_PR + "/activities", baseUrl, pr.project(), pr.repository(), pr.pullRequestId()),
"Error!"
).map(StashCollector::extractCommentFromActivity).flatMap(StashPluginUtils::removeEmpty).collect(Collectors.toList());
}

public StashCommentReport getPullRequestComments(PullRequestRef pr, String path)
throws StashClientException {
StashCommentReport result = new StashCommentReport();

long start = 0;
boolean isLastPage = false;
String url = MessageFormat.format(API_ONE_PR_COMMENT_PATH,
baseUrl,
pr.project(),
pr.repository(),
pr.pullRequestId(),
path);

while (!isLastPage) {
getPaged(url,
MessageFormat.format(COMMENT_GET_ERROR_MESSAGE, pr.repository(), pr.pullRequestId())
).forEach(v -> {
try {
String request = MessageFormat.format(API_ONE_PR_COMMENT_PATH,
baseUrl,
pr.project(),
pr.repository(),
pr.pullRequestId(),
path,
start);
JsonObject jsonComments = get(request,
MessageFormat.format(COMMENT_GET_ERROR_MESSAGE,
pr.repository(),
pr.pullRequestId()));
result.add(StashCollector.extractComments(jsonComments));

// Stash pagination: check if you get all comments linked to the pull-request
isLastPage = StashCollector.isLastPage(jsonComments);
start = StashCollector.getNextPageStart(jsonComments);
result.add(StashCollector.extractComment(v));
} catch (StashReportExtractionException e) {
throw new StashClientException(e);
throw new RuntimeException(e);
}
}
});

return result;
}
Expand Down Expand Up @@ -310,6 +313,10 @@ private JsonObject get(String url, String errorMessage) throws StashClientExcept
return performRequest(httpClient.prepareGet(url), null, HttpURLConnection.HTTP_OK, errorMessage);
}

private Stream<JsonObject> getPaged(String url, String errorMessage) throws StashClientException {
return performPagedRequest(httpClient.prepareGet(url), null, HttpURLConnection.HTTP_OK, errorMessage);
}

private JsonObject post(String url, JsonObject body, String errorMessage) throws StashClientException {
return performRequest(httpClient.preparePost(url), body, HttpURLConnection.HTTP_OK, errorMessage);
}
Expand Down Expand Up @@ -456,4 +463,110 @@ AsyncHttpClient createHttpClient(String sonarQubeVersion) {
.build()
);
}

private Stream<JsonObject> performPagedRequest(BoundRequestBuilder requestBuilder,
JsonObject body,
int expectedStatusCode,
String errorMessage) {
return StreamSupport.stream(
new StashClientSpliterator(this, requestBuilder, body, expectedStatusCode, errorMessage),
false
);
}

private abstract class BatchedSpliterator<T> implements Spliterator<T> {
private List<T> buffer = new ArrayList<>();

abstract void fillBuffer(Collection<T> buffer);
abstract boolean isDone();

@Override
public boolean tryAdvance(Consumer<? super T> action) {
if (nextElement(action)) {
return true;
}

if (isDone()) {
return false;
}

fillBuffer(buffer);
return nextElement(action);
}

private boolean nextElement(Consumer<? super T> action) {
if (!buffer.isEmpty()) {
action.accept(buffer.remove(0));
return true;
}
return false;
}

}

private class StashClientSpliterator extends BatchedSpliterator<JsonObject> {

private StashClient stashClient;
private final BoundRequestBuilder requestBuilder;
private final JsonObject body;
private final int expectedStatusCode;
private final String errorMessage;

private boolean isLastPage = false;
private int nextPageStart = 0;
// FIXME size/limit support

StashClientSpliterator(
StashClient stashClient, BoundRequestBuilder requestBuilder,
JsonObject body, int expectedStatusCode, String errorMessage) {
this.stashClient = stashClient;
this.requestBuilder = requestBuilder;
this.body = body;
this.expectedStatusCode = expectedStatusCode;
this.errorMessage = errorMessage;
}

@Override
boolean isDone() {
return isLastPage;
}

@Override
void fillBuffer(Collection<JsonObject> buffer) {
// FIXME should we mutate this here?
if (nextPageStart > 0) {
requestBuilder.addQueryParam("start", String.valueOf(nextPageStart));
}

try {
JsonObject res = stashClient.performRequest(requestBuilder, body, expectedStatusCode, errorMessage);
((JsonArray) res.get("values")).asCollection(buffer);
isLastPage = res.getBoolean("isLastPage");
if (isLastPage) {
nextPageStart = -1;
} else {
nextPageStart = res.getInteger("nextPageStart");
}
} catch (StashClientException e) {
// FIXME
throw new RuntimeException(e);
}

}

@Override
public Spliterator<JsonObject> trySplit() {
return null;
}

@Override
public long estimateSize() {
return Long.MAX_VALUE;
}

@Override
public int characteristics() {
return Spliterator.DISTINCT | Spliterator.IMMUTABLE | Spliterator.NONNULL;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.sonar.plugins.stash.issue.collector;

import java.math.BigDecimal;
import java.util.Objects;
import java.util.Optional;
import org.json.simple.JsonArray;
import org.json.simple.JsonObject;
import org.sonar.plugins.stash.PullRequestRef;
Expand All @@ -20,9 +22,7 @@ public final class StashCollector {
private static final String AUTHOR = "author";
private static final String VERSION = "version";

private StashCollector() {
// Hiding implicit public constructor with an explicit private one (squid:S1118)
}
private StashCollector() {}

public static StashCommentReport extractComments(JsonObject jsonComments) throws StashReportExtractionException {
StashCommentReport result = new StashCommentReport();
Expand All @@ -41,8 +41,11 @@ public static StashCommentReport extractComments(JsonObject jsonComments) throws
return result;
}

public static StashComment extractComment(JsonObject jsonComment, String path, Long line) {
public static Optional<StashComment> extractCommentFromActivity(JsonObject json) {
return Optional.ofNullable((JsonObject) json.get("comment")).filter(Objects::nonNull).map(j -> StashCollector.extractComment(j, null, null));
}

public static StashComment extractComment(JsonObject jsonComment, String path, Long line) {
long id = getLong(jsonComment, "id");
String message = (String)jsonComment.get("text");

Expand All @@ -51,7 +54,10 @@ public static StashComment extractComment(JsonObject jsonComment, String path, L
JsonObject jsonAuthor = (JsonObject)jsonComment.get(AUTHOR);
StashUser stashUser = extractUser(jsonAuthor);

return new StashComment(id, message, path, line, stashUser, version);
StashComment result = new StashComment(id, message, path, line, stashUser, version);
// FIXME do this at some central place
updateCommentTasks(result, (JsonArray) jsonComment.get("tasks"));
return result;
}

public static StashComment extractComment(JsonObject jsonComment) throws StashReportExtractionException {
Expand Down

0 comments on commit c3fa85a

Please sign in to comment.