From: Julien Lancelot Date: Thu, 18 Apr 2013 07:36:50 +0000 (+0200) Subject: SONAR-4188 Close issues when resource has been moved or has been deleted X-Git-Tag: 3.6~648 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=b5479b6e99b9b68a132c5a66fdb5b3b373793625;p=sonarqube.git SONAR-4188 Close issues when resource has been moved or has been deleted --- diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssuesWorkflowDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssuesWorkflowDecorator.java index 4a69f7e1603..26552d58fa5 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssuesWorkflowDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssuesWorkflowDecorator.java @@ -76,14 +76,16 @@ public class IssuesWorkflowDecorator implements Decorator { issueTracking.track(resource, openIssues, newDefaultIssues); updateIssues(newDefaultIssues); - addManualIssuesAndCloseResolvedOnes(openIssues, resource); - closeResolvedStandardIssues(openIssues, newIssues, resource); - keepFalsePositiveIssues(openIssues, resource); - reopenUnresolvedIssues(openIssues, resource); + Set issueKeys = Sets.newHashSet(Collections2.transform(newIssues, new IssueToKeyfunction())); + for (IssueDto openIssue : openIssues) { + addManualIssuesAndCloseResolvedOnes(openIssue, resource); + closeResolvedStandardIssues(openIssue, issueKeys, resource); + keepFalsePositiveIssues(openIssue, resource); + reopenUnresolvedIssues(openIssue, resource); + } if (ResourceUtils.isRootProject(resource)) { - // TODO be carefullto take updated openIssue and not the ones coming directly from db (We should probably use a different sensor) -// closeIssuesOnDeletedResources(openIssues, resource); + closeIssuesOnDeletedResources(initialOpenIssuesStack.getAllIssues(), resource); } } } @@ -94,46 +96,37 @@ public class IssuesWorkflowDecorator implements Decorator { } } - private void addManualIssuesAndCloseResolvedOnes(Collection openIssues, Resource resource) { - for (IssueDto openIssue : openIssues) { - if (openIssue.isManualIssue()) { - DefaultIssue issue = toIssue(openIssue, resource); - if (Issue.STATUS_RESOLVED.equals(issue.status())) { - close(issue); - } - moduleIssues.addOrUpdate(issue); + private void addManualIssuesAndCloseResolvedOnes(IssueDto openIssue, Resource resource) { + if (openIssue.isManualIssue()) { + DefaultIssue issue = toIssue(openIssue, resource); + if (Issue.STATUS_RESOLVED.equals(issue.status())) { + close(issue); } + moduleIssues.addOrUpdate(issue); } } - private void closeResolvedStandardIssues(Collection openIssues, Collection issues, Resource resource) { - Set issueKeys = Sets.newHashSet(Collections2.transform(issues, new IssueToKeyfunction())); - - for (IssueDto openIssue : openIssues) { - if (!openIssue.isManualIssue() && !issueKeys.contains(openIssue.getUuid())) { - closeAndSave(openIssue, resource); - } + private void closeResolvedStandardIssues(IssueDto openIssue, Set issueKeys, Resource resource) { + if (!openIssue.isManualIssue() && !issueKeys.contains(openIssue.getUuid())) { + closeAndSave(openIssue, resource); } } - private void keepFalsePositiveIssues(Collection openIssues, Resource resource) { - for (IssueDto openIssue : openIssues) { - if (!openIssue.isManualIssue() && Issue.RESOLUTION_FALSE_POSITIVE.equals(openIssue.getResolution())) { - DefaultIssue issue = toIssue(openIssue, resource); - issue.setResolution(openIssue.getResolution()); - issue.setStatus(openIssue.getStatus()); - issue.setUpdatedAt(new Date()); - moduleIssues.addOrUpdate(issue); - } + private void keepFalsePositiveIssues(IssueDto openIssue, Resource resource) { + if (!openIssue.isManualIssue() && Issue.RESOLUTION_FALSE_POSITIVE.equals(openIssue.getResolution())) { + DefaultIssue issue = toIssue(openIssue, resource); + issue.setResolution(openIssue.getResolution()); + issue.setStatus(openIssue.getStatus()); + issue.setUpdatedAt(new Date()); + moduleIssues.addOrUpdate(issue); } + } - private void reopenUnresolvedIssues(Collection openIssues, Resource resource) { - for (IssueDto openIssue : openIssues) { - if (Issue.STATUS_RESOLVED.equals(openIssue.getStatus()) && !Issue.RESOLUTION_FALSE_POSITIVE.equals(openIssue.getResolution()) - && !openIssue.isManualIssue()) { - reopenAndSave(openIssue, resource); - } + private void reopenUnresolvedIssues(IssueDto openIssue, Resource resource) { + if (Issue.STATUS_RESOLVED.equals(openIssue.getStatus()) && !Issue.RESOLUTION_FALSE_POSITIVE.equals(openIssue.getResolution()) + && !openIssue.isManualIssue()) { + reopenAndSave(openIssue, resource); } } diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/IssuesWorkflowDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/IssuesWorkflowDecoratorTest.java index 5f4bd71fdb8..bb89f11eb1b 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/IssuesWorkflowDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/IssuesWorkflowDecoratorTest.java @@ -21,7 +21,6 @@ package org.sonar.plugins.core.issue; import com.google.common.collect.Lists; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.sonar.api.issue.Issue; @@ -144,18 +143,18 @@ public class IssuesWorkflowDecoratorTest extends AbstractDaoTestCase { } @Test - @Ignore public void should_close_remaining_open_issue_on_root_project() { when(moduleIssues.issues(anyString())).thenReturn(Collections.emptyList()); - when(initialOpenIssuesStack.selectAndRemove(anyInt())).thenReturn(newArrayList( - new IssueDto().setUuid("100").setRuleId(1))); + when(initialOpenIssuesStack.selectAndRemove(anyInt())).thenReturn(Collections.emptyList()); + + when(initialOpenIssuesStack.getAllIssues()).thenReturn(newArrayList(new IssueDto().setUuid("100").setRuleId(1))); Resource resource = mock(Resource.class); when(resource.getQualifier()).thenReturn(Qualifiers.PROJECT); decorator.decorate(resource, null); ArgumentCaptor argument = ArgumentCaptor.forClass(DefaultIssue.class); - verify(moduleIssues, times(2)).addOrUpdate(argument.capture()); + verify(moduleIssues).addOrUpdate(argument.capture()); assertThat(argument.getValue().status()).isEqualTo(Issue.STATUS_CLOSED); assertThat(argument.getValue().updatedAt()).isNotNull(); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/InitialOpenIssuesStack.java b/sonar-batch/src/main/java/org/sonar/batch/issue/InitialOpenIssuesStack.java index f6b6dec817a..ba070cfd084 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/InitialOpenIssuesStack.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/InitialOpenIssuesStack.java @@ -20,7 +20,6 @@ package org.sonar.batch.issue; -import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableList; import com.google.common.collect.ListMultimap; @@ -56,8 +55,7 @@ public class InitialOpenIssuesStack implements BatchExtension { } } - @VisibleForTesting - Collection getAllIssues(){ + public Collection getAllIssues(){ return issuesByResourceId.values(); } }