S-JIS[2007-03-09/2008-11-03] 変更履歴

compsyncタスク

syncタスクを拡張したタスクです。→タスクのアーカイブ(hmant.jar)
syncはファイルのタイムスタンプが新しいかどうかによってコピー要否の判断をしますが、compsyncはファイルの内容の相違によってコピー要否を判断します。
ファイル内容の比較には正規表現を使えるようにしました。これにより、特定パターンでは相違があっても同等と判断することが出来ます。


ファイルの比較ロジック

ソースとターゲットのディレクトリの双方にファイルが存在しているとき、ファイルをテキストファイルと見なして1行ずつ比較する。

行の内容が完全に一致していれば、次の行の比較に移る。
違っていた場合、指定された正規表現を双方に適用し、その結果が等しければ一致したものと見なし、次の行の比較に移る。

複数の正規表現が指定されている場合は、どれか1つのパターンが一致すれば 一致したものと見なす。

ある行が全ての正規表現で一致しなければ、そのファイルの内容は異なっていると判断する。


compsyncの説明

パラメータ

属性 説明 必須
todir ファイルセットで同期をとるターゲットディレクトリー。 Yes
verbose ファイルのコピーの有無を記録する。 No; デフォルトは、false
execsync noのとき、ログ出力のみを行い、実際のコピーや削除動作は行わない。デフォルトはyes[2007-08-11] No; デフォルトは、true

ネストする要素として指定されるパラメータ

fileset

FileSetは、同期をとるソースディレクトリを指定するのに使う。
ここで指定したディレクトリ内のファイルだけがターゲットディレクトリに存在を許される。

filesmatch.reg

正規表現を指定するのに使う。

パラメータ

属性 説明 必須
encoding1 比較対象のソースファイルのエンコーディング No
encoding2 比較対象のターゲットファイルのエンコーディング No
regexp 正規表現での比較パターン No
format 書式指定での比較パターン No

ネストする要素として指定されるパラメータ

fileset

このFileSetは、 実際に比較を行うファイル群を指定するのに使う。
ここで指定したディレクトリ内のファイルだけを実際に比較する。
ソースディレクトリと同じ場所を指定し、実際に比較するファイルだけを含むようにする。
除外されたファイルはターゲットディレクトリ内に残る。

filesetを省略した場合は、全てのファイルを比較する。

expression

Expressionは、正規表現または書式を指定する。

パラメータ

属性 説明 必須
regexp 正規表現での比較パターン regexp か format のどちらかを定義する必要がある
format 書式指定での比較パターン

log

ログの出力用メッセージを指定するのに使う。→使用例 [2007-03-10]

パラメータ

属性 説明 必須
file ログファイル名。指定しない場合は標準出力に出力する。 No
property プロパティファイル名。ログメッセージのキーと書式を書いておく。 No
logonly execysncに変更。[2007-08-11]  

ネストする要素として指定されるパラメータ

param

ログメッセージのキーと書式を指定する。

パラメータ

属性 説明 必須
name メッセージのキー Yes
value メッセージ書式 Yes

backup

バックアップ用ディレクトリを指定するのに使う。→使用例 [2007-08-11]

パラメータ

属性 説明 必須
newdir この属性を指定すると、コピーする際のコピー元ファイルをこのディレクトリにコピーする。 No
olddir この属性を指定すると、コピーする際の古いコピー先ファイルをこのディレクトリにコピーする。 No
deldir この属性を指定すると、同期先で削除されるファイルをこのディレクトリにコピーする。 No

正規表現書式

正規表現(regexp)は、Java標準のPatternクラスを使用している。

書式(format)は、独自のもの。「%s」や「%d」といった形式(Javadoc参照)で指定し、内部で正規表現に変換している。


ログで使えるキーと書式

メッセージには、「%s」「%d」という書式が使える。(「%%」は「%」そのもの)[2007-03-10]
メッセージ出力時に、コピー元ファイル名・コピー先ファイル名に置換される。

キーは動作の種類を表している。
キーに対応したメッセージが指定されていない場合、その動作のメッセージは出力されない。

キー 説明 %s %d
cp_sf_df コピー(コピー先がファイル) コピー元ファイル名 コピー先ファイル名
cp_sf_dd コピー(コピー先がディレクトリ) コピー元ファイル名 コピー先ディレクトリ名
cp_sf コピー(コピー先のファイルが存在しない) コピー元ファイル名 コピー先ファイル名
cp コピー(上記のcp*が存在しない場合) コピー元ファイル名 コピー先ファイル名
no_sf_df 種類はcpと同じ。
更新日時の条件等によってコピー不要と判断されたもの
コピー元ファイル名 コピー先ファイル名
no_sf_dd コピー元ファイル名 コピー先ディレクトリ名
no_sf コピー元ファイル名 コピー先ファイル名
no コピー元ファイル名 コピー先ファイル名
eq_sf_df ファイルの内容が等しい 比較元ファイル名 比較先ファイル名
eq ファイルの内容が等しい(上記のeq*が存在しない場合) 比較元ファイル名 比較先ファイル名
rm_df 削除(削除対象がファイル)   削除ファイル名
rm_dd 削除(削除対象がディレクトリ)   削除ディレクトリ名
rm 削除(上記のrm*が存在しない場合)   削除ファイル名
md ディレクトリ作成   作成ディレクトリ名

指定の例:

	<log>
		<param name="cp"    value="copy %s %d" />
		<param name="rm_df" value="del %d" />
		<param name="rm_dd" value="rmdir %d" />
	</log>

