diff --git a/frontend/src/styles/_colors.scss b/frontend/src/styles/_colors.scss index ca250b293a..e7ba7fc5c8 100644 --- a/frontend/src/styles/_colors.scss +++ b/frontend/src/styles/_colors.scss @@ -303,7 +303,8 @@ $mui-colors: ( 'github': ( 'title-background': #FAFBFC, 'border': #E1E4E8, - 'authored-code-background': #E6FFED, + 'full-authored-code-background': #C8E6C9, + 'partial-authored-code-background': #E6FFED, ), 'grey': ( '50': #FAFAFA, diff --git a/frontend/src/views/c-authorship.vue b/frontend/src/views/c-authorship.vue index 7222b86146..550025dfd6 100644 --- a/frontend/src/views/c-authorship.vue +++ b/frontend/src/views/c-authorship.vue @@ -984,7 +984,7 @@ export default defineComponent({ .segment { border-left: .25rem solid mui-color('green'); .code { - background-color: mui-color('github', 'authored-code-background'); + background-color: mui-color('github', 'full-authored-code-background'); padding-left: 1rem; } .line-number { @@ -1009,7 +1009,7 @@ export default defineComponent({ } &.isNotFullCredit { .code { - background-color: mui-color('green', '100'); + background-color: mui-color('github', 'partial-authored-code-background'); } } &.untouched { diff --git a/src/main/java/reposense/authorship/analyzer/AuthorshipAnalyzer.java b/src/main/java/reposense/authorship/analyzer/AuthorshipAnalyzer.java index 5284ef95ba..c19a8b7ab4 100644 --- a/src/main/java/reposense/authorship/analyzer/AuthorshipAnalyzer.java +++ b/src/main/java/reposense/authorship/analyzer/AuthorshipAnalyzer.java @@ -23,7 +23,7 @@ public class AuthorshipAnalyzer { private static final Logger logger = LogsManager.getLogger(AuthorshipAnalyzer.class); - private static final double SIMILARITY_THRESHOLD = 0.8; + private static final double ORIGINALITY_THRESHOLD = 0.51; private static final String DIFF_FILE_CHUNK_SEPARATOR = "\ndiff --git a/.*\n"; private static final Pattern FILE_CHANGED_PATTERN = @@ -55,10 +55,10 @@ public static boolean analyzeAuthorship(RepoConfiguration config, String filePat return true; } - CandidateLine deletedLine = getDeletedLineWithHighestSimilarity(config, filePath, lineContent, commitHash); + CandidateLine deletedLine = getDeletedLineWithLowestOriginality(config, filePath, lineContent, commitHash); - // Give full credit if there are no deleted lines found or deleted line is less than similarity threshold - if (deletedLine == null || deletedLine.getSimilarityScore() < SIMILARITY_THRESHOLD) { + // Give full credit if there are no deleted lines found or deleted line is more than originality threshold + if (deletedLine == null || deletedLine.getOriginalityScore() > ORIGINALITY_THRESHOLD) { return true; } @@ -84,14 +84,14 @@ public static boolean analyzeAuthorship(RepoConfiguration config, String filePat } /** - * Returns the deleted line in {@code commitHash} that has the highest similarity with {@code lineContent}. + * Returns the deleted line in {@code commitHash} that has the lowest originality with {@code lineContent}. */ - private static CandidateLine getDeletedLineWithHighestSimilarity(RepoConfiguration config, String filePath, + private static CandidateLine getDeletedLineWithLowestOriginality(RepoConfiguration config, String filePath, String lineContent, String commitHash) { String gitLogResults = GitLog.getParentCommits(config.getRepoRoot(), commitHash); String[] parentCommits = gitLogResults.split(" "); - CandidateLine highestSimilarityLine = null; + CandidateLine lowestOriginalityLine = null; for (String parentCommit : parentCommits) { // Generate diff between commit and parent commit @@ -112,28 +112,28 @@ private static CandidateLine getDeletedLineWithHighestSimilarity(RepoConfigurati continue; } - CandidateLine candidateLine = getDeletedLineWithHighestSimilarityInDiff( + CandidateLine candidateLine = getDeletedLineWithLowestOriginalityInDiff( fileDiffResult, lineContent, parentCommit, preImageFilePath); if (candidateLine == null) { continue; } - if (highestSimilarityLine == null - || candidateLine.getSimilarityScore() > highestSimilarityLine.getSimilarityScore()) { - highestSimilarityLine = candidateLine; + if (lowestOriginalityLine == null + || candidateLine.getOriginalityScore() < lowestOriginalityLine.getOriginalityScore()) { + lowestOriginalityLine = candidateLine; } } } - return highestSimilarityLine; + return lowestOriginalityLine; } /** - * Returns the deleted line in {@code fileDiffResult} that has the highest similarity with {@code lineContent}. + * Returns the deleted line in {@code fileDiffResult} that has the lowest originality with {@code lineContent}. */ - private static CandidateLine getDeletedLineWithHighestSimilarityInDiff(String fileDiffResult, String lineContent, + private static CandidateLine getDeletedLineWithLowestOriginalityInDiff(String fileDiffResult, String lineContent, String commitHash, String filePath) { - CandidateLine highestSimilarityLine = null; + CandidateLine lowestOriginalityLine = null; String[] hunks = fileDiffResult.split(HUNK_SEPARATOR); @@ -155,11 +155,13 @@ private static CandidateLine getDeletedLineWithHighestSimilarityInDiff(String fi if (lineChanged.startsWith(DELETED_LINE_SYMBOL)) { String deletedLineContent = lineChanged.substring(DELETED_LINE_SYMBOL.length()); - double similarityScore = similarityScore(lineContent, deletedLineContent); + double originalityScore = computeOriginalityScore(lineContent, deletedLineContent); - if (highestSimilarityLine == null || similarityScore > highestSimilarityLine.getSimilarityScore()) { - highestSimilarityLine = new CandidateLine( - currentPreImageLineNumber, deletedLineContent, filePath, commitHash, similarityScore); + if (lowestOriginalityLine == null + || originalityScore < lowestOriginalityLine.getOriginalityScore()) { + lowestOriginalityLine = new CandidateLine( + currentPreImageLineNumber, deletedLineContent, filePath, commitHash, + originalityScore); } } @@ -169,7 +171,7 @@ private static CandidateLine getDeletedLineWithHighestSimilarityInDiff(String fi } } - return highestSimilarityLine; + return lowestOriginalityLine; } /** @@ -191,11 +193,11 @@ private static int getPreImageStartingLineNumber(String linesChangedHeader) { } /** - * Calculates the similarity score of {@code s} with {@code baseString}. + * Calculates the originality score of {@code s} with {@code baseString}. */ - private static double similarityScore(String s, String baseString) { + private static double computeOriginalityScore(String s, String baseString) { double levenshteinDistance = StringsUtil.getLevenshteinDistance(s, baseString); - return 1 - (levenshteinDistance / baseString.length()); + return levenshteinDistance / baseString.length(); } /** diff --git a/src/main/java/reposense/authorship/model/CandidateLine.java b/src/main/java/reposense/authorship/model/CandidateLine.java index e03e89056d..6916b9b5c2 100644 --- a/src/main/java/reposense/authorship/model/CandidateLine.java +++ b/src/main/java/reposense/authorship/model/CandidateLine.java @@ -8,15 +8,15 @@ public class CandidateLine { private final String lineContent; private final String filePath; private final String gitBlameCommitHash; - private final double similarityScore; + private final double originalityScore; public CandidateLine(int lineNumber, String lineContent, String filePath, String gitBlameCommitHash, - double similarityScore) { + double originalityScore) { this.lineNumber = lineNumber; this.lineContent = lineContent; this.filePath = filePath; this.gitBlameCommitHash = gitBlameCommitHash; - this.similarityScore = similarityScore; + this.originalityScore = originalityScore; } public int getLineNumber() { @@ -35,7 +35,7 @@ public String getGitBlameCommitHash() { return gitBlameCommitHash; } - public double getSimilarityScore() { - return similarityScore; + public double getOriginalityScore() { + return originalityScore; } }