Macでの開発効率をアップする、マウントせずにローカルのソースコードをサーバーと同期するスクリプト書いた。
しかだよ。
変更があったローカルのソースコードをサーバーのソースコードと同期しながらwebアプリを開発できるスクリプトを作りました。
shikajiro/eventsync.py
2012/07/10 追記
下で説明するソースコードは古いので、shikajiro/eventsync.pyの方を見てくださいね。
webアプリ開発の問題点
- マウントしたりsshでサーバーに接続してwebアプリを開発してると、回線が遅くて画面が固まることがあり、ストレスフルなコーディングを強いられている。
- ローカルのソースをgitでpushしてサーバーに反映するのは複数人の場合はいいけど、一人用の場合は毎回add commit push がめんどい。
プログラマーが楽しくプログラミングできないのは罪です。直ちに懺悔するか解決しましょう。
開発中のwebアプリを動かす場所を比較検討
実行場所 | 公開範囲 | 反応スピード | PC負荷 | 柔軟性 |
---|---|---|---|---|
ローカルのmac | × | ◯ | △ | × |
vmwareのLinux | × | △ | × | ◯ |
レンタルサーバー | ◯ | × | ◯ | △ |
- ローカルでwebアプリを動かすとレスポンスとか速いんだけど、複数環境などで柔軟性に欠ける。
- vmwareだと柔軟性高いんだけど、メモリとCPU消費が激しくて遅い。
- 上記2つはさらにネットに公開されていないのでテストしにくい。
- レンサバは公開されてて扱い易いけど、直接コーディングするにはレスポンスが遅い。
今この瞬間作っているものをストレス無くサーバーで確認したいのです!
というわけで、「サーバーに常時接続せず」「ローカルで開発できて」「ソースコードに変更があったらサーバーを更新する」方法を探りました。
ソースコードの同期はrsyncで
コードの同期はrsyncでできました。問題は「ソースコードの追加・変更・削除」をどうやって検知するかです。
lsync
Linuxディストリビューションならlsyncを使うとファイルの変更検知ができるみたいですが、Mac OS X はBSDなので、これは使えませんでした。
フォルダアクション
Mac OS X にはフォルダアクションというフォルダ監視の仕組みがあります。フォルダに変更があるとautomatorを実行出来たりします。しかしこれは「フォルダへのファイルの追加」のみ検知可能だったため断念しました。
kevent kqueue
BSDはLinuxとは別の方法でファイルを監視する事が可能でした。それが kevent kqueueです。
*BSD で kqueue・kevent を使ってみよう
pythonスクリプト
んで、色んなサイトのソースコードを参考にしてできました。
shikajiro/eventsync.py
import select import os import sys def kevent(file): ke = select.kevent(file, filter=select.KQ_FILTER_VNODE, flags=select.KQ_EV_ADD | select.KQ_EV_ENABLE | select.KQ_EV_CLEAR, fflags=select.KQ_NOTE_DELETE | select.KQ_NOTE_WRITE ) return ke argvs = sys.argv argc = len(argvs) if(argc != 3): print 'Usage: python {} filename.'.format(argvs[0]) quit() folder = argvs[1] ssh = argvs[2] print '{} to {}'.format(folder, ssh) print 'file update watching...' dirs = os.walk(folder) l = [] for root, dirs, files in dirs: f = os.open(root, os.O_RDONLY) l.append(kevent(f)) for a in files: f = os.open(root + '/' + a, os.O_RDONLY) l.append(kevent(f)) kq = select.kqueue() events = kq.control(l, 0, None) while True: r_events = kq.control(l, 1, None) for event in r_events: print event if event.fflags & select.KQ_NOTE_DELETE or event.fflags & select.KQ_NOTE_WRITE: print "file was updated!" command = 'rsync -av --delete -e ssh {} {}'.format(os.path.join(os.getcwd(), folder), ssh) print command os.system(command)
python eventsync.py watchdir/ shikajiro@hostname:/dir/
第一引数に監視するディレクトリ名、第二引数に同期するsshサーバーとそのフォルダを指定します。
起動するとこんな感じ。
hogehoge/ to root@www.kojika-ya.me:/root/hogehoge/
file update watching...
ファイルに変更などがあると
building file list ... done
deleting urls.pyc
deleting settings.pyc
deleting middleware.pyc
deleting __init__.pyc
deleting api/urls.pyc
deleting api/handlers.pyc
deleting api/__init__.pyc
deleting app/models.pyc
deleting app/admin.pyc
deleting app/__init__.pyc
./
sqlite
test
api/
app/sent 7501 bytes received 1876 bytes 6251.33 bytes/sec
total size is 3252109 speedup is 346.82
.....
こんな感じでどんどん同期されていきます。
これできっとストレスフリーな開発ができる(はず)です。