ひきこもりプログラマ

C++のこととか。

Visual SourceSafeからPerforceに移行する

2014-06-19 | Software

VSSのデータベースをPerforceのレポジトリに変換するにはVSSToP4というユーティリティを使います。このユーティリティは

  • 基本処理が書かれたPerlスクリプト
  • PerlからPerforceのコマンド(P4コマンド)を実行するためのPerlライブラリP4Perl

から構成されています。公開されているスクリプトでじっさいに移行を試みたところ,いくつか問題が発生したので,解決策をメモしておきます。

国際語モードへの対応

スクリプトを実行してすぐに

Unicode server permits only unicode enabled clients.

と出力された場合,Perforceサーバが国際語モード(internationalized mode)で動作しているのにクライアント側がそれに対応していないのが原因かもしれません。国際語モードに関する注意英語版)に書かれているように,サーバ側はメタデータをUTF8で管理するので,クライアント側ではそれをどの文字コードに変換して表示すればいいかを指定してやる必要があるのです。

この指定には通常は環境変数P4CHARSETを使うのですが,P4Perlは実行環境の環境変数を引き継がないようで,明示的に指定してやる必要があります。P4PerlでPerforceコマンドを実行するときはP4オブジェクトを生成することになっており,これが生成されるのは

  • convert.pl
  • mkdepot.pl

の2箇所です。それぞれのスクリプトに

$p4->SetPort($convert::p4port);
$p4->SetClient($convert::p4client);
$p4->SetUser($convert::p4user);

と書かれた部分がありますので,このうしろに

$p4->SetCharset("shiftjis");

と追加してください。もうちょっと真面目に書くとすると,国際語対応サーバで運用している場合,つまり環境変数P4CHARSETが設定されている場合にだけこの処理を追加したいので

if (defined($ENV{'P4CHARSET'})) {
  $p4->SetCharset($ENV{'P4CHARSET'});
}

となるでしょう。

ちなみに,Perforceの代理店の東陽テクニカさんにコンタクトして商談が始まると,各種資料をいただけるのですが,その中に含まれるVSSToP4では上記の変更を適用ずみです。めんどくさがらずにちゃんとPerforce本社に連絡して本家のスクリプトを更新してくれよと思ったり思わなかったり。

SourceSafeは英語版で

スクリプトはエラーなしで実行されたみたいだけどなにも起きないよ? という場合,ひょっとしたらVisual SourceSafeが日本語版じゃないですか? VSSToP4のスクリプトは,VSSのコマンドライン(ss.exe)でファイルの履歴やプロパティを取得してそれをパースするのですが,ss.exeの出力が日本語のままだとパース処理がまともに動きません。VSSの言語設定を英語にしておきましょう。

ファイルタイプのマッピング修正

[VSSのパス] is not valid SourceSafe syntax
というエラーが出て,よくみるとエラーのアタマにutf8とかutf16とか書かれていたら,ファイルタイプのマッピングを修正する必要があります。VSSのファイルタイプをPerforceのファイルタイプに変換する処理がreadhist.pl内にあるのですが,残念ながらUTFに非対応です。もともとのコードは

$type = lc($value);
# The following lines handle new VSS 2005 file types.
$type =~ s/ auto-detect//g;
$type =~ s@text: ansi/mbcs@text@g;

となっているのですが,ここに

$type =~ s/text: utf8/text/g;
$type =~ s/text: utf16 le/utf16/g;
$type =~ s/text: utf16 be/utf16/g;

を追加してください。

余談

東陽テクニカ版のVSSToP4ではtextタイプをすべてunicodeタイプにしてしまっています。オリジナルのmkdepot.plでは

my @addcmd = ("add", "-f", "-t", "$file_type{$vss_file}");

となっているのですが,これが

my $tmp_type = $file_type{$vss_file};
if ($tmp_type eq "text") {
  $tmp_type = "unicode";
}
my @addcmd = ("add", "-f", "-t", "$tmp_type");

と変更されているんですね。この指定をすると,ファイルの中身が

  • サーバ側ではUTF-8で保存され
  • クライアントワークスペースではP4CHARSETの値(つまりShift JIS)でエンコードされる

わけなんですが,これってクライアント側でUTF-8をUTF-8のまま保持したいときは使えないじゃないですか。なのでUTF-8のファイルはファイルタイプをunicode以外,つまりtextなりbinaryなりにしないといけないというわけのわからないことになってしまいます。そんなことに注意しないといけないのなら,国際語モードは使わないほうがいいんじゃないかという気がしてならないのですがどうなんでしょう。

参照: Internationalization and Localization