SZZ算法是软件工程领域使用最为广泛的一个算法,但目前可用的实现还比较少。这里介绍一个比较新的SZZ算法的实现。因为其运行起来还有些麻烦,所以简单总结一下。
我们下面介绍这个项目的基本使用方法:https://github.com/wogscpar/SZZUnleashed
首先下载其项目文件夹,在fetch_jira_bugs这个目录下运行:
python fetch.py --issue-code JENKINS --jira-project issues.jenkins-ci.org
注意这里需要是python 3。通过运行这行命令,可以将Jenkins这个项目的一些issues数据下载到本地。具体对这个命令的解释可以参看这个页面:https://github.com/wogscpar/SZZUnleashed/blob/master/examples/Fetch.md
第二步中,我们还是需要Jenkins这个项目的本地Repo,其GitHub链接在:https://github.com/jenkinsci/jenkins,所以直接clone到本地即可:
git clone https://github.com/jenkinsci/jenkins.git
下面这个操作将Git log转成后续环节可以处理的格式,运行类似这样的命令:
python git_log_to_array.py --from-commit <SHA-1_of_initial_commit> --repo-path D:\Projects\Subject-Versions\jenkins
当然,这里就有个疑问,什么叫initial commit呢?指的是单个commit?还是起始或者终止commit?这个我实在不知道,尝试分析一下,在jenkins目录下运行:
git rev-parse HEAD
看到当前commit的hash code是:e2da5e41c75d3e1545a424483b91811b32f37a33,所以我们运行:
python git_log_to_array.py --from-commit e2da5e41c75d3e1545a424483b91811b32f37a33 --repo-path D:\Projects\Subject-Versions\jenkins
经过挺长时间运行后,发现在文件夹下面生成了一个gitlog.json的文件,看来这里的--from-commit指的是从某个commit开始往后算。
接下来按照这里:https://github.com/wogscpar/SZZUnleashed/blob/master/examples/FindBugFixes.md 的介绍,运行类似:
python find_bug_fixes.py --gitlog gitlog.json --issue-list issues --gitlog-pattern "JENKINS-{nbr}\D|#{nbr}\D|HUDSON-{nbr}\D"
的命令,即可以生成issue_list.json文件,里面记录了所有和修复issue相关的commit。注意在运行上面这段python代码的时候,如果是Win10中文操作系统,有可能会报错: 'gbk' codec can't decode byte 0x93 in position 100666,此时把对应位置的代码修改为类似:
with open(path + '/' + filename, encoding='UTF-8') as f:
的情况即可。到目前为止就把所有修复issue的commit找到了,接下来是使用SZZ算法定位introduce issue的commit:
下面到了JAR包的编译过程,按照其GitHub页面上的介绍,我们应该使用Gradle这个类似于Maven的工具进行编译,我之前没用过,简单尝试了一下,其实和Maven的配置过程基本相同,在这里下载其Binary即可:https://gradle.org/releases/。之后按照其GitHub页面介绍进行编译即可。编译好之后,在这个目录下:SZZUnleashed-master\szz\build\libs,可以看到有一个szz_find_bug_introducers-0.1.jar,将其和我们之前生成的issue_list.json放到一起,然后运行:
java -jar szz_find_bug_introducers-0.1.jar -i issue_list.json -r D:/SubjectProgram-Git/jenkins
就会在Jar包所在的目录下生成一个results的目录,这里简单介绍一下生成的几个文件:annotations.json,commits.json,fix_and_introducers_pairs.json,其中fix_and_introducers_pairs.json给出了修复和引入Bug的commit对,由于我们在前面步骤中已经有了issue_list.json这个文件,在加上这些commit对,我们就可以精确知道一个bug是什么时候引入和修复的了,再具体看看commit对中对应修改的文件,就知道具体bug在文件中存在的生命周期了。
补充:
今天按照上面的流程操作完后,发现还是有不少问题,例如有些系统分析不了。另外需要立刻解决的一个问题是,作者在fetch.py中,将jql的规则搞错了,具体来说,这条语句:
-
request = 'https://' + jira_project_name + '/rest/api/2/search?'\
-
+ 'jql={}&start_at={}&max_results={}'
应该修改成这样:
-
request = 'https://' + jira_project_name + '/rest/api/2/search?'\
-
+ 'jql={}&startAt={}&maxResults={}'
话说,这种错误实在太不应该了。