StatCVS提供了对CVS储存库活动的深入观察

简介:StatCVS 是一个创建并发版本系统(Concurrent Versions System – CVS)储存库活动图表的方便工具。在本文中,开发人员 Tom Copeland 将解释 如何安装、运行 StatCVS,概述生成的报告,然后还将介绍如何为多个储存库生 成报告,StatCVS 的内幕及限制等多项内容。

如果要接手一个已经运行了好几年的软件项目,那么怎样才能得到对项目开 发历史的认识呢?最好的方法可能就是与曾经参与该项目的开发人员对话,但是 这说起来容易,做起来却很困难。原有的开发人员通常都已转到了其他项目中, 而且要找到他们也很难。您可以查看释出频率(release frequency),尽管这 可能受非技术性的强制规定控制(有时可能只是出于“我们要在本财政年度末做 一个发布”的理由)。您可以查看 bug 和特性请求跟踪器,还可以在开放和关 闭的 bug 讨论中挖掘信息。或者可以直接进入源代码历史记录,用 StatCVS 这 样的工具查看曾做过哪些记录,这些记录是谁修改的。我将 StatCVS 运用在各 种大型项目上已经有好几年的时间了,它生成的报告一直都很不错。在本文中, 将演示如何在项目上设置、运行 StatCVS,如何阅读它生成的报告,以及 StatCVS 需要改进的地方。

安装 StatCVS

StatCVS 是一个 Java 程序,需要 JDK 1.4 或更高版本的支持。从命令行安 装 StatCVS 最容易:只要下载最新的发行版(请参阅参考资料),将它解压到 一个目录中即可;我用的是 /usr/local/statcvs/ 目录。而且,如清单 1 所示 ,我还创建了一个符号链接,叫作 statcvs,它链接到刚刚安装的版本上。这可 以节约日后的一些打字工作时间,更重要的是,日后只要把符号链接修改为指向 要使用的版本,就可以在 StatCVS 的不同版本间切换。

清单 1. StatCVS 的符号链接

[root@hal local]# pwd  /usr/local  [root@hal local]# ln -s statcvs-0.2.2 statcvs  [root@hal local]# ls -l | grep statcvs  lrwxrwxrwx  1 root   root      13 Jan 13 14:27 statcvs -> statcvs-0.2.2  drwxrwxr-x  2 root   root      4096 Oct 13 23:32 statcvs-0.2.2  -rw-rw-r--  1 tom   tom     1344753 Jan 13 13:49 statcvs-0.2.2.zip

如果列出 statcvs 目录中的文件,就可以看到那里没有任何适用于 StatCVS 的支持 JAR 文件(supporting JAR file)。惟一的 JAR 文件是 statcvs.jar ,它包含 StatCVS 使用的惟一的第三方库:JFreeChart。这种方法使得开始了 解 StatCVS 变得更容易,因为不需要关于类路径的更多知识。

运行 StatCVS

为了演示 StatCVS 的工作方式,需要找到一个带有有趣的 CVS 历史记录的 项目,并生成一些活动报告。developerWorks 的项目 Jikes(请参阅参考资料 )已经进行了一段时间,有大量开发人员,还有一个公共的 CVS 储存库,所以 它是一个好例子。

从 CVS 中获得源代码

为了从 StatCVS 得到 Jikes 的报告,需要得到最新的源代码,并生成一个 CVS 日志文件让 StatCVS 分析。所以,需要从 Jikes 的 CVS 储存库签出它的 源代码。Jikes 的开发人员允许拥有只读权限的匿名用户对其储存库进行访问, 所以可以用这个方法得到源代码,如清单 2 所示:

清单 2. 从 Jikes 的 CVS 储存库中签出源代码

[tom@hal tmp]$ cvs -d:pserver:anoncvs@www- 124.ibm.com:/usr/cvs/jikes login  Logging in to :pserver:anoncvs@www-124.ibm.com:2401/usr/cvs/jikes  CVS password: [ Type "anoncvs" here ]  [tom@hal tmp]$ cvs - d:pserver:anoncvs@www-124.ibm.com:/usr/cvs/jikes co jikes  cvs server: Updating jikes  U jikes/.cvsignore  ... several thousand lines elided ...

