compoundJSをinstallしようとしたらnpmが古くてハマった件

sudo npm install compound -g

とやるとエラー。。

$ sudo npm install compound -g
Password:
npm http GET https://registry.npmjs.org/compound
npm http 304 https://registry.npmjs.org/compound
npm http GET https://registry.npmjs.org/compound/-/compound-1.1.7-11.tgz
npm http 200 https://registry.npmjs.org/compound/-/compound-1.1.7-11.tgz
npm ERR! tar pack Error reading /Users/takayuki/tmp/npm-93579/1383704569828-0.4227180201560259/package
npm ERR! TypeError: Cannot call method 'filter' of undefined
npm ERR!     at Packer.IgnoreReader.addIgnoreRules (/Users/takayuki/.nvm/v0.8.4/lib/node_modules/npm/node_modules/fstream-npm/node_modules/fstream-ignore/ignore.js:148:13)
npm ERR!     at Packer.IgnoreReader.addIgnoreFile (/Users/takayuki/.nvm/v0.8.4/lib/node_modules/npm/node_modules/fstream-npm/node_modules/fstream-ignore/ignore.js:133:10)
npm ERR!     at fs.readFile (fs.js:176:14)
npm ERR!     at fs.close (/Users/takayuki/.nvm/v0.8.4/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:94:5)
npm ERR!     at Object.oncomplete (fs.js:297:15)
npm ERR! If you need help, you may report this log at:
npm ERR!     <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR!     <npm-@googlegroups.com>

