ふにゃるんv2

もとは、http://d.hatena.ne.jp/Wacky/

一括でバージョン管理する為に、ショートカット先の最新ファイルを取ってくるスクリプト

テスト用にプログラムを書き散らかすと、後が大変だったりします。
まぁ、ここいら辺は、仕事とか、そこいらの作業と同じですね。


几帳面な人だと、フォルダ分けや専用ソフトを使ったりして整理するんでしょうが、私はダラケた人なので、中々うまく整理できません。


専用ソフトで思いつくのは、バージョン管理ソフトなんですが(他にありますかね?)、あれの問題は、

  • バージョン管理するフォルダツリーを決めて配置しないといけない
  • 複数のフォルダツリーを作ると、複数のリポジトリに分かれたりして面倒

と、思います。
いや、手放せないほど便利なんですが、これが又面倒。


どうにかして楽が出来ないかな?と考え込んでいたんですが、以下のような管理方法を思いつきました。

  1. 管理したいファイルやフォルダのショートカットを作る
    gcollect1
    gcollect1 (C)wacky
  2. 専用の回収プログラムで、ショートカット先のファイルやフォルダを、一つの場所にコピーする
    gcollect2
    gcollect2 (C)wacky
  3. コピーしてきた、この場所に対して、バージョン管理ソフトで管理する
  4. なお、回収プログラムは、ショートカット先が更新されたら、コピーし直す

これなら、何とかなりそうです。

コード

という訳で、早速プログラムを作りました。
下のコードを gcollect.cmd とでもしてファイル保存して下さい。


余談ですが、先頭行は、.cmd なコマンドバッチファイルを、WSH(Windows Script Host)のVBScriptエンジンで動かすハックです。
変な設定しなくても、エクスプローラからCScriptを呼び出せるのがオツです。(普通、エクスプローラからダブルクリックすると、WScriptが呼び出されてしまう)

REM:&@CScript.exe //E:VBS //NoLogo "%~f0" %* & GOTO :EOF 
'上の行は、.cmdなバッチファイルからVBScriptを呼び出すハック
'バッチファイルプログラミング 3.bat
'http://pc10.2ch.net/test/read.cgi/tech/1148485555/

' =============================================================================
' グローバル変数:ファイルシステムオブジェクト
Set fso = CreateObject("Scripting.FileSystemObject")

' 現在実行しているスクリプトのフォルダ位置を返す
Function GetExecScriptFolder()
    f1 = WScript.ScriptFullName
    Set f2 = fso.GetFile(f1)
    f3 = f2.ParentFolder.Path
    GetExecScriptFolder = f3
End Function

' system関数のように、引数のコマンドを呼び出す
' 子プロセスの実行を表示したくないなら、Runメソッドの第2引数を0にして
Function CallSystem(arg)
    WScript.Echo arg
    Set WshShell = CreateObject("WScript.Shell")
    CallSystem = WshShell.Run(arg, 7, True)
End Function

' CheckFilesのコールバック関数
' リンク先と手元の実体を比較し、相違があれば、リンク先から実体を引っ張ってくる
' memo: フォルダをFCで比較する場合、"fc hoge\*.* hoge2\*.*"
Function CallbackLinkObject(item, link)
    WScript.Echo "CallbackLinkObject ", item.Name, link.Path
    
    If fso.FileExists(link.Path) Then       ' リンク先はファイル
        WScript.Echo "file!!!"
        
        chk = fso.GetFile(item.Path).ParentFolder.Path + "\" + link.Target
        arg = "fc /B """ + link.Path + """ """ + chk + """"
        If CallSystem(arg) <> 0 Then            ' リンク先と手元の実体が違う
            fso.CopyFile link.Path, chk
            WScript.Echo "copy: " + link.Path + " -> " + chk
        End If
    ElseIf fso.FolderExists(link.Path) Then ' リンク先はフォルダ
        WScript.Echo "folder!!!"
        
        chk = fso.GetFile(item.Path).ParentFolder.Path + "\" + link.Target
        arg = "fc /B """ + link.Path + "\*.*"" """ + chk + "\*.*"""
        If CallSystem(arg) <> 0 Then            ' リンク先と手元の実体が違う
            fso.CopyFolder link.Path, chk
            WScript.Echo "copy folder: " + link.Path + " -> " + chk
        End If
    End If
End Function

' フォルダ内のファイル群をチェックする(フォルダ再帰付き)
' callbackLinkFuncはコールバック関数である。GetRefを使って関数ポインタを取得して渡す事
Function CheckFiles(folder, callbackLinkFunc)
    For Each item in folder.Items
        WScript.StdOut.Write vbCr + ">" + item.Name + " "
        
        If item.IsFolder Then           ' フォルダだよ
            WScript.Echo ""
            Set fdr = item.GetFolder
            CheckFiles fdr, callbackLinkFunc
        ElseIf item.IsLink Then         ' リンクだよ
            WScript.Echo ""
            Set lnk = item.GetLink
            Wscript.Echo item.Name
            callbackLinkFunc item, lnk
        ElseIf item.IsBrowsable Then    ' HTMLファイルだよ
        ElseIf item.IsFileSystem Then   ' 普通のファイルだよ / no=仮想(マイコンピュータとか)
        End If
    Next
End Function

' 以下、メインルーチン
fdr = GetExecScriptFolder()
WScript.Echo "now script folder:", fdr

Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(fdr)
CheckFiles objFolder, GetRef("CallbackLinkObject")

MsgBox "実行完了したよ"

呼び出し結果の例

↓こんな感じになります。

F:\Wacky\Test\wsh\20070212.shortcut test>gcollect.vbs.cmd

F:\Wacky\Test\wsh\20070212.shortcut test>REM: &
now script folder: F:\Wacky\Test\wsh\20070212.shortcut test
>src lect.vbs.cmd
>db.py へのショートカット
db.py へのショートカット
CallbackLinkObject  db.py へのショートカット F:\Wacky\Test\python\20070127.sqlit
e\db.py
file!!!
fc /B "F:\Wacky\Test\python\20070127.sqlite\db.py" "F:\Wacky\Test\wsh\20070212.s
hortcut test\src\db.py"
copy: F:\Wacky\Test\python\20070127.sqlite\db.py -> F:\Wacky\Test\wsh\20070212.s
hortcut test\src\db.py
>pyC へのショートカット
pyC へのショートカット
CallbackLinkObject  pyC へのショートカット F:\Wacky\Test\python\pyC
folder!!!
fc /B "F:\Wacky\Test\python\pyC\*.*" "F:\Wacky\Test\wsh\20070212.shortcut test\s
rc\pyC\*.*"
copy folder: F:\Wacky\Test\python\pyC -> F:\Wacky\Test\wsh\20070212.shortcut tes
t\src\pyC

これで

これで、少しは整理できるようになるかにゃ〜?