%
% gate-toroku-system cvs リポジトリ作成メモ
%
%    履歴  森川 靖大  2004/10/10  いまさらながら作成
%

以下は, gate-toroku-system
の CVS リポジトリを作成した際のメモ書きである.

■ CVS に関する情報源

   CVS のポリシーや設定, 使い方に関する情報に関しては
   CVS に関するメモ や,  gate システム 開発での CVS 利用の手引き を参照のこと

■ 前提

   リポジトリを作成するホストには cvs ソフトウェアが入っている
   必要がある. Debian ならば以下のパッケージが必要である

   

   
■ ポリシー

   ・ gate-toroku-system のリポジトリはホスト www.ep.sci.hokudai.ac.jp の
      /home/gate/cvsroot に作成する

   ・ gate-toroku-system のリポジトリ内のファイルを編集可能なのは,
      www.ep.sci.hokudai.ac.jp にアカウントを持ち (ssh で www.ep.sci.hokudai.ac.jp
      にログインでき), gate グループに入っているユーザのみとする.

   ・ コミット時には gate ユーザにメールを送信する.
      - 本来は開発グループの全員にメールを送るべきであろう.
        gate ユーザにメールを送るのは, gate に送られたメールが
        gate グループ全員に送られるような設定が別途なされている
        からである.

   ・ gate-toroku-system のリポジトリ内のテキストデータの日本語文字コードは EUC
      とする. (単にプラットフォームが Linux で, その標準文字コードが
      EUC であるという理由に基づいているのみである).

   ・ 上記と同様に, commit 時のログメッセージに関しても, 英字または
      EUC の日本語のみとする.

■ 参考資料

   以下の作業は概ね以下の資料を参考におこなった.
   もしも作業の際に分からないことがあったり, より詳細なことを
   知りたい場合には参照して頂きたい.

     カール フォーゲル (著), バー モシュ (著), Karl Franz Fogel (原著),
        Moshe Bar (原著), 竹内 里佳 (翻訳), でびあんぐる (翻訳), 2002:
        CVSによるオープンソース開発.
        [Open Source Development with CVS, Second Edition].
        オーム社, ISBN: 4274064735, 380 pp.


■ CVS リポジトリ作成

   ※ 以下のリポジトリ作成に関しては一回こっきりで良いため,
      既に作成済みである場合には下の「■ プロジェクト開始」
      へ行って欲しい.

   GATE の CVS リポジトリは www.ep.sci.hokudai.ac.jp の
   /home/gate/cvsroot に作成する.
   そのためにはまず www.ep.sci.hokudai.ac.jp へログインする.

     $ ssh www.ep.sci.hokudai.ac.jp

   ログインしたら /home/gate/ まで移動する.

     $ cd /home/gate/

   ここで cvs コマンドを実行すれば cvsroot を作成可能であるが,
   グループでの開発であることを考え, 作成するファイルのグループが
   gate となるように, そしてグループに書き込み権限を与えるように
   グループと環境変数を変更する.

     $ sg gate
     $ umask 002

   現在のグループは id コマンドで, umask は umask コマンドで知ることが
   できる. 準備が出来たら以下のコマンドを実行する.

     $ cvs -d /home/gate/cvsroot init

   これで cvsroot ディレクトリが作成されたはずである.


