オープンソースこねこね

Webプログラミングなどについてあれこれ。

Github Pagesでプロジェクトページを作ってみた

3ヶ月ほど前になるのですけど、PHPマイグレーションツールを作ったのです。

PHPMigrate - PHPでマイグレーションツールを作った

これはPHPファイル一つで動作する簡易マイグレーションツールで、実際にしばらく使っていたのですが、運用しているシステムが複数のDBスキーマ管理したり、同じスキーマだけど自動テスト用と開発用、本番用で接続先が違ったりと複雑化してきて、どうにも使いにくくなってきました。

とういうわけでファイル一つで動作するという手軽さは捨てて、もっと構成管理しやすくしたバージョンに新しく書き直しました。テストコードもつけてpackagistに登録してComposerでのインストールに対応させたりもしました。

LibMigration

で、ドキュメント書くついでにGithub Pagesもいじってみようと思って、ちょっと調べながらプロジェクトページを作ってみました。わりと簡単にそれっぽいページができましたよ。

f:id:kohkimakimoto:20130703011030p:plain

リポジトリ自体は自分でつけたスターいっこしかないけど、ちょっと気分がいいのでブログ書きます。

Github Pages

一応Github Pagesについて、ざっくり説明しておきます。これはGithubのリポジトリやユーザアカウントに関連付けたWebサイトが作れて、ホスティングしてくれるGithubのサービスです。

http://pages.github.com/

最初の登録方法は以下などを参考にすればいいと思います。

https://gist.github.com/weed/3608503

GithubらしいのがページのソースはGitリポジトリにコミットして管理するという点。今回私が作ったリポジトリに関連づけるページではgh-pagesというブランチが作られるので、そこにサイトのソース一式をコミット、pushする。そうして決められたURLにアクセスするとWebページを表示してくれる仕組みになっています。

また、デザインテーマに最初からかっこいいやつがいろいろ用意されています。

Jekyll

さて、このGithub Pagesですがページを編集するためのCMSみたいなものはなく、基本的には自分で生のHTMLをいじくることになります。ただGithub Pagesはサイトを表示する時JekyllというRuby製のHTMLジェネレータを通してリポジトリの内容をWebページにレンダリングしています。

Jekyllは普通のHTMLはそのままHTMLとして出力して、markdownで書いたページがあれば、HTMLにしてくれるます。またlayout機能をもっているので、デザインテンプレート部分だけHTMLで書いてコンテンツ部分をmarkdownで書くようなことができます。

プログラムのように動的にコンテンツを変えることはできませんが、共通部分を抜き出して部品化できるので、効率的にサイトを編集できます。

ページ作成を始める - ローカル仮想環境にJekyllをインストールする

さて、markdownで書いたコンテンツを確認するのにいちいちGithubにpushするのは面倒なので、 ローカルにあるCentOS仮想環境RubyとJekyllを入れて、 手元でも確認できる環境をつくります。RubyはRVMでインストールしました。以下の記事などを参考にどうぞ

http://kohkimakimoto.hatenablog.com/entry/2013/04/09/185204

Jekyllはgemでインストールするだけ。以下のコマンドを実行します。

$ gem install jekyll

ページのブランチをcloneする

ページのソースを管理しているブランチをローカルにcloneします。

$ git clone git@github.com:kohkimakimoto/lib-migration.git
$ cd lib-migration/
$ git checkout gh-pages

Jekyllの確認用のサーバを立ち上げる

Jekyllには組み込みサーバがバンドルされています。ページ編集中にこれを立ち上げておき、ファイルを更新すると随時自動でHTMLを再生成してくれてブラウザで確認できるようになります。

$ jekyll serve --watch

デフォルトでport4000でサーバが起動するので

http://192.168.56.1:4000/

とかブラウザでアクセスすればサイト表示が確認できます。

レイアウトファイルを作って、デザインとコンテンツを分離する

_layoutsディレクトリを作ってその配下にdefault.htmlというファイルを作ります。以下の様な構成でHTMLを書きます。{{ content }}となっているところが、後で別途作るコンテンツ用のページに置き換わることになります。

<html>
  <head><title>{{ page.title }}</title><head>
  <body>
    {{ content }}
  </body>
</html>

コンテンツをmarkdownで書く

index.mdを作成して以下のような感じにコンテンツをmarkdownで書きます。上部にあるlayout,titleの指定で、layoutを選択し、タイトルを差し込んでいます。

---
layout: default
title: LibMigration
---

