Home | Info | Research | Blog | Repos | Messages | Contact Me

<!> 이 문서의 저작권은 PYRASIS에게 있고 무단도용시 법적 제재를 받을 수 있습니다. 복사, 재배포, 게시할 수 없으며 링크만 허용합니다. 자신의 블로그에 담고자 할 경우 비공개로 설정해 주시기 바랍니다.


윈도우에서 Subversion과 ViewVC 사용하기

이재홍 http://www.pyrasis.com 2007.2.28 버전 1.0


Subversion의 웹 인터페이스인 ViewVC를 윈도우(Windows)에서 Apache와 mod_python을 이용해서 사용하는 방법을 설명하도록 하겠습니다. (원래는 ViewCVS 였는데 Subversion을 지원하면서 ViewVC로 이름이 바뀌었습니다.)


Contents

1 필요한 파일들
2 프로그램 설치
3 Subversion 저장소 만들기
4 각 프로그램 설정
4.1 diff, enscript, sed 설정
5 한글 설정
6 사용하기

2 프로그램 설치 #

윈도우에서 Subversion과 아파치를 이용한 서버를 구성하는 방법은 SubversionServerForWindows을 참고하세요.

Subversion, Apache, Python, Python extensions for Windows, Subversion Python Bindings, Mod_python은 모두 자동 인스톨러 형식이므로 일반적인 프로그램을 설치하듯이 설치합니다. 단, 설치 경로는 기본 값을 사용합니다

그리고 받은 viewvc-1.0.3.zip를 C:\temp에 압축을 해제합니다.
C:\temp\viewvc-1.0.3\viewvc-1.0.3>c:\python24\python.exe viewvc-install
기본값 대로 설치하면 C:\Program Files\viewvc-1.0.3에 설치됩니다.

3 Subversion 저장소 만들기 #

저장소의 기본 경로는 C:\repos로 하겠습니다.
C:\repos>svnadmin create sample

4 각 프로그램 설정 #

C:\Program Files\Apache Group\Apache2\conf\httpd.conf
LoadModule python_module modules/mod_python.so

ScriptAlias /viewvc "C:/Program Files/viewvc-1.0.3/bin/mod_python/viewvc.py"
<Location /viewvc>
    AddHandler mod_python .py
    PythonPath "[r'C:\\Program Files\\viewvc-1.0.3\\bin\\mod_python']+sys.path"
    PythonHandler handler
    PythonDebug On
    AddDefaultCharset UTF-8
    Options +Includes
</Location>

C:\Program Files\viewvc-1.0.3\viewvc.conf
[general]
# 저장소의 최상위 디렉토리를 설정합니다.
root_parents = c:\repos : svn

# default_root는 주석 처리합니다.
#default_root = cvs

# Subversion이 설치된 경로
svn_path = C:\Program Files\Subversion\bin

[options]
# URL로 저장소를 구분합니다. 
# 이것을 0으로 하면 위의 default_root에서 기본 저장소를 지정해줘야 합니다.
root_as_url_component = 1

# UTC를 사용하지 않고 대한민국 표준시를 사용합니다.
use_localtime = 1

ViewVC의 handler.py 파일의 apache.import_module 부분을 다음과 같이 수정합니다. 이것을 수정하지 않으면 mod_python에서 모듈을 찾지 못하여 ViewVC를 실행할 수 없습니다.
C:\Program Files\viewvc-1.0.3\bin\mod_python\handler.py
def handler(req):
  path, module_name = os.path.split(req.filename)
  module_name, module_ext = os.path.splitext(module_name)
  try:
    #module = apache.import_module(module_name, path=[path])
    module = apache.import_module(module_name, path)
  except ImportError:
    raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND

  req.add_common_vars()
  module.index(req)

  return apache.OK

4.1 diff, enscript, sed 설정 #

diff는 각 리비전간의 차이점을 볼 때 꼭 필요한 프로그램입니다.

enscript는 소스 코드 컬러링(Syntax highlighting)에 필요한 프로그램이며, sed는 enscript로 변환된 html 파일에서 특정 태그를 제거할 때 필요합니다.

diffutils와 ensript, sed는 설치파일 형태이기 때문에 별다른 설정 없이 바로 설치하면 됩니다. 설치경로는 기본값 그대로 합니다.

diff와 sed를 사용하기 위해 시스템 환경변수의 Path에 C:\Program Files\GnuWin32\bin를 추가합니다.

enscript 경로를 설정합니다.
C:\Program Files\viewvc-1.0.3\viewvc.conf
# 0을 1로 수정합니다.
use_enscript = 1

# enscript.exe가 있는 디렉토리를 설정해줍니다.
enscript_path = C:\Program Files\GnuWin32\bin

5 한글 설정 #