npm ERR! System Darwin 12.5.0
npm ERR! command "/Users/takayuki/.nvm/v0.8.4/bin/node" "/Users/takayuki/.nvm/v0.8.4/bin/npm" "install" "compound" "-g"
npm ERR! cwd /Users/takayuki
npm ERR! node -v v0.8.4
npm ERR! npm -v 1.1.45
npm ERR! type non_object_property_call
npm ERR! addLocalDirectory Could not pack "/Users/takayuki/tmp/npm-93579/1383704569828-0.4227180201560259/package" to "/Users/takayuki/.npm/compound/1.1.7-11/package.tgz"
npm ERR! SyntaxError: Unexpected token {
npm ERR!     at Object.parse (native)
npm ERR!     at Packer.readRules (/Users/takayuki/.nvm/v0.8.4/lib/node_modules/npm/node_modules/fstream-npm/fstream-npm.js:188:33)
npm ERR!     at Packer.IgnoreReader.addIgnoreFile (/Users/takayuki/.nvm/v0.8.4/lib/node_modules/npm/node_modules/fstream-npm/node_modules/fstream-ignore/ignore.js:132:22)
npm ERR!     at fs.readFile (fs.js:176:14)
npm ERR!     at fs.close (/Users/takayuki/.nvm/v0.8.4/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:94:5)
npm ERR!     at Object.oncomplete (fs.js:297:15)
npm ERR! If you need help, you may report this log at:
npm ERR!     <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR!     <npm-@googlegroups.com>

npm ERR! System Darwin 12.5.0
npm ERR! command "/Users/takayuki/.nvm/v0.8.4/bin/node" "/Users/takayuki/.nvm/v0.8.4/bin/npm" "install" "compound" "-g"
npm ERR! cwd /Users/takayuki
npm ERR! node -v v0.8.4
npm ERR! npm -v 1.1.45
npm ERR! file /Users/takayuki/tmp/npm-93579/1383704569828-0.4227180201560259/package/templates/package.json
npm ERR! path /Users/takayuki/tmp/npm-93579/1383704569828-0.4227180201560259/package/templates
npm ERR! type unexpected_token
npm ERR! fstream_path /Users/takayuki/tmp/npm-93579/1383704569828-0.4227180201560259/package/templates
npm ERR! fstream_type Directory
npm ERR! fstream_class Packer
npm ERR! fstream_stack Packer.readRules (/Users/takayuki/.nvm/v0.8.4/lib/node_modules/npm/node_modules/fstream-npm/fstream-npm.js:191:10)
npm ERR! fstream_stack Packer.IgnoreReader.addIgnoreFile (/Users/takayuki/.nvm/v0.8.4/lib/node_modules/npm/node_modules/fstream-npm/node_modules/fstream-ignore/ignore.js:132:22)
npm ERR! fstream_stack fs.readFile (fs.js:176:14)
npm ERR! fstream_stack fs.close (/Users/takayuki/.nvm/v0.8.4/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:94:5)
npm ERR! fstream_stack Object.oncomplete (fs.js:297:15)
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /Users/takayuki/npm-debug.log
npm ERR! not ok code 0

ぎょええ。。「TypeError: Cannot call method 'filter' of undefined」を調べると、npmの最新では治ってるYO!とあったので、バージョンを確認。

npmとnodeのバージョンは下記。

$ npm -v
1.1.45

$node -v
v0.8.4

npmはnodeのバージョンに依存しているようなので、nodeのバージョンを上げてみる。 nvmが早速役に立つとは。

nvm ls-remote

をするとなんとv0.11.8まえある。。v0.10.6まで上げてみる。

nvm install v0.10.6

で再チャレンジしたところ・・通ったーーー!

nvmをmacに入れてnodeのバージョン管理

nodeのバージョン管理するためにnvmをインストール

git clone git://github.com/creationix/nvm.git ~/.nvm

nvmコマンドを使えるようにする

source ~/.nvm/nvm.sh

ターミナル起動時にこれを自動化するために

[[ -s "$HOME/.nvm/nvm.sh" ]] && source "$HOME/.nvm/nvm.sh"

を.bash_profileに追加。

参考:【Node.js】nvmをインストールして設定するまでの方法 | creator note

その他にも

  • nodebrew
  • nave

という管理ツールがあるそうです。

参考:nvmでnode.jsを管理する | MOL

kaminariを使ってpaginationを実装したら思ったより簡単だった

kaminariって?

amatsuda/kaminari https://github.com/amatsuda/kaminari

ページングの実装をやってくれるgemです。

例えばこんな感じのものです。

f:id:shmztkyk:20131031013712p:plain

自前で作ったこともありますが、最後のページのとき表示を変えるとか、ページ数が多いときは省略表示にするとか、細かいロジックを入れだすとけっこうたいへんなので、今回はkaminariを使うことに。

使い方

サンプルにpersonテーブルを作ってやってみます。

1 . gemfileに追加

gem 'kaminari'

2 . bundle install

3 . scaffoldでテーブル作成

rails g scaffold person name:string

peopleテーブルのひな形ができます。

4 . migrateしてでもデータ入れる

rake db:migrate

データはrails sしてPerson.create(:name=>'hoge')で適当にデータを作成

5 . themeの変更 見た目をいくつかのthemeに変更したり、カスタマイズしたりもできるので、やってみました。 bootstrapにも対応しているようなので

rails g kaminari:views bootstrap

とやってみると

$rails g kaminari:views bootstrap
      downloading app/views/kaminari/_first_page.html.erb from kaminari_themes...
      create  app/views/kaminari/_first_page.html.erb
      downloading app/views/kaminari/_gap.html.erb from kaminari_themes...
      create  app/views/kaminari/_gap.html.erb
      downloading app/views/kaminari/_last_page.html.erb from kaminari_themes...
      create  app/views/kaminari/_last_page.html.erb
      downloading app/views/kaminari/_next_page.html.erb from kaminari_themes...
      create  app/views/kaminari/_next_page.html.erb
      downloading app/views/kaminari/_page.html.erb from kaminari_themes...
      create  app/views/kaminari/_page.html.erb
      downloading app/views/kaminari/_paginator.html.erb from kaminari_themes...
      create  app/views/kaminari/_paginator.html.erb
      downloading app/views/kaminari/_prev_page.html.erb from kaminari_themes...
      create  app/views/kaminari/_prev_page.html.erb

てな感じでviewsを生成してくれます。

6 . controllerを編集 先ほどscaffoldでつくったpeopleテーブルの一覧で表示させてみます。

   def index
     @people = Person.all.page(params[:page]).per(3)
   end

とするとページングしたレコードをとてきてくれます。per=3であればlimit3で、pageが増えるごとにoffsetが増えたSQLが発行されます。

7 . viewsを編集

あとは表示したい部分で

<%= paginate @people %>

としてあげればOK.

のはずでしたが、どうもcssが効いてないものが表示されてしまったので、おかしいなと思って、app/views/kaminari/_paginator.html.erb を見てみると

<%= paginator.render do -%>                                                                                                                                                     
  2   <div class="pagination">
  3     <ul>
  4       <%= first_page_tag unless current_page.first? %>
  5       <%= prev_page_tag unless current_page.first? %>
  6       <% each_page do |page| -%>
  7         <% if page.left_outer? || page.right_outer? || page.inside_window? -%>
  8           <%= page_tag page %>
  9         <% elsif !page.was_truncated? -%>
 10           <%= gap_tag %>
 11         <% end -%>
 12       <% end -%>
 13       <%= next_page_tag unless current_page.last? %>
 14       <%= last_page_tag unless current_page.last? %>
 15     </ul>
 16   </div>
 17 <% end -%>

となっており、ulにpaginationのクラスが書かれてないことが判明。。これは僕の使っているbootstrapが3.0だからなのかthemeが違うのか不明ですが、

<ul class='pagination'>

と書き換えて完了。

f:id:shmztkyk:20131031013715p:plain

こんな感じになりました。

Brakemanでrailsアプリケーションのセキュリティチェックしてみる

f:id:shmztkyk:20131023152545p:plain

brakemanっていうセキュリティチェックのgemを使ってみた。

Brakeman - Rails Security Scanner http://brakemanscanner.org/

gem install brakeman

でインストールして、既存のrailsプロジェクト直下で

brakeman

とするだけで、簡単なレポートが表示されます。

brakeman -o report.html
open report.html

でhtmlでレポートを見ることも可能。Basic Authのパスワードがベタ打ちで書いてあるよー、QL Injection の可能性があるコードがあるよーなど、具体的に教えてくれる。

これでどこまでセキュリティが担保されるのかは細かく見てないけど、3分もかからず見れるのでやってみる価値ありですね。

jenkinsのpluginがあるので自動化して定期的にmailでreport出せるとよさそうだなぁ

Titanium Mobileでアプリをどう書くか - マルチコンテキストからクラス設計まで -

Titanium でアプリ開発でなにげに苦労したのが

「この機能をどう書くか」

でなく

「全体としてどう書くか」

のお作法というか設計よりの部分。
自分はけっこういろいろ変わったので時系列にそってまとめておきます。

・目次(時系列順)



1.マルチコンテキスト+include (2011/6~)
2.マルチコンテキスト+include+coffeescript (2011/9~)
3.シングルコンテキスト+require(CommonJs) (2012/2~)
4.シングルコンテキスト+require+coffeescriptでクラスベース設計 (2012/3~)
5.MVCではなくMOVE(Model/Oparation/View/Event/)で (2012/5~)
6.公式に出たAlloyがデフォ?(今後?)



1.マルチコンテキスト+include(2011/6~)



このころ初めて教本片手にtitaniumを触ってみました。

このころ主流だったマルチコンテキストは、ざっくり言うとwindowオブジェクトを作るときにurlプロパティで渡すようにする書き方で、文字通りコンテキスト(一番大きいスコープ)がwindow単位で切り分けられます。

varwindow = Ti.UI.createWindow({ url:"lib/hoge.js"});
window.open();


利点:
・教本もありわかりやすかった
・初学者にシングルコンテキストより理解しやすい(個人的にそう思いました)

デメリット:
・Window間の文字の受け渡しが煩雑
・挙動が不安定
・即時関数を使ってスコープをちゃんと切り分けないとややこしいことになる。


 自分はまずはお勉強でさわっていたので気にならなかったですが、やはりちゃんとプロダクトとして出すことを考えるととくに挙動が不安定な点はネックでした。
はwindowを切り替わる際に新しいwindowのファイルを読み込むため、ガタンっともたつく感じがあったり。


あとincludeするというのは、ファイルを切り分けているとはいえ、スコープは大きい一つのファイルに上からダーッと書いてるものと同様なので、include先はそれぞれ即時関数でスコープをちゃんと切ってやる必要があったりして最初手こずった記憶があります。


しかし、プログラミング経験数ヶ月のあのときの自分でも教本見ながら理解できて、iphoneアプリっぽいものがある程度の自由度を持って作れることは魅力的でした。



2.マルチコンテキスト+include+coffeescript



1,2ヶ月してサンプルくらいは作れるようになってさて実際なにかオリジナルなものを作ってみるかといったタイミングで、javascriptを生で書くのではなくcoffeescriptで書いてみることにしました。


ここはいろいろ意見がわかれる点かと思いますが、記述がシンプルになったり、jsにコンパイルするときにいろいろ最適化してくれるというタレコミのもと、とりあえずお勉強だと思って使ってみました。


結果クラスベースっぽくその先で書くことになり、今も愛用しております。


ファイル保存をフックに、coffeeファイルをjsに自動コンパイルするための準備はこちらを参考に。
GuardでTitanium+CoffeeScriptの開発を快適に

coffeescriptってなにが便利って方はこちら:
CoffeeScript で Titanium Mobile すると嬉しいのか?


3.シングルコンテキスト+require(CommonJs)



開いた時間にマイペースで開発を続けること数ヶ月、ある程度アプリが形になってきた!ってタイミングですごい変更が入りました。


マルチコンテキストをシングルコンテキストにしろと言うのです。大枠としてCommonJsにしたがってという方針になったようでその関係でincludeはもう非推奨ですよと。requireでファイルを読み込んでくださいと。


ぐふぅっ・・っとなったのですが、まぁしょうがないか、と切り替えすべてコードを書き換えることに。。
思った以上の大仕事でした。


参考ページ:
CommonJS + シングルコンテキストで実装?? #titaniumjp 
公式ドキュメント:Mobile Best Practices




4.シングルコンテキスト+require+coffeescriptでクラスベース設計



アプリを作っていると、ホーム画面とユーザー画面のUIがほぼ一緒だったり、セルの若干のUIの違いだけであとは同じみたいなリストビューとかがでてくることが増えてきました。


そこでクラスをつくって、基底クラスをしっかりつくって幸せになりたいなと思うところなのですが、jsのプロトタイプベースでやるのはちょっと億劫、、というところでcoffeescriptのクラスを使いました。


coffeeスクリプトのスラスの書き方についてはコチラ:
CoffeeScript入門 


プロジェクト途中から入れるのはいろいろめんどくさい作業が発生するので、できれば初期から使うか考えとくのをおすすめします。


5.MVCというよりMOVEで



だいぶ幸せに開発ができるようになってきたのですが、クラスベースにして、再利用性を少し上げても、ある程度の大きさのアプリを書こうとすると、一画面にUI生成, リクエスト、モジュールの読み込み、イベント、ビューの状態の情報などロジックと様々な要素が混在し始めます。

たとえば最近リリースしましたこのTitanium Mobile製アプリ:


英語1000時間 - TAKAYUKI SHIMIZU



シンブルなように見えますが、ユーザーのアクションによって表示要素を変えたり保存したり、カレンダーの日付を保持したり、日付の計算ロジックだったり、他のwindowを開いたりと、裏では思ったより要素が盛り盛りとなっています。


そんなごちゃごちゃのところでバグのリファクタなどしても精神衛生上よろしくないので、このアプリを作る前にちゃんとクラス設計をして書いたほうがよいなと思い、いろいろ思考錯誤していました。


そこで厳密にはMVCではないながら、それっぽい書き方を改良してやっていたら、それはMOVEと言われるものに近いようでしたので、MOVEということにしときます。


原文: MVC is dead, it's time to MOVE on. 
翻訳してくれてるところはこちら: http://d.hatena.ne.jp/nowokay/20120704


ざっくり言うと、


MOVE = モデル(M),オペレーション(O),ビュー(V),イベント(E)


という4つの役割を定義し、それにもとづいてクラスを設計していきます。
これにより、記述すべきファイルにコードが分断され、またより疎結合なコードになります。



自分は主に以下のようなフォルダ構成でやっています。EventはEventを定義するだけのファイルで、他はWindow(Scene)ごとにそれぞれ作られます。
.
├── Component(View)
├── Event(Event)
├── Model(Model)
└── Window(Oparation)

このあたりについては次の機会にもうすこし具体的にまとめようと思います。


6.公式に出たAlloyがデフォ?



ちょっと前にbetaで出ていたAppceleratorの公式アプリケーションフレームワーク
ちゃんと正式リリースされたようですね。


5の俺俺フレームワークでひとまず事足りているのであまり触れていないのですが、最終的にはこっちのほうがよいのかな?先人の方に伺いたいところ。


以上TitaniumMobileの書き方振り返りでした。

deamontools+starmanなサーバーで初歩的ミス

deamontoolsをつかってstarman+psgiなサーバーを使っていたわけですが、どうもgit pullしたコードが反映されない。。とおもっていたら

サーバー再起動忘れていましたorz
apacheのときと同じようにやればよかったようです。

deamontoolsの使い方は以下。再開して確認したらちゃんと反映されていました。

# 状況確認
svstat /service/MyApp
# 一時停止
svc -d /service/MyApp
# 再開
svc -u /service/MyApp
# 停止(.で置き換えて監視下から外す
mv /service/MyApp /service/.MyApp;
# svc -dx /service/.MyApp