diff --git a/src/services/S3MHandlersAnalysis/datacollection/DataAnalyser.groovy b/src/services/S3MHandlersAnalysis/datacollection/DataAnalyser.groovy index b5088a09f..e06d325e5 100644 --- a/src/services/S3MHandlersAnalysis/datacollection/DataAnalyser.groovy +++ b/src/services/S3MHandlersAnalysis/datacollection/DataAnalyser.groovy @@ -11,6 +11,14 @@ import java.nio.file.Path class DataAnalyser { + /** + * Analyses each merge scenario's directories after S3M has run. It constructs a {@link MergeScenarioSummary} for each + * merge scenario and a global {@link MergeCommitSummary} for each merge commit. + * @param project + * @param mergeCommit + * @param mergeScenarios + * @return a summary of results of the merge commit + */ static MergeCommitSummary analyseScenarios(Project project, MergeCommit mergeCommit, List mergeScenarios) { MergeCommitSummary summary = new MergeCommitSummary() buildCommitSummary(summary, mergeScenarios) diff --git a/src/services/S3MHandlersAnalysis/datacollection/MergeScenarioCollector.groovy b/src/services/S3MHandlersAnalysis/datacollection/MergeScenarioCollector.groovy index 768556142..a9cfb8728 100644 --- a/src/services/S3MHandlersAnalysis/datacollection/MergeScenarioCollector.groovy +++ b/src/services/S3MHandlersAnalysis/datacollection/MergeScenarioCollector.groovy @@ -9,8 +9,17 @@ import java.nio.file.Files import java.nio.file.Path import java.util.stream.Collectors +/** + * Class responsible for collecting and storing eligible merge scenarios (modified from base java files). + */ class MergeScenarioCollector { + /** + * Stores merge scenarios (left, base, right and merge files) encountered in the merge commit. + * @param project + * @param mergeCommit + * @return a list of directory paths where each merge scenario is located + */ static List collectMergeScenarios(Project project, MergeCommit mergeCommit) { return getModifiedJavaFiles(project, mergeCommit).stream() .map(modifiedFile -> storeAndRetrieveMergeQuadruple(project, mergeCommit, modifiedFile)) diff --git a/src/services/S3MHandlersAnalysis/datacollection/S3MRunner.groovy b/src/services/S3MHandlersAnalysis/datacollection/S3MRunner.groovy index 15a5f10fc..570eaaf72 100644 --- a/src/services/S3MHandlersAnalysis/datacollection/S3MRunner.groovy +++ b/src/services/S3MHandlersAnalysis/datacollection/S3MRunner.groovy @@ -12,6 +12,14 @@ class S3MRunner { static final Path S3M_PATH = Paths.get("src/services/S3MHandlersAnalysis/s3m.jar") + /** + * Runs S3M for each merge scenario and for each handler. Store the results at the same directory + * the merge scenario is located, in a directory for each handler. + * + * To extend the analysis for more handlers, check {@link #runHandlerVariants(Path, List < Handlers >)} + * @param mergeScenarios + * @param handlers + */ static void collectS3MResults(List mergeScenarios, List handlers) { mergeScenarios.parallelStream() .forEach(mergeScenario -> runHandlerVariants(mergeScenario, handlers)) diff --git a/src/services/S3MHandlersAnalysis/datacollection/SpreadsheetBuilder.groovy b/src/services/S3MHandlersAnalysis/datacollection/SpreadsheetBuilder.groovy index f4e1db997..74461222e 100644 --- a/src/services/S3MHandlersAnalysis/datacollection/SpreadsheetBuilder.groovy +++ b/src/services/S3MHandlersAnalysis/datacollection/SpreadsheetBuilder.groovy @@ -14,6 +14,13 @@ class SpreadsheetBuilder { private static final String COMMIT_SPREADSHEET_HEADER = 'project,merge commit,file,number of TM conflicts,number of CT conflicts,number of SF conflicts,number of MM conflicts,number of KB conflicts,CT text = SF text,CT text = MM text,CT text = KB text,SF text = MM text, SF text = KB text,MM text = KB text,CT conflicts = SF conflicts,CT conflicts = MM conflicts,CT conflicts = KB conflicts,SF conflicts = MM conflicts,SF conflicts = KB conflicts,MM conflicts = KB conflicts' private static final String SPREADSHEET_NAME = 'results.csv' + /** + * Builds a global spreadsheet, based on the merge commit's summary, and a local spreadsheet, for each merge commit, based on + * the merge scenario's summary. + * @param project + * @param mergeCommit + * @param summary + */ static synchronized void buildSpreadsheets(Project project, MergeCommit mergeCommit, MergeCommitSummary summary) { buildGlobalSpreadsheet(project, mergeCommit, summary) buildCommitSpreadsheet(project, mergeCommit, summary.mergeScenarioSummaries) diff --git a/src/services/S3MHandlersAnalysis/implementations/MergesCollector.groovy b/src/services/S3MHandlersAnalysis/implementations/MergesCollector.groovy index 07a0a23b8..fc2c42883 100644 --- a/src/services/S3MHandlersAnalysis/implementations/MergesCollector.groovy +++ b/src/services/S3MHandlersAnalysis/implementations/MergesCollector.groovy @@ -3,8 +3,10 @@ package services.S3MHandlersAnalysis.implementations import main.interfaces.DataCollector import main.project.MergeCommit import main.project.Project +import services.S3MHandlersAnalysis.Handlers import services.S3MHandlersAnalysis.datacollection.DataAnalyser import services.S3MHandlersAnalysis.datacollection.MergeScenarioCollector +import services.S3MHandlersAnalysis.datacollection.S3MRunner import services.S3MHandlersAnalysis.datacollection.SpreadsheetBuilder import services.S3MHandlersAnalysis.util.MergeCommitSummary @@ -18,8 +20,8 @@ class MergesCollector implements DataCollector { List mergeScenarios = MergeScenarioCollector.collectMergeScenarios(project, mergeCommit) println 'Collected merge scenarios' -// S3MRunner.collectS3MResults(mergeScenarios, [Handlers.Renaming]) -// println 'Collected S3M results' + S3MRunner.collectS3MResults(mergeScenarios, [Handlers.Renaming]) + println 'Collected S3M results' MergeCommitSummary summary = DataAnalyser.analyseScenarios(project, mergeCommit, mergeScenarios) println 'Summarized collected data' diff --git a/src/services/S3MHandlersAnalysis/util/BuildRequester.groovy b/src/services/S3MHandlersAnalysis/util/BuildRequester.groovy index aab619ec0..b2e7d885f 100644 --- a/src/services/S3MHandlersAnalysis/util/BuildRequester.groovy +++ b/src/services/S3MHandlersAnalysis/util/BuildRequester.groovy @@ -26,6 +26,14 @@ final class BuildRequester { private static Map buildScripts = ['Maven': 'mvn package', 'Gradle': './gradlew build'] + /** + * Replaces the files in a project by its correspondent merge results in a new branch and triggers a Travis build from a push + * @param project + * @param mergeCommit + * @param mergeScenarios + * @param mergeAlgorithmIndex + * @return the link for the Travis build triggered by this method + */ static String requestBuildWithRevision(Project project, MergeCommit mergeCommit, List mergeScenarios, int mergeAlgorithmIndex) { String toReplaceFile = Handlers.mergeResultPaths[mergeAlgorithmIndex] String mergeAlgorithm = Handlers.mergeAlgorithms[mergeAlgorithmIndex] diff --git a/src/services/S3MHandlersAnalysis/util/MergeCommitSummary.groovy b/src/services/S3MHandlersAnalysis/util/MergeCommitSummary.groovy index 822618a5e..a6f9907f8 100644 --- a/src/services/S3MHandlersAnalysis/util/MergeCommitSummary.groovy +++ b/src/services/S3MHandlersAnalysis/util/MergeCommitSummary.groovy @@ -19,6 +19,10 @@ class MergeCommitSummary { this.checkingBuilds = [:] } + /** + * Add the merge scenario summary's information to this summary. + * @param scenarioSummary + */ void addMergeSummary(MergeScenarioSummary scenarioSummary) { numberOfModifiedFiles++ addConflicts(scenarioSummary.numberOfConflicts) @@ -29,6 +33,11 @@ class MergeCommitSummary { mergeScenarioSummaries.add(scenarioSummary) } + /** + * Add a link for a Travis build. + * @param link + * @param mergeAlgorithm + */ void markAsChecking(String link, String mergeAlgorithm) { checkingBuilds[mergeAlgorithm] = link } diff --git a/src/services/S3MHandlersAnalysis/util/MergeConflict.groovy b/src/services/S3MHandlersAnalysis/util/MergeConflict.groovy index 687ced7ec..1cb7898a4 100644 --- a/src/services/S3MHandlersAnalysis/util/MergeConflict.groovy +++ b/src/services/S3MHandlersAnalysis/util/MergeConflict.groovy @@ -33,6 +33,10 @@ class MergeConflict { && StringUtils.deleteWhitespace(right) == StringUtils.deleteWhitespace(((MergeConflict) o).right) } + /** + * @param file + * @return the set of merge conflicts present in the given file + */ static Set extractMergeConflicts(Path file) { Set mergeConflicts = new HashSet() diff --git a/src/services/S3MHandlersAnalysis/util/Utils.groovy b/src/services/S3MHandlersAnalysis/util/Utils.groovy index 7f236faeb..47cf45a7d 100644 --- a/src/services/S3MHandlersAnalysis/util/Utils.groovy +++ b/src/services/S3MHandlersAnalysis/util/Utils.groovy @@ -10,6 +10,11 @@ import java.nio.file.Paths final class Utils { + /** + * Runs a git command, waiting for it to finish. + * @param repositoryPath + * @param arguments + */ static void runGitCommand(Path repositoryPath, String... arguments) { Process gitCommand = ProcessRunner.startProcess(buildGitCommand(repositoryPath, arguments)) gitCommand.getInputStream().eachLine { @@ -23,14 +28,28 @@ final class Utils { return gitCommand } + /** + * Equivalent to Paths.get(MiningFramework.arguments.getOutputPath()) + * @return a path to the output path given as argument + */ static Path getOutputPath() { return Paths.get(MiningFramework.arguments.getOutputPath()) } + /** + * @param project + * @param mergeCommit + * @return the output path resolved in the project/merge commit directory + */ static Path commitFilesPath(Project project, MergeCommit mergeCommit) { return getOutputPath().resolve(project.getName()).resolve(mergeCommit.getSHA()) } + /** + * @param list + * @param separator + * @return a concatenation of all the string representation of the elements of the list, separated by the separator + */ static String toStringList(List list, String separator) { if (list.isEmpty()) return '' @@ -45,6 +64,12 @@ final class Utils { return string.toString() } + /** + * @param link + * @param name + * @return a link in the format required by Google Sheets for hyperlinks, using {@code link} + * as link and {@code name} as its name in the cell + */ static String getHyperLink(String link, String name) { return "=HYPERLINK(\"${link}\";\"${name}\")" }