天天看點

ReviewBoard安裝和配置劄記



目前部門還沒有采用Pair Programming那種時時刻刻都在review代碼的工作方式,代碼Review多采用走查方式,即代碼寫完後召開一個Code Review的Meeting,集中時間和經驗豐富的人力對重點代碼進行篩查,這種方式的代碼Review有利,但也有弊。其弊端在于低效和覆寫面小。做一次走查需要N多人參與若幹個小時,而在這段時間裡不是每個參與者都能極其高效的參與到走查中的,實踐證明隻有少數幾個人能真正在一次代碼走查會議上起到關鍵的作用。另外走查一次能覆寫的代碼範圍又較小,一些看似不重要卻很可能帶來BUG的代碼在走查會上很容易被遺漏。

Code Review工具對代碼走查是一種很好的補充。目前比較流行的開源Code Review工具有Review Board、CodeStriker等。對于ReviewBoard,我關注已久。在其還在rc階段我就曾經嘗試安裝過,不過無論是在Windows和Unix下都以失敗告終。開源工具的安裝的确有些讓人頭痛,一堆互相依賴的軟體包,版本稍有差異就很可能導緻安裝運作失敗。而且失敗的原因還很難得知。

ReviewBoard今年終于Release了,目前最新版是1.0.3,其官方推薦在Linux和Windows上安裝。我選擇了Ubuntu 9.04。Ubuntu的包管理工具apt最大的好處就是能自動幫你分析開源包的依賴關系并自動下載下傳安裝依賴包。恰巧在CSDN的一個部落格上發現一篇'ReviewBoard on Ubuntu 9.04 Server'的安裝步驟,我就按照文章中的步驟超級順利的完成了ReviewBoard的安裝,這裡我也将其步驟貼出來,并做一些簡單注釋(有些地方略有不同):

