#!/usr/bin/env coffee
do ->
co = require 'co'
params = []
for i, v of process.argv
if i > 2
params.push v
task = require './tasks/' + process.argv[2]
if not task
console.log 'Nothing to do.'
return
co.apply this, [task].concat params
.catch (e)->
console.error e.stack
.then ->
console.info '[DONE]'
で task
みたいな名前で保存して
$ chmod a+x task
しておく。
.
├── task
└── tasks
├── a.coffee
└── user
├── add.coffee
├── remove.coffee
└── show.coffee
みたいな構成で、 tasks/a.coffeeに
module.exports = (p1, p2)->
console.log p1
yield new Promise (r)->
setTimeout ->
do r
, 2000
console.log p2
yield new Promise (r)->
setTimeout ->
do r
, 1000
みたいに書いて
$ ./task a 1 2
を実行すると、まず1
って出て、二秒後に2
って出て、一秒後に[DONE]
と出て終わる。これを利用すればユーザーをmongoose経由でmongoに追加する処理であれば./tasks/user/add.coffeeに、
module.exports = (p1, p2)->
models = require '../../models'
User = models.User
if not p1 or not p2
console.log 'plz specify username and password'
return
admin = new User
username: p1
password: p2
approved: true
u = yield admin.save()
console.log 'added user: ', JSON.stringify u, 0, 4
みたいに書けば
./task user/add takuya mugendai
とやってやればそのまま有効なユーザーが作成できる。これの何が嬉しいって、
User.pre 'save', (next)->
co (->
salt = yield bcryptGenSalt 10
@password = yield bcryptHash @password, salt
do next
).call this
.catch (err)->
next err
こんな感じにパスワードを暗号化したものに差し替える処理とか保存時に引っかかっててもちゃんと保存できるようになるのである。mongoのシェルも便利だが、直接触るとどうしてもリレーションがぶっ壊れたりして鬱陶しいので、こうやって内部に割り込めると非常に助かる。ちょうどrails console
とかpython manage.py shell
みたいなノリだ(RailsやDjangoは保存とかもすべて同期的にやってくれるので、あまりこういう悩みはないけど)。
とにかくgenerator文はめっちゃ便利。