svn 的hook機制方便了使用者根據svn動作自訂一些操作,post-commithook是當使用者執行commit後執行的使用者自訂動作。如使用者commit後,自動調用post-commit hook script群發郵件到項目組。實現過程是Commit後post-commithook 自動調用,發送郵件。
我自己寫了一個功能簡單的sendmail.py來輔助發送郵件。
現在關注一下主要的實現:post-commit, sendmail.py
post-commit的內容如下:
# REPOS-PATH (the path to this repository)REPOS="$1"# REV (the number of the revision just committed)REV="$2"LANG=zh_CN.GB18030#沒有這句不起作用export LANGHOOK_DIR=/root/gaoyj/test_repo/hooksSVNLOOK_BIN=/usr/local/subversion/bin/svnlookPYTHON_BIN=/usr/bin/python${PYTHON_BIN} ${HOOK_DIR}/sendmail.py ${REPOS} ${REV}
有以下注意事項:
(1)svn調用post-commit時,傳遞了兩個參數: REPOS-PATH(Repository路徑)和REV版本號碼
(1) 如果收到郵件中,無法顯示中文,應在post-commit中設定環境變數LANG並且export
(2) post-commit執行時,無法獲得PATH變數的值,所以script中應使用絕對路徑
(3) 將Repository的hook目錄下post-commit.tmpl改為post-commit(windows下改為post-commit.bat),並賦予執行許可權。
sendmail.py的原理是通過調用svnlook獲得提交資訊(版本號碼、提交時間、提交者、commitlog,發生變更的檔案),內容如下:
#coding: gb2312import sysimport osimport smtplibfrom email.mime.text import MIMETextmail_host = 'smtp.example.com' #發送郵件的smtp地址mail_user = 'example' # 發送通知訊息的使用者名稱mail_pass = 'example_passwd' # 使用者的密碼me = 'Example' + '<' + 'example' + '@' + 'example.com' + '>' #發送郵件人的地址標識to_list = ['person_a@example.com', 'person_b@example.com', 'person_c@example.com'] # 收件者html_template = """<html> <h2 style="color:#FFFFFF; background: #008040;">基本資料</h2> <div> <b>版本庫:</b> <a href="svn:%s">%s</a> </div> <div> <b>版本號碼:</b>%s </div> <div> <b>提交者:</b>%s </div> <div> <b>提交時間:</b>%s </div> <h2 style="color:#FFFFFF; background: #4682B4;">提交說明</h2> <font size="4" color="#BF6000"><xmp>%s</xmp></font> <h2 style="color:#FFFFFF; background: #5353A8;">檔案清單</h2> <xmp>%s</xmp> <hr> <center> ☆ Powered by <a href="http://garyelephant.me">Gary</a> </center> <center> ☆ Inspired by <a href="http://crearo-sw.blogspot.com">CREARO-SW</a> </center></html>"""def write_mail_content(repo, rev): """ repo: repository rev: revision """ repo_name = get_repo_name(repo) author = get_author(repo, rev) date = get_date(repo, rev) log = get_log(repo, rev) file_list = get_file_list(repo, rev) content = html_template % (repo, repo_name, rev, author, date, log, file_list return contentdef get_repo_name(repo): return os.path.basename(repo)def get_author(repo, rev): """svnlook author -r REV REPOS 獲得提交者 """ cmd = '%s author -r %s %s' % (svnlook_bin_path, rev, repo) output = os.popen(cmd).read() return outputdef get_date(repo, rev): """svnlook date -r REV REPOS 獲得提交時間 """ cmd = '%s date -r %s %s' % (svnlook_bin_path, rev, repo) output = os.popen(cmd).read() return outputdef get_log(repo, rev): """svnlook log -r REV REPOS 獲得提交日誌 """ cmd = '%s log -r %s %s' % (svnlook_bin_path, rev, repo) output = os.popen(cmd).read() return outputdef get_file_list(repo, rev): """svnlook changed -r REV REPOS 獲得發生變更的檔案 """ cmd = '%s changed -r %s %s' % (svnlook_bin_path, rev, repo) output = os.popen(cmd).read() return outputdef send_mail(msg, sender, to_list): try: s = smtplib.SMTP() s.connect(mail_host) s.login(mail_user,mail_pass) s.sendmail(sender, to_list, msg.as_string()) s.close() return True except Exception, e: print str(e) return Falsedef write_mail(sender, to_list, sub, content): msg = MIMEText(content, _subtype = 'html', _charset='gb2312') msg['Subject'] = sub msg['From'] = sender msg['To'] = ';'.join(to_list) return msgglobal svnlook_bin_pathif __name__ == '__main__': svnlook_bin_path = '/usr/local/subversion/bin/svnlook' subject = 'SVN Commit Notification' content = write_mail_content(sys.argv[1], sys.argv[2]) msg = write_mail(me, to_list, subject, content) send_mail(msg, me, to_list)
有以下注意事項:
(1)發送通知訊息使用者的密碼是明文儲存的,存在安全隱患
(2)用os.popen調用svnlook需要使用svnlook的絕對路徑
源碼託管在Github上:https://github.com/garyelephant/SVN-Hooks
References:
[1] SVN伺服器與用戶端Hooks指令碼的使用http://scmbob.org/subversion-hooks-windows.html
[2] O'Reilly Media 出版的Subversion與版本控制,http://svnbook.red-bean.com/
[3] Subversion Hooks,
http://www.worldhello.net/doc/svn_hooks/svn_hooks.mm.htm
[4]
A SubversionPre-Commit Hook
http://wordaligned.org/articles/a-subversion-pre-commit-hook
[5]
Svn hookencoding problem
http://stackoverflow.com/questions/2213670/svn-hook-encoding-problem
轉載本文請註明作者和出處[Gary的影響力]http://garyelephant.me,請勿用於任何商業用途!
Author: Gary Gao( garygaowork[at]gmail.com) 關注互連網、分布式、高效能、NoSQL、自動化、軟體團隊