创建 CVS 日志文件

现在机器上已经有了 Jikes 代码,需要创建一个 CVS 日志文件供 StatCVS 处理。要创建这个文件,需要进入 jikes 目录,运行 cvs log 命令。正如从清 单 3 中看到的,我把命令的输出重定向到了一个叫作 logfile.txt 的文件:

清单 3. 创建 CVS 日志文件

[tom@hal tmp]$ cd jikes/  [tom@hal jikes]$ time cvs - d:pserver:anoncvs@www-124.ibm.com:/usr/cvs/jikes log > logfile.txt  real  0m40.719s  user  0m0.516s   sys   0m0.314s  [tom@hal jikes]$

只是为了好玩,我对此进行了计时。在我的工作站上,这大约花费了 40 秒 的时间,生成的日志文件大小约为 3.3 MB。

命令行界面

现在可以运行 StatCVS 生成报告了。可以从命令行运行 StatCVS,也可以从 Ant 运行(请参阅参考资料)。首先来看一下命令行界面,然后再来讨论 Ant。

StatCVS 从命令行运行很容易,因为只有一个 JAR 文件,而且可以把 JAR 文件名直接传给虚拟机。可以用不同的选项控制输出。这里是一些比较有用的选 项:

-title [标题] —— 放在报告上的显示标题。

-output-dir [目录] —— 报告文件存放的位置;如果目录不存在,则自动 创建该目录。

-include [模式] —— 只包含与指定模式匹配的文件。

-viewcvs [ViewCVS url] —— 储存库的 ViewCVS Web 界面的 URL(请参阅 参考资料)。

下面用以上选项创建报告。首先,必须移动到 jikes/ 目录上,然后从命令 行运行 StatCVS,如清单 4 所示:

清单 4. 从命令行运行 StatCVS

[tom@hal tmp]$ time java -jar /usr/local/statcvs/statcvs.jar /   -include "cpp;**/*.h" /   -output-dir report /   -title "Jikes" /   -viewcvs http://www- 124.ibm.com/developerworks/oss/cvs/jikes/jikes/ jikes/logfile.txt jikes/  StatCVS - CVS statistics generation  real   0m15.232s  user  0m12.014s  sys   0m0.326s   [tom@hal tmp]$

注意,上面使用了 -include 参数,只捕获 C++ 源代码文件和头文件。在 CVS 模块中有许多其他文件(文档、配置脚本、报告、Web 页面等),但是本文 只关心源代码。

Ant 任务

清单 5 显示了与清单 4 的命令行调用功能相同的 Ant 任务定义:

清单 5. 用 Ant 运行 StatCVS

                       

图表和图形

报告放在清单 4 指定的报告目录中。如果用浏览器打开该目录中的 index.html 页面,该页面如图 1 所示:

图 1. Jikes 的 StatCVS 主报告页面

可以看到可用报告的分类:关于代码作者的一些统计数据、查看提交日志、 代码段的行,以及关于文件和目录大小的一些统计。

代码行

代码行图表如清单 2 所示,它可能非常有趣:

图 2. Jikes 一段时间内的代码行数

从这个图表中可以看出,代码最初是在 1999 年初导入的。从那以后,它增 长得非常稳定,一直到 2001 底,那时代码的数量开始略有下降。还有几次,新 的代码被引入或者旧的代码被重构出去,这些可以从代码行计数的急剧升降上表 现出来。从 2004 年开始,似乎没有加入太多代码,这可能表明 Jikes 已经成 熟到了某种程度,主要对它做些维护工作即可。

如果从主报告页上单击 Authors 链接,就可以看到数字和图表,它们指出每 个参与者贡献了多少代码,如图 3 所示:

图 3. 每个参与者的代码行数

