2011年6月28日火曜日

metric_fu/CruiseControl.rbの準備

コードメトリクスを測定するmetric_fu、
継続的インテグレーションのCruiseControl.rb
を準備する。

metric_fuの準備

公式サイトを見る
http://metric-fu.rubyforge.org/

RcovとかRailsBestPracticeとか色々やってくれる。
たくさんあって最初はどれがどれか覚えられないな。
CruiseControl.rbへのリンクもある。

実際にやってみよう。
新しくRails3プロジェクトを作る。
使うgemは前と同じでfwifferを使う。
$ rvm use 1.9.2@fwiffer



metric_fuのインストール
新しくRailsプロジェクトを作る。
名前はci_testにしよう。
$ cd Desktop
$ rails new ci_test
$ cd ci_test
Gemfileに下記を追加。
Production環境では使わないので、開発とテストに追加。
テストを実行する必要があるから、Rspecも追加。
group :development, :test do
  gem 'rspec'
  gem 'rspec-rails'
  gem 'metric_fu'
end

インストール
$ bundle install
本当はGemにインストールしないで、フォルダを指定した方が良いんだよな。
こんな風に。
$ bundle install --path vendor/bundle
インストール完了。かなり沢山インストールされた。

$ rake -T
を実行したらrake metrics:allが出てきた。

Rails3+Rspecの場合に追加するプログラムをRakefileに追加する。

