Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
8c94943
fix: Replace existing on copy. Include copy in execution time calcula…
jpedroh Aug 18, 2024
8948eb5
feat: use built in filter to discard fast forwards
jpedroh Aug 21, 2024
49ffc49
feat: improve logging
jpedroh Aug 21, 2024
8c1b8c7
feat: Add trigger of build on scenarios
jpedroh Sep 8, 2024
062144f
fix: issues and use in commit list
jpedroh Sep 8, 2024
eca411c
fix: incorrect condition
jpedroh Sep 8, 2024
ef43c87
fix: simplify code
jpedroh Sep 8, 2024
4de63d5
fix: is in commit list initialization
jpedroh Sep 8, 2024
fcf3971
fix: tweak code
jpedroh Sep 8, 2024
52174a4
fix: add more logs
jpedroh Sep 8, 2024
86d2eff
fix: issues on build reqquesting
jpedroh Sep 8, 2024
060cd61
fix: wrong serialization
jpedroh Sep 11, 2024
6710eab
fix: remove commmit filter
jpedroh Sep 11, 2024
3ea7fbd
fix: incorrect commit filter
jpedroh Sep 12, 2024
a684347
feat: ignore empty lines on report
jpedroh Sep 13, 2024
aa3df93
feat: run 10 times for perf sampling
jpedroh Sep 19, 2024
057a3ee
feat: add flag to include pull request branches in analysis
jpedroh Oct 22, 2024
d6aedf8
feat: add commit filter by project and merge sha
jpedroh Oct 22, 2024
ad28002
feat: alter commit filter
jpedroh Oct 22, 2024
c0b778b
feat: update github actions job to add retries and multiple jdk versions
jpedroh Oct 23, 2024
59611af
feat: run merge tool onyl once
jpedroh Oct 23, 2024
d9cac37
feat: tweak logging
jpedroh Oct 25, 2024
168f9c0
feat: add logging
jpedroh Oct 25, 2024
a93f035
feat: wrong worder
jpedroh Oct 25, 2024
395223d
fix: add missing flag
jpedroh Oct 31, 2024
04d31b3
fix: equals or substring
jpedroh Nov 3, 2024
2d3bf9b
feat: discard unstaged changes
jpedroh Nov 3, 2024
f29fe8b
feat:comment datacollectors
jpedroh Nov 3, 2024
5d26ca5
feat: add waitFor
jpedroh Nov 3, 2024
a5fdd46
feat: add logging
jpedroh Nov 3, 2024
74728e7
feat: add more logs
jpedroh Nov 3, 2024
70d658d
feat: skip output for now
jpedroh Nov 3, 2024
83c7dba
feat: implement new merge tool executor idea
jpedroh Nov 6, 2024
05fa257
feat: testing
jpedroh Nov 6, 2024
d5d591a
skip normalization on non fast forward
jpedroh Nov 6, 2024
23b0321
feat: use non mutual modified
jpedroh Nov 6, 2024
ef62a0e
feat: remove initialization
jpedroh Nov 6, 2024
317ed55
feat: add comparison between output files
jpedroh Nov 6, 2024
81e7c52
fix: wrong serialization
jpedroh Nov 6, 2024
51e18ab
feat: run some collectors in parallel
jpedroh Nov 6, 2024
69b09de
feat: add collection of merge conflicts information
jpedroh Nov 6, 2024
90dd48d
feat: remove normalization in base left right.
jpedroh Nov 6, 2024
c617a17
feat: add logging
jpedroh Nov 6, 2024
af4d08d
do not run in parallel, fix psork command
jpedroh Nov 6, 2024
793294a
feat: do not override if it already exists
jpedroh Nov 6, 2024
31e6601
feat: delete old files
jpedroh Nov 7, 2024
bfdbcdb
chore: revert
jpedroh Nov 7, 2024
ffbb1d0
chore: revert chnages
jpedroh Nov 7, 2024
e7b17a2
chore: revert changes
jpedroh Nov 7, 2024
d8757e2
feat: add possibility to customize commit merges list
jpedroh Nov 7, 2024
3346037
feat: remove some logics
jpedroh Nov 7, 2024
f875e68
fix: dangling reference
jpedroh Nov 7, 2024
88f21c7
feat: add code syntatic normalization with spork
jpedroh Nov 18, 2024
3115b0e
refactor: alter normalization logic
jpedroh Nov 23, 2024
859b2b2
feat: add error treating when spork fails
jpedroh Nov 23, 2024
4d80933
feat: extract reports write to syncronized block
jpedroh Nov 24, 2024
c7823fa
feat: add synchronized on CompareScenarioMergeConflictsDataCollector.…
jpedroh Nov 24, 2024
91d5a5c
feat: add extra collectors
jpedroh Nov 24, 2024
3ef944f
feat: add perf optimization for running collectors in parallel
jpedroh Nov 24, 2024
0944541
feat: comment some data collectors
jpedroh Nov 26, 2024
b5d2088
feat: use java parser for code formatting
jpedroh Dec 14, 2024
1754661
feat: skip execution of tools
jpedroh Dec 14, 2024
cbdf88b
feat: add normalization with spoon
jpedroh Dec 15, 2024
f038812
feat: remove run of tools
jpedroh Dec 15, 2024
71242f0
feat: tweak configuration
jpedroh Dec 16, 2024
eca5ccd
feat: add build tool collection
jpedroh Dec 16, 2024
db2d949
feat: add logs
jpedroh Dec 16, 2024
1749450
feat: add config
jpedroh Dec 16, 2024
6f6dd5f
feat: testing spork normalziation in spork output
jpedroh Dec 18, 2024
2de1158
feat: adjust return
jpedroh Dec 18, 2024
7ed6152
feat: add mergiraf data collector
jpedroh Jan 1, 2025
1d9d7aa
feat: add log of error stream
jpedroh Jan 1, 2025
206981a
feat: adjust generic merge
jpedroh Jan 1, 2025
a296180
feat: add normalization of mergiraf and comparison
jpedroh Jan 7, 2025
698b0fe
feat: adjsut missing pieces
jpedroh Jan 7, 2025
97c6d07
feat: run only spork
jpedroh Jan 27, 2025
b286bf3
feat: adjust spork execution
jpedroh Jan 27, 2025
0c852b8
feat: run merge tools on the scenarios
jpedroh Feb 1, 2025
eecf738
feat: refine normalizations
jpedroh Feb 4, 2025
7d41dec
fix: issues on file normalization
jpedroh Feb 4, 2025
8ef4d07
feat: adjust syntactical comparisons
jpedroh Feb 6, 2025
0ed3255
fix: incorrect comparisons
jpedroh Feb 6, 2025
aba2ca0
feat: add comparison between tools
jpedroh Feb 6, 2025
24f53bf
feat: format before comparing
jpedroh Feb 6, 2025
b0c96f0
chore: tweak logging
jpedroh Feb 12, 2025
fa085b7
feat: add build/test trigger for jdime
jpedroh Feb 12, 2025
ef192ac
fix: rename branch
jpedroh Feb 12, 2025
80fff30
feat: run build check for last merge
jpedroh Feb 12, 2025
4191a69
chore: alter tool
jpedroh Feb 12, 2025
8911b65
run spork
jpedroh Feb 17, 2025
3391961
improve experiment
jpedroh Mar 11, 2025
51e47eb
chore: alter mergiraf
jpedroh Mar 13, 2025
a8e2661
fix: incorrect args for mergiraf
jpedroh Mar 17, 2025
c55befb
feat: adjust tool executors
jpedroh Mar 17, 2025
eb916ae
feat: override execution directory
jpedroh Mar 17, 2025
b9cd192
fix: issues
jpedroh Mar 18, 2025
ccf0f8c
feat: run once
jpedroh Mar 18, 2025
f70ec87
fix: abosulte path
jpedroh Mar 18, 2025
d51be2f
fix: incorrect output name
jpedroh Mar 18, 2025
96afa97
feat: replace spork with dummy file
jpedroh Mar 18, 2025
514df90
feat: revert changes
jpedroh Mar 18, 2025
4d0d729
Merge branch 'fix-unstructured-merge' of github.com:jpedroh/miningfra…
jpedroh Aug 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added dependencies/spork.jar
Binary file not shown.
33 changes: 22 additions & 11 deletions src/main/app/MiningWorker.groovy
Original file line number Diff line number Diff line change
@@ -1,27 +1,37 @@
package app