## A minimum database migration library and framework for MySQL.

LibMigration is a minimum database migration library and framework for MySQL.
...

さらにdocumentation.mdとかcommands.mdとかページごとにmarkdownファイルを作ってコンテンツ増やしていきます。

コミットしてpush

ひと通り、ページを作成したら、コミットしてpushします。

$ git add .
$ git commit -a
$ git push origin gh-pages

キャッシュされているのかジェネレートにタイムラグがあるのか、Github Pages上ではすぐに更新内容が反映されないことがあるので、その場合はしばらく待ちます。

あとソースコードの記述をハイライトさせたかったので、jQueryjQuery Syntax Highlighterを使いました。javascriptcssもそのままコミットすればいいです。コードのハイライトは以下の様な表示に。

f:id:kohkimakimoto:20130703011025p:plain

というわけで、ひと通りの作業はこんな感じです。完成したページは以下からどうぞ。

LibMigration Github Pages

RVMをインストールするとchefが"Could not find chef"となってしまう場合の対処方法

chefがOmnibus Installationで/opt/chef/配下に組み込みRubyと一緒にインストールされている環境にて、別途RVMのRubyを入れると、以下のようなエラーが表示されて動作しなくなりました。

# chef-solo -c /var/chef/config/solo.rb -j /var/chef/nodes/devel.localdomain.json

/opt/chef/embedded/lib/ruby/site_ruby/1.9.1/rubygems/dependency.rb:247:in `to_specs': Could not find chef (>= 0) amongst [bundler-1.3.5, bundler-unload-1.0.1, rake-10.1.0, rubygems-bundler-1.2.0, rvm-1.11.3.8] (Gem::LoadError)
        from /opt/chef/embedded/lib/ruby/site_ruby/1.9.1/rubygems/dependency.rb:256:in `to_spec'
        from /opt/chef/embedded/lib/ruby/site_ruby/1.9.1/rubygems.rb:1231:in `gem'
        from /opt/chef/bin/chef-solo:22:in `<main>'

そんでちょっと調べてみたら、公式サイトにもこの現象について書かれています。

http://wiki.opscode.com/display/chef/Installing+Omnibus+Chef+Client+on+Linux+and+Mac

OmnibusのGemよりRVMのGemを先に探しに行くらしいのでエラーになるらしい。

対処法ですが、sudosudo -sを使って実行すれば、/etc/profile.d/rvm.shをロードしなくなるのでRVMの影響をさけることができ、Omunibusの閉じた環境で実行してくれます。

# sudo chef-solo -c /var/chef/config/solo.rb -j /var/chef/nodes/devel.localdomain.json

現在のログインユーザがrootでもsudoするのがミソです。

RailsのControllerで使用するparamsは変数でなかった件

Railsの話。最近Rubyを少し触りはじめました。

で、RailsのControllerでリクエストパラメータを取得するのに利用するparamsというHashパラメータがあるのですけど、 メソッドの引数定義はないし、@がついてないのでインスタンス変数でもない。どこで定義されてるのよっこの変数は、と思ってたんですが、StackOverflowに同じ疑問をもつヒトの質問と回答がありましたので以下にリンクと和訳を。

なるほど。メソッドだったのねん。

Rails: "params" はどこで定義されている?

私はparamsを自分のコントローラでこんなふうに使っている。

class ProductsController < ApplicationController
  def create
    @product = Product.new(params[:aircon])
    ...
  end
end

paramsはApplicationControllerのアトリビュートなのか? @のプリフィクスがついてないので違うと思う。 それで、paramsは実際のところなんなの? ProductsController内のカスタムメソッドでも使えるの?

回答

これはActionController::Metalで定義されている。 ApplicationControllerはActionController::Metal を継承しているActionController::Baseを継承している。 Rails API (http://api.rubyonrails.org/) を見ればparamsがrequestオブジェクトのパラメータを 戻す関数であることがわかるよ。

RVMでRuby2.0をCentOS6にインストールする

Ruby2.0のインストールなのですが、最初はcheckinstallでソースからRPM化しようとしてみたものの、いろいろ無理があったりうまく行かなかったりしたので見送り。rvmを使います。

rvm公式サイト

ユーザごとの独立した環境

最近はユーザのHOMEディレクトリ配下の独立した環境にインストールするのが流行りらしいです。 個人的には一人でサーバー管理やっていて、常時rootユーザでオペレーションしている身なので、システム(/usr/local配下)にインストールするのがいつものスタイルです。ですが、ここでは推奨される方法にしたがってみます。

依存パッケージのインストール

epelリポジトリを入れておく(いくつかの依存パッケージが標準のリポジトリにないため)

# wget http://ftp.jaist.ac.jp/pub/Linux/Fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
# rpm -ivh epel-release-6-8.noarch.rpm

依存パッケージをインストール

# yum install gcc-c++ patch readline readline-devel
# yum install zlib zlib-devel libffi-devel
# yum install openssl-devel make bzip2 autoconf automake libtool bison
# yum install gdbm-devel tcl-devel tk-devel
# yum install libxslt-devel libxml2-devel
# yum install --enablerepo=epel libyaml-devel

rvmをインストール

以下のコマンドを叩く。

$ curl -L https://get.rvm.io | bash -s stable

ちなみにシステム(/usr/local配下)にインストールするときはrootユーザで作業するか、以下のようにsudoで実行します。

$ curl -L https://get.rvm.io | sudo bash -s stable

rvmのパスを設定するための記述が以下のファイルに追記されるので、確認しておく

$ vim .bash_profile
$ vim .bashrc

再ログインしてbash_profile.bashrcの変更をロードする。

rvmの確認

バージョン確認

$ rvm -v

対応しているRubyの一覧

$ rvm list known

Ruby2.0.0をインストール

以下のコマンドを叩く。

$ rvm install 2.0.0

RubyGemsのインストールでエラーが出力される

Extracting rubygems-2.0.3 ...
Removing old Rubygems files...
Installing rubygems-2.0.3 for ruby-2.0.0-p0.............................................................................................................................
Error running 'env GEM_PATH=/home/kohkimakimoto/.rvm/gems/ruby-2.0.0-p0:/home/kohkimakimoto/.rvm/gems/ruby-2.0.0-p0@global:/home/kohkimakimoto/.rvm/gems/ruby-2.0.0-p0:/home/kohkimakimoto/.rvm/gems/ruby-2.0.0-p0@global GEM_HOME=/home/kohkimakimoto/.rvm/gems/ruby-2.0.0-p0 /home/kohkimakimoto/.rvm/rubies/ruby-2.0.0-p0/bin/ruby -d /home/kohkimakimoto/.rvm/src/rubygems-2.0.3/setup.rb --verbose',
please read /home/kohkimakimoto/.rvm/log/ruby-2.0.0-p0/rubygems.install.log
Installation of rubygems did not complete successfully.

が、害はないらしいので、よしとする。以下参考サイト

バージョン確認しておしまい。

$ ruby -v
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux]

CentOSにRubyをcheckinstallでRPMにしてインストールする。

checkinstallrubyをRPM化する方法はネットに結構情報があるので、それを参考にすればできるのですが、作ったRPMをいざインストールしようとしたときに

# rpm -ivh ruby-1.8.7-p357.i386.rpm
エラー: 依存性の欠如:
/usr/bin/rubyruby-1.8.7-p357.i386 に必要とされています

のようなエラーがでて悩まされてました。これは

# rpm -ivh --nodeps ruby-1.8.7-p357.i386.rpm

とかで依存性を無視してインストールする方法はあるのですが、これだと依存性を解決できないのでローカルのyumリポジトリに置くこともできないですし、アンインストールしてもなぜか/usr/bin/rubyが残ってたりして、全然パッケージ管理されてなくね?ってな感じでもんもんとしてました。

でも、いろいろ調べたらなんとか解決できたっぽいのでその記録を残します。

まず前提としてcheckinstallをつかったrubyのRPM化の手順は

http://yktweb.sakura.ne.jp/blog/home-server/207.html
http://tejunsho.com/ruby/20110321000051.html
http://blog.flatlabs.net/20100415_202351/

などのサイトを参考にさせていただきました。

※(追記)checkinstallについて後日、別記事を書いたのでそちらも参照のこと

http://kohkimakimoto.hatenablog.com/entry/2012/04/15/140128

んでインストールでエラーに遭遇。

# rpm -ivh ruby-1.8.7-p357.i386.rpm
エラー: 依存性の欠如:
/usr/bin/rubyruby-1.8.7-p357.i386 に必要とされています

パッケージの情報を調べてみる。

# rpm2cpio ruby-1.8.7-p357.i386.rpm | cpio --list
./usr
./usr/bin
./usr/bin/erb
./usr/bin/irb
./usr/bin/rdoc
./usr/bin/ri
./usr/bin/testrb
./usr/doc
./usr/doc/ruby
./usr/doc/ruby/COPYING
./usr/doc/ruby/COPYING.ja
./usr/doc/ruby/ChangeLog
./usr/doc/ruby/GPL
./usr/doc/ruby/NEWS
./usr/doc/ruby/README
./usr/doc/ruby/README.EXT
./usr/doc/ruby/README.EXT.ja
./usr/doc/ruby/README.ja
./usr/doc/ruby/doc
./usr/doc/ruby/doc/ChangeLog-1.8.0
./usr/doc/ruby/doc/NEWS-1.8.0
./usr/doc/ruby/doc/forwardable.rd
./usr/doc/ruby/doc/forwardable.rd.ja
./usr/doc/ruby/doc/irb
./usr/doc/ruby/doc/irb/irb-tools.rd.ja
./usr/doc/ruby/doc/irb/irb.rd
./usr/doc/ruby/doc/irb/irb.rd.ja
./usr/doc/ruby/doc/shell.rd
./usr/doc/ruby/doc/shell.rd.ja
./usr/lib
./usr/lib/ruby
./usr/lib/ruby/1.8
./usr/lib/ruby/1.8/thread.rb
3486 blocks

お? /usr/bin/rubyがなくね?

でもcheckinstallを実行したときに/usr/bin/rubyもインストールはされているのだ。/usr/bin/rubyがインストールされていてもパッケージ管理されていないのがエラーの原因っぽいと推測。ちなみにyumでインストールしたruby1.8.5のrpmを調べると/usr/bin/rubyがちゃんとある。

RPMについて調べると、管理するファイルの情報は.specファイルに設定を書くとのこと。checkinstallで.specファイルをカスタマイズする方法はないものか調査する。checkinstallのREADMEファイルを読むとREVIEW_SPECというパラメータをtrueにすればパッケージ作成前に.specファイルを編集できるらしい。

checkinstallの起動コマンドはシェルスクリプトなのでこの中を読んでみたりもすると以下のように--review-specオプションつきでcheckinstallを起動すればよいことがわかった。

# checkinstall --fstrans=no --review-spec

このコマンドを実行すると実行途中で.specファイル編集画面に切り替わるので

Summary:   Package created with checkinstall 1.6.2
Name:      ruby
Version:   1.8.7
Release:   p357
License: GPL
Packager:  checkinstall-1.6.2
Group:     Applications/System
BuildRoot: /var/tmp/tmp.GWEdXG1817/package
Provides:  ruby-1.8.7
Requires:  ,/bin/sh

%description
Package created with checkinstall 1.6.2

%files
%dir "//usr/"
%dir "//usr/bin/"
"//usr/bin/ruby"   # ここを追加
"//usr/bin/irb"
"//usr/bin/erb"
....

のようにしてみる修正してみる。続行するが、エラー発生。

エラー: ファイルが見つかりません: /var/tmp/tmp.bqPnjt4646/package/usr/bin/ruby
伸張ファイルの検査中: /usr/lib/rpm/check-files /var/tmp/tmp.bqPnjt4646/package

RPM ビルドエラー:
  ファイルが見つかりません: /var/tmp/tmp.bqPnjt4646/package/usr/bin/ruby

./usr/bin/rubyがない? おお確かに。make済みのrubyソースディレクトリをみると、トップの階層にrubyのバイナリファイルがある。これをbinの階層にコピーしてしまおう。

# cd /var/tmp/ruby-1.8.7-p357
# cp -p ./ruby ./bin/

も一回トライ。

# checkinstall --fstrans=no --review-spec

エラーなく突破する! パッケージの内容を確認してみる。

# rpm2cpio /usr/src/redhat/RPMS/i386/ruby-1.8.7-p357.i386.rpm | cpio --list

./usr/bin/rubyがちゃんとありました。続けてインストール~。

# rpm -ivh /usr/src/redhat/RPMS/i386/ruby-1.8.7-p357.i386.rpm
準備中...                ########################################### [100%]
  1:ruby                   ########################################### [100%]

無事イケました。アンインストールもしてみる。

# rpm -e ruby
# which ruby
/usr/bin/which: no ruby in (/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin)

ちゃんとアンインストールされている。よかった~。

※追記。
--install=noをつければcheckinstall実行時にインストールしないので、yumやrpmコマンドで改めてインストールしたい場合はこれをつけたほうが良さげ。

# checkinstall --fstrans=no --review-spec --install=no