Skip to content
This repository was archived by the owner on Jan 7, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ private void postInfoAndPRsActions(
stashRequestFacade.resetPullRequestApproval(pr, stashClient);
}
}

if (config.canMarkPullRequestNeedsWork()) {
if (!shouldApprovePullRequest(config.getApprovalSeverityThreshold(), issueReport)) {
stashRequestFacade.markPullRequestNeedsWork(pr, stashClient);
}
}
}

static boolean shouldApprovePullRequest(Optional<Severity> approvalSeverityThreshold, List<PostJobIssue> report) {
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/org/sonar/plugins/stash/StashPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public enum IssueType {
public static final String STASH_PASSWORD = "sonar.stash.password";
public static final String STASH_PASSWORD_ENVIRONMENT_VARIABLE = "sonar.stash.password.variable";
public static final String STASH_REVIEWER_APPROVAL = "sonar.stash.reviewer.approval";
public static final String STASH_REVIEWER_MARK_NEEDS_WORK = "sonar.stash.reviewer.mark.needs.work";
public static final String STASH_REVIEWER_APPROVAL_SEVERITY_THRESHOLD = "sonar.stash.reviewer.approval.severity.threshold";
public static final String STASH_ISSUE_THRESHOLD = "sonar.stash.issue.threshold";
public static final String STASH_ISSUE_SEVERITY_THRESHOLD = "sonar.stash.issue.severity.threshold";
Expand Down Expand Up @@ -191,7 +192,14 @@ public void define(Context context) {
.type(PropertyType.STRING)
.subCategory(CONFIG_PAGE_SUB_CATEGORY_STASH)
.onQualifiers(Qualifiers.PROJECT)
.defaultValue(DEFAULT_STASH_EXCLUDE_RULES).build()
.defaultValue(DEFAULT_STASH_EXCLUDE_RULES).build(),
PropertyDefinition.builder(STASH_REVIEWER_MARK_NEEDS_WORK)
.name("Stash reviewer marking NEEDS WORK")
.description("Does SonarQube mark the pull-request NEEDS WORK if there are new issues?")
.subCategory(CONFIG_PAGE_SUB_CATEGORY_STASH)
.onQualifiers(Qualifiers.PROJECT)
.type(PropertyType.BOOLEAN)
.defaultValue("false").build()
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ public int getStashTimeout() {
public boolean canApprovePullRequest() {
return settings.getBoolean(StashPlugin.STASH_REVIEWER_APPROVAL);
}
public boolean canMarkPullRequestNeedsWork() {
return settings.getBoolean(StashPlugin.STASH_REVIEWER_MARK_NEEDS_WORK);
}

public boolean resetComments() {
return settings.getBoolean(StashPlugin.STASH_RESET_COMMENTS);
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/org/sonar/plugins/stash/StashRequestFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,24 @@ public void approvePullRequest(PullRequestRef pr, StashClient stashClient) {
}
}

/**
* Mark pull-request needs work
*/
public void markPullRequestNeedsWork(PullRequestRef pr, StashClient stashClient) {
try {
stashClient.markPullRequestNeedsWork(pr);

// squid:S2629 : no evaluation required if the logging level is not activated
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Pull-request {} ({}/{}) marked NEEDS WORK by user \"{}\"",
pr.pullRequestId(), pr.project(), pr.repository(), stashClient.getLogin());
}

} catch (StashClientException e) {
LOGGER.error("Unable to mark pull-request NEEDS WORK", e);
}
}

/**
* Reset pull-request approval
*/
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/org/sonar/plugins/stash/client/StashClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,12 @@ 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_NEEDS_WORK = API_ONE_PR + "/participants/{4}";
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_ONE_COMMENT = API_ONE_PR_ALL_COMMENTS + "/{4}?version={5}";

private static final String PULL_REQUEST_MARK_NEEDS_WORK_PUT_ERROR_MESSAGE = "Unable to set NEEDS WORK status of pull-request {0}";
private static final String PULL_REQUEST_APPROVAL_POST_ERROR_MESSAGE = "Unable to change status of pull-request {0}"
+ " #{1,number,#}.";
private static final String PULL_REQUEST_GET_ERROR_MESSAGE = "Unable to retrieve pull-request {0} #{1,number,#}.";
Expand Down Expand Up @@ -278,6 +280,21 @@ public void resetPullRequestApproval(PullRequestRef pr) throws StashClientExcept
MessageFormat.format(PULL_REQUEST_APPROVAL_POST_ERROR_MESSAGE, pr.repository(), pr.pullRequestId()));
}

