-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathdevNote.sh
More file actions
214 lines (188 loc) · 5.71 KB
/
devNote.sh
File metadata and controls
214 lines (188 loc) · 5.71 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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#!/bin/sh
# A POSIX variable
###### This loop script can be used to launch every analysis
#
##!/bin/sh
#
#appsFile="apps.csv"
#outDir="output"
#inputDir="databases"
#githubKeyFile="./githubKey"
#
#for db in $(ls $inputDir); do;
# appName=$(baseName $db)
# appPath=$(grep -- $appName $appsFile)
# echo "# Computing metrics for project $appName - $appPath"
# ./devNote.sh -d $db -p $appPath -k "$(cat $githubKeyFile)" -o $appName
#done
#######
OPTIND=1 # Reset in case getopts has been used previously in the shell.
# Initialize our own variables:
verbose=0
appDB=""
project=""
outputDir=$(date)
githubAPIKey=""
function show_help {
echo -e "$(basename $0): Transform the raw application database to developer rating\n
Usage: $(basename $0) [-h] [-v] -d inputDatabase -k apiKey -p username/project -o outputDir
-h Print this help message
-v Verbose
-d application database to use as input
-p GitHub identifier of the analyzed project
-k GitHub API key
-o Output directory.
" >&2
}
# Parse args
while getopts "h?vo:d:o:p:k:" opt; do
case "$opt" in
h|\?)
show_help
exit 0
;;
v) verbose=1
;;
p) project=$OPTARG
;;
d) appDB=$(realpath $OPTARG)
;;
k) githubAPIKey=$OPTARG
;;
o) outputDir=$(realpath $OPTARG)
;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
# Check mandatory arguments
if [ -z $appDB ]; then
echo "Missing argument: '-d'"
show_help
exit 2;
fi
if [ -z $project ]; then
echo "Missing argument '-p'"
show_help
exit 2;
fi
if [ -z $githubAPIKey ]; then
echo "Missing argument '-k'"
show_help
exit 2;
fi
if [[ -f $outputDir ]]; then
echo "$outputDir is a file, cannot proceed"
exit 2
fi
# Parsing done, starting out script
WORKDIR=$(dirname $(realpath -s $0))
GIT_MINER="$WORKDIR/GitHubMiner.jar"
METRICS_CALC="$WORKDIR/CSVSmellTracker.jar"
DETECTOR="$WORKDIR/SmellDetector.jar"
##
# Query Detector jar to process the smells for a given application.
# We are setting a bigger stacktrace size in this method (512Mo).
#
# $1 - The application database to query
# $2 - The output directory
##
function detectorQuery {
appDB="$1"
smellsDir="$2"
mkdir -p "$smellsDir"
[[ $verbose -eq "0" ]] || echo "## Will use database: $appDB, file: $(ls $appDB/..)"
cd "$smellsDir" # We can't provide an output directory to DETECTOR unfortunately
java -Xss512m -jar $DETECTOR query -r NONFUZZY -db "$1/databases/graph.db" -d true
cd -
}
##
# Retrieve the developpers associated to the given project
# and serialize the results in a database and a CSV.
#
# $1 - The project identifier on GitHub (i.e. 'username/project')
# $2 - The GitHub API key
# $3 - The output directory
##
function findDevelopers {
apiUrl="https://api.github.com/repos/$1"
devOutputDir=$3
mkdir -p "$devOutputDir"
cd $devOutputDir
[[ $verbose -eq "0" ]] || echo "## Will contact Github API with url: $apiUrl"
java -jar $GIT_MINER getCommits -l "$apiUrl" -k $2 -d "$devOutputDir/database"
cd -
}
##
# Find the developer associated to each commit in smell files
# and add a row with his ID.
#
# $1 - Directory containing smells files
# $2 - File containing developers output
##
function addDeveloperRow {
csvFile=$2
# The header 'key' being found, the "id" element is added on the smells CSV.
cat $csvFile | while IFS=, read hash name id email; do
[[ $verbose -eq "0" ]] || echo "## Putting developer $id for commit $hash"
sed -E -i "s/(.*$hash.*)/\1,$id/" $1/*.csv
done
}
##
# Analyse the smell results in order to give number of Introduced/Refactored smells per developer
#
# $1 - The directory containing smell results
# $2 - smell summary output file
# $3 - GitMiner output containing project commits
# $4 - GitHub project identifier to set in output
# $5 - Project logs in correct order
# $6 - Project database containing Detector analysis
##
function metricsCalculation {
java -jar $METRICS_CALC -d "$1" -o "$2" -c "$3" -p "$4" -l "$5" -db "$6"
}
##
# Clone the project and sort the commits in topological order
#
# $1 - Project path on GitHub
# $2 - output file
##
function topologicalCommitsOrder {
project=$1
logFile=`realpath $2`
repoPath="/tmp/git/$project"
if [[ ! -d $repoPath ]]; then
git clone github.com:$project $repoPath
fi
cd $repoPath
git log --topo-order --reverse --pretty="%H" > $logFile
cd -
}
[[ $verbose -eq "0" ]] || echo "## verbose=$verbose, appDB=$appDB, outputDir=$outputDir, project: $project, apiKey=$githubAPIKey, Leftovers: $@"
appDB="$appDB/databases/graph.db"
echo "Using appDB $appDB"
smellsDir="$outputDir/smells"
[[ $verbose -eq "0" ]] || echo "## Temporary results for Detector will be in $smellsDir"
echo "# Cleaning previous smells"
rm -rf $smellsDir
echo "# Parsing project database to find smells"
detectorQuery "$appDB" "$smellsDir"
devDir="$outputDir/devs"
devFile="$devDir/COMMITS.csv" # TODO: Can we define a custom output file?
[[ $verbose -eq "0" ]] || echo "## Temporary results for devs will be in $devDir"
if [[ -f $devFile ]];then
echo "# Developpers already present in $devFile"
else
echo "# Retrieving project developers profiles on github"
findDevelopers "$project" "$githubAPIKey" "$devDir"
fi
echo "# Merging developers with smells files"
addDeveloperRow "$smellsDir" "$devFile"
echo "# Creating log file with topological order"
timestamp=$(date +"%Y-%m-%d_%H-%M-%S")
logFile="/tmp/commits-$timestamp"
topologicalCommitsOrder $project $logFile
echo "# Generating global metrics file"
metricsDir="$outputDir/metrics"
metricsCalculation "$smellsDir" "$metricsDir" "$devFile" "$project" "$logFile" "$appDB"
echo "Done; output can be find in $metricsDir"