■ グループ書き込み許可の設定

   上記で umask などの設定をおこなったものの, s ビットを立てるなど,
   パーミッションの設定が必要となる. また cvs init コマンドで
   作成したディレクトリやファイルの中にはグループ書き込み権限が
   無いものもあるので, 以下で設定する.

   □ リポジトリ cvsroot パーミッションの設定

      cvsroot 以下で作成されるファイル, ディレクトリのグループを
      gate にするため, cvsroot に s ビットを立て, 書き込み権限を
      与える. 念のためにグループも gate に設定する.
   
        $ chmod g+s cvsroot
        $ chmod g+w cvsroot
        $ chgrp gate cvsroot
   
   □ 管理用ディレクトリ CVSROOT 内のパーミッションの設定

      cvsroot が作成されれば, そのリポジトリに関する CVS の動作を
      制御する CVSROOT ディレクトリも作成されているはずである.

      このディレクトリ, およびそれ以下の特定のファイルに関して
      グループの変更と書き込み権限変更をおこなう.

      ・ CVSROOT ディレクトリ本体

         グループを gate とし, グループに書き込み権限を与える.
         (これは少しアンセキュアな方針かもしれない. よりセキュアな
         方法として, 代表的な管理者 1 人にのみ書き込み権限を与える
         という方針もあり得るだろう).

           $ cd cvsroot
           $ chgrp gate CVSROOT
           $ chmod g+s CVSROOT
           $ chmod g+w CVSROOT

      ・ history, val-tags へグループ書き込み権限を与える

         CVSROOT 以下にある history, val-tags にグループ書き込み権限
         を与える. (グループは既に gate であると仮定している).

         なお, history とはこのリポジトリ以下のプロジェクトに対して
         行なわれた checkout, commit, rtag, update, release を記録
         しているファイルである. cvs history コマンドで見ることが出来る.
         (動作の詳細は cvs history -x コマンドを参照のこと).
         ここではグループ gate で開発することを念頭に置くため,
         グループに書き込み権限を与えておく.

           $ cd CVSROOT
           $ chmod g+w history

         val-tags は検索を高速化するために, 有効なタグ名をキャッシュ
         しているファイルである. GATE プロジェクトではタグも使用するので,
         これにもグループ書き込み権限を与える.

           $ chmod g+w val-tags

      
■ プロジェクト開始

   プロジェクトを開始する. そのために, まずは cvsroot を指定する
   環境変数 CVSROOT と www.ep.sci.hokudai.ac.jp へのアクセス方法を指定する
   環境変数 CVS_RSH を設定する.
   (これらを指定しなくともコマンドに直接指定する方法もある).

     $ export CVSROOT=:ext:www.ep.sci.hokudai.ac.jp:/home/gate/cvsroot
     $ export CVS_RSH=ssh

   なお, www.ep.sci.hokudai.ac.jp 内で作業をおこなう場合には

     $ export CVSROOT=/home/gate/cvsroot

   のみでも構わない.
  
   次に, プロジェクトとして含むファイル群の位置まで移動する.
   仮に /home/morikawa/gate 以下にプロジェクトのソース,
   ドキュメントなど全て含めて置いてあるならば, まず
   そこへ移動する.

     $ cd /home/morikawa/gate

   ここで cvs import コマンドを実行するとカレントディレクトリを先頭
   として全てのファイルがインポートされる. 余計なファイルは全て
   消しておくこと. ( .*** ファイルは ls では見えないので ls -a で
   ちゃんと探すこと).

   掃除が終ったらプロジェクトを開始させる.
   開始は以下のコマンドでおこなう.

     $ cvs import -m \
       "gate-toroku-system " gate-toroku-system gate Initial
                        ↑            ↑        ↑    ↑
                      コメント   プロジェクト名 | リリースタグ
                                      ||        |
                                 ディレクトリ名 |
                                               ベンダー

   「No conflicts created by this import」 というような
   メッセージが出れば, インポート成功.

   
■ プロジェクトのパーミッションの確認

   プロジェクトのディレクトリのパーミッションを確認しておく.

     $ ssh www.ep.sci.hokudai.ac.jp
     $ cd /home/gate/cvsroot
     $ ls -l
     drwxrwsr-x    3 morikawa gate          53  8月 31 19:40 gate-toroku-system/

   上記のようにグループが gate で権限が rws の場合は問題ない.
   もしそうでないのなら, 以下のコマンドでグループとパーミッションを
   変更すること.

     $ chgrp gate gate-toroku-system
     $ chmod g+s gate-toroku-system
     $ chmod g+w gate-toroku-system

   なお, もしも gate-toroku-system が上記のようなパーミッションになっていなかった
   場合, それよりも下層ディレクトリのパーミッションもそれと同様な
   可能性がある. それらに関してもグループとパーミッションを設定すること.

     ※ プロジェクト以下にある「ファイル」に関しては (グループは gate
        である必要があるが) パーミッションは -r--r--r--
        で問題ない. cvs コマンドを介せば, 正しく commit, add, remove
        などが可能である.

     
