diff --git a/src/main/java/reposense/authorship/FileInfoAnalyzer.java b/src/main/java/reposense/authorship/FileInfoAnalyzer.java index ba3f65b315..748de08a16 100644 --- a/src/main/java/reposense/authorship/FileInfoAnalyzer.java +++ b/src/main/java/reposense/authorship/FileInfoAnalyzer.java @@ -64,7 +64,7 @@ public FileResult analyzeTextFile(RepoConfiguration config, FileInfo fileInfo, b aggregateBlameAuthorModifiedAndDateInfo(config, fileInfo, shouldAnalyzeAuthorship); fileInfo.setFileType(config.getFileType(fileInfo.getPath())); - AnnotatorAnalyzer.aggregateAnnotationAuthorInfo(fileInfo, config.getAuthorConfig()); + AnnotatorAnalyzer.aggregateAnnotationAuthorInfo(fileInfo, config.getAuthorConfig(), shouldAnalyzeAuthorship); if (!config.getAuthorList().isEmpty() && fileInfo.isAllAuthorsIgnored(config.getAuthorList())) { return null; diff --git a/src/main/java/reposense/authorship/analyzer/AnnotatorAnalyzer.java b/src/main/java/reposense/authorship/analyzer/AnnotatorAnalyzer.java index 8e32caa994..51ac0a7a7c 100644 --- a/src/main/java/reposense/authorship/analyzer/AnnotatorAnalyzer.java +++ b/src/main/java/reposense/authorship/analyzer/AnnotatorAnalyzer.java @@ -48,8 +48,10 @@ public class AnnotatorAnalyzer { * * @param fileInfo FileInfo to be further analyzed with author annotations. * @param authorConfig AuthorConfiguration for current analysis. + * @param shouldAnalyzeAuthorship whether credit info needs to be overwritten. */ - public static void aggregateAnnotationAuthorInfo(FileInfo fileInfo, AuthorConfiguration authorConfig) { + public static void aggregateAnnotationAuthorInfo(FileInfo fileInfo, AuthorConfiguration authorConfig, + boolean shouldAnalyzeAuthorship) { Optional currentAnnotatedAuthor = Optional.empty(); Path filePath = Paths.get(fileInfo.getPath()); for (LineInfo lineInfo : fileInfo.getLines()) { @@ -60,7 +62,7 @@ public static void aggregateAnnotationAuthorInfo(FileInfo fileInfo, AuthorConfig boolean isUnknownAuthorSegment = !currentAnnotatedAuthor.isPresent() && !newAnnotatedAuthor.isPresent(); if (isEndOfAnnotatedSegment) { - lineInfo.setAuthor(currentAnnotatedAuthor.get()); + lineInfo.updateAuthorAndCredit(currentAnnotatedAuthor.get(), shouldAnalyzeAuthorship); currentAnnotatedAuthor = Optional.empty(); } else if (isUnknownAuthorSegment) { currentAnnotatedAuthor = Optional.of(Author.UNKNOWN_AUTHOR); @@ -68,7 +70,7 @@ public static void aggregateAnnotationAuthorInfo(FileInfo fileInfo, AuthorConfig currentAnnotatedAuthor = newAnnotatedAuthor.filter(author -> !author.isIgnoringFile(filePath)); } } - currentAnnotatedAuthor.ifPresent(lineInfo::setAuthor); + currentAnnotatedAuthor.ifPresent(author -> lineInfo.updateAuthorAndCredit(author, shouldAnalyzeAuthorship)); } } diff --git a/src/main/java/reposense/authorship/model/LineInfo.java b/src/main/java/reposense/authorship/model/LineInfo.java index ea5e3d909f..56c8b07382 100644 --- a/src/main/java/reposense/authorship/model/LineInfo.java +++ b/src/main/java/reposense/authorship/model/LineInfo.java @@ -65,6 +65,21 @@ public void setIsFullCredit(boolean isFullCredit) { this.isFullCredit = isFullCredit; } + /** + * If {@code newAuthor} is not the same as current author, then {@code newAuthor} will get partial credit. + * Else nothing happens since the 2 authors are the same, the credit info is retained. + * {@code isFullCredit} is only updated if {@code shouldAnalyzeAuthorship} is set to True. + */ + public void updateAuthorAndCredit(Author newAuthor, boolean shouldAnalyzeAuthorship) { + if (!author.equals(newAuthor)) { + author = newAuthor; + + if (shouldAnalyzeAuthorship) { + isFullCredit = false; + } + } + } + @Override public boolean equals(Object other) { if (this == other) { diff --git a/src/test/java/reposense/authorship/AuthorshipAnalyzerTest.java b/src/test/java/reposense/authorship/AuthorshipAnalyzerTest.java index 2fbb9a655f..f31f143a7d 100644 --- a/src/test/java/reposense/authorship/AuthorshipAnalyzerTest.java +++ b/src/test/java/reposense/authorship/AuthorshipAnalyzerTest.java @@ -18,13 +18,15 @@ public class AuthorshipAnalyzerTest extends GitTestTemplate { private static final LocalDateTime SINCE_DATE = TestUtil.getSinceDate(2018, Month.JANUARY.getValue(), 1); - private static final LocalDateTime UNTIL_DATE = TestUtil.getUntilDate(2019, Month.DECEMBER.getValue(), 1); + private static final LocalDateTime UNTIL_DATE = TestUtil.getUntilDate(2023, Month.DECEMBER.getValue(), 1); private static final String TEST_FILENAME = "analyzeAuthorshipTest.java"; private static final String TEST1_FILENAME = "analyzeAuthorshipTest1.java"; private static final String TEST2_FILENAME = "analyzeAuthorshipTest2.java"; + private static final String TEST3_FILENAME = "analyzeAuthorshipTest3.java"; private static final String BRANCH_NAME = "945-FileAnalyzerTest-analyzeAuthorship"; private static final CommitHash IGNORE_HASH = new CommitHash("f874c0992645bed626de2113659ce48d7a2233dd"); private static final Author MINGYI_AUTHOR = new Author(MINGYI_AUTHOR_NAME); + private static final Author SHICHEN_AUTHOR = new Author(SHICHEN_AUTHOR_NAME); private RepoConfiguration config; @@ -43,6 +45,7 @@ public void before() throws Exception { config.addAuthorNamesToAuthorMapEntry(FAKE_AUTHOR, FAKE_AUTHOR_NAME); config.addAuthorNamesToAuthorMapEntry(MINGYI_AUTHOR, MINGYI_AUTHOR_NAME); + config.addAuthorNamesToAuthorMapEntry(SHICHEN_AUTHOR, SHICHEN_AUTHOR_NAME); } @Test @@ -147,6 +150,25 @@ public void analyzeAuthorship_sameAuthor_success() { Assertions.assertTrue(fileInfo.getLine(3).isFullCredit()); } + @Test + public void analyzeAuthorship_annotatedAuthorOverride_success() { + FileInfo fileInfo = analyzeTextFile(TEST3_FILENAME); + + // Line 1 - 4 is annotated to ming yi (myteo) + // Partial credit given since the blamed author is not the same as the annotated author + for (int i = 1; i <= 4; i++) { + Assertions.assertEquals(MINGYI_AUTHOR, fileInfo.getLine(i).getAuthor()); + Assertions.assertFalse(fileInfo.getLine(i).isFullCredit()); + } + + // Line 5 - 8 is annotated to shi chen (SkyBlaise) + // Full credit is inherited since the blamed author is the same as the annotated author + for (int i = 5; i <= 8; i++) { + Assertions.assertEquals(SHICHEN_AUTHOR, fileInfo.getLine(i).getAuthor()); + Assertions.assertTrue(fileInfo.getLine(i).isFullCredit()); + } + } + private FileInfo analyzeTextFile(String relativePath) { FileInfoExtractor fileInfoExtractor = new FileInfoExtractor(); FileInfo fileInfo = fileInfoExtractor.generateFileInfo(config, relativePath); diff --git a/src/test/java/reposense/template/GitTestTemplate.java b/src/test/java/reposense/template/GitTestTemplate.java index 0b530560e0..7daa689f74 100644 --- a/src/test/java/reposense/template/GitTestTemplate.java +++ b/src/test/java/reposense/template/GitTestTemplate.java @@ -56,6 +56,7 @@ public class GitTestTemplate { protected static final String EUGENE_AUTHOR_NAME = "eugenepeh"; protected static final String YONG_AUTHOR_NAME = "Yong Hao TENG"; protected static final String MINGYI_AUTHOR_NAME = "myteo"; + protected static final String SHICHEN_AUTHOR_NAME = "SkyBlaise"; protected static final String JAMES_AUTHOR_NAME = "jamessspanggg"; protected static final String JAMES_ALTERNATIVE_AUTHOR_NAME = "James Pang"; protected static final String JINYAO_AUTHOR_NAME = "jylee-git";