Macでの開発効率をアップする、マウントせずにローカルのソースコードをサーバーと同期するスクリプト書いた。

Macでの開発効率をアップする、マウントせずにローカルのソースコードをサーバーと同期するスクリプト書いた。

Table of Contents

しかだよ。

変更があったローカルのソースコードをサーバーソースコードと同期しながらwebアプリを開発できるスクリプトを作りました。

shikajiro/eventsync.py

2012/07/10 追記

下で説明するソースコードは古いので、shikajiro/eventsync.pyの方を見てくださいね。

webアプリ開発の問題点

  • マウントしたりsshでサーバーに接続してwebアプリを開発してると、回線が遅くて画面が固まることがあり、ストレスフルなコーディングを強いられている。
  • ローカルのソースをgitでpushしてサーバーに反映するのは複数人の場合はいいけど、一人用の場合は毎回add commit push がめんどい。

プログラマーが楽しくプログラミングできないのはです。直ちに懺悔するか解決しましょう。

開発中のwebアプリを動かす場所を比較検討

実行場所公開範囲反応スピードPC負荷柔軟性
ローカルのmac××
vmwareLinux××
レンタルサーバ×
  • ローカルでwebアプリを動かすとレスポンスとか速いんだけど、複数環境などで柔軟性に欠ける。
  • vmwareだと柔軟性高いんだけど、メモリとCPU消費が激しくて遅い。
  • 上記2つはさらにネットに公開されていないのでテストしにくい。
  • レンサバは公開されてて扱い易いけど、直接コーディングするにはレスポンスが遅い。

今この瞬間作っているものをストレス無くサーバーで確認したいのです!

というわけで、「サーバーに常時接続せず」「ローカルで開発できて」「ソースコードに変更があったらサーバーを更新する」方法を探りました。

ソースコードの同期はrsync

コードの同期はrsyncでできました。問題は「ソースコードの追加・変更・削除」をどうやって検知するかです。

lsync

Linuxディストリビューションならlsyncを使うとファイルの変更検知ができるみたいですが、Mac OS XBSDなので、これは使えませんでした。

フォルダアクション

Mac OS X にはフォルダアクションというフォルダ監視の仕組みがあります。フォルダに変更があるとautomatorを実行出来たりします。しかしこれは「フォルダへのファイルの追加」のみ検知可能だったため断念しました。

kevent kqueue

BSDLinuxとは別の方法でファイルを監視する事が可能でした。それが kevent kqueueです。

*BSD で kqueue・kevent を使ってみよう

pythonスクリプト

んで、色んなサイトのソースコードを参考にしてできました。

shikajiro/eventsync.py

f:id:re_shikajiro:20120614015745p:image

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): printUsage: python {} filename.’.format(argvs[0]) quit() folder = argvs[1] ssh = argvs[2] print{} to {}’.format(folder, ssh) printfile 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

.....

こんな感じでどんどん同期されていきます。

これできっとストレスフリーな開発ができる(はず)です。