■ コミット時には gate ユーザにメールを送信する

   以下では, コミット時にユーザにメールを送信するための設定を記す.

   □ CVSROOT のチェックアウト

      コミット時にメールを送信するためにはリポジトリ以下の
      CVSROOT ディレクトリの loginfo を編集する必要がある.
      直接書き換えることも不可能ではないが, ちゃんとしたお作法として,
      まず CVSROOT をチェックアウトする.
      チェックアウトの方法はその他のプロジェクトと同様である.

        $ export CVSROOT=:ext:www.ep.sci.hokudai.ac.jp:/home/gate/cvsroot
        $ export CVS_RSH=ssh
        $ cd <適当なディレクトリ>
        $ cvs checkout CVSROOT

      すると, CVSROOT ディレクトリが展開される.

   □ cvsform.pl の追加

      あまり難しいことをしなくても, 数行 loginfo に加えるだけでコミッ
      トメールを出すことは可能だが, より見やすいログメッセージを出すべ
      く cvsform.pl を作成する. これは gtool4 開発時に toyoda さんが作
      成した cvsdiff.pl を改造したものである.

      以下に, cvs add した cvsfrom.pl を記しておく. (動作未保証)
      (最新版は CVSROOT をチェックアウトして調べて欲しい).

      ================================================================
      #!/usr/bin/perl
      #
      # cvsform.pl by Morikawa Yasuhiro, 2004
      #   original is cvsdiff.pl by TOYODA Eizi, 2001
      
      $mailto0 = 'foo@gfd-dennou.org';
      $project = 'hoge0';
      $charcode = 'iso-2022-jp';
      
      # umask 0;
      # open(LOG, ">/tmp/cvsform.tmp");
      
      $mailto = $ARGV[0] || $mailto0;
      $loginfo = $ARGV[1];
      $user = $ENV{'USER'} || $ENV{'LOGNAME'} || $<;
      
      # GMT Time
      ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);
      $date = sprintf("%04d-%02d-%02dT%02d:%02d-00:00",
      		$year + 1900, $mon + 1, $mday, $hour, $min);
      
      # # Local Time (Assume Japan Time)
      # ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
      # $localdate = sprintf("%04d-%02d-%02dT%02d:%02d+09:00",
      # 		     $year + 1900, $mon + 1, $mday, $hour, $min);
      
      open(MAIL, "|nkf|/usr/lib/sendmail $mailto"); # convert to JIS
      select(MAIL);
       print <) {
          s/\x0D\x0A|\x0D|\x0A/\n/g;  # convert each OS linefeed code to "\n"
          print;
      }
      
      close(MAIL);
      ================================================================

      これを cvs add, cvs commit で CVSROOT に追加する.

        $ cvs add cvsform.pl
        $ cvs commit -m "Format Messages of commit mail." cvsform.pl


   □ CVSROOT 内に cvsform.pl を作成するために

      cvsform.pl を commit したことで, CVSROOT 内に cvsform.pl,v が
      作成されたはずである. しかしこのままでは, CVSROOT 内に 
      cvsform.pl が存在しないので, 本来の役目を果たせない.
      よくよく CVSROOT 内を見ると,

        $ cd cvsroot/CVSROOT
        $ ls -l

        Emptydir/       cvsform.pl,v   loginfo,v  taginfo
        checkoutlist    cvswrappers    modules    taginfo,v
        checkoutlist,v  cvswrappers,v  modules,v  val-tags
        commitinfo      editinfo       notify     verifymsg
        commitinfo,v    editinfo,v     notify,v   verifymsg,v
        config          history        rcsinfo
        config,v        loginfo        rcsinfo,v

      のようにファイルの作業用コピーが RCS リビジョン (****,v) ファイル
      と並んで含まれているのが分かる. CVSROOT という管理ディレクトリの
      特殊機能として, RCS リビジョンを cvs コマンドによって更新すると
      作業用コピーもアップデートされるようになっているのである.

      cvsform.pl もこのようにするには checkoutlist にそのファイルを
      追加すると良い. この場合の更新も, 先と同様, CVSROOT を checkout
      し, その中の checkoutlist を更新し, commit すると良い.

        $ export CVSROOT=:ext:www.ep.sci.hokudai.ac.jp:/home/gate/cvsroot
        $ export CVS_RSH=ssh
        $ cd <ローカルの適当なディレクトリ>
        $ cvs checkout CVSROOT
        $ cd CVSROOT
        $ emacs checkoutlist

      以下の一行を追加する

        cvsform.pl        unable to check out / update cvsform.pl in CVSROOT

      行頭はファイル名, 空白を挟んだ後半がチェックアウトできない場合に
      表示されるエラーメッセージである. 編集が終ったら commit する

        $ cvs ci -m "Add cvsform.pl" checkoutlist

      こうすることで, commit が完了されると共に, メッセージ

        cvs server: Rebuilding administrative file database

      にもあるように, CVSROOT 以下のファイルがリビルドされ,
      cvsform.pl,v から cvsform.pl が作成される. 今後, cvsform.pl
      を commit する毎に, CVSROOT 以下の cvsform.pl も更新される.
      

   □ loginfo の編集 (プロジェクトと宛先の設定)

      最後に loginfo を編集する. ここに, 各々のプロジェクト名と
      宛先を設定する. cvsform.pl を作成したので, 以下のように
      記述する.

        gate-toroku-system  perl $CVSROOT/CVSROOT/cvsform.pl gate@ep.sci.hokudai.ac.jp %{sVv}
        DEFAULT perl $CVSROOT/CVSROOT/cvsform.pl gate@ep.sci.hokudai.ac.jp %{sVv}

      これにより, gate-toroku-system プロジェクトで行なわれた変更は
      gate@ep.sci.hokudai.ac.jp 宛てに送られる. また, それ以外のプロジェクト
      を立ち上げた場合も gate@ep.sci.hokudai.ac.jp に送られる.
      もしも新しくプロジェクトを始めたならば, 同じように記述すると
      良いだろう.

      以上で作業は終了である. 実際のメール配送に関しては gate-toroku-system
      プロジェクト以下のファイルを commit してみて確認して欲しい.