我是在Ubuntu 9.04 Desktop上安裝的,這個版本預設自帶Gcc、Python等軟體包。我們隻需安裝其他工具:(如果你是通過公司代理上外網,别忘了在你的Shell配置檔案中設定http_proxy環境變量,格式是:export http_proxy=http://user:[email protected]:port)

1、安裝easy_install

sudo apt-get install python-setuptools python-dev;

2、安裝apache2和mod_python

sudo apt-get install apache2 libapache2-mod-python

sudo a2enmod python

3、安裝mysql

sudo apt-get install mysql-server python-mysqldb libmemcache-dev

sudo easy_install http://gijsbert.org/downloads/cmemcache/cmemcache-0.95.tar.bz2

建立資料庫、資料庫使用者for ReviewBoard(這塊要注意資料庫的字元集設定,預設是UTF-8,如果你要用其他中文字元編碼标準,這裡就需要顯式指定,查查mysql的Manual吧)

mysql -u root -p 

mysql> create database reviewboard;

Query OK, 1 row affected (0.00 sec)

mysql> create user 'reviewboard'@'localhost' identified by 'reviewboard'; 

Query OK, 0 rows affected (0.00 sec)

mysql> grant all on reviewboard.* to 'reviewboard'@'localhost'; 

Query OK, 0 rows affected (0.00 sec)

mysql> exit

4、安裝subversion (目前大多數公司都用subversion)

sudo apt-get install patch subversion python-svn

5、安裝reviewboard

sudo easy_install reviewboard

6、建立你的reviewboard站點

sudo rb-site install /var/www/reviewboard  

    · Domain = localhost

    · Root Path = /

    · Media URL = media/

    · Database Type = mysql

    · Database Name = reviewboard

    · Database server = localhost

    · Database username = 'reviewboard'

    · Database password = 'reviewboard'

    · Cache Type = memcache

    · Memcache Server = memcached://localhost:11211/

    · Webserver = apache

    · Python loader = modpython

7、配置站點,啟動Apache2

sudo chown -R www-data /var/www/reviewboard/htdocs/media/uploaded

sudo cp /var/www/reviewboard/conf/apache-modpython.conf /etc/apache2/sites-available/reviewboard

sudo a2dissite default

sudo a2ensite reviewboard

sudo /etc/init.d/apache2 restart

在你的浏覽器裡敲入:http://localhost:80,ReviewBoard的登入界面就會出現在你的面前。

順利安裝完ReviewBoard後,你可以到官網去看Manual,學習如何使用ReviewBoard。簡單說ReviewBoard支援兩種Review Code的模式,一種是在code沒有commit之前送出diff/patch檔案進行review,叫做pre-commit review,另外一種則是在code commit之後,由工具自動根據送出的版本号生成diff/patch檔案,并形成一條新的Review Request,這種模式也叫post-commit review。

先說pre-commit review模式。生成pre-commit review request有兩種方法,第一種就是通過頁面手工送出patch/diff檔案的方法:首先通過界面設定好你的svn repository,比如:svn://10.1.1.23:3344;然後在你的DashBoard中“New Review Request",有三個字段需要你填寫:

Repository:    

Base Diff Path:

Diff:

填好後,送出,這時你就會看到一個處于draft狀态的Request,繼續編輯它,指定Reviewer,然後Publish這個Request,這樣你指定的Reviewer就能看到這個Request了。這塊如果你設定了Email通知,Publish過程會有一定延遲,特别是如果你的Email設定出錯了,那Publish将一直處于ing狀态,你重新整理一下頁面後,實際上你的Request已經publish結束了。

另外一種送出pre-commit review request的方法是通過一個名為'Post-Review'的python腳本實作的。這個腳本在RBTools工具包中,在使用之前先執行:'sudo easy_install -U RBTools'安裝這一腳本。

Post-Review需要知道兩類資訊,一個是ReviewBoard Server的資訊, 一個是你的svn repository的資訊,第一種資訊我們可以通過編輯~/.reviewboardrc,添加一行REVIEWBOARD_URL="http://localhost:80"。至于svn repository的資訊,post-review腳本可自動從你本地checkout出的代碼working copy中攜帶的repository資訊中獲得,前提你要進入到該working copy所在的目錄下去執行post-review。比如:你将svn://10.1.1.23:3344/trunk/testproj checkout到~/proj/testproj下面,那麼你就應該先cd ~/proj/testproj後再執行post-review,post-review工具在預設情況下會将目前本地代碼uncommitted的changes形成一個review request并送出到reviewboard server。你也可以在post-review後面加上檔案名字來指定将特定的檔案的changes而不是目前項目目錄下所有的uncommitted changes。

下面是我配置和執行Post-review出現的一些問題和解決方法:

首次在testproj下執行'sudo post-review',出現如下列印日志:

Traceback (most recent call last):

  File "/usr/local/bin/post-review", line 5, in <module>

    pkg_resources.run_script('RBTools==0.2beta1', 'post-review')

  File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 448, in run_script

    self.require(requires)[0].run_script(script_name, ns)

  File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 1166, in run_script

    execfile(script_filename, namespace, namespace)

  File "/usr/local/lib/python2.6/dist-packages/RBTools-0.2beta1-py2.6.egg/EGG-INFO/scripts/post-review", line 2314, in <module>

    main(sys.argv[1:])

  File "/usr/local/lib/python2.6/dist-packages/RBTools-0.2beta1-py2.6.egg/EGG-INFO/scripts/post-review", line 2292, in main

    server.login()

  File "/usr/local/lib/python2.6/dist-packages/RBTools-0.2beta1-py2.6.egg/EGG-INFO/scripts/post-review", line 308, in login

    'password': password,

  File "/usr/local/lib/python2.6/dist-packages/RBTools-0.2beta1-py2.6.egg/EGG-INFO/scripts/post-review", line 570, in api_post

    return self.process_json(self.http_post(path, fields, files))

  File "/usr/local/lib/python2.6/dist-packages/RBTools-0.2beta1-py2.6.egg/EGG-INFO/scripts/post-review", line 481, in process_json

    rsp = simplejson.loads(data)

  File "/usr/local/lib/python2.6/dist-packages/simplejson-2.0.9-py2.6-linux-i686.egg/simplejson/__init__.py", line 307, in loads

    return _default_decoder.decode(s)

  File "/usr/local/lib/python2.6/dist-packages/simplejson-2.0.9-py2.6-linux-i686.egg/simplejson/decoder.py", line 335, in decode

    obj, end = self.raw_decode(s, idx=_w(s, 0).end())

  File "/usr/local/lib/python2.6/dist-packages/simplejson-2.0.9-py2.6-linux-i686.egg/simplejson/decoder.py", line 353, in raw_decode

    raise ValueError("No JSON object could be decoded")

ValueError: No JSON object could be decoded

這種錯誤資訊弄得我一頭霧水,在Google上找了半天,也沒有什麼好的辦法。在ReviewBoard的issue archive裡有人遇到了和我一樣的問題,而ReviewBoard的維護人員建議:修改/usr/local/lib/python2.6/dist-packages/RBTools-0.2beta1-py2.6.egg/EGG-INFO/scripts/post-review中的代碼(在/usr/local/lib/python2.6/dist-packages下你可能會發現RBTools-0.2beta1-py2.6.egg是個檔案而不是目錄,不要緊,.egg檔案就是一個zip檔案,可将其用unzip指令解壓後再放到一個名為RBTools-0.2beta1-py2.6.egg的目錄中即可,解壓後原始RBTools-0.2beta1-py2.6.egg做好更名和備份),在process_json method開始處加上一行代碼:debug(data)。然後在執行post-review時加上--debug選項,觀察http post的response資料。

按照網上的建議做了修改:執行sudo post-review --debug,果然有效果,能看到http post後傳回的應答内容,居然是公司代理伺服器websense的攔截應答。

哇,原來如此,我的.bashrc配置了http_proxy,似乎post-review是向代理發出的http post請求,結果被代理攔截掉了。注釋掉.bashrc中的http_proxy變量後,再重複執行post-review指令,這下一切ok了,一個New Review Request成功生成。

第二種模式post-committed review同樣是通過post-review工具完成的。指令格式:post-review --revision-range=STARTREV[:STOPREV]。腳本會自動diff兩個revision之間的差别并形成review request送出到reviewboard server的。

關于post-review的更多用法,這裡不細說了,可閱讀官方的Manual。ReviewBoard功能還是很強大的,Review時你可以針對每行代碼寫Comments,這種Review Code的方式給你足夠時間去思考,隻要你認真對待,就不會出現盲區、死角,是以新送出的代碼就都能被Review到。

注:安裝reviewboard時,遇到一個問題, 使用easy_install不能下載下傳ftp://ftp.tummy.com/pub/python-memcached/old-releases/python-memcached-1.45.tar.gz。 但是能通過浏覽器或者curl下載下傳該壓縮包。

解決方法:

先通過curl下載下傳該包。在使用easy_install -f . python-memcached-1.45.tar.gz 進行離線安裝。

然後再執行reviewboard的easy_install.