import exception.UnstagedChangesException
import interfaces.CommitFilter
import interfaces.DataCollector
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import project.MergeCommit
import project.Project
import project.commitHashesExtraction.CommitHashesExtractor
import services.util.Utils
import util.FileManager
import util.MergeHelper
import util.ProcessRunner
import java.util.Collections
import java.util.Random
import java.text.SimpleDateFormat

import static app.MiningFramework.arguments
import java.text.SimpleDateFormat
import java.util.concurrent.BlockingQueue

import project.*
import interfaces.*
import exception.UnstagedChangesException
import util.*

import services.util.Utils;
import static app.MiningFramework.arguments

class MiningWorker implements Runnable {
private static Logger LOG = LogManager.getLogger(MiningWorker.class)

private Set<DataCollector> dataCollectors
private CommitFilter commitFilter
private BlockingQueue<Project> projectList
private String baseDir
private CommitHashesExtractor commitHashesExtractor

MiningWorker(Set<DataCollector> dataCollectors, CommitFilter commitFilter, BlockingQueue<Project> projectList, String baseDir) {
this.commitHashesExtractor = CommitHashesExtractor.Factory.build()
this.dataCollectors = dataCollectors
this.commitFilter = commitFilter
this.projectList = projectList
Expand All @@ -41,7 +51,7 @@ class MiningWorker implements Runnable {
checkForUnstagedChanges(project);
}

def (mergeCommits, skipped) = project.getMergeCommits(arguments.getSinceDate(), arguments.getUntilDate())
def (mergeCommits, skipped) = project.getMergeCommits(commitHashesExtractor)

Random random = new Random(arguments.getRandomSeed())
Collections.shuffle(mergeCommits, random)
Expand Down Expand Up @@ -97,7 +107,7 @@ class MiningWorker implements Runnable {
}

private void cloneRepository(Project project, String target) {
println "Cloning repository ${project.getName()} into ${target}"
LOG.info("Cloning repository ${project.getName()} into ${target}")

File projectDirectory = new File(target)
if (projectDirectory.exists()) {
Expand All @@ -114,10 +124,11 @@ class MiningWorker implements Runnable {
}

ProcessBuilder builder = ProcessRunner.buildProcess('./', 'git', 'clone', url, target)
builder.redirectOutput(ProcessBuilder.Redirect.INHERIT)

Process process = ProcessRunner.startProcess(builder)
process.getInputStream().eachLine(LOG::trace)
process.getErrorStream().eachLine(LOG::warn)
process.waitFor()
LOG.info("Finished cloning repository ${project.getName()} into ${target}")

project.setPath(target)
}
Expand Down
5 changes: 5 additions & 0 deletions src/main/arguments/ArgsParser.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class ArgsParser {
this.cli.e(longOpt: 'extension', args: 1, argName: 'file extenson', 'Specify the file extension that should be used in the analysis (e.g. .rb, .ts, .java, .cpp. Default: .java)')
this.cli.l(longOpt: 'language-separators', args: 1, argName: 'language syntactic separators', 'Specify the language separators that should be used in the analysis. Required for (and only considered when) running studies with the CSDiff tool. Default: \"{ } ( ) ; ,\"')
this.cli.log(longOpt: 'log-level', args: 1, argName: 'log level', 'Specify the minimum log level: (OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL). Default: \"INFO\"')
this.cli.pchf(longOpt: 'project-commit-hashes-file', args: 1, argName: 'project commit hashes file', 'Path to a file with projects and commits to be analyzed')
}

Arguments parse(args) {
Expand Down Expand Up @@ -142,6 +143,10 @@ class ArgsParser {
if(this.options.log) {
args.setLogLevel(Level.toLevel(this.options.log))
}

if (this.options.pchf) {
args.setProjectCommitHashesFile(this.options.pchf)
}
}

private boolean repositoryExists(String repositoryURL) {
Expand Down
10 changes: 10 additions & 0 deletions src/main/arguments/Arguments.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class Arguments {
private String syntacticSeparators
private String fileExtension
private Level logLevel
private String projectCommitHashesFile

Arguments() { // set the default values for all parameters
randomSeed = 1
Expand All @@ -37,6 +38,7 @@ class Arguments {
syntacticSeparators = '{ } ( ) ; ,'
fileExtension = '.java'
logLevel = Level.INFO
projectCommitHashesFile = ''
}

void setRandomSeed(int randomSeed) {
Expand Down Expand Up @@ -167,4 +169,12 @@ class Arguments {
this.logLevel = logLevel
Configurator.setRootLevel(logLevel)
}

String getProjectCommitHashesFile() {
return projectCommitHashesFile
}

void setProjectCommitHashesFile(String projectCommitHashesFile) {
this.projectCommitHashesFile = projectCommitHashesFile
}
}
90 changes: 58 additions & 32 deletions src/main/injectors/GenericMergeModule.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -6,51 +6,77 @@ import interfaces.CommitFilter
import interfaces.DataCollector
import interfaces.OutputProcessor
import interfaces.ProjectProcessor
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import services.commitFilters.MutuallyModifiedFilesCommitFilter
import services.dataCollectors.GenericMerge.GenericMergeConfig
import services.dataCollectors.GenericMerge.GenericMergeDataCollector
import services.dataCollectors.GenericMerge.MergeConflictsComparator
import services.dataCollectors.GenericMerge.MergeToolsComparator
import services.dataCollectors.GenericMerge.ScenarioLOCsCounter
import services.dataCollectors.GenericMerge.UnstructuredMergeCollector
import services.outputProcessors.GenericMergeDataOutputProcessor
import services.dataCollectors.buildRequester.RequestBuildForRevisionWithFilesDataCollector
import services.dataCollectors.common.CompareScenarioMergeConflictsDataCollector
import services.dataCollectors.common.RunDataCollectorsInParallel
import services.dataCollectors.common.SyntacticallyCompareScenarioFilesDataCollector
import services.dataCollectors.fileSyntacticNormalization.FormatFileSyntacticNormalizationDataCollector
import services.dataCollectors.fileSyntacticNormalization.JDimeFileSyntacticNormalizationDataCollector
import services.dataCollectors.fileSyntacticNormalization.SporkFileSyntacticNormalizationDataCollector
import services.dataCollectors.mergeToolExecutors.JDimeMergeToolExecutorDataCollector
import services.dataCollectors.mergeToolExecutors.LastMergeMergeToolExecutorDataCollector
import services.dataCollectors.mergeToolExecutors.MergirafMergeToolExecutorDataCollector
import services.dataCollectors.mergeToolExecutors.SporkMergeToolExecutorDataCollector
import services.outputProcessors.EmptyOutputProcessor
import services.projectProcessors.DummyProjectProcessor
import services.util.ci.CIPlatform
import services.util.ci.TravisPlatform

import java.nio.file.Files
import java.nio.file.Paths

class GenericMergeModule extends AbstractModule {
private static Logger LOG = LogManager.getLogger(GenericMergeModule.class)

@Override
protected void configure() {
Multibinder<ProjectProcessor> projectProcessorBinder = Multibinder.newSetBinder(binder(), ProjectProcessor.class)
projectProcessorBinder.addBinding().to(DummyProjectProcessor.class)

Multibinder<DataCollector> dataCollectorBinder = Multibinder.newSetBinder(binder(), DataCollector.class)
dataCollectorBinder.addBinding().to(ScenarioLOCsCounter.class)
dataCollectorBinder.addBinding().to(GenericMergeDataCollector.class)
dataCollectorBinder.addBinding().to(MergeToolsComparator.class)
dataCollectorBinder.addBinding().to(MergeConflictsComparator.class)
dataCollectorBinder.addBinding().to(UnstructuredMergeCollector.class)

Multibinder<OutputProcessor> outputProcessorBinder = Multibinder.newSetBinder(binder(), OutputProcessor.class)
outputProcessorBinder.addBinding().to(GenericMergeDataOutputProcessor.class)
// Run the merge tools on the scenarios
dataCollectorBinder.addBinding().to(JDimeMergeToolExecutorDataCollector.class)
dataCollectorBinder.addBinding().to(LastMergeMergeToolExecutorDataCollector.class)
dataCollectorBinder.addBinding().to(SporkMergeToolExecutorDataCollector.class)
dataCollectorBinder.addBinding().to(MergirafMergeToolExecutorDataCollector.class)

bind(CommitFilter.class).to(MutuallyModifiedFilesCommitFilter.class)
bind(CIPlatform.class).to(TravisPlatform.class)
// Run, in parallel, normalizations on resulting files
dataCollectorBinder.addBinding().toInstance(new RunDataCollectorsInParallel([
new JDimeFileSyntacticNormalizationDataCollector("merge.java", "merge.jdime_normalized.java"),
new JDimeFileSyntacticNormalizationDataCollector("merge.last_merge.java", "merge.last_merge.jdime_normalized.java"),
new SporkFileSyntacticNormalizationDataCollector("merge.java", "merge.spork_normalized.java"),
new SporkFileSyntacticNormalizationDataCollector("merge.spork.java", "merge.spork.spork_normalized.java"),
new SporkFileSyntacticNormalizationDataCollector("merge.mergiraf.java", "merge.mergiraf.spork_normalized.java"),
]))

createExecutionReportsFile()
}
// Run, in parallel, syntactical comparisons between files and textual comparison between commits
dataCollectorBinder.addBinding().toInstance(new RunDataCollectorsInParallel([
// Syntactic comparison with merge commits
new SyntacticallyCompareScenarioFilesDataCollector("merge.java", "merge.last_merge.java"),
new SyntacticallyCompareScenarioFilesDataCollector("merge.jdime_normalized.java", "merge.jdime.java"),
new SyntacticallyCompareScenarioFilesDataCollector("merge.spork_normalized.java", "merge.spork.spork_normalized.java"),
new SyntacticallyCompareScenarioFilesDataCollector("merge.java", "merge.mergiraf.java"),

// Syntactic comparison between tools themselves
new SyntacticallyCompareScenarioFilesDataCollector("merge.jdime.java", "merge.last_merge.jdime_normalized.java"),
new SyntacticallyCompareScenarioFilesDataCollector("merge.mergiraf.spork_normalized.java", "merge.spork.spork_normalized.java"),
new SyntacticallyCompareScenarioFilesDataCollector("merge.mergiraf.java", "merge.last_merge.java"),

// Conflicts comparison between tools themselves
new CompareScenarioMergeConflictsDataCollector("merge.jdime.java", "merge.last_merge.java"),
new CompareScenarioMergeConflictsDataCollector("merge.mergiraf.java", "merge.spork.java"),
new CompareScenarioMergeConflictsDataCollector("merge.mergiraf.java", "merge.last_merge.java"),
]))

private static void createExecutionReportsFile() {
LOG.info("Creating Generic Merge report file")
Files.createDirectories(Paths.get(GenericMergeConfig.GENERIC_MERGE_REPORT_PATH))
def reportFile = new File(GenericMergeConfig.GENERIC_MERGE_REPORT_FILE_NAME)
reportFile.createNewFile()
dataCollectorBinder.addBinding().toInstance(new RunDataCollectorsInParallel([new FormatFileSyntacticNormalizationDataCollector("merge.last_merge.java", "merge.last_merge.format_normalized.java"),
new FormatFileSyntacticNormalizationDataCollector("merge.mergiraf.java", "merge.mergiraf.format_normalized.java")]))

dataCollectorBinder.addBinding().toInstance(new SyntacticallyCompareScenarioFilesDataCollector("merge.mergiraf.format_normalized.java", "merge.last_merge.format_normalized.java"))


dataCollectorBinder.addBinding().toInstance(new RequestBuildForRevisionWithFilesDataCollector("merge.last_merge.java"))
dataCollectorBinder.addBinding().toInstance(new RequestBuildForRevisionWithFilesDataCollector("merge.jdime.java"))
dataCollectorBinder.addBinding().toInstance(new RequestBuildForRevisionWithFilesDataCollector("merge.mergiraf.java"))
dataCollectorBinder.addBinding().toInstance(new RequestBuildForRevisionWithFilesDataCollector("merge.spork.java"))

Multibinder<OutputProcessor> outputProcessorBinder = Multibinder.newSetBinder(binder(), OutputProcessor.class)
outputProcessorBinder.addBinding().to(EmptyOutputProcessor.class)

bind(CommitFilter.class).to(MutuallyModifiedFilesCommitFilter.class)
}
}
68 changes: 30 additions & 38 deletions src/main/project/Project.groovy
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package project

import util.ProcessRunner
import exception.UnexpectedOutputException
import org.apache.logging.log4j.LogManager
import project.commitHashesExtraction.CommitHashesExtractor
import util.ProcessRunner

import java.util.Collections
import java.util.Random
import java.util.regex.Pattern
import java.util.regex.Matcher
import java.util.regex.Pattern

class Project {
private static LOG = LogManager.getLogger(Project.class)

private String name
private String path
Expand Down Expand Up @@ -42,49 +43,41 @@ class Project {
return matcher.find()
}

List getMergeCommits(String sinceDate, String untilDate) {
List getMergeCommits(CommitHashesExtractor commitHashesExtractor) {
ArrayList<String> skipped = new ArrayList<String>()
ArrayList<MergeCommit> mergeCommits = new ArrayList<MergeCommit>()

Process gitLog = constructAndRunGitLog(sinceDate, untilDate)
def expectedOutput = ~/.*-(.* .*)+/
gitLog.getInputStream().eachLine {

// Each line contains the hash of the commit followed by the hashes of the parents.
if(it ==~ expectedOutput) {

String[] informations = it.split('-') // <commit hash>-<parents hash>
String SHA = getSHA(informations)
String[] parentsSHA = getParentsSHA(informations)
commitHashesExtractor.extractCommitHashes(this).each(commitHashes -> {
def SHA = commitHashes.mergeSha
def parentsSHA = commitHashes.parents

try {
String ancestorSHA = getCommonAncestor(SHA, parentsSHA)
MergeCommit mergeCommit = new MergeCommit(SHA, parentsSHA, ancestorSHA)
mergeCommits.add(mergeCommit)
} catch (UnexpectedOutputException e) {
println e.message
try {
println "Trying to fetch it"
// Let's try fetching it before skipping it
constructAndRunGitFetch(SHA)
String ancestorSHA = getCommonAncestor(SHA, parentsSHA)
MergeCommit mergeCommit = new MergeCommit(SHA, parentsSHA, ancestorSHA)
mergeCommits.add(mergeCommit)
} catch (UnexpectedOutputException e) {
} catch (UnexpectedOutputException ex) {
println "Skipping merge commit ${SHA}"
println e.message
println ex.message
skipped.add(SHA)
}
} else {
throw new UnexpectedOutputException('Git log returned an unexpected output. Could not retrieve merge commits.', '<commit hash>-<parents hash>', it)
}
}
})

if(mergeCommits.isEmpty())
println "No merge commits."

return [mergeCommits, skipped]
}

private String getSHA(String[] informations) {
return informations[0]
}

private String[] getParentsSHA(String[] informations) {
return informations[1].split(' ')
}

private String getCommonAncestor(mergeCommitSHA, parentsSHA) {
Process gitMergeBase = constructAndRunGitMergeBase(mergeCommitSHA, parentsSHA)
def expectedOutput = ~/[0-9a-z]{7,}/
Expand All @@ -96,6 +89,14 @@ class Project {
throw new UnexpectedOutputException('Git merge-base returned an unexpected output. Could not retrieve the ancestor commit.', '<commit hash>', actualOutput)
}

private void constructAndRunGitFetch(String mergeCommitSHA) {
ProcessBuilder gitMergeBaseBuilder = ProcessRunner.buildProcess(path, 'git', 'fetch', 'origin', mergeCommitSHA)
def exitCode = ProcessRunner.startProcess(gitMergeBaseBuilder).waitFor()
if (exitCode > 0) {
throw new UnexpectedOutputException("Could not fetch merge commit ${mergeCommitSHA} from origin", "Exit code 0", "Exit code ${exitCode}")
}
}

private Process constructAndRunGitMergeBase(String mergeCommitSHA, String[] parentsSHA) {
ProcessBuilder gitMergeBaseBuilder = ProcessRunner.buildProcess(path, 'git', 'merge-base')
if (parentsSHA.length > 2)
Expand All @@ -105,15 +106,6 @@ class Project {
return ProcessRunner.startProcess(gitMergeBaseBuilder)
}

private Process constructAndRunGitLog(String sinceDate, String untilDate) {
ProcessBuilder gitLogBuilder = ProcessRunner.buildProcess(path, 'git', '--no-pager', 'log', '--merges', '--pretty=%H-%p')
if(!sinceDate.equals(''))
ProcessRunner.addCommand(gitLogBuilder, "--since=\"${sinceDate}\"")
if(!untilDate.equals(''))
ProcessRunner.addCommand(gitLogBuilder, "--until=\"${untilDate}\"")
return ProcessRunner.startProcess(gitLogBuilder)
}

String getName() {
return name
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package project.commitHashesExtraction

import project.Project

import static app.MiningFramework.arguments

interface CommitHashesExtractor {
class CommitHashes {
public String mergeSha
public String[] parents

CommitHashes(String mergeSha, String... parents) {
this.mergeSha = mergeSha
this.parents = parents
}
}

class Factory {
static CommitHashesExtractor build() {
if (arguments.projectCommitHashesFile != '') {
def file = new File(arguments.projectCommitHashesFile)
if (!file.exists()) {
throw new RuntimeException("File ${file.path} not found")
}
return new ProjectCommitListCommitHashesExtractor(file)
}

return new GitLogCommitHashesExtractor(arguments.sinceDate, arguments.untilDate)
}
}

List<CommitHashes> extractCommitHashes(Project project)
}
Loading