■ バイナリデータの扱い

   CVS は $Revision$ などというような特殊な文字列を $Revision: 1.3 $
   のように置き換えたり, 改行コードを LF 形式に置き換えたりするように
   なっている. これは便利な機能の1つなのだが, バイナリデータなどで
   偶然こういった文字列と認識されて置き換えられると, 結果的に
   データが壊れてしまう. そのため, ある拡張子のデータに関しては
   バイナリデータと取り扱うようにする. これには CVSROOT 以下の
   cvswrappers に以下のような記述を加えると良い.

      *.gif -k 'b'
      *.GIF -k 'b'
      *.jpg -k 'b'

   こうすることで, 拡張子が gif, GIF, jpg のものに関してはバイナリ
   データと扱われ, 文字列の置換が行なわれなくなる.
   (これは開発者個々人が cvs add する際に -kb オプションを付けるのと
   同じ効果を発揮する.)


■ ファイルの文字コードチェック

   上記ポリシーで「日本語文字コードは EUC」としていたが, 各ユーザの
   開発環境を完全に EUC にすることは難しく, Shift-JIS などで
   commit されてしまう可能性がある. よって, EUC 以外のデータに
   関しては, commit されないように設定する.
   改行コードは CVS の仕様で自動的に UNIX 形式 (LF 形式) に
   変換されるので, ここでは気にしないことにする.
   

   □ 文字コードチェック用 Perl スクリプト kanjichecker.pl

      以下では, 文字コードのチェック用の Perl スクリプトを作成する.

      以下に, 2004/09/04 現在利用される kanjichecker.pl を記しておく.
      (最新版は CVSROOT をチェックアウトして調べて欲しい).

      ================================================================
      #!/usr/bin/perl
      #
      # kanjichecker.pl by Morikawa Yasuhiro, 2004
      
      require "jcode.pl";
      $correct_default = 'euc';  # 'euc' or 'sjis' or 'jis'
      
      if ($#ARGV < 2){
          die "Usage: kanjichecker.pl [euc|sjis|jis] dir filename\n";
      }
      
      $current = $ARGV[0] || $current_default;
      $dir     = $ARGV[1];
      $file    = $ARGV[2];
      
      # if file was removed already, check isn't need.
      unless (-f $file) {
          exit 0;
      }
      
      open(FILE, "<$file")
          || die "$file: cannot open for reading.";
      
      while () {
          undef $code;
          $code = &jcode::getcode(\$_);
          if ($code eq 'binary') {
              exit 0;
          } elsif (! $code ) {
              next;
          } elsif ($code eq $current) {
              next;
          } else {
              die "$file include $code, current code is $current.\n";
          }
      
      
      exit 0;
      ================================================================
   
      これを前回同様 CVSROOT に commit する.
      
        $ cvs add kanjichecker.pl
        $ cvs commit -m "Kanji code checker." kanjichecker.pl

      また, checkoutlist に以下の一行を加え, それもまた commit する.

          kanjichecker.pl   unable to check out / update kanjichecker.pl in CVSROOT

        $ cvs commit -m "Add kanjichecker.pl" checkoutlist


   □ commitinfo にフィルターを設定

      commitinfo に以下のように記述する.

        ALL       perl $CVSROOT/CVSROOT/kanjichecker.pl euc

      これにより, Shift-JIS や JIS コードのファイルは commit
      出来ないようになる.

      もしも sjis や jis コードのファイルを commit しようとすると
      以下のようなメッセージが返る.

      === cd /home/morikawa/GATE/gate-toroku-system/
      === /usr/bin/cvs commit -m 'This is test.' cvs_test.txt

      cvs_test.txt include sjis, current code is euc.
      cvs server: Pre-commit check failed
      cvs [server aborted]: correct above errors first!
      === Exit status: 1


■ ログメッセージの文字コードチェック

   上記の手法だと書き換えられるファイル本体の文字コードのチェックは
   可能だが, ログメッセージの文字コードのチェックが出来ない.
   RCS ファイルには本体もログメッセージも両方書き込まれていることから,
   文字コードは本体と一致させたい. また, リビジョン毎にメッセージの
   文字コードが違うのは気持ち悪いので, それも単一の文字コード
   (ここでは EUC) にする.

   □ ログメッセージ文字コードチェック用 Perl スクリプト msgchecker.pl

      以下では, ログメッセージの文字コードのチェック用の Perl
      スクリプトを作成する.

      以下に, 2004/09/03 現在利用される msgchecker.pl を記しておく.
      (最新版は CVSROOT をチェックアウトして調べて欲しい).

      なお, 上記の kanjichecker.pl と異なるのは,

        1) 2 つ目の引数をファイル名として取る
        2) バイナリファイルに対してはエラーを返す
        3) ASCII 文字のみ (一切日本語を入れてはダメ) 制限が可能

      ================================================================
      #!/usr/bin/perl
      #
      # msgchecker.pl by Morikawa Yasuhiro, 2004
      
      require "jcode.pl";
      
      if ($#ARGV < 1){
          die "Usage: msgchecker.pl [ASCII|euc|sjis|jis] file\n";
      }
      
      $logcode = $ARGV[0];   # 'ASCII', 'euc', 'sjis', 'jis'.
      $msg     = $ARGV[1];
      
      if (!$logcode){
          $logcode = 'ASCII';
      }
      
      open(MSG, "<$msg")
              || die "$msg: cannot find log message.";
      
      while () {
          undef $code;
          $code = &jcode::getcode(\$_);
          if ($code eq 'binary') {
              die "log message is $code , Please write log message ASCII.\n"
                  if ($logcode eq 'ASCII');
              die "log message is $code , Please write log message ASCII or $logcode .\n";
          } elsif (! $code ) {
      	next;
          } elsif ($code eq $logcode) {
      	next;
          } else {
              die "log message is $code , Please write log message ASCII.\n"
                  if ($logcode eq 'ASCII');
              die "log message is $code , Please write log message ASCII or $logcode .\n";
          }
      }
      
      close(MSG);
      
      exit 0;
      ================================================================

      これを前回同様 CVSROOT に commit する.
      
        $ cvs add msgchecker.pl
        $ cvs commit -m "log message code checker." msgchecker.pl

      また, checkoutlist に以下の一行を加え, それもまた commit する.

          msgchecker.pl   unable to check out / update msgchecker.pl in CVSROOT

        $ cvs commit -m "Add msgchecker.pl" checkoutlist

   □ verifymsg にフィルターを設定

      verifymsg に以下のように記述する.

        gate-toroku-system perl $CVSROOT/CVSROOT/msgchecker.pl euc
        DEFAULT            perl $CVSROOT/CVSROOT/msgchecker.pl ASCII


      これにより, gate-toroku-system プロジェクトに対しては ASCII or euc の
      ログメッセージが許可され, その他のプロジェクトに対しては
      ASCII のみが許可されるようになった.

      もしも sjis や jis コードのログメッセージで commit しようとすると
      以下のようなメッセージが返る.

      === cd /home/morikawa/GATE/gate-toroku-system/
      === /usr/bin/cvs commit -m 'テスト' cvs_test.txt

      log message is sjis , Please write log message ASCII or euc .
      cvs [server aborted]: Message verification failed
      === Exit status: 1