プロパティファイルで指定する例:

	<log property="compsync.log.properties" />

compsync.log.properties

cp      =cp %s %d
cp_sf   =cp f=%s %d
cp_sf_df=cp f=%s f=%d
cp_sf_dd=cp f=%s d=%d
no      =no %s %d
no_sf   =no f=%s %d
no_sf_df=no f=%s f=%d
no_sf_dd=no f=%s d=%d
eq      =eq %s %d
eq_sf_df=eq f=%s f=%d
rm      =rm %d
rm_df   =rm f=%d
rm_dd   =rd d=%d
md      =md %d

Javadocのコピー例

Javadocの生成日の行以外が変わっているファイルだけをコピーする例です。

Javadocを生成すると、ファイル内には生成日が書き込まれます。
それ以外の部分は変わらないことも多い為、実質的な内容が変わったファイルだけをコピーしたいことがよくあります。

build.xml:

	<property name="doc" location="../doc" />
	<property name="to_doc" location="../dest_doc" />

	<typedef resource="typedef.properties" classpath="../lib/hmant.jar" />

	<target name="javadoc_sync">
		<compsync todir="${to_doc}">
			<fileset dir="${doc}" excludes="**/CVS" />
			<filesmatch.reg>
				<expression format="Generated by javadoc%s on %3s %3s %D %H:%m:%S JST %Y" />
				<expression format='META NAME="date" CONTENT="%Y-%M-%D"' />
			</filesmatch.reg>
		</compsync>
	</target>

CVSワークディレクトリのコピー例

CVSのワークディレクトリを別のワークディレクトリにコピーする例です。

CVSの作業ディレクトリには「CVS」という名前のディレクトリが各ディレクトリに存在しており、これを上書きすると予期せぬ動作をすることがあります。したがって、「CVSディレクトリ」は同期をとる対象から除外します。
(標準のsyncタスクfilesetを用いてCVSディレクトリを除外すると、ターゲットディレクトリから削除されてしまう!(嘆))

また、各ファイルにCVSキーワードを入れている場合、その部分だけが異なっているファイルはやはり除外します。
(ブランチからトランクへのコピーでは、リビジョンや日付や更新者だけが違ってるなんてファイルが大量に出てくる…)

build.xml:

	<property name="cvs_src" location="../branch" />
	<property name="cvs_dst" location="../head" />

	<typedef resource="typedef.properties" classpath="../lib/hmant.jar" />

	<target name="cvs_sync">
		<compsync todir="${cvs_dst}">
			<fileset dir="${cvs_src}" defaultexcludes="no" /> …CVSディレクトリを含む
			<filesmatch.reg regexp="\$$\w+.*?\$$">	    …「$keyword〜$」にマッチする
				<fileset dir="${cvs_src}" />	    …CVSディレクトリを除く
			</filesmatch.reg>
		</compsync>
	</target>

filesetでは、いくつかのパターン(ディレクトリやファイル)がデフォルトで除外されている。例えばCVSディレクトリが除外されている。[2007-05-13]
 したがって、defaultexcludesにnoを指定するとデフォルトが解除され、CVSディレクトリも含まれるようになる。


ログメッセージの出力例

実際に行うコピーや削除のログを出力する例です。[2007-03-10/2007-08-11]

行う動作(キー)と、それを行う時に出力するメッセージを指定します。

build.xml:

	<typedef resource="typedef.properties" classpath="../lib/hmant.jar" />

	<target name="cvs_diff">
		<compsync todir="${cvs_dst}" execsync="no">
			<fileset dir="${cvs_src}" defaultexcludes="no" />
			<filesmatch.reg regexp="\$$\w+.*?\$$">
				<fileset dir="${cvs_src}" />
			</filesmatch.reg>
			<log file="log.txt">
				<param name="cp" value="copy %s %d" />
				<param name="rm" value="del %d" />
			</log>
		</compsync>
	</target>

コピーする場合は「copy 転送元ファイル名 転送先ファイル名」を、削除する場合は「del 削除ファイル名」をlog.txtに出力します。
execsyncにnoを指定しているので、ログ出力のみを行い、実際のコピー・削除は行いません。

これにより、事前にどういう処理が行われるのかを確認することが出来ます。


バックアップする例

実際に行うコピーや削除を行う際に、変更される前のファイルをバックアップする例です。[2007-08-11]

build.xml:

	<property name="src" location="../src" />
	<property name="dst" location="../dst" />
	<property name="bak" location="../old" />

	<typedef resource="typedef.properties" classpath="../lib/hmant.jar" />

	<target name="sync_and_backup">
		<compsync todir="${dst}">
			<fileset dir="${src}" />
			<backup olddir="${bak}" deldir="${bak}" />
		</compsync>
	</target>

変更ファイルを抽出する例

2つの新旧ディレクトリ間で、変更されたファイルだけを抽出する例です。[2007-08-11]

build.xml:

	<property name="old" location="../old" />
	<property name="new" location="../new" />
	<property name="chg" location="../diff/chg" />
	<property name="del" location="../diff/del" />

	<typedef resource="typedef.properties" classpath="../lib/hmant.jar" />

	<target name="diff">
		<compsync todir="${old}" execsync="no">
			<fileset dir="${new}" />
			<backup newdir="${chg}" deldir="${del}" />
		</compsync>
	</target>

変更履歴

更新日 変更内容
2008-11-03 Eclipse3.4のAnt(Ant1.7?)に対応。

自作Antタスクへ戻る / 自作ソフトへ戻る / 技術メモへ行く / 独自タスクの作り方へ行く
メールの送信先:ひしだま