この段階で一度rakeタスクを実行してみよう。
$ rake metrics:all
エラーが出た。これはRakeのバージョン0.9.xのエラーだ。
いつも忘れるな。。。
Rakefileにを編集。
再度実行。
$ rake metrics:all
fatal: Not a git repository (or any of the parent directories): .git
F, [2011-06-16T21:17:09.408553 #29688] FATAL -- : Churning requires a subversion or git repo (RuntimeError)
またエラー。
gitかsubversionのリポジトリが必要なのか。

作るって再度実行
$ git init
$ git add .
$ git commit -m "initial"

$ rake metrics:all
/home/k10i/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych.rb:148:in `parse': couldn't parse YAML at line 4 column 60 (Psych::SyntaxError)
.
.
** Running the specs/tests in the [test] environment
Analyzing:     100% |ooooooooooooooooooooooooooooooooooooooooooo| Time: 00:00:00
Generating graphs
Generating graphs for tmp/metric_fu/_data/20110616.yml

エラーが出ているけど、データファイルが作られたよう。
見てみると、flayやreekやrcovなどの実行結果がyaml形式で保存されている。
このPsychとは何だろう?

同様のエラーが出ている人を発見。
bundlerのバージョンが問題になっているみたい。
http://d.hatena.ne.jp/masa_w/20110223/1298456829
バージョンを調べると1.0.14だった。
$ gem list bundler

先ほどのページからのリンクでStackoverflowのページ
http://stackoverflow.com/questions/4980877/rails-error-couldnt-parse-yaml
boot.rbに追加して、RedClothを削除したら大丈夫だったとか記述があるけれど、RedClothは削除したくない。

yamlの配列の書き方が悪いような事が書いてある。この対策も今回は見送る。

bundlerのバージョンを下げてみる。
$ gem uninstall bundler
rails_best_practices-0.9.0 depends on [bundler (>= 0)]
cucumber-rails-0.5.1 depends on [bundler (>= 1.0.13)]
...cucumber-rails-0.5.1がbundlerお1.0.13以上に依存しているのか。

うーん。これは困った。
Rubyのredmineでもまだ直っていないしな。
http://redmine.ruby-lang.org/issues/4301

ソースを見る。
/home/k10i/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych.rb
148行目のparser.parse yamlでエラー。
yamlには何が入っているかファイルに書き込んで見ると、2種類渡ってきた。
1つは、文字列と、もう1つがファイル。

どうやら、metric_fuのそれぞれの結果が入ってきている。
yamlの中を出力してみると、エラーが出るときは、Saikuroとかエラーが出るようになった。metric_fuで実行するmetricを制限してみる。

saikuroはこんなエラーが出る。
WARNING: Global access to Rake DSL methods is deprecated.  Please include
    ...  Rake::DSL into classes and modules which use the Rake DSL methods.
WARNING: DSL method MetricFu::Saikuro#sh called at /home/k10i/.rvm/gems/ruby-1.9.2-p180@fwiffer/gems/metric_fu-2.1.1/lib/generators/saikuro.rb:13:in `emit'

roodiのエラー
/home/k10i/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych.rb:155:in `parse': couldn't parse YAML at line 4 column 60 (Psych::SyntaxError)

それ以外は大丈夫。

最終的にRakefileのMetricFuの設定は下記になった。
MetricFu::Configuration.run do |config|
  config.rcov[:test_files] = ['spec/**/*_spec.rb']  
  config.rcov[:rcov_opts] << "-Ispec" # Needed to find spec_helper

  config.metrics  = [:flog, :flay, :rcov, :rails_best_practices, :reek, :stats, :churn]
  config.graphs   = [:flog, :flay, :rcov, :rails_best_practices, :reek, :stats,]
end
よく分かっていない指定もあるが、churnをグラフに追加した所、
uninitialized constant MetricFu::ChurnBluffGrapher
とエラーが出たので外した。

準備ができたので、scaffoldで1つ作成してmetric_fuをテストする。
$ script/rails generate scaffold user name:string password:string
$ rake db:migrate
$ rake metrics:all
明らかに出力が違う。
出来上がったymlファイルを見ると、テストされた数が増えている。
うまくいっていそう。

ただymlだと少々みづらい。htmlで見れるはずなんだけれど、オプションが必要なのかな。
tmp/metric_fu/output/フォルダを見てみるとファイルができていた。
index.htmlを開くと結果がhtmlで見れる。
ChurnとFlayとRcovが何も行われていないのかな。
Rcovはcoverageが0%だし。

これは実際に進めていく時に設定しよう。

metric_fuは以上。

CruiseControl.rbのインストール

公式サイトを確認
http://cruisecontrolrb.thoughtworks.com/

Get startedを見る。
ダウンロードして、プロジェクトを追加して、起動。

インストールから設定までのscreencastがある。
http://cruisecontrolrb.thoughtworks.com/documentation/screencasts

ダウンロードして/var/www/に配置
$ sudo cp -R '/home/k10i/Desktop/cruisecontrol-1.4.0' /var/www/

フォルダに移動してプロジェクトを追加。
helpで設定を確認する。
$ cd /var/www/cruisecontrol-1.4.0/
$ ./cruise --help
start、add、buildの3つのコマンドがある。
addを詳しく見る。
$ ./cruise add --help
-rでリポジトリを指定して、-sはvcを設定できる。
実際に登録してみよう。

gitレポジトリを指定する。
と思ったけれど、bareリポジトリを設定していない。別の指定方法があったりするのかな。
Redmineを登録したときはどうやったんだっけ。
確認する。

...と思ったらまだredmineではリポジトリの設定をしていなかった。
最近gitレポを登録した気がしたんだけれど。

redmineのリポジトリの登録画面を見ると、gitの場合、
Bare、かつ、ローカルリポジトリとなっている。
やっぱりBareを作らないといけないんだろうな。

ci_testはgitに追加されているのでBareリポジトリを作成する。

$ sudo mkdir /var/git
$ cd ~/ci_test
$ sudo git clone --bare . /var/git/ci_test.git
$ git remote add origin /var/git/ci_test.git
$ cat .git/config
[remote "origin"]
 url = /var/git/ci_test.git
追加された。

試しにコミット。ちょうど編集されたファイルがあった。
$ git add .
$ git commit -m "change"
$ git push origin
Counting objects: 56, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (36/36), done.
Writing objects: 100% (44/44), 7.47 KiB, done.
Total 44 (delta 8), reused 0 (delta 0)
error: insufficient permission for adding an object to repository database ./objects

fatal: failed to write object
error: unpack failed: unpack-objects abnormal exit
To /var/git/ci_test.git
 ! [remote rejected] master -> master (n/a (unpacker error))
error: failed to push some refs to '/var/git/ci_test.git'
パーミッションのエラーが出る。
/var/git/ci_test.gitはroot権限になっている。
変更して再度push

$ sudo chown -R k10i:k10i /var/git/ci_test.git
$ git push origin
Counting objects: 56, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (36/36), done.
Writing objects: 100% (44/44), 7.47 KiB, done.
Total 44 (delta 8), reused 0 (delta 0)
Unpacking objects: 100% (44/44), done.
To /var/git/ci_test.git
   3dbeb49..e56aca9  master -> master

うまくpushできた。redmineで確認。

redmineでリポジトリを設定
git://var/git/ci_test.git
リポジトリを見ると、ファイルが無い。
設定の方法が違った。
redmineのリポジトリ設定を削除して再作成。その時のパスは、
/var/git/ci_test.git

リポジトリを確認するとファイルが表示された。
...でも本来やりたかったのは、git://でアクセスさせるのが確かめたかった。
それは置いておいて、ローカルアクセスでもbareならcruisecontrol.rbからアクセスできるかテスト。

$ cd /var/www/cruisecontrol-1.4.0
$ ./cruise add -r git -s /var/git/ci_test.git
Project name and repository location are mandatory

プロジェクト名が無かった。mondatoryって何だ? 命令とか受任とかそう意味らしい。

プロジェクト名を追加して追加。
$ ./cruise add ci_test -r git -s /var/git/ci_test.git
Adding project 'ci_test' (this may take a while)...
cruise data root = '/home/k10i/.cruise'
<internal:lib/rubygems/custom_require>:29:in `require': /var/www/cruisecontrol-1.4.0/vendor/rails/activesupport/lib/active_support/inflector.rb:266: syntax error, unexpected ':', expecting keyword_then or ',' or ';' or '\n' (SyntaxError)
        when 1: "#{number}st"

シンタックスエラーが出ている。もしかしてruby1.9では動作しないのかな?

Googleで調べる。(cruisecontrol.rb ruby1.9)
同じ現象のユーザがいた。
https://github.com/thoughtworks/cruisecontrol.rb/issues/18

2011/3/17にパッチが作られている。
https://github.com/thoughtworks/cruisecontrol.rb/commit/5308ece2963246d6bf1ef329c24fddf21733a3da

さっきダウンロードした最新でもcruisecontrol.rbは1.4.0で2009-6-30のバージョン。
パッチで上書きしてみる。

...と思ったらgithubにはもっと新しいバージョンがあるじゃないか。
gitでチェックアウトしてそっちを使ってみる。
$ cd /var/www/
$ sudo git clone https://github.com/thoughtworks/cruisecontrol.rb.git
$ cd cruisecontrol.rb/
$ ./cruise add ci_test -r git -s /var/git/ci_test.git
Could not find api_cache-0.2.0 in any of the sources

api_cacheが見つからないと。gemであるのかな?

$ less Gemfile
を見るとapi_cacheが必要。
これを期にgemsetを作ってその中で使おう。
$ rvm gemset create cruisecontrol.rb
'cruisecontrol.rb' gemset created (/home/k10i/.rvm/gems/ruby-1.9.2-p180@cruisecontrol.rb).
$ sudo vi .rvmrc
rvm use 1.9.2-p180@cruisecontrol.rb
$ cd .
で切り替える。

bundlerをインストールしてGemfileにあるライブラリをインストールする。
$ gem install bundler
$ bundle install
インストール後に再度プロジェクトを追加。
$ ./cruise add ci_test -r git -s /var/git/ci_test.git
cruise data root = '/home/k10i/.cruise'
Rails Error: Unable to access log file. Please ensure that /var/www/cruisecontrol.rb/log/development.log exists and is chmod 0666. The log level has been raised to WARN and the output directed to STDERR until the problem is fixed.
Adding project 'ci_test' (this may take a while)...
[debug] /var/www/cruisecontrol.rb k10i$ git clone git /home/k10i/.cruise/projects/ci_test/work
FAILED: /var/www/cruisecontrol.rb k10i$ git clone git /home/k10i/.cruise/projects/ci_test/work
fatal: 'git' does not appear to be a git repository
fatal: The remote end hung up unexpectedly
["Initialized empty Git repository in /home/k10i/.cruise/projects/ci_test/work/.git/\n"]

エラー。
まずは権限がない。ubuntuなので/var/wwwに作らない方が良いのかな。
$ sudo chown -R k10i:k10i ../cruisecontrol.rb/
$ ./cruise add ci_test -r git -s /var/git/ci_test.git
cruise data root = '/home/k10i/.cruise'
Adding project 'ci_test' (this may take a while)...
[debug] /var/www/cruisecontrol.rb k10i$ git clone git /home/k10i/.cruise/projects/ci_test/work
FAILED: /var/www/cruisecontrol.rb k10i$ git clone git /home/k10i/.cruise/projects/ci_test/work
fatal: 'git' does not appear to be a git repository
fatal: The remote end hung up unexpectedly
["Initialized empty Git repository in /home/k10i/.cruise/projects/ci_test/work/.git/\n"]
次は、やっぱりgitのレポジトリがおかしいとのエラー。

gitデーモンを起動させないと駄目かと考えていたら、

...-rと-sが逆じゃん。。。

$ ./cruise add ci_test -s git -r /var/git/ci_test.git
cruise data root = '/home/k10i/.cruise'
Adding project 'ci_test' (this may take a while)...
[debug] /var/www/cruisecontrol.rb k10i$ git clone /var/git/ci_test.git /home/k10i/.cruise/projects/ci_test/work
Project 'ci_test' added.

追加できた。
続いて起動。

$ ./cruise start

http://127.0.0.1:3333/
にアクセスして確認。
前に使っていたときと比べると、画面が新しくなっている。

buildが成功した。画面がかっこいいな。
このままだとテストもmetric_fuも動作していないので、設定する。

$ vi /home/k10i/.cruise/projects/ci_test/cruise_config.rb
project.rake_task = 'metrics:all'
project.scheduler.polling_interval = 24.hours
を追加。
gemsetにmetric_fuを追加。
$ vi Gemfile
gem 'metric_fu'
これはdevelopmentの下に書いてみた。rcovとかもそこに記述があるから。
testの下に書かないのかなと思ったけれど、
bundle installしたときに、環境をしていしないとdevelopmentになるから、その方が楽なんだろうな。
$ bundle install
インストール後サーバを起動。
$ ./cruise start

サイトにアクセスして、Build Nowをクリックする。
成功した。
Build Logを見ると、"metrics:all"が実行されている。
ファイルは、Build Artifactsをクリックしてoutputを見るとmetric_fuの結果が表示される。

Build Logを見ると、
下記エラーが出ていた。spec_helperが無いみたい。
spec/models/user_spec.rb:1:in `require': no such file to load -- spec_helper (LoadError)
 from spec/models/user_spec.rb:1:in `<top (required)>'
 from /home/k10i/.cruise/projects/ci_test/work/vendor/ruby/1.9.1/gems/rcov-0.9.9/bin/rcov:516:in `load'
 from /home/k10i/.cruise/projects/ci_test/work/vendor/ruby/1.9.1/gems/rcov-0.9.9/bin/rcov:516:in `<top (required)>'
 from /home/k10i/.cruise/projects/ci_test/work/vendor/ruby/1.9.1/bin/rcov:19:in `load'
 from /home/k10i/.cruise/projects/ci_test/work/vendor/ruby/1.9.1/bin/rcov:19:in `<main>'

cruisecontrol.rbからではなくて、ローカルでmetrics:allを実行しても同様のエラーが出ていた。
$ rake spec
を実行しても同様のエラーが表示された。
これはrspec:installを実行していないのか。
$ script/rails generate rspec:install
$ rake spec
pendingが出るけど、実行された。spec:installで作成されたファイルをコミットしてプッシュ
$ git add .
$ git commit -m "spec:install"
$ git push origin

cruiscontrol.rbでBuild Nowボタンをクリック。
Build Logを見るとエラーが消えた。

調べているうちに、rcovは1.9ではまだ未対応らしい。
1.9ではcover_meというgemライブラリを使うと良いらしい。
この辺は後日調べる。

以上。

0 件のコメント:

コメントを投稿