-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSourceCodeAggregation.py
More file actions
174 lines (161 loc) · 7.05 KB
/
SourceCodeAggregation.py
File metadata and controls
174 lines (161 loc) · 7.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import subprocess
import sys
import os
import re
from ConfigParser import SafeConfigParser
from filecmp import dircmp
internalConfiguration = {}
"""
Reads configuration file called parse_defects4j.cfg
@param {String} sectionName: name of the section in configuration file
"""
def readConfigurations():
#Default option
sectionName = "Basic"
try:
config = SafeConfigParser()
config.read('parse_defects4j.cfg')
internalConfiguration["project"] = config.get(sectionName,"project")
internalConfiguration["projectNum"] = config.get(sectionName,"projectNum")
internalConfiguration["version"] = config.get(sectionName,"version")
internalConfiguration["examplesPath"] = config.get(sectionName,"examplesPath")
internalConfiguration["srcPath"] = config.get(sectionName,"srcPath")
internalConfiguration["copiedFiles"] = config.get(sectionName, "copiedFiles")
internalConfiguration["projectPath"] = config.get(sectionName, "projectPath")
internalConfiguration["genprogPath"] = config.get(sectionName, "genprogPath")
internalConfiguration["jdkSeven"] = config.get(sectionName, "jdkSeven")
internalConfiguration["jdkEight"] = config.get(sectionName, "jdkEight")
internalConfiguration["grammarModel"] = config.get(sectionName, "grammarModel")
except:
print "Error with Configuration file. Please make sure it meets these specifications: "
print "FileName: parse_defects4j.cfg File Path: same directory as diffBugs.py"
print "---CONFIG SPECIFICATION---"
print "[Basic]"
print "project = <name of projet according to Defects4j>"
print "projectNum = <number of version IDs to iterate>"
print "version = <b or f>"
print "examplesPath = <absolute path to directory with GenProg defects4j projects>"
print "srcPath = <relative path from project directory to source code path>"
print "copiedFiles = <absolute path to resulting directory>"
print "projectPath = <Absolute Path to resulting project directory>"
print "genprogPath = <Absolute Path to GenProg4java>"
print "jdkSeven = <Absolute Path to JVM 7>"
print "jdkEight = <Absolute Path to JVM 8>"
print "grammarModel = <Absolute path to a directory where your .tsg files are located>"
print "------"
print sys.exc_info()
sys.exit()
"""
Parses defect4j info command
@param {String} bugID; index of bug version
@return {Dictionary} Keys are file names, Values are file paths.
"""
def defects4jInfo(bugID):
bashCommand = "defects4j info -p " + internalConfiguration["project"] + " -b " + bugID
output = executeBash(bashCommand)
fileStrings = parseDefects4JInfo(internalConfiguration["srcPath"],output)
#fileNames are found on the end of the path
fileNames = [i.split('/')[-1] for i in fileStrings]
filePackage = dict(zip(fileNames, fileStrings))
return filePackage
"""
Special parsing for defect4j's format
@param {String} defectOutput: Given output string from defect's info command
@param {String} bashOutput: Given output from executing bash
"""
def parseDefects4JInfo(defectOutput,bashOutput):
#Parsing default defects4j info command
return ["%s%s%s" % (defectOutput,i[3:].replace('.','/'), ".java") for i in
bashOutput.split("--------------------------------------------------------------------------------")
[-2].strip('\n').split("\n")[1:] ]
"""
Checkout fixed project into Example directory
@param {String} bugID; index of bug version
"""
def checkoutFixedProject(bugID):
bashCommand = ''.join([
"defects4j checkout -p ", internalConfiguration["project"],
" -v ", bugID,
"f -w ", internalConfiguration["examplesPath"],internalConfiguration["project"], bugID, "Fixed"
])
executeBash(bashCommand)
#Must execute bash command to set fixedPath in internal Configs
internalConfiguration["fixedPath"] = internalConfiguration["examplesPath"] + internalConfiguration["project"] + bugID + "Fixed"
"""
Bash command to checkout Defects4j projects with GenProg internalConfiguration. Follow GenProg installation before executing
@param {String} bugID; index of bug version
"""
def checkoutGenProgDefects4j(bugID):
bashCommand = ''.join([
"bash ", internalConfiguration["genprogPath"], "/defects4j-scripts/prepareBug.sh ",
internalConfiguration["project"], " ",
bugID, " humanMade 1 ",
internalConfiguration["examplesPath"], " " ,
internalConfiguration["jdkSeven"] , " " ,
internalConfiguration["jdkEight"], " " ,
internalConfiguration["genprogPath"] , " " ,
internalConfiguration["grammarModel"], "/", internalConfiguration["project"].lower() , bugID , "b.tsg"
])
print executeBash(bashCommand)
"""
Bash copies modified files to Copies directory
@param {String} bugID: index of bug version
@param {List} filePaths: list of relative paths
"""
def copyModifiedFiles(filePaths, bugID):
if not os.path.lexists(internalConfiguration["projectPath"]):
os.makedirs(internalConfiguration["projectPath"])
#Multiple files may have been modified in each version, hence this iteration
for name, path in filePaths.items():
buggyCommand = ''.join([
"scp ", internalConfiguration["examplesPath"],
internalConfiguration["project"].lower(),
bugID, "Buggy/",
path,
" ",
internalConfiguration["projectPath"], "/",
bugID, "/",
"b", "/",
name
])
fixedCommand = ''.join([
"scp ", internalConfiguration["fixedPath"] ,"/",
path,
" ",
internalConfiguration["projectPath"], "/",
bugID, "/",
"/f/",
name
])
projectIDPath = internalConfiguration["projectPath"]+"/"+bugID
checkDirectory(projectIDPath)
checkDirectory(projectIDPath+"/b")
checkDirectory(projectIDPath+"/f")
print executeBash(buggyCommand)
print executeBash(fixedCommand)
"""
Helper function for making directory
@param {Sting} path: path to directory to create
"""
def checkDirectory(path):
if not os.path.lexists(path):
os.makedirs(path)
"""
Helper function for executing bash commands
@param {String} command: bash command
@return {String} output: Any output print from bash command execution
"""
def executeBash(command):
process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
output, error = process.communicate()
return output
def main():
readConfigurations()
projectNum = str(internalConfiguration["projectNum"])
for i in range(1,36):
projectNum = str(i)
checkoutGenProgDefects4j(projectNum)
checkoutFixedProject(projectNum)
copyModifiedFiles(defects4jInfo(projectNum), projectNum)
if __name__ == "__main__":
main()