diff --git a/analysis/import/SCMLogParser/README.md b/analysis/import/SCMLogParser/README.md index 1fa9f055cd..220c13dbc6 100644 --- a/analysis/import/SCMLogParser/README.md +++ b/analysis/import/SCMLogParser/README.md @@ -8,7 +8,7 @@ Generates visualisation data from repository (Git or SVN) logs. It supports the | `weeks_with_commits` | weeks with commits | | `number_of_authors` | number of authors with commits | -Additionally it saves the names of authors. +Additionally it saves the names of authors when the --a flag is set. ## Usage @@ -21,6 +21,6 @@ The generated logs must be in UTF-8 encoding. ### Executing the SCMLogParser -> `ccsh scmlogparser [--git|--svn] []` +> `ccsh scmlogparser [--git|--svn] [--a] []` The result is written as JSON to standard out or into the specified output file. diff --git a/analysis/import/SCMLogParser/src/main/java/de/maibornwolff/codecharta/importer/scmlogparser/ProjectConverter.java b/analysis/import/SCMLogParser/src/main/java/de/maibornwolff/codecharta/importer/scmlogparser/ProjectConverter.java index 1b71446128..7964fd25a4 100644 --- a/analysis/import/SCMLogParser/src/main/java/de/maibornwolff/codecharta/importer/scmlogparser/ProjectConverter.java +++ b/analysis/import/SCMLogParser/src/main/java/de/maibornwolff/codecharta/importer/scmlogparser/ProjectConverter.java @@ -47,23 +47,25 @@ private ProjectConverter() { // utility class } - public static Project convert(String projectName, List versionControlledFiles) { + public static Project convert(String projectName, List versionControlledFiles, boolean containsAuthors) { Project project = new Project(projectName); - versionControlledFiles.forEach(vcFile -> ProjectConverter.addVersionControlledFile(project, vcFile)); + versionControlledFiles.forEach(vcFile -> ProjectConverter.addVersionControlledFile(project, vcFile, containsAuthors)); return project; } - private static void addVersionControlledFile(Project project, VersionControlledFile versionControlledFile) { - Map attributes = extractAttributes(versionControlledFile); + private static void addVersionControlledFile(Project project, VersionControlledFile versionControlledFile, boolean containsAuthors) { + Map attributes = extractAttributes(versionControlledFile, containsAuthors); Node newNode = new Node(extractFilenamePart(versionControlledFile), NodeType.File, attributes, "", Collections.emptyList()); NodeInserter.insertByPath(project, PathFactory.fromFileSystemPath(extractPathPart(versionControlledFile)), newNode); } - private static Map extractAttributes(VersionControlledFile versionControlledFile) { + private static Map extractAttributes(VersionControlledFile versionControlledFile, boolean containsAuthors) { HashMap attributes = new HashMap<>(); attributes.put("number_of_commits", versionControlledFile.getNumberOfOccurrencesInCommits()); attributes.put("weeks_with_commits", versionControlledFile.getNumberOfWeeksWithCommits()); - attributes.put("authors", versionControlledFile.getAuthors()); + if (containsAuthors) { + attributes.put("authors", versionControlledFile.getAuthors()); + } attributes.put("number_of_authors", versionControlledFile.getNumberOfAuthors()); return attributes; } diff --git a/analysis/import/SCMLogParser/src/main/java/de/maibornwolff/codecharta/importer/scmlogparser/SCMLogParser.java b/analysis/import/SCMLogParser/src/main/java/de/maibornwolff/codecharta/importer/scmlogparser/SCMLogParser.java index 2c3e321e1a..1dfac1f168 100644 --- a/analysis/import/SCMLogParser/src/main/java/de/maibornwolff/codecharta/importer/scmlogparser/SCMLogParser.java +++ b/analysis/import/SCMLogParser/src/main/java/de/maibornwolff/codecharta/importer/scmlogparser/SCMLogParser.java @@ -25,9 +25,24 @@ public static void main(String[] args) throws IOException { String pathToLog = args[0]; String gitOrSvn = args[1]; - Project project = parseDataFromLog(pathToLog, gitOrSvn); + String outputFile = null; + + boolean containsAuthors = false; + if (args.length >= 3) { - ProjectSerializer.serializeProjectAndWriteToFile(project, args[2]); + if ("--a".equals(args[2])) { + containsAuthors = true; + if (args.length >= 4) { + outputFile = args[3]; + } + } else { + outputFile = args[2]; + } + } + + Project project = parseDataFromLog(pathToLog, gitOrSvn, containsAuthors); + if (outputFile != null) { + ProjectSerializer.serializeProjectAndWriteToFile(project, outputFile); } else { ProjectSerializer.serializeProject(project, new OutputStreamWriter(System.out)); } @@ -36,7 +51,7 @@ public static void main(String[] args) throws IOException { } } - private static Project parseDataFromLog(String pathToLog, String gitOrSvn) throws IOException { + private static Project parseDataFromLog(String pathToLog, String gitOrSvn, boolean containsAuthors) throws IOException { LogParserStrategy parserStrategy = null; switch (gitOrSvn) { case "--git": @@ -49,7 +64,7 @@ private static Project parseDataFromLog(String pathToLog, String gitOrSvn) throw showErrorAndTerminate(); } Stream lines = Files.lines(Paths.get(pathToLog)); - return new LogParser(parserStrategy).parse(lines); + return new LogParser(parserStrategy, containsAuthors).parse(lines); } private static void showErrorAndTerminate() { @@ -58,8 +73,9 @@ private static void showErrorAndTerminate() { } private static void showHelpAndTerminate() { - System.out.println("Please use the following syntax\n\"SCMLogParser-x.x.jar --git/--svn\" []\n" + + System.out.println("Please use the following syntax\n\"SCMLogParser-x.x.jar --git/--svn [--a] []\"\n" + "The log file must have been created by using \"svn log --verbose\" or \"git log --name-status\"\n" + + "Set the --a parameter to add an array of authors to every file of your output\n" + "If no output file was specified, the output will be piped to standard out"); System.exit(0); } diff --git a/analysis/import/SCMLogParser/src/main/java/de/maibornwolff/codecharta/importer/scmlogparser/parser/LogParser.java b/analysis/import/SCMLogParser/src/main/java/de/maibornwolff/codecharta/importer/scmlogparser/parser/LogParser.java index a64f351ea6..ca7143c258 100644 --- a/analysis/import/SCMLogParser/src/main/java/de/maibornwolff/codecharta/importer/scmlogparser/parser/LogParser.java +++ b/analysis/import/SCMLogParser/src/main/java/de/maibornwolff/codecharta/importer/scmlogparser/parser/LogParser.java @@ -12,9 +12,11 @@ public class LogParser { private final LogParserStrategy parserStrategy; + private final boolean containsAuthors; - public LogParser(LogParserStrategy parserStrategy) { + public LogParser(LogParserStrategy parserStrategy, boolean containsAuthors) { this.parserStrategy = parserStrategy; + this.containsAuthors = containsAuthors; } public Project parse(Stream lines) { @@ -29,7 +31,7 @@ List parseLoglines(Stream logLines) { } private Project convertToProject(List versionControlledFiles) { - return ProjectConverter.convert("SCMLogParser", versionControlledFiles); + return ProjectConverter.convert("SCMLogParser", versionControlledFiles, containsAuthors); } Commit parseCommit(List commitLines) { diff --git a/analysis/import/SCMLogParser/src/test/java/de/maibornwolff/codecharta/importer/scmlogparser/ProjectConverterTest.java b/analysis/import/SCMLogParser/src/test/java/de/maibornwolff/codecharta/importer/scmlogparser/ProjectConverterTest.java index 584e812045..5a347e6006 100644 --- a/analysis/import/SCMLogParser/src/test/java/de/maibornwolff/codecharta/importer/scmlogparser/ProjectConverterTest.java +++ b/analysis/import/SCMLogParser/src/test/java/de/maibornwolff/codecharta/importer/scmlogparser/ProjectConverterTest.java @@ -1,8 +1,12 @@ package de.maibornwolff.codecharta.importer.scmlogparser; import de.maibornwolff.codecharta.model.Project; +import de.maibornwolff.codecharta.model.input.Commit; +import de.maibornwolff.codecharta.model.input.VersionControlledFile; import org.junit.Test; +import java.time.LocalDateTime; +import java.util.Arrays; import java.util.Collections; import static org.assertj.core.api.Assertions.assertThat; @@ -15,12 +19,40 @@ public void canCreateAnEmptyProject() throws Exception { String projectname = "Projectname"; // when - Project project = ProjectConverter.convert(projectname, Collections.emptyList()); + Project project = ProjectConverter.convert(projectname, Collections.emptyList(), true); //then assertThat(project.getNodes()).hasSize(0); assertThat(project.getProjectName()).isEqualTo(projectname); } + @Test + public void canConvertProjectWithAuthors() { + //given + String projectname = "ProjectWithAuthors"; + VersionControlledFile file1 = new VersionControlledFile("File 1"); + file1.registerCommit(new Commit("Author", Arrays.asList("File 1, File 2"), LocalDateTime.now())); + + //when + Project project = ProjectConverter.convert(projectname, Arrays.asList(file1), true); + + //then + assertThat(project.getRootNode().getChildren().get(0).getAttributes().containsKey("authors")).isTrue(); + } + + @Test + public void canConvertProjectWithoutAuthors() { + //given + String projectname = "ProjectWithoutAuthors"; + VersionControlledFile file1 = new VersionControlledFile("File 1"); + file1.registerCommit(new Commit("Author", Arrays.asList("File 1, File 2"), LocalDateTime.now())); + + //when + Project project = ProjectConverter.convert(projectname, Arrays.asList(file1), false); + + //then + assertThat(project.getRootNode().getChildren().get(0).getAttributes().containsKey("authors")).isFalse(); + } + } diff --git a/analysis/import/SCMLogParser/src/test/java/de/maibornwolff/codecharta/importer/scmlogparser/parser/LogParserTest.java b/analysis/import/SCMLogParser/src/test/java/de/maibornwolff/codecharta/importer/scmlogparser/parser/LogParserTest.java index 54b82ad1b5..cb0acc20f3 100644 --- a/analysis/import/SCMLogParser/src/test/java/de/maibornwolff/codecharta/importer/scmlogparser/parser/LogParserTest.java +++ b/analysis/import/SCMLogParser/src/test/java/de/maibornwolff/codecharta/importer/scmlogparser/parser/LogParserTest.java @@ -36,7 +36,7 @@ public class LogParserTest { @Test public void logParserSVNGoldenMasterTest() throws Exception { // given - LogParser svnLogParser = new LogParser(new SVNLogParserStrategy()); + LogParser svnLogParser = new LogParser(new SVNLogParserStrategy(), true); InputStreamReader ccjsonReader = new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream(EXPECTED_SVN_CC_JSON)); Project expectedProject = ProjectDeserializer.deserializeProject(ccjsonReader); URL resource = this.getClass().getClassLoader().getResource(SVN_LOG); @@ -54,7 +54,7 @@ public void logParserSVNGoldenMasterTest() throws Exception { @Test public void logParserGitGoldenMasterTest() throws Exception { // given - LogParser gitLogParser = new LogParser(new GitLogParserStrategy()); + LogParser gitLogParser = new LogParser(new GitLogParserStrategy(), true); InputStreamReader ccjsonReader = new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream(EXPECTED_GIT_CC_JSON)); Project expectedProject = ProjectDeserializer.deserializeProject(ccjsonReader); URL resource = this.getClass().getClassLoader().getResource(GIT_LOG); @@ -83,7 +83,7 @@ public void parseCommitRaisesExceptionWhenAuthorIsMissing() { when(parserStrategy.parseAuthor(any())).thenReturn(Optional.empty()); when(parserStrategy.parseDate(any())).thenReturn(Optional.of(LocalDateTime.now())); when(parserStrategy.parseFilenames(any())).thenReturn(Collections.emptyList()); - LogParser logParser = new LogParser(parserStrategy); + LogParser logParser = new LogParser(parserStrategy, true); // when & then assertThatThrownBy(() -> logParser.parseCommit(Collections.emptyList())).isInstanceOf(RuntimeException.class); @@ -96,7 +96,7 @@ public void parseCommitRaisesExceptionWhenCommitDateIsMissing() { when(parserStrategy.parseAuthor(any())).thenReturn(Optional.of("An Author")); when(parserStrategy.parseDate(any())).thenReturn(Optional.empty()); when(parserStrategy.parseFilenames(any())).thenReturn(Collections.emptyList()); - LogParser logParser = new LogParser(parserStrategy); + LogParser logParser = new LogParser(parserStrategy, true); // when & then assertThatThrownBy(() -> logParser.parseCommit(Collections.emptyList())).isInstanceOf(RuntimeException.class); @@ -113,7 +113,7 @@ public void parseCommit() { when(parserStrategy.parseAuthor(input)).thenReturn(Optional.of(author)); when(parserStrategy.parseDate(input)).thenReturn(Optional.of(commitDate)); when(parserStrategy.parseFilenames(input)).thenReturn(filenames); - LogParser logParser = new LogParser(parserStrategy); + LogParser logParser = new LogParser(parserStrategy, true); // when Commit commit = logParser.parseCommit(input); diff --git a/analysis/import/SCMLogParser/src/test/java/de/maibornwolff/codecharta/importer/scmlogparser/parser/ParserStrategyContractTest.java b/analysis/import/SCMLogParser/src/test/java/de/maibornwolff/codecharta/importer/scmlogparser/parser/ParserStrategyContractTest.java index 7aa06adea5..7cdbaf791d 100644 --- a/analysis/import/SCMLogParser/src/test/java/de/maibornwolff/codecharta/importer/scmlogparser/parser/ParserStrategyContractTest.java +++ b/analysis/import/SCMLogParser/src/test/java/de/maibornwolff/codecharta/importer/scmlogparser/parser/ParserStrategyContractTest.java @@ -34,7 +34,7 @@ public abstract class ParserStrategyContractTest { @Test public void parsesCommit() { - LogParser logParser = new LogParser(getLogParserStrategy()); + LogParser logParser = new LogParser(getLogParserStrategy(), true); Commit commit = logParser.parseCommit(getFullCommit()); assertThat(commit) .extracting(Commit::getAuthor, Commit::getFilenames, Commit::getCommitDate) @@ -70,7 +70,7 @@ public void canProvidesAnAproppriateLogLineCollectorToSeparateCommits() throws E @Test public void accumulatesCommitFiles() { Stream logLines = Stream.concat(getFullCommit().stream(), getFullCommit().stream()); - List files = new LogParser(getLogParserStrategy()).parseLoglines(logLines); + List files = new LogParser(getLogParserStrategy(), true).parseLoglines(logLines); assertThat(files) .extracting(VersionControlledFile::getFilename, VersionControlledFile::getNumberOfOccurrencesInCommits, VersionControlledFile::getAuthors) .containsExactlyInAnyOrder(