バージョン管理ツールに svn
を使用しています。
redmine と svn は連携することができ、
redmine の該当するチケット番号を svn にコミットする際、入力していることにより、
チケットに関連する修正ファイルを redmine 上で確認することができます。
開発ブランチからリリースブランチへ、該当ファイルをコミットしていく作業が負担になっていましたので、処理を自動化してみました。
基本的にシェルスクリプトによるコマンド実行ですが、
commit comment から 該当のファイルを抽出する際、 PHP による処理も行っています。
以下、コードです。
まだまだ未熟者ですので、厳しい突っ込みお待ちしております!
-----------------------------------------------------------------
シェルスクリプト
-----------------------------------------------------------------
#!/bin/sh
## コンストラクタ
cd {カレントディレクトリ}
SVN_DEV="{開発ブランチリポジトリパス}"
SVN_PRO="{リリースブランチリポジトリパス}"
DEV_DIR="{開発ブランチ作業コピー}"
PRO_DIR="{リリースブランチ作業コピー}"
LOGFILE="{ログファイルパス}"
XMLFILE="{workファイルパス}"
LISTFILE="{workファイルパス}"
MOVEFILE="{workファイルパス}"
CURDIR=`pwd`
PHP=`which php`" ${CURDIR}/xml_parser.php"
## workファイル削除
if [ -e ${XMLFILE} ]; then
rm -f ${XMLFILE}
fi
if [ -e ${LISTFILE} ]; then
rm -f ${LISTFILE}
fi
## リリースブランチへコミットする対象チケットを決定する
echo "チケット番号を # を省略して入力してください"
echo "複数ある場合は 半角スペース で区切って入力してください"
read ANS
TICKET=${ANS}
FIELDS=`echo ${TICKET} | wc -w`
## 開発ブランチの svn log 結果を xml 形式で吐き出す
svn log ${SVN_DEV} -v --stop-on-copy --xml > ${XMLFILE}
for i in `seq 1 ${FIELDS}`
do
NO=`echo "${TICKET}" | awk --assign awk_var="$i" '{ print $awk_var }'`
echo "================================================"
echo "チケット番号 : ${NO}"
echo "================================================"
${PHP} ${NO}
done
## 重複ファイルを削除する
cat ${LISTFILE} | sort | uniq > ${CURDIR}/sort.log
rm -f ${LISTFILE}
cp -p ${CURDIR}/sort.log ${LISTFILE}
rm -f ${CURDIR}/sort.log
## 開発ブランチ/リリースブランチの作業コピーを最新にします
echo "================================================"
echo "${DEV_DIR} を 最新にします"
echo "================================================"
echo "${DEV_DIR}"
svn revert -R ${DEV_DIR}
svn up ${DEV_DIR}
echo "================================================"
echo "${PRO_DIR} を 最新にします"
echo "================================================"
echo "${PRO_DIR}"
svn st "${PRO_DIR}" |grep '^?'|awk '{print $2}'|xargs rm -rf
svn revert -R ${PRO_DIR}
svn up ${PRO_DIR}
## 対象ファイルをリリースブランチにコミットします
echo "================================================"
echo "今回のリリースブランチへのコミット対象一覧"
echo "================================================"
cat ${LISTFILE}
echo "================================================"
while :
do
echo "上記をコミットしてもよろしいでしょうか?[y/n]"
read ANS
if [ "${ANS}" = "y" ]; then
break
elif [ "${ANS}" = "n" ]; then
echo "操作は取り消されました"
exit 0;
fi
done
## 移動先ディレクトリを定義する
cat ${LISTFILE} | sed -e "s/\/{開発ブランチ}\//\/{リリースブランチ}\//g" > ${MOVEFILE}
while read line
do
MOVE=`echo ${line} | sed -e "s/\/{開発ブランチ}\//\/{リリースブランチ}\//g"`
if [ ! -e ${line} ]; then
echo "削除開始 : ${MOVE}"
rm -rf ${MOVE}
fi
done < ${LISTFILE}
# svn commit を行う
## svn add 対象がある場合 svn add を実行する
ADD_NUM=`svn st "${PRO_DIR}" |grep '^?'|awk '{print $2}'| wc -l`
DEL_NUM=`svn st "${PRO_DIR}" |grep '^!'|awk '{print $2}'| wc -l`
if [ "${ADD_NUM}" != 0 ]; then
echo "================================================"
echo "新規追加ファイルを add します"
echo "================================================"
svn st "${PRO_DIR}" |grep '^?'|awk '{print $2}'|xargs svn add
fi
if [ "${DEL_NUM}" != 0 ]; then
echo "================================================"
echo "削除ファイルを del します"
echo "================================================"
svn st "${PRO_DIR}" |grep '^!'|awk '{print $2}'|xargs svn del
fi
## コミットコメント作成
for i in `seq 1 ${FIELDS}`
do
NO=`echo "${TICKET}" | awk --assign awk_var="$i" '{ print $awk_var }'`
if [ `echo ${#REFS}` = 0 ]; then
REFS="refs\ #${NO}"
elif [ `echo ${#REFS}` != 0 ]; then
REFS="${REFS} refs\ #${NO}"
fi
done
## svn commit 実行
echo "================================================"
echo "コミットを行います"
echo "================================================"
cd ${PRO_DIR}
svn commit ./ -m ${REFS}
echo "================================================"
echo "処理正常に終了しました"
echo "================================================"
exit 0;
-----------------------------------------------------------------
-----------------------------------------------------------------
PHP
-----------------------------------------------------------------
-----------------------------------------------------------------
-----------------------------------------------------------------
PHP
-----------------------------------------------------------------
<?php
// コンストラクタ
$xmlfile = (__DIR__."/work/svnlog.xml");
$filename = (__DIR__."/work/xml_parse.log");
// XMLファイルの読込み
$content=file_get_contents($xmlfile);
// XMLデータを配列に格納
$xml_parser=xml_parser_create();
xml_parse_into_struct($xml_parser,$content,$vals);
xml_parser_free($xml_parser);
// 1回のコミット情報を纏める
$count = count($vals);
$cnt = 0;
$array = array();
for ($i=0; $i < $count; $i ++)
{
$array[$cnt][] = $vals[$i];
// コミット情報の最後の情報は commit comment のため、
//MSG だった場合は次の配列に格納させる
if ($vals[$i]["tag"] == 'MSG')
{
$cnt ++;
}
}
// 該当するチケット番号が格納されている配列の key を取得する
unset($count);
$count = count($array);
for ($i=0; $i < $count; $i ++)
{
foreach ($array[$i] as $commit_log)
{
foreach ($commit_log as $key => $commit_log2)
{
if ($key === "value" && strstr($commit_log2,"refs #".$argv[1]) !== FALSE)
{
$array_key[] = $i;
}
}
}
}
if (empty($array_key))
{
echo "該当するチケット番号に紐づく修正ファイルはありませんでした\n";
return;
}
// 抽出した key の配列に格納されている file_path を取得する
// 取得した file_path は /tmp/xml_parse.log に出力する
unset($count);
$count = count($array_key);
for ($i = 0; $i < $count; $i ++)
{
$cnt = 0;
foreach ($array[$array_key[$i]] as $key => $value)
{
if ($value["tag"] === "PATH")
{
echo $array[$array_key[$i]][$cnt]["value"]."\n";
file_put_contents($filename,$array[$array_key[$i]][$cnt]["value"]."\n",FILE_APPEND);
}
$cnt ++;
}
}
?>
