2016年2月29日月曜日

[Jenkins] ビルドのパラメータ「List Subversion tags (and more)」に branches にあるディレクトリが列挙されないときに確認すること

trunk/branches/tags の基本ディレクトリはありますか?


うん。普通はあるよね。
でも、それでハマったんだ。

もし、同じことで困っている人は trunk/branches/tags の基本ディレクトリがあるか確認してみてください。
以下は、経緯と理由です。

やりたかったこと
やりたかったことは、これ。
iutest の場合)
「List Subversion tags (and more)」を普通に設定すると trunk,branches/*,tags/* のディレクトリが列挙されます。
が、問題のリポジトリはなぜか列挙されなかったのです。


再現用に作ったリポジトリの構成は以下。


こんな感じで列挙されない。


フィルターの正規表現を間違えたのか?プラグインのバージョンで違う?とかやって時間を潰してしまいました…

理由
調べたところ、プラグインのソースに行きつきました。(subversion-2.5.7)
https://github.com/jenkinsci/subversion-plugin/blob/subversion-2.5.7/src/main/java/hudson/scm/listtagsparameter/ListSubversionTagsParameterDefinition.java

getTags

getSVNRootRepoDirectories

getTags 関数を見ると、isSVNRepositoryProjectRoot が true の場合のみ、getSVNRootRepoDirectories が呼ばれて branches/tags 以下のディレクトリをリストアップしてくれます。

isSVNRepositoryProjectRoot

isSVNRepositoryProjectRoot を見ると、trunk/branches/tags ディレクトリがあることが条件であることがわかります。

つまり、ルートディレクトリと判断されてない!!誰だよこのリポジトリ作ったのは…



この記事が誰かの助けになれば幸いでございます。

2016年2月24日水曜日

[Jenkins] Plot Plugin を使って見える化

最近、見える化って大事だよなー
と、より強く思うようになってきました。けど、見える化って難しかったりしますよね?

今回は、見える化に使えそうな Jenkins プラグインを紹介したいと思います。
(こんなんあるよ程度の紹介です。すごく便利というわけではなかったり…)

Plot Plugin
Plot Plugin は csv ファイルや xml ファイルなどを集計して、グラフ化してくれるプラグインです。

今回は簡単に csv ファイルを出力してグラフ化してみました。
出力するデータは、 iutest のリリースパッケージのファイルサイズです。

段々とファイルサイズが大きくなっているのが一目瞭然ですね。

csv の出力は、Jenkins の「Windows バッチコマンドの実行」で以下のコマンドを実行しています。
Windows バッチでは、変数参照で %z のようにすると、ファイルサイズが取得できます。
echo tar.gz, zip > package_size.csv
for %%F in (iutest*.tar.gz) do SET /p SS=%%~zF< nul >> package_size.csv
for %%F in (iutest*.zip) do echo , %%~zF>> package_size.csv
exit /b 0

出力される csv はこんなかんじです。
tar.gz, zip 
796836, 1188539
1行目にデータの名前を列挙、2行目にデータの値を列挙する形式なので注意。
あとは、この .csv ファイルを集計するように Jenkins の設定をすれば、上図のようなグラフが表示できます。



今回は簡単な事例を紹介しましたが、ちょっとのことでも視覚化されるとイイ感じですよね。

その他事例
Jenkinsにスローテストのグラフを表示する - くりにっき
Rails Best Practices を CI (Jenkins) で確認する | Aiming 開発者ブログ
Hudsonでコードの行数を記録する - みずぴー日記

2016年2月17日水曜日

NuGet のパッケージバージョンをバッジにする

NuGet のパッケージバージョンを Github でバッジ表示したいな~と思ったので、調べてみました。

こちらのスライドで、「Version Badge」というのが紹介されていたので使ってみることにしました。


Version Badge にアクセスすると、以下のようなページが開くので NuGetを選択します。

検索ボックスにパッケージ名を入れて、Find ボタンを押すと
こんな感じにバッジの URL がでるので、あとはコピペして完了です。

簡単ですね!
NuGet version

2016年2月15日月曜日

iutest v1.15.0 をリリースしました

C++ テスティングフレームワーク iutest v1.15.0 をリリースしました。
変更点は以下の通りです。

  • 追加
    • --iutest_output オプションで repeat 回数のフォーマットに対応 e.g. --iutest_output=xml:test_%d.xml
    • CSV ファイルから値のパラメータ作成に対応
    • 値のパラメータ化テストのテスト名指定方法の Google Test 互換対応
  • 変更
    • IUTEST_ALIAS_TESTNAME_F,IUTEST_JAPANESE_NAME_F の引数の順番を変更
    • 値のパラメータ化テストのテスト名指定方法を変更
    • IUTEST_TYPED_TEST_APPEND_TYPENAME を IUTEST_HAS_TYPED_TEST_APPEND_TYPENAME に変更
  • 修正
    • バグ修正

今回 v1.15.0 の追加機能は、3つです。

1つ目は、--iutest_output オプションでテスト結果を出力する際に、リピート回数をファイル名に含められるようにしました。
今までリピート実行した場合に出力されるテスト結果のファイルは1つだけでしたが、フォーマット指定でリピート回数をファイル名に含めることで、リピート毎にファイルを出力できるようになりました。
e.g. --iutest_output=xml:test_%d.xml

2つ目は、CSV ファイルから動的に値のパラメータを生成できるようになりました。以下のように使います。
class CSVValuesTest : public ::iutest::TestWithParam<int> {};

IUTEST_P(CSVValuesTest, Test)
{
 int v = GetParam();
 IUTEST_SUCCEED() << v;
}
IUTEST_INSTANTIATE_TEST_CASE_P(A, CSVValuesTest, ::iutest::CSV<int>("csvparams.csv"));
::iutest::CSV 関数のテンプレートパラメータに型を指定してください。その型で csv をパースします。
第一引数に csv ファイルのパスを指定します。
(実行ファイルからの相対パス。パス解決方法をもう少しなんとかしたい…)
動的にパラメータを生成するので、リビルドすることなく csv ファイルを更新するだけでパラメータの変更ができるのがメリットです。

3つ目は、Google Test 互換の値のパラメータ化テストのテスト名指定方法に対応しました。
こちらの機能を含んだ Google Test はまだリリースされていませんが、github で確認できます。
(そろそろ出るかなぁ~と思っていたのですが、まだみたいですね。)



また、今回は破壊的変更が2件あります。
1つ目は IUTEST_ALIAS_TESTNAME_F と IUTEST_JAPANESE_NAME_F の引数の順番を入替えました。
これにより、このマクロを使用していたテストコードに変更が必要になりますが、
こちらの機能は C++03 環境でテスト名に日本語を使いたいために用意したもので、まぁそんなに使われいないだろうということで変えちゃいました。

2つ目は値のパラメータ化テストのテスト名指定方法を変更しています。
v1.14.0 で試験的に入れた機能でしたが Google Test の実装方法との互換性を考慮して、今回から変更がされています。

今回は以上です。

2016年2月8日月曜日

[AppVeyor] MinGW/Cygwin を使う方法

今回は AppVeyor で MinGW/Cygwin を使ってビルド/テストする方法を紹介します。

MinGW
MinGW は簡単です。
設定の「Environment」の「Operating system」に MinGW があるので、それを選択するだけです。
(※ 2016/3/15 追記:現在は 「Build worker image」になっており MinGW はないが MinGW が使えることは確認済み)

iutest の実行結果はこちら


Cygwin
Cygwin の場合は、「Operating system」にないのでインストールする必要があります。
方法は以下のページに書いてありました。
Pre-install Cygwin / Suggestions / Discussion Area - AppVeyor Support

「Operating system」に Unstable があり、そのイメージには cygwin の setup.exe が入っているそうです。
(※ 2016/3/15 追記:現在は 「Build worker image」になっており Unstable はないが setup.exe が使えることは確認済み)
なので、あとは以下のようにコマンドラインで cygwin のセットアップをするだけです。
$ c:\cygwin\setup-x86.exe -qnNdO -R C:/cygwin -s http://cygwin.mirror.constant.com -l C:/cygwin/var/cache/setup -P autoconf -P automake -P bison -P gcc-core -P gcc-g++ -P libtool -P make -P gettext -P intltool -P libiconv -P pkg-config -P wget -P curl
$ SET PATH=c:\cygwin\bin;%PATH%


iutest の実行結果はこちら

2016年2月2日火曜日

[C/C++][Clang] include 解析ツールを作った

無駄な include を消したいなーと思って、そのためにまずは解析できるようにならないと、と Clang を使ってやってみました。

ビルド環境構築
clang ソースのセットアップ
LLVM.org から LLVM と clang のソースをダウンロードします。
それぞれ展開をし、LLVM は任意のファルダに保存してください。

ここでは、 D:\usr\local\LLVM に置いたこととします。
clang は展開したフォルダを "clang" にリネームして、 D:\usr\local\LLVM\tools\clang に置きます。

clang のビルド
今回は Visual Studio 2015 向けにビルドします。
その前に CMake が必要になるので、インストールしておいて下さい。

コマンドプロンプトを開き、LLVM ソースフォルダに移動して、以下のコマンドを実行します。
LLVM> set path=%ProgramFiles(x86)%\CMake\bin
LLVM>mkdir build
LLVM>cd build
LLVM\build>cmake -G "Visual Studio 14" -D CMAKE_INSTALL_PREFIX=D:\LLVM ..

最初に path を書き換えているのは、cygwin のパスが通ってると CMake に失敗するためです。
CMAKE_INSTALL_PREFIX にはインストールフォルダを指定します。今回は D:\LLVM としています。
CMake が成功すると、LLVM.sln が出来上がってるのでビルドします。

ビルドができたら、INSTALL プロジェクトを選択してビルドします。
CMAKE_INSTALL_PREFIX に指定したところにインストールがされますので、これで完了です。

事始め
まずは、なにかサンプル的なものをビルド・実行できるようにするとイイと思います。
今回私は、以下のページを参考にしました。

include の解析
今回は #include の依存関係を知ることが目的です。
プリプロセスの追跡には PPCallbacksTracker を使うことになります。

そして include の依存関係から dot ファイルを作成するスゴク参考になりそうなものが clang/lib/Frontend/DependencyGraph.cpp にあります。
これを参考に書いたのがこちら。
https://github.com/srz-zumix/cincluder

システムファイルを除外したり、複数ファイルから include されているファイルに色付けするようにしています。
iutest を解析した結果がこちら。


コマンドラインオプション
cincluder を書いていて独自のコマンドラインオプションに対応したいなと思って調べたのでメモ。

static cl::OptionCategory CincluderCategory("cincluder");
static cl::opt< ::std::string > DotFile("dot", cl::init("cincluder.dot"), cl::desc("output dot file"), cl::cat(CincluderCategory));

cl::opt でオプションを定義します。
最初の文字列がオプション名で、あとは init で初期値、 desc で説明、 cat でカテゴリ情報を付与しています。
これらの設定には、cl::Positional とか、 cl::Required とかもあるみたいです。
他にどんな設定があるかは、 LLVM/include/llvm/Support/CommandLine.h を参照してください。

最後に
LibTooling 難しそうと思ってましたが使ってみたらそうでもなく、やりたいことがこんなにも簡単にできてしまうのかー、と驚きました。
「できる」というのが分かってしまえば気楽なもんで、お仕事とかでも気軽にツール作りができそうです。