很明显,ericb 和 shields 对 lion 负责的代码有所贡献,而其他参与者也 偶尔参与其中。注意,没有任何一个参与者从头到尾都参与了该项目。这个事实 清楚地证明:长期项目需要那些拥有良好变量名和干净设计的清晰代码。

偶尔,StatCVS 在生成报告时表现得更聪明。如果 CVS 储存库只有一个参与 者,那么主报告页上的链接只会写上“Author page for joe_smith”,而且不 会生成比较图表。这样 StatCVS 会运行得更快,报告页也会更整洁。

现在再来看一个参与者的活动图表。在主报告页面上,单击 Authors 链接可 以访问 Author Activity,如图 4 所示,图中显示了每个参与者是添加了文件 ,还是修改了文件:

“代码行”仅仅是数字

代码行计数有多重要呢?时至今日,只有项目中的人才能说得清。请考虑以 下这些情况。只要加入一个很大的格式变化,使所有的 for和 while循环看起来 更整洁,就很容易增加代码的行数。项目中可能有大量自动生成的文件(例如, 语言语法分析程序),而这些文件都是由一个人签入的。项目可能是一个围绕算 术库构建的应用程序,虽然很小,但是非常复杂;UI 代码可能频繁变化,但库 的代码只会偶尔变化。图表虽然漂亮,但是不一定能够表现出来谁做的工作最多 。它仅仅是原始数据的图形化显示,需要人来诠释它。

图 4. 添加代码 vs. 修改代码

您可以看到,shields 添加了大多数代码,这在预料之中,因为这个人显然 是代码导入 CVS 之后的第一个维护者。同样,ericb 在项目启动之后几年之间 一直进行类似的工作,主要在修改文件。

提交日志

提交日志(Commit Log)仅仅是对模块做的全部修改的一个列表。这个报告 显示了谁做了修改,以及提交者在所做修改上附加的注释。而且,因为 Jikes 的储存库中有一个 ViewCVS 界面,运行 StatCVS 时还使用了一个 -viewcvs参 数,所以报告中包含了到已实际修改的源代码的链接。例如,在 2004 年 12 月 12 日,src/decl.cpp有一个改动。如果点击 decl.cpp,会 看到添加了一个 if语句,还有一个注释。图 5 显示了 ViewCVS 的一部分,展 示了两个文件版本之间的差异:

图 5. 一个具体的代码变化

还有其他一些报告:一个报告显示了平均文件大小,另外一个显示了如何通 过目录树分布代码,还有一个则显示了哪个文件的版本改动最多。Jikes 的整个 报告可以通过单击本文顶部或底部的 代码图标得到,也可从 下载小节得到。只要将它解压,并用浏览器打开 index.html,就可以看到这个 报告。

关于 Maven?

对于 Maven 用户来说,会高兴地听到 StatCVS-XML 有一个 Maven 插件,该 插件是 StatCVS 的扩展。这个插件是可定制的;它甚至提供了一些好方法,可 以将 CVS 用户名映射到真实的用户名,这会使报告看起来更漂亮。有关的更多 信息,请参阅 参考资料。

为多个项目生成报告

前面已经看到了如何在一个 CVS 储存库上运行 StatCVS。但是,如果拥有多 个储存库,那么您就会希望有一种方法能够每天夜里为所有的储存库生成 StatCVS 报告。因为可以从命令行运行 StatCVS,所以这是一个用脚本就可以解 决的简单问题。以下是一些需要牢记的事项:

StatCVS 是一个 Java 程序,所以需要大量内存才能启动。处理大型 CVS 储 存库时也需要相当一段时间。所以如果运行它的机器还有其他用途,那么最好在 处理不同的储存库之间让机器休息一会。如果运行的系统支持优先级设置,那么 用低优先级来运行耗时比较长的任务是一个好主意。

如果定期将储存库添加到机器或从机器中删除储存库,那么某些储存库可能 不包含模块。所以请事先检测这种可能性,免得没有必要地启动 StatCVS。

清单 6 显示了一个小小的 Ruby 脚本,可以在拥有公共父目录的多个储存库 上运行 StatCVS(关于 Ruby 的更多内容,请参阅 参考资料);在下载代码中 也有这个脚本:

清单 6. 运行 StatCVS 处理多个储存库的脚本

#!/usr/local/bin/rubyrequire 'fileutils'HOME_DIR = "/tmp/"CVS_DIR= "/path/to/my/cvs/"BASE_OUTPUT_DIR = "/var/www/my-projects/"DELAY = 5Dir.chdir(HOME_DIR)# get a list of all the reposiToriesDir.new(CVS_DIR).entries.grep(/^[^.]/).each {|file|# create a working direcToryworking_direcTory = "tmp_" + rand().to_sDir.mkdir(working_direcTory)Dir.chdir(working_direcTory)`cvs -d#{CVS_DIR}#{file} -Q co .`FileUtils.rm_rf(%w{CVS CVSROOT})# no need to run StatCVS if no modules exist yetif !Dir.new(".").entries.grep(/^[^.]/).empty?`cvs -d#{CVS_DIR}#{file} -Q log > log`cmd = "/usr/java/java/bin/java "cmd = cmd + "-jar /usr/local/statcvs/statcvs.jar "cmd = cmd + "-output-dir #{output_direcTory} log ."`#{cmd}`FileUtils.rm("log", :force=>true)end# clean up and sleep for a bit to let things settle downDir.chdir(HOME_DIR)FileUtils.rm_rf(working_direcTory)sleep DELAY}

StatCVS 内幕和限制

因为 StatCVS 是一个开源项目,所以您可以得到它的代码。要得到 StatCVS 的代码,请从 StatCVS 的页面下载源代码 zip 文件(请参阅 参考资料),或 者从这个 Web 站点上的 CVS 储存库签出代码。

内幕

这里是一些关键的统计数字:

4,463 行代码,由 JavaNCSS 测量。

176 个 JUnit 测试。

一个很好的 Ant 构建文件,可以促进定制构建的编辑。

一个好标志 —— PMD 在 StatCVS 中找不到未使用代码的例子。

有关 JavaNCSS、JUnit、Ant 和 PMD 的更多信息,请参阅 参考资料。

StatCVS 用 JFreeChart 来创建图表和图形。所有的图表都用可移植网络图 形(Portable Network Graphics – PNG)格式生成,大多数现代 Web 浏览器都 支持这种格式。生成图表的代码被很好地封装在 net.sf.statcvs.renderer包中 。

限制

最大的限制可能是 StatCVS 不支持分支;它只能报告对每个模块的 HEAD 所 做的修改。所以,如果开发团队的应用模式是为产品的每个版本建立一个新分支 ,并且只提交到这个分支,那么 StatCVS 无法返回正确的结果。这个问题曾在 StatCVS 的邮件列表上讨论过(请参阅 参考资料),但是看起来近期不会得到 解决。但是,既然它是开源的,谁会知道以后会怎样呢?

另一个限制是 StatCVS 只支持 CVS。随着 Subversion 正在迅速赢得 CVS 继承人的地位,所以如果 StatCVS 能够两者都支持,那就太棒了。在 StatCVS 的邮件列表上已经有了一些关于这点的讨论,但是 Subversion 修改集的格式看 来正是目前的障碍。

结束语

挖掘 CVS 储存库来查找使用信息,可能产生大量的数字和图表。但是要认识 这些数字的有用性,以及它们能够为特定项目开发提供什么样的深入观察,这些 则要取决于您的判断。在脑子里要有这样一些概念,StatCVS 可以提供一些有趣 的可视快照,让您了解项目源代码在其生命期间发生的事。

而且,StatCVS 也是开源项目良好运行的一个优秀模型。它的代码整洁、构 建过程简单、文档清晰。如果您对于如何做好开源项目有兴趣,那么可以从了解 StatCVS 中学到许多东西。

下载:http://www.ibm.com/developerworks/cn/java/j-statcvs/

如果心胸不似海,又怎能有海一样的事业。

StatCVS提供了对CVS储存库活动的深入观察

相关文章:

你感兴趣的文章:

标签云: