1.  资料与文档

核心站点:

我自己用的上的插件:

可能有用的插件:

2.  第一次安装、第一次使用

安装文档见:http://trac.edgewall.org/wiki/TracInstall (附:Trac官方网站

最简单的办法是使用easy_install,使用以下语句就可以完成Trac安装:

 easy_install Trac
注意easy_install的运行通常需要管理员权限。如果这一步没有报错就算是安装成功了。

然后得使用Trac的命令行管理工具来初始化一个代码项目,管理工具会问一些问题来完成初始设置:

 trac-admin /path/to/myproject initenv

然后就可以用Trac自带的http服务器来启动服务了:

 tracd --port 8000 /path/to/myproject

现在可以用浏览器访问:http://localhost:8000/ 就能够见到刚才创建的代码项目。


从 svn 安装最新的开发版代码也不复杂,参考Trac Installation Guide for 0.12dev。按照页面上的说明准备好各对应版本的依赖包,然后

 easy_install http://svn.edgewall.org/repos/trac/trunk
就行。或者
svn co http://svn.edgewall.org/repos/trac/trunk
python ./setup.py compile_catalog -f
python ./setup.py install
效果是完全一样的,同样是会安装成 egg 包。其中第二步是为了引入 i18n 翻译数据,如果不做这一步,则安装好的 Trac 界面只有英文。

开发版 Trac 依赖的有些库也是 svn 上的开发版,比如 Genshi 。可以用类似 Trac 开发版的安装方法或者

 easy_install -U "Genshi==dev"
都可以。

2.1  启用用户认证

进一步的设置需要设置trac.ini文件(在创建的代码项目的conf目录下),Trac 0.11以后也集成了Web界面的管理工具来维护trac.ini文件,但Web管理界面要求当前登录在Trac上的用户有管理员权限,否则会报“No administration panels available”的错误。因此现在我们来为Trac启用用户认证功能。

用tracd方式启动的服务要开启用户认证,相关的文档可参考:http://trac.edgewall.org/wiki/TracStandalone 这里使用的是Apache里面带的htdigest工具来创建认证文件:

 htdigest [-c] passwordfile realm username
,比如我用
 htdigest -c users.htdigest Test elias
就创建了一个名为users.htdigest的文件,里面有Test这个域下面的名为elias的用户的登录信息。

然后将users.htdigest文件拷贝到trac.ini相同的目录下。改为使用以下语句来启动Trac:

 tracd -p 8000 --auth=*,/path/to/users.htdigest,mycompany.com /path/to/project1
比如我这里就是
 tracd --port 8000 --auth=*,D:\tmp\trac\conf\users.htdigest,Test D:\tmp\trac

现在就可以用elias用户登录了。我们还得给新建的用户赋以管理员权限。相关的文档参考:http://trac.edgewall.org/wiki/TracPermissions 比如给elias用户管理员权限,那么可以这样操作:

 trac-admin /path/to/projenv permission add elias TRAC_ADMIN
然后重启Trac服务就可以在网址 http://localhost:8000/trac/admin 看到Web形式的trac.ini修改界面了。

2.2  使用MySQL做数据存储

MySQL 支持不是必须的,默认情况下 Trac 会使用 Sqlite 作为数据存储引擎。用户较多时可以用 MySQL 或 PostgreSQL 作为存储引擎提高并发性能,其中 MySQL 相关的配置方式参考:http://trac.edgewall.org/wiki/MySqlDb 。Trac 用到了事务,所以要求 MySQL 启用 InnoDB 支持;另外正确处理中文最关键的步骤是在创建 MySQL 数据库时选择为 utf-8 编码就可以了。

 easy_install MySQL-python

MySQL-Python在DarwinPorts下面编译得有点问题,如果用localhost会直接导向DarwinPorts下的MySQL,如果未开启就会造成连接失败。用127.0.0.1就可以正常连接到非DarwinPorts的MySQL。

0.11.1版本只要在MySQL库启用utf-8就能正确存储和显示中文(不用修改trac.ini中的默认编码)。

  • 之前在mac中执行trac-admin遇到编码错误时,修改了text.py文件的tounicode函数实现,使之忽略locale的设置,永远使用utf-8进行编码,不确定这是否有关。
  • 由于同样的原因,修改了trac/util/datefmt.py的113行,在其之前加入encoding = 'utf-8'

2.3  改用 Form 方式的用户认证

安装插件Account Manager Plugin,并按照其说明进行配置。插件的功能基本上都可以通过 Web Admin 的界面开启/关闭,只是如果用 form 认证代替 HttpAuth ,则除了在 Web 界面调整之外,还需要在 trac.ini 文件的“[components]”一节中加入

 trac.web.auth.LoginModule = disabled
来关闭 Trac 自带的 HttpAuth 认证方式。

2.4  Web服务器集成

我选用的是 FastCGI 方式的 lighttpd,参见:http://trac.edgewall.org/wiki/TracFastCgi

一般应该按照http://trac.edgewall.org/wiki/TracCgi 页面最开始的说明,用

 trac-admin /path/to/env deploy /path/to/www/trac
来生成 Web 服务器所需的文件。但 0.12 开发版的这个部署功能无法正常工作,所以我手工从 Trac 源代码中把“/trunk/trac/htdocs/”目录复制到 Web 服务器所属的 “htdocs/common”目录下;并且把“/trunk/cgi-bin/trac.fcgi”文件也拷出来备用。

最后我的 lighttpd 配置是这样的:

$HTTP["host"] == "trac.elias.cn" {
    server.document-root = "/var/www/trac/htdocs"
    alias.url            = (
        "/chrome/" => "/var/www/trac/htdocs/",
    )

    # rewrite for multiple svn project
    url.rewrite-final    = (
        "^/[^/]+/chrome/(.*)" => "/chrome/$1",
    )

    $HTTP["url"] =~ "^(?!/chrome)"{
        fastcgi.server    = (
            "/" => (          # if trac_prefix is empty, use "/"
                (
                    # options needed to have lighty spawn trac
                    "bin-path"        => "/var/www/trac/htdocs/cgi-bin/trac.fcgi",
                    "max-procs"       => 1,
                    "bin-environment" => (
                        "TRAC_ENV" => "/var/www/trac",
                        "PYTHONPATH" => "/usr/lib/python2.5/site-packages",
                        "PYTHON_EGG_CACHE" => "/tmp/trac/",
                    ),

                    # options needed in all cases
                    "socket"          => "/tmp/trac.sock",
                    "check-local"     => "disable",

                    # optional
                    "disable-time"    => 1,

                    # needed if trac_prefix is empty; and you need >= 1.4.23
                    "fix-root-scriptname" => "enable",
                ),
            ),
        )
    } # end of $HTTP["url"] =~ "^/trac_prefix"
} # end of $HTTP["host"] == "trac.example.com"
这个配置能将 common 目录下的资源文件当作静态文件由 lighttpd 处理,没有启用基于htpasswd 的 basic 方式认证(lighttpd 虽然也支持 digest 方式认证,但是对标准支持得不完善,暂时不推荐使用),因为不够安全。这里我们在上一节使用了 Account Manager Plugin 的 form 方式认证来代替。

在 1.4.23 之前版本的 lighttpd 有个 Bug ,当 fastcgi.server 的绑定路径为“/”时,会使得动态程序丢失部分路径,参见:http://trac.edgewall.org/ticket/2418 。如果不方便升级 lighttpd (比如 Debian Lenny 下),那么可以修改 trac.fcgi 为如下内容来绕过这个问题:

from trac.web import _fcgi
from trac.web.main import dispatch_request
def application(environ, start_request):
    environ['PATH_INFO'] = environ['SCRIPT_NAME'] + environ['PATH_INFO']
    environ['SCRIPT_NAME'] = ''
    return dispatch_request(environ, start_request)
_fcgi.WSGIServer(application).run()


Apache在Mac下的mod_fastcgi安装步骤见:http://rikugun.javaeye.com/blog/258616

  • 需要用到xampp源代码中的build和include目录。
  • fcgi目录不能放到htdocs下面。
  • trac.fcgi要有可执行权限
  • .egg目录里面有deploy_trac.fcgi作为trac.fcgi的模板,只要替换首行的python路径,以及加入Trac资源所在路径即可。
  • trac官方的cgi方式设置说明的映射htdocs是不必要的,但怀疑不做会影响服务器效率。
  • AuthName和AuthDigestDomain都要写成htdigest生成密钥时使用的域,才能正确完成登陆。

2.5  解决日期格式无法被正确解析问题

在“时间线”(TimeLine)等栏目中,提供有条件过滤查询框,其中的一个参数是查询起始时间。依据服务器 locale 设置不同,有时这个时间会显示为中文的本地化版本,比如“2010年8月17日”,但在直接提交这个过滤条件时,这个时间格式又无法被正确解析(目前是 Babel 0.9 版本,还没有实现本地化时间格式的解析,以后版本可能会解决这个问题)。这样每次手工修改时间格式比较麻烦,所以参考How do I change the format used for displaying date and time?,把 Trac 使用的时间格式转为英文处理。

具体地,我是在 lighttpd 的 "bin-environment" 中增加如下行解决(注意:这里给 LC_TIME 设置的 locale 必须是系统中目前存在的 locale ,否则 Trac 会报错):

"LC_TIME" => "en_US.utf8",

2.6  版本控制后台 Mercurial

安装配置文档参见:http://trac.edgewall.org/wiki/TracMercurial ,目前最新版的 Trac 和 TracMercurial 都已经集成了多版本库支持,所以可以参考http://trac.edgewall.org/wiki/MultipleRepositorySupport 配置多个 Mercurial 版本库集成。再有,TracMercurial 是不需要像 svn 集成那样使用 post-commit 钩子的,而是会自动在需要时访问和解析 Mercurial 仓库的代码结构。

Mecurial集成插件(TracMercurial)以前对超过几十M量级的版本库存在严重的性能问题。但其实有办法搞定,在Ticket 7746页面有补丁能够改善这一性能问题,该页面上的最新补丁已经能够将这一块的处理性能提升几个数量级,于是TracMercurial对大型的源代码库重新变得好用。TracMercurial的维护者已经将这个补丁提交到了2008年12月5号以后的正式版本中。

Debian Lenny 下自带的 Mercurial 版本是 1.0.1 ,会报“TypeError: 'mqrepo' object is unsubscriptable”错误,参见:http://trac.edgewall.org/ticket/8986 。可以利用 lenny-backports 里头的mercurial 和 mercurial-common 包来升级解决。

2.7  Mercurial 和 Trac 中 Ticket 模块的绑定

利用HgTracHook,可以比较简单地实现 Mercurial 和 Ticket 模块的联动。也即,如果在 Mercurial 日志中提及 Ticket 编号,对应 Ticket 的描述文本中能够自动加入指向该 ChangeSet 的链接;而且还可以通过日志修改 Ticket 的状态。

比如日志中写“fix #1”就会把编号为 1 的 Ticket 状态设置为 Fixed ;写“see #1”虽不改变 Ticket 状态,但会在 Ticket 中加入一条评论,提供指向该修改集的链接。一次 commit 引用多个 Ticket 可以这样写: see #1, #3, #5.

HgTracHook 脚本有个 Bug :如果一次提交多个修改集,而且其中涉及对同一个 Ticket 的多次引用,那么其中有的引用信息无法正确记录到 Trac 上,而且会报类似如下错误
 remote: Unexpected error while processing ticket ID 15: (1062, "Duplicate entry '15-1270110950-comment' for key 1")
这主要是因为 Hook 生效的时候,使用 hg push 到服务器上这一动作发生的时间作为修改 Ticket 评论的时间。在代码仓库很小时,记录一次 push 的多个修改集中涉及的多次 Ticket 引用几乎是同时的。但 Trac 对评论发生时间的记录只精确到秒,且不允许在同一时间对同一 Ticket 进行评论。解决的办法是在 HgTracHook 脚本最后的循环末尾加入一句
 time.sleep(1)
人工延时即可。

如果是在 mercurial-server 中通过设置 .hgrc 启用 hook ,可以参考如果在服务器端启用 hook

启用 hook 之后,要检查一下 Trac 所在目录的 log/trac.log 文件的读写权限设置,因为一方面要允许 Trac 向其写日志(Trac 有可能运行在 lighttpd 或者 Apache 下),另一方面又要允许 mercurial-server 在 hook 被触发时通过 trac-admin 指令向其写入信息。所以 trac.log 得对这两种用户都开放写入权限。

2.8  解决 Mercurial 插件乱码问题

如果使用 Mercurial 作为 Trac 的代码库后台以后,浏览非 ASC II 的更新日志和代码内容出现乱码,那么需要设置 conf/trac.ini 文件中的“default_charset = utf-8”,然后重启 Web 服务器即可正常显示。有可能因为 Trac 的运行模式(比如 mod_wsgi 下),这样设置以后仍然乱码,那么就要给 Trac 设置环境变量 “HGENCODING=utf-8”,比如 lighttpd 下看起来可能就像这样:

....
 "bin-environment" =>
     ("TRAC_ENV_PARENT_DIR" => "/var/lib/trac/" ,
     "LC_TIME" => "bg_BG.UTF-8",
     "PYTHON_EGG_CACHE" => "/tmp/.python_eggs",
     "HGENCODING" => "utf-8")
....

参考:Ticket 7217Ticket 7160

----

这个解决乱码的办法能正常工作的前提是 Mercurial 版本库中的所有内容都使用 utf-8 编码(包括文件名、路径名和文件内容)。但有些情况还是可能不小心使用到其他的文件名编码(比如 Windows 就有可能把文件名弄成 GB18030),而这些文件名编码错误的内容会永远存在于 Mercurial 的版本历史中(除了 rollback 之外我还没找到能修改 Mercurial 版本历史的办法,而 rollback 只能回滚本地刚刚完成的仅仅一次提交,这点儿后悔药是不够的。。),导致在 Trac 中浏览源代码时遇到类似下面的错误:

 UnicodeDecodeError: 'ascii' codec can't decode byte 0xd3 in position 15: ordinal not in range(128)

相关的解决办法参考:UnicodeDecodeError when file names in Mercurial repo use multi encoding。这个条目其实是我提交的,其中包含一个很简陋的补丁。

为避免这种编码混乱的情况,参考HgMini#encoding“避免乱码”章节中的提示。

3.  外观定制

定制外观其实应该用 Site Appearance机制 或者 Themes机制。

目前偷懒直接改的 common/css/trac.css ,把 bodymargin 改成了 auto、增加 max-width 并设置为 72em,这样使页面整体不是太宽,在读 Wiki 或者读 Ticket 的时候感觉舒服一些。

4.  功能定制

4.1  更灵活的权限控制

如果是闭源项目使用 Trac ,启用No Anonymous Access,以禁止未登陆用户访问。

svn co http://trac-hacks.org/svn/noanonymousplugin
cd noanonymousplugin/0.11
python setup.py install

从 0.12 版本开始,Fine grained permissions已经内置在主代码树中了,在 Web Admin 的插件管理界面找到“tracopt.perm.authz_policy.*”插件,启用,点加号展开说明,按照说明进行配置即可。

之后为了维护权限方便,继续配置Editor for Fine Grained Authz Permissions File。注意页面上的配置说明,它要求必须设置一个“group_file”变量,指向一个类似 Linux 中 /etc/group 文件格式那样的文件。如果用户组完全由 authz_policy 来控制,那么只要让“group_file”指向一个空文件或者每一行第一个字符都是 # 的文件即可(不能指向不存在的文件,否则访问这个权限编辑器的时候会报错)。注意 authz 配置文件的现有内容格式必须正确,否则无法正常显示当前文件内容。

authz 权限配置文件中内容的顺序是越靠上的设置优先级越高。各种权限的具体含义参见:Trac Permissions

4.2  启用 SectionEdit

在一个 Wiki 页面中内容较多时,对整个页面进行修改会觉得比较麻烦,不但每次传输的数据量过大,而且也很难定位想要修改的位置。一个不错的解决办法是启用SectionEditPlugin,对页面上的每一个章节(Section)单独编辑。

按照该插件主页上的配置说明完成配置后,还要注意插件源码 htdocs 目录下的 js 文件需要能通过“/chrome/tracsectionedit/js/tracsectionedit.js”路径访问到,否则鼠标停在章节标题上的时候,旁边不会出现编辑链接。如果是按照Web 服务器集成章节的配置文件路径配置的,那么只需要把 SectionEditPlugin 源码目录下的 js 目录复制到 Trac 的 htdocs/tracsectionedit 目录下即可。

GlossyBlue theme adapted by David Gilbert
Powered by PmWiki