public void markPullRequestNeedsWork(PullRequestRef pr ) throws StashClientException {
String request = MessageFormat.format(API_ONE_PR_NEEDS_WORK,
baseUrl,
pr.project(),
pr.repository(),
pr.pullRequestId(),
credentials.getUserSlug());
JsonObject json = new JsonObject();
json.put("status", "NEEDS_WORK");
put(request,
json,
MessageFormat
.format(PULL_REQUEST_MARK_NEEDS_WORK_PUT_ERROR_MESSAGE, pr.repository(), pr.pullRequestId()));
}

public void postTaskOnComment(String message, Long commentId) throws StashClientException {
String request = baseUrl + TASKS_API;

Expand Down
24 changes: 21 additions & 3 deletions src/main/java/org/sonar/plugins/stash/issue/MarkdownPrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,13 @@ private String fileNameList(List<PostJobIssue> issues) {
issues.sort(issueFormatComparator);

for (PostJobIssue issue: issues.subList(0, Math.min(includeFilesInOverview, issues.size()))) {
names.add(String.format("%s:%s", issuePathResolver.getIssuePath(issue), issue.line()));
String path = issuePathResolver.getIssuePath(issue);
Integer line = issue.line();
if (line == null) {
names.add(path);
} else {
names.add(String.format("%s:%s", path, line));
}
}
if (issues.size() > includeFilesInOverview) {
names.add("...");
Expand All @@ -171,13 +177,25 @@ private static String link(String title, String target) {
.comparing(i -> issuePathResolver.getIssuePath(i).length());

private Comparator<PostJobIssue> issueLine = Comparator
.comparing(PostJobIssue::line);
// -1 sorts before all issues with lines
.comparing(issue -> firstNonNull(issue.line(), -1));

private Comparator<PostJobIssue> fileNameLexical = Comparator
.comparing(i -> issuePathResolver.getIssuePath(i));

private Comparator<PostJobIssue> issueFormatComparator =
fileNameLength
.thenComparing(issueLine)
.thenComparing(fileNameLexical);
.thenComparing(fileNameLexical)
;

@SafeVarargs
private static <T> T firstNonNull(T... args) {
for (T t: args) {
if (t != null) {
return t;
}
}
throw new IllegalStateException("At least one of the arguments should have been non-null");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,12 @@ public void testApprovePullRequest() throws Exception {
verify(stashClient, times(1)).approvePullRequest(pr);
}

@Test
public void testmarkPullRequestNeedsWork() throws Exception {

myFacade.markPullRequestNeedsWork(pr, stashClient);
verify(stashClient, times(1)).markPullRequestNeedsWork(pr);
}

@Test
public void testApprovePullRequestException() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,38 @@ public void testPrintReportMarkdownWithIssueLimitation() {
assertEquals(reportString, issueReportMarkdown);
}

@Test
public void testPrintReportMarkdownWithFileWideIssues() {
PostJobIssue issueWithoutLine = new DefaultIssue().setKey("key36")
.setSeverity(Severity.CRITICAL)
.setMessage("messageCritical")
.setRuleKey(RuleKey.of("RepoCritical", "RuleCritical"))
.setInputComponent(new DefaultInputFile("foo2", "scripts/file2.example"))
.setLine(null);
report.add(issueWithoutLine);
printer = new MarkdownPrinter(100, SONAR_URL, 100, new DummyIssuePathResolver());
String issueReportMarkdown = printer.printReportMarkdown(report);
String reportString = "## SonarQube analysis Overview\n"
+ "| Total New Issues | 6 |\n"
+ "|-----------------|------|\n"
+ "| BLOCKER | 1 |\n"
+ "| CRITICAL | 2 |\n"
+ "| MAJOR | 3 |\n"
+ "| MINOR | 0 |\n"
+ "| INFO | 0 |\n\n\n"
+ "| Issues list |\n"
+ "|-------------|\n"
+ "| *BLOCKER* - messageBlocker [[RepoBlocker:RuleBlocker](sonarqube/URL/coding_rules#rule_key=RepoBlocker:RuleBlocker)] |\n"
+ "| &nbsp;&nbsp; *Files: scripts/file1.example:1* |\n"
+ "| *CRITICAL* - messageCritical [[RepoCritical:RuleCritical](sonarqube/URL/coding_rules#rule_key=RepoCritical:RuleCritical)] |\n"
+ "| &nbsp;&nbsp; *Files: scripts/file2.example, scripts/file2.example:1* |\n"
+ "| *MAJOR* - messageMajor [[RepoMajor:RuleMajor](sonarqube/URL/coding_rules#rule_key=RepoMajor:RuleMajor)] |\n"
+ "| &nbsp;&nbsp; *Files: scripts/file3.example:1, scripts/file3.example:15, scripts/tests/file3.example:5* |\n";

assertEquals(reportString, issueReportMarkdown);

}

@Test
public void testPrintEmptyReportMarkdown() {
report = new ArrayList<>();
Expand Down