ViewVC는 기본적으로 로그는 UTF-8로 표시해주지만 소스코드는 변환없이 그대로 출력합니다. 그래서 윈도우에서 저장한 소스파일은 cp949(euc-kr)이기 때문에 브라우저에서는 깨져서 출력됩니다. 브라우저의 인코딩을 euc-kr로 바꾸면 잘 보이지만 UTF-8로 인코딩된 로그가 깨져서 볼 수 없게 됩니다.

그래서 소스코드도 UTF-8로 변환하도록 ViewVC를 수정해 줘야 합니다. use_localtime을 1로 설정했을 경우 나오는 "대한민국 표준시"도 깨지지 않도록 UTF-8로 변환합니다. 아래는 패치입니다. (버전 1.0.3 기준)
(http://plone.mucius.jp/blog/y2006m02d27e01[] 페이지를 참고하였습니다.)
소스를 직접 수정하기 귀찮으신 분들은 아래 패치가 적용된 handler.py viewvc.py blame.py을 사용하세요.
Index: blame.py
===================================================================
--- blame.py    (revision 5)
+++ blame.py    (working copy)
@@ -34,6 +34,7 @@
 import cgi
 import vclib
 import vclib.ccvs.blame
+import viewvc


 re_includes = re.compile('\\#(\\s*)include(\\s*)"(.*?)"')
@@ -82,7 +83,7 @@
     diff_url = None
     if item.prev_rev:
       diff_url = '%sr1=%s&amp;r2=%s' % (self.diff_url, item.prev_rev, item.rev)
-    thisline = link_includes(cgi.escape(item.text), self.repos,
+    thisline = link_includes(cgi.escape(viewvc.to_utf8(item.text)), self.repos,
                              self.path_parts, self.include_url)
     return _item(text=thisline, line_number=item.line_number,
                  rev=item.rev, prev_rev=item.prev_rev,
Index: viewvc.py
===================================================================
--- viewvc.py   (revision 5)
+++ viewvc.py   (working copy)
@@ -971,6 +971,7 @@
 _re_rewrite_url = re.compile('((http|https|ftp|file|svn|svn\+ssh)
(://[-a-zA-Z0-9%.~:_/]+)((\?|\&amp;)([-a-zA-Z0-9%.~:_]+)=
([-a-zA-Z0-9%.~:_])+)*(#([-a-zA-Z0-9%.~:_]+)?)?)')
 _re_rewrite_email = re.compile('([-a-zA-Z0-9_.\+]+)@(([-a-zA-Z0-9]+\.)+[A-Za-z]{2,4})')
 def htmlify(html):
+  html = to_utf8(html)
   html = cgi.escape(html)
   html = re.sub(_re_rewrite_url, r'<a href="\1">\1</a>', html)
   html = re.sub(_re_rewrite_email, r'<a href="mailto:\1&#64;\2">\1&#64;\2</a>', html)
@@ -1159,7 +1160,16 @@
         time.sleep(1)
         continue
     return chunk
-  
+
+def to_utf8(txt):
+  for enc in ['utf-8', 'euc-kr', 'cp949']:
+    try:
+      u = unicode(txt, enc)
+      return u.encode('utf-8')
+    except UnicodeError:
+      pass
+  return txt
+
 def copy_stream(src, dst=None, htmlize=0):
   if dst is None:
     dst = sys.stdout
@@ -1169,6 +1179,8 @@
       break
     if htmlize:
       chunk = htmlify(chunk)
+    else:
+      chunk = to_utf8(chunk)
     dst.write(chunk)

 class MarkupPipeWrapper:
@@ -1341,7 +1353,7 @@
     return 'Unknown date'
   if cfg.options.use_localtime:
     localtime = time.localtime(date)
-    return time.asctime(localtime) + ' ' + time.tzname[localtime[8]]
+    return time.asctime(localtime) + ' ' + to_utf8(time.tzname[localtime[8]])
   else:
     return time.asctime(time.gmtime(date)) + ' UTC'

6 사용하기 #

이제 아파치를 재시작 하면 ViewVC를 사용할 수 있습니다.
<!> 아파치는 재부팅을 하지 않으면 시스템 환경변수의 Path를 인식하지 못합니다. 그래서 diff, enscript, sed가 제대로 실행되지 않기 때문에 꼭 재부팅을 해줘야 합니다.
<!> ViewVC 소스를 수정하였을 경우 아파치를 재시작 해야 적용이 되며, 그래도 적용이 안될 경우 ViewVC 아래에 있는 확장자가 .pyc 파일을 모두 삭제하면 됩니다.


Login | Title Index | Recent Changes | Edit | Page Info | Search | Subscribe

Copyright © 2003-2009 PYRASIS.COM,. All rights reserved.