pirosikick's diary

君のハートにunshift

yeomanでcompass_twitter_bootstrapでエラーが出る

% mkdir hoge
% cd hoge

# 全部Yにする
% yo angular
Would you like to include Twitter Bootstrap? (Y/n) Y
If so, would you like to use Twitter Bootstrap for Compass (as opposed to vanilla CSS)? (Y/n) Y
Would you like to include angular-resource.js? (Y/n) Y
Would you like to include angular-cookies.js? (Y/n) Y
Would you like to include angular-sanitize.js? (Y/n) Y

(省略)

% npm install && bower install 

(省略)

こんな感じでyeomanでangularjsのひな形を作って、

% grunt server

ってやるとブラウザが起動するんだけど、

Syntax error: File to import not found or unreadable: compass_twitter_bootstrap.
              Load paths:
                /Users/hanai/work/hoge/app/styles
                /Users/hanai/.rbenv/versions/2.0.0-dev/lib/ruby/gems/2.0.0/gems/compass-0.12.2/frameworks/blueprint/stylesheets
                /Users/hanai/.rbenv/versions/2.0.0-dev/lib/ruby/gems/2.0.0/gems/compass-0.12.2/frameworks/compass/stylesheets
                /Users/hanai/work/hoge/app/components
                Compass::SpriteImporter
        on line 1 of /Users/hanai/work/hoge/app/styles/main.scss

っていうエラーが出る。

main.scssには、

@import 'compass_twitter_bootstarp`;

の1行だけだったので、

% gem install compass_twitter_bootstrap

でインストールしたんだけどダメ。。これで1週間くらいわからず放置。

解決方法

compassでgemからパーツをimportするには、config.rbを置いてそのgemをrequireしなくちゃいけないらしい。 なので、config.rbにrequireを書いたら出なくなりました!やほーい!

# config.rb
require 'compass_twitter_bootstrap'

PHP5.4のClosure::bindToを使ってJavaScriptのクロージャもどき作った

php

PHP5.4からClosure::bindToClosure::bindというのが追加されている。

これは何かというと、JavaScriptで言うところのFunction.prototype.callみたいな感じで、無名関数に対してオブジェクトを割り当てることができ、その無名関数をそのオブジェクトのメソッドと同等のスコープで実行できるようにする。

<?php

/**
 * 適当にクラスを定義
 */
class Hoge
{
    private $_hoge = "hoge";
}

/**
 * 無名関数を定義
 */
$function = function () {
    var_dump($this->_hoge);
};

/**
 * Hogeクラスのインスタンスをbind
 */
$function = $function->bindTo(new Hoge());

$function(); // string(4) "hoge";

PHP5.3で同じようなことをしようと思うとuseキーワードを使って静的に行う必要があったので、それが動的にできるというのは結構いいかもしれない。

本題

で、ちょっと遊んでみようと思ってJavaScriptのクロージャもどきを作ったんだけど、誰得なんだよwwwと一人でニヤニヤしてしまったので久々にブログを書きました。

phpenvインストールして、php-5.4.5をインストール

php

参考

homebrewで下記をインストール

$ brew install phpenv
$ brew install php_build

# phpenvでphpをインストールするときに必要
$ brew install wget re2c libmcrypt 

rbenv的なやつを.zshrcに書く。参考資料によるとrbenvの設定より後に書かないと行けないらしい。

which phpenv > /dev/null
if [ $? != 0 ]; then
  eval "$(phpenv init -)"
fi

PATHに$HOME/.phpenv/binを追加する

export PATH=$PATH:$HOME/.phpenv/bin

設定を読みこませるためにzshを再度起動

$ exec zsh

php-buildでphp-5.4.5をインストール

$ php-build 5.4.5 ~/.phpenv/versions/5.4.5
...

# インストール確認
$ phpenv versions
  5.4.5 (set by /Users/hanai/.phpenv/version)

phpenv globalで5.4.5を指定し、phpenv rehashする

$ phpenv global 5.4.5
$ phpenv rehash
$ php -v
PHP 5.4.5 (cli) (built: Mar 19 2013 00:58:18)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
    with Xdebug v2.2.0, Copyright (c) 2002-2012, by Derick Rethans

OS X 10.8.2 MySQL PHP PDOでエラーが出る

fuelのmigrateで下記エラーが出る

$ oil refine migrate
Error: PDO::__construct(): [2002] No such file or directory (trying to connect via unix:///var/mysql/mysql.sock) in /Users/hanai/work/hoge/fuel/core/classes/database/pdo/connection.php on 89

デフォルトのphp.iniが/var/mysql/mysql.sockを見に行くような設定になっているのが原因。homebrewでmysqlをインストールした場合だと/tmp/mysql.sockなのでそっちを見るように変更する。

$ diff -u /etc/php.ini.default /etc/php.ini

--- /etc/php.ini.default	2012-07-26 23:49:20.000000000 +0900
+++ /etc/php.ini	2012-12-07 01:13:46.000000000 +0900
@@ -1074,7 +1074,8 @@
 ; Default socket name for local MySQL connects.  If empty, uses the built-in
 ; MySQL defaults.
 ; http://php.net/pdo_mysql.default-socket
-pdo_mysql.default_socket=/var/mysql/mysql.sock
+;pdo_mysql.default_socket=/var/mysql/mysql.sock
+pdo_mysql.default_socket=/tmp/mysql.sock
 
 [Phar]
 ; http://php.net/phar.readonly
@@ -1228,7 +1229,8 @@
 ; Default socket name for local MySQL connects.  If empty, uses the built-in
 ; MySQL defaults.
 ; http://php.net/mysql.default-socket
-mysql.default_socket = /var/mysql/mysql.sock
+;mysql.default_socket = /var/mysql/mysql.sock
+mysql.default_socket = /tmp/mysql.sock
 
 ; Default host for mysql_connect() (doesn't apply in safe mode).
 ; http://php.net/mysql.default-host
@@ -1287,7 +1289,8 @@
 ; Default socket name for local MySQL connects.  If empty, uses the built-in
 ; MySQL defaults.
 ; http://php.net/mysqli.default-socket
-mysqli.default_socket = /var/mysql/mysql.sock
+;mysqli.default_socket = /var/mysql/mysql.sock
+mysqli.default_socket = /tmp/mysql.sock
 
 ; Default host for mysql_connect() (doesn't apply in safe mode).
 ; http://php.net/mysqli.default-host

Redmine Plugin migrationの作成

プラグインチュートリアル

RedmineのPlugin作成時にController, Modelを作るときは下記コマンドで自動生成される

# model生成
# ex)hogeモデル
$ rails generate redmine_plugin_model plugin_name hoge column_name:column_type ...
# cntroller生成
# ex) hoges_controller
$ rails generate redmine_plugin_controller plugin_name hoges_controller action_name action_name ...

が、migrationを作成するコマンドは無いらしい。

Plugin migrations for Redmine

上記ページによると、Redmineのディレクトリトップで rails generate migration を実行し、db/migrate配下にmigrationを作成後、plugins/プラグイン名/db/migrate配下に移動するのが良いとのこと。 注意点として、コピーするときにタイムスタンプ(201201...)になっている部分を連番(001_..)に変える必要がある。

Redmineのapp/models/user.rbにメソッドを追加しようとしてハマった

このページの「Redmine の本体機能の拡張」>「新しいメソッドの追加」を参考にapp/models/user.rbにメソッド追加しようとしたら、Redmine起動時に下記エラーが出た。

$ RAILS_ENV=development be rails
=> Booting WEBrick
=> Rails 3.2.8 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
Exiting
/Users/hanai/dev/redmine/vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.8/lib/active_support/dependencies.rb:503:in `load_missing_constant': Expected /Users/hanai/dev/redmine/app/models/user.rb to define User (LoadError)

メソッドを追加するコードは下記で$REDMINE/plugin/$PLUGIN_NAME/lib/user_patch.rbというファイル名で保存。 $REDMINE/plugin/$PLUGIN_NAME/init.rbに「require_dependency 'user_patch'」の1行を追加し、読みこむようにする。

#
# lib/user_patch.rb
#
require_dependency 'user'

module UserPatch
  def self.included(base)
    base.extend(ClassMethods)

    base.send(:include, InstanceMethods)

    base.class_eval do
    end
  end

  module ClassMethods
  end

  module InstanceMethods
  	# 追加したいメソッド
    def hoge_method
    	"hello plugin"
    end
  end
end

User.send(:include, UserPatch)

解決方法は、user_patch.rbでprincipal, projectもrequire_dependencyすればよろし。

#
# lib/user_patch.rb
#

# 追加
require_dependency 'project'
require_dependency 'principal'

require_dependency 'user'

module UserPatch
  def self.included(base)
    base.extend(ClassMethods)

    base.send(:include, InstanceMethods)

    base.class_eval do
    end
  end

  module ClassMethods
  end

  module InstanceMethods
  	# 追加したいメソッド
    def hoge_method
    	"hello plugin"
    end
  end
end

User.send(:include, UserPatch)

なぜこうなるかは結局よくわからなかった。。issue.rbはサンプル通りでOKだったし、サンプルのissue_patch.rbを一緒に読み込むとうまくいったりと普段rubyやらrailsを触らない俺にとっては謎だった。

参考資料

Doesn't patch "User" model in a plugin

OS X Moutain Lionにredmineをインストール

redmineのプラグインの作り方を勉強するためにMBAredmineを動かす環境を構築したときのメモ。

rbenv, bundlerインストール

自分の環境にはすでに入っていますが、これからインストールする人はこちらを参考にしてください。 いちいちbundle execって打つのは面倒なので、下記aliasを.zshrcなり.bashrcなりに入れてくだされ。

alias be="bundle exec"

redmineダウンロード

rubyforgeから2.1.2をダウンロード

$ wget http://rubyforge.org/frs/download.php/76497/redmine-2.1.2.zip
$ unzip redmine-2.1.2
$ cd redmine-2.1.2

ImageMagickインストール

homebrewでインストール可

$ brew install imagemagick

(途中省略)

Warning: Could not link imagemagick. Unlinking...
Error: The `brew link` step did not complete successfully
The formula built, but is not symlinked into /usr/local
You can try again using `brew link imagemagick'
Error: Permission denied - /usr/local/etc/ImageMagick

linkできなかったのでbrew link imagemagickを叩いて手動でリンクしろとのこと。

$ brew link imagemagick
Linking /usr/local/Cellar/imagemagick/6.7.7-6... Warning: Could not link imagemagick. Unlinking...
Error: Permission denied - /usr/local/etc/ImageMagick

/usr/local/etcがroot権限で作成されており、リンクが貼れない様子。 こちらを見る感じだと、homebrewを介さずにインストールした時に/usr/local以下のパーミッションがおかしくなってしまうことがあるとのこと。 brew doctorっていうコマンドで検知できるっぽい。叩いてみたらいろいろあったので自分の環境もおかしくなっていたのだろう。 ということで、/usr/local/etcをchownし自分の権限で所有する。

$ sudo chown -R `whoami` /usr/lcoal/etc
$ brew link imagemagick
Linking /usr/local/Cellar/imagemagick/6.7.7-6... 65 symlinks created

OK!

bundle install

必要ないパッケージは省いてインストール。今回はsqlite3で構築するので、mysqlpostgresqlも省く

$ bundle install --path vender/bundle --without=development test mysql postgresqlkk

セッション暗号化用鍵の生成

$ bundle exec rake generate_secret_token

DB初期化

DBの構築。すんなりOK!

$ RAILS_ENV=production bundle exec rake db:migrate

初期データの流しこみでコケる。

$ RAILS_ENV=production rake redmine:load_default_data
(in /Users/hanai/dev/redmine-2.1.2)
rake aborted!
uninitialized constant Rake::DSL
(省略)

こちらをみるとrakeのバージョンを0.8.7に固定すると治るらしい。 Gemfileに下記1行を追加。

gem 'rake', '0.8.7'

bundle update rakeを実行

$ bundle update rake

成功。もう1度、データ流し込み

$ RAILS_ENV=production rake
(in /Users/hanai/dev/redmine-2.1.2)

Select language: ar, bg, bs, ca, cs, da, de, el, en, en-GB, es, et, eu, fa, fi, fr, gl, he, hr, hu, id, it, ja, ko, lt, lv, mk, mn, nl, no, pl, pt, pt-BR, ro, ru, sk, sl, sq, sr, sr-YU, sv, th, tr, uk, vi, zh, zh-TW [en] ja ← jaと入力してEnter
====================================
Default configuration data loaded.

OK!

WEBrickで起動

$ be ruby script/rails server webrick -e production
=> Booting WEBrick
=> Rails 3.2.8 application starting in production on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2012-10-15 00:43:30] INFO  WEBrick 1.3.1
[2012-10-15 00:43:30] INFO  ruby 1.9.2 (2011-07-09) [x86_64-darwin11.4.2]
[2012-10-15 00:43:30] INFO  WEBrick::HTTPServer#start: pid=34361 port=3000

ブラウザでhttp://localhost:3000/に接続し、redmineのホーム画面が表示されればOK!

参考

http://redmine.jp/guide/RedmineInstall/