PR
リスト1●簡易バージョンプログラムのコード(JScript)
リスト1●簡易バージョンプログラムのコード(JScript)
[画像のクリックで拡大表示]
図1●src_back.htaの画面
図1●src_back.htaの画面
[画像のクリックで拡大表示]
図2●src_back.htaと同じフォルダに,test_0.txt,test_1.txt…と連番の付いたファイルが生成されていく
図2●src_back.htaと同じフォルダに,test_0.txt,test_1.txt…と連番の付いたファイルが生成されていく
[画像のクリックで拡大表示]
レシピ
■ WSH(Windows Script Host)のJScript
■ Windows 2000/XP(98SE以前のWindowsとWindows Meでは正しく動きません)

 今回は指定されたソースコードを継続的に監視して,変更が認められたら履歴として自動的にバックアップをとるツールを作ってみます。単純な機能なので「バージョン管理システム」と呼ぶにはやや差し出がましい気はしますが,案外役に立ってくれます。

 ちょっと1行修正したらプログラムが動かなくなって焦った,でもどこを編集したのか思い出せないという経験は,特に夜型プログラマ(自分のことだ…)ならば,必ず一度ならず経験していることでしょう。しかし,CVS(Concurrent Versions System) やVisual SourceSafeのような「バージョン管理プログラム」を積極的に使っている人は,そんなに多くはないように思います。差分だけ記録されていたり,復元のためにいろいろな操作が必要だと,本当にある時点までソースを戻さなくてはならないような切羽詰っておろおろしている状況では面倒くさすぎるからなんでしょうね。

 今回作成するプログラムは,指定されたソース・ファイルをタイマー・ループで監視して,直前の保存ファイルと比較したうえで,内容に変化が発生した場合に元のファイル名に連番を付けて保存します。HDD上のファイルを見ることになるので,プログラマが保存したタイミングでのみバックアップをとります。ファイルを保存する前の段階でバージョンを管理するならば,エディタが使っているメモリー領域をのぞく必要が出てくるので,かなり高度なものを作る必要があります。今回は,そこまで高機能なものは作りません。

 何か問題が発生したら,このプログラムを止めて,連番とファイルのタイムスタンプから大体の予想をつけて適当なファイルをリネームで戻せばいいわけです。なぜかこうしたヒューマン・オペレーションのほうが,信頼性が高いというか管理が楽に思えるから不思議です。とりあえずバージョン管理というものの入り口として体験して,「こういう機能はないのか」という疑問や要望が出てきたら,専用ツールを使ってみてください。

ファイルのコンペアは
MS-DOSコマンドを使うだけ

 プログラムはリスト1の通りです。src_back.htaという名前で保存して,ダブルクリックで起動するとフォームが出ます(図1[拡大表示])。「監視するファイルのフルパス:」の部分に,C:\Sample\test.txtのような名前で監視したいファイル名をフルパスで入れて「監視開始」ボタンを押してください。これでファイルに変更が加えられると,src_back.htaと同一フォルダ(元のソースがあるフォルダではありません)に,ファイル名に連番が付いたバックアップ・ファイルが作成されていきます(図2[拡大表示])。「監視停止」で処理を中止します。

<script language="JScript">
var FSO = new ActiveXObject("Scripting.FileSystemObject");
var OSh = new ActiveXObject("WScript.Shell");
var VER,save_name;

//監視開始
function bk_start(){
    alert ("監視を開始します");
    var src_file_path = form1.src_file.value.split("\\");
    f_name = src_file_path.length - 1;
    var src_file_name = src_file_path[f_name].split(".");
    save_name = src_file_name[0] + "_0." + src_file_name[1];
    FSO.CopyFile(form1.src_file.value, save_name);
    VER = 0;
    bk_check(); //タイマー監視開始
}

function bk_check(){
    cmdline = "fc.exe " + form1.src_file.value + " " + save_name;
    var FC = OSh.Run(cmdline, 2, 1);
    if(FC==1){
        VER = VER + 1; //バージョンをあげる
        src_file_path = form1.src_file.value.split("\\");
        f_name = src_file_path.length - 1;
        src_file_name = src_file_path[f_name].split(".");
        save_name = src_file_name[0] + "_" + VER + "." + src_file_name[1];
        FSO.CopyFile(form1.src_file.value, save_name);
    }
    TM = setTimeout ("bk_check()",5000); // 5秒(5000ミリ秒)間隔でチェック
}

function bk_stop(){
    alert ("監視を停止します");
    clearTimeout(TM);
}
</script>

<html><head><title>簡易バージョン管理</title></head>
<body>
<form name="form1">
監視するファイルのフルパス:<br>
<input type="text" size="100" name="src_file"><br><br>
<input type="button" name="btn_start" value="監視開始"
    onClick="bk_start()">  
<input type="button" name="btn_stop" value="監視停止"
    onClick="bk_stop()">
</form>
</body></html>

 このプログラムは,5秒に一度,元のファイルと1回前にバックアップしたファイルの内容を比較します。比較方法(コンペアといいます)はファイル内を全部読み込んで1バイトずつ比較するといった手間のかかるものではなくて,MS-DOSのファイル比較コマンドであるFC.EXEをWSHから呼び出して使っています。FC.EXEは,ファイルを比較して中身が違っていたら1を返します。コンペアのような機能をゼロから作る必要はありません。車輪の再発明は無駄というものです。使えるものがあるんですから使っちゃいましょう。

 例によってサンプルはエラー・トラップがゆるいので,ファイル名を指定せずに「監視開始」したり,ファイル名が間違っていたりするとエラーになります。また,src_back.htaを起動するたびに,バージョン情報は0からになりますので,src_back.htaを止めたり動かしたりを繰り返していると,毎回0からのスタートとなります。恒久的に連番にする場合には,現在のバージョン番号をデータ・ファイルとして保存するといった拡張方法と,連番のところに今日の日付と時間などを入れて重複しないようにするといった手段があります。いろいろと工夫してみてください。