-
Notifications
You must be signed in to change notification settings - Fork 118
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Runs analysis tools on the HEAD of the local git repository and reports to the log. Allows someone to check for any comments before pushing to Gerrit/Gitlab.
- Loading branch information
Marquis Wong
authored and
Marquis Wong
committed
Oct 25, 2019
1 parent
01f0303
commit ae6a433
Showing
10 changed files
with
259 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
package pl.touk.sputnik.connector; | ||
|
||
public enum Connectors { | ||
STASH, GERRIT, GITHUB, SAAS | ||
STASH, GERRIT, GITHUB, SAAS, LOCAL | ||
} |
96 changes: 96 additions & 0 deletions
96
src/main/java/pl/touk/sputnik/connector/local/LocalFacade.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package pl.touk.sputnik.connector.local; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.eclipse.jgit.api.Git; | ||
import org.eclipse.jgit.api.errors.GitAPIException; | ||
import org.eclipse.jgit.diff.DiffEntry; | ||
import org.eclipse.jgit.diff.DiffEntry.ChangeType; | ||
import org.jetbrains.annotations.NotNull; | ||
import pl.touk.sputnik.configuration.Configuration; | ||
import pl.touk.sputnik.configuration.GeneralOption; | ||
import pl.touk.sputnik.configuration.GeneralOptionNotSupportedException; | ||
import pl.touk.sputnik.connector.ConnectorFacade; | ||
import pl.touk.sputnik.connector.ConnectorValidator; | ||
import pl.touk.sputnik.connector.Connectors; | ||
import pl.touk.sputnik.connector.ReviewPublisher; | ||
import pl.touk.sputnik.review.Comment; | ||
import pl.touk.sputnik.review.Review; | ||
import pl.touk.sputnik.review.ReviewFile; | ||
|
||
import java.util.List; | ||
|
||
import static java.util.stream.Collectors.toList; | ||
|
||
@AllArgsConstructor | ||
@Slf4j | ||
public class LocalFacade implements ConnectorFacade, ConnectorValidator, ReviewPublisher { | ||
private final Git git; | ||
private final LocalFacadeOutput output; | ||
|
||
@NotNull | ||
@Override | ||
public List<ReviewFile> listFiles() { | ||
try { | ||
List<DiffEntry> diffs = git.diff().call(); | ||
return diffs.stream() | ||
.filter(this::isNotDeleted) | ||
.map(DiffEntry::getNewPath) | ||
.map(ReviewFile::new) | ||
.collect(toList()); | ||
} catch (GitAPIException e) { | ||
throw new RuntimeException("Error when listing files", e); | ||
} | ||
} | ||
|
||
private boolean isNotDeleted(DiffEntry aDiffEntry) { | ||
return aDiffEntry.getChangeType() != ChangeType.DELETE; | ||
} | ||
|
||
@Override | ||
public void publish(@NotNull Review review) { | ||
long numFilesWithComments = review.getFiles().stream().filter(files -> !files.getComments().isEmpty()).count(); | ||
if (numFilesWithComments == 0) { | ||
output.info("No sputnik comments"); | ||
return; | ||
} | ||
|
||
for (String message : review.getMessages()) { | ||
output.warn(message); | ||
} | ||
|
||
for (ReviewFile file : review.getFiles()) { | ||
if (file.getComments().isEmpty()) { | ||
continue; | ||
} | ||
|
||
output.warn(""); | ||
|
||
output.warn("{} comment(s) on {}", file.getComments().size(), file.getReviewFilename()); | ||
for (Comment comment : file.getComments()) { | ||
output.warn("Line {}: {}", comment.getLine(), comment.getMessage()); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public Connectors name() { | ||
return Connectors.LOCAL; | ||
} | ||
|
||
@Override | ||
public void validate(Configuration configuration) throws GeneralOptionNotSupportedException { | ||
boolean commentOnlyChangedLines = Boolean.parseBoolean(configuration | ||
.getProperty(GeneralOption.COMMENT_ONLY_CHANGED_LINES)); | ||
|
||
if (commentOnlyChangedLines) { | ||
throw new GeneralOptionNotSupportedException("This connector does not support " | ||
+ GeneralOption.COMMENT_ONLY_CHANGED_LINES.getKey()); | ||
} | ||
} | ||
|
||
@Override | ||
public void setReview(@NotNull Review review) { | ||
publish(review); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/main/java/pl/touk/sputnik/connector/local/LocalFacadeBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package pl.touk.sputnik.connector.local; | ||
|
||
import org.eclipse.jgit.api.Git; | ||
import org.eclipse.jgit.lib.Repository; | ||
import org.eclipse.jgit.storage.file.FileRepositoryBuilder; | ||
|
||
import java.io.IOException; | ||
|
||
public class LocalFacadeBuilder { | ||
public LocalFacade build() { | ||
try (Repository repository = new FileRepositoryBuilder().readEnvironment().findGitDir().build()) { | ||
try (Git git = new Git(repository)) { | ||
return new LocalFacade(git, new LocalFacadeOutput()); | ||
} | ||
} catch (IOException e) { | ||
throw new RuntimeException("Error getting git repository", e); | ||
} | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/main/java/pl/touk/sputnik/connector/local/LocalFacadeOutput.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package pl.touk.sputnik.connector.local; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
@AllArgsConstructor | ||
@Slf4j | ||
public class LocalFacadeOutput { | ||
void info(String message, Object ... arguments) { | ||
log.info(message, arguments); | ||
} | ||
|
||
void warn(String message, Object ... arguments) { | ||
log.warn(message, arguments); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
119 changes: 119 additions & 0 deletions
119
src/test/java/pl/touk/sputnik/connector/local/LocalFacadeTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package pl.touk.sputnik.connector.local; | ||
|
||
import com.google.common.collect.ImmutableList; | ||
import org.eclipse.jgit.api.Git; | ||
import org.eclipse.jgit.api.errors.GitAPIException; | ||
import org.eclipse.jgit.diff.DiffEntry; | ||
import org.eclipse.jgit.diff.DiffEntry.ChangeType; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
import org.mockito.InOrder; | ||
import org.mockito.Mock; | ||
import org.mockito.Mockito; | ||
import org.mockito.junit.jupiter.MockitoExtension; | ||
import pl.touk.sputnik.review.Comment; | ||
import pl.touk.sputnik.review.Review; | ||
import pl.touk.sputnik.review.ReviewFile; | ||
|
||
import java.util.List; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.mockito.Answers.RETURNS_DEEP_STUBS; | ||
import static org.mockito.ArgumentMatchers.anyString; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.never; | ||
import static org.mockito.Mockito.verify; | ||
import static org.mockito.Mockito.when; | ||
|
||
@ExtendWith(MockitoExtension.class) | ||
class LocalFacadeTest { | ||
@Mock(answer = RETURNS_DEEP_STUBS) | ||
private Git git; | ||
@Mock | ||
private DiffEntry modifiedFile; | ||
@Mock | ||
private DiffEntry deletedFile; | ||
@Mock | ||
private DiffEntry newFile; | ||
@Mock | ||
private Review review; | ||
@Mock | ||
private LocalFacadeOutput output; | ||
|
||
private LocalFacade localFacade; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
localFacade = new LocalFacade(git, output); | ||
} | ||
|
||
private void setUpDiff() throws GitAPIException { | ||
when(modifiedFile.getNewPath()).thenReturn("/path/to/modifiedFile"); | ||
when(modifiedFile.getChangeType()).thenReturn(ChangeType.MODIFY); | ||
|
||
when(newFile.getNewPath()).thenReturn("/path/to/newFile"); | ||
when(newFile.getChangeType()).thenReturn(ChangeType.ADD); | ||
|
||
when(deletedFile.getChangeType()).thenReturn(ChangeType.DELETE); | ||
|
||
when(git.diff().call()).thenReturn(ImmutableList.of(modifiedFile, deletedFile, newFile)); | ||
} | ||
|
||
@Test | ||
void shouldParseListFilesResponse() throws GitAPIException { | ||
setUpDiff(); | ||
|
||
List<ReviewFile> reviewFiles = localFacade.listFiles(); | ||
assertThat(reviewFiles).isNotEmpty(); | ||
} | ||
|
||
@Test | ||
void shouldNotListDeletedFiles() throws GitAPIException { | ||
setUpDiff(); | ||
|
||
List<ReviewFile> reviewFiles = localFacade.listFiles(); | ||
assertThat(reviewFiles) | ||
.hasSize(2) | ||
.extracting(ReviewFile::getReviewFilename).containsExactly(modifiedFile.getNewPath(), newFile.getNewPath()); | ||
} | ||
|
||
@Test | ||
void shouldPublishNoCommentsIfAllFilesHaveNoComments() { | ||
ReviewFile review1 = mock(ReviewFile.class); | ||
ReviewFile review2 = mock(ReviewFile.class); | ||
when(review.getFiles()).thenReturn(ImmutableList.of(review1, review2)); | ||
|
||
localFacade.publish(review); | ||
|
||
verify(output).info("No sputnik comments"); | ||
verify(output, never()).warn(anyString()); | ||
} | ||
|
||
@Test | ||
void shouldWarnWithCommentsAndLineNumbers() { | ||
ReviewFile review1 = mock(ReviewFile.class); | ||
when(review1.getReviewFilename()).thenReturn("/path/to/file1"); | ||
ReviewFile review2 = mock(ReviewFile.class); | ||
ReviewFile review3 = mock(ReviewFile.class); | ||
when(review3.getReviewFilename()).thenReturn("/path/to/file3"); | ||
when(review1.getComments()).thenReturn(ImmutableList.of(new Comment(11, "Comment 1"), new Comment(14, "Comment 2"))); | ||
when(review3.getComments()).thenReturn(ImmutableList.of(new Comment(15, "Comment 3"))); | ||
when(review.getMessages()).thenReturn(ImmutableList.of("message 1", "message 2")); | ||
when(review.getFiles()).thenReturn(ImmutableList.of(review1, review2, review3)); | ||
|
||
localFacade.publish(review); | ||
|
||
verify(output, never()).info(anyString()); | ||
InOrder order = Mockito.inOrder(output); | ||
order.verify(output).warn("message 1"); | ||
order.verify(output).warn("message 2"); | ||
order.verify(output).warn(""); | ||
order.verify(output).warn("{} comment(s) on {}", 2, "/path/to/file1"); | ||
order.verify(output).warn("Line {}: {}", 11, "Comment 1"); | ||
order.verify(output).warn("Line {}: {}", 14, "Comment 2"); | ||
order.verify(output).warn(""); | ||
order.verify(output).warn("{} comment(s) on {}", 1, "/path/to/file3"); | ||
order.verify(output).warn("Line {}: {}", 15, "Comment 3"); | ||
} | ||
} |