2011年2月20日日曜日

github で pull request をされたとき・するときの手順

github に自分のリポジトリを公開していると、たまに pull request をされることがあります。また逆に、他人のリポジトリのコードを使っていて、どうしても気になるバグを見つけて修正したときなど、相手に pull request を送りたいことがあります。こんなときにどうすればよいかをまとめてみました。


■pull request をしたいとき

pull request をしたいときは、まず相手のリポジトリを fork する必要があります。


このボタンをぽちっとな。

fork したら、 fork して自分の管理下に入ったリポジトリを clone して、コードを修正します。
git clone https://akisute@github.com/akisute/asi-http-request.git
コードの修正が終わったら、自分の fork したリポジトリに push しておきます。
git push origin master
ではコードの修正が終わったので pull request をします。


このボタンをぽちっとな。


するとこうなります。デフォルトでは相手の master に対して自分の master を pull request することになりますが、もちろんこの画面で変更可能です。 request をする先のリポジトリ・ブランチと、リクエストされるブランチをそれぞれ指定できます。それからコメントをつけて送れます。ここでつけたコメントは相手側のリポジトリの Pull Requests タブに記載されるので、それなりにかっこいい内容を書いておくと良いかと思います。あとは相手が受け入れてくれるのを待つばかりです。自分のコメントにコメントがついたらメールとかで通知が来ますんで、適当に返事して相手と連絡を取りながらやる感じになります。


■pull request をされたとき

逆に自分が pull request をされることもありますので、そのときの対処法も。


pull request されると、こんな風に Inbox の Notifications の中に通知が来ます。


対象のリポジトリの Pull Requests タブにもこんな具合でリクエストが入ります。


クリックしてリクエストの詳細を開きます。ファイルの diff 一覧とかどっからどこに対してリクエストが飛んでいるのよとか全部ここで見られます。相手のコメントに対してコメントを返したり、 diff に対してコメントをつけたりできます。 diff につけたコメントは相手にも公表されます。

ここで相手とコメントやりとりとかして、じゃあ取り込もうか、となりましたら、実際に pull request を取り込む作業を行います。自分のリポジトリにマージ用のブランチを用意して、 pull して確認し、問題なければマージ用のブランチと本線をマージして終了。コマンドがよくわからなくても github が全てのコマンドを表示してくれるのでそれを見れば一発です。本当に親切。以下、 master ブランチに対して pull request があったとすると、
git checkout -b pull-request-master master
git pull http://github.com/applicant/his-repository
# 相手のコミットが自分のブランチに pull されてくるので、この状態で動作を確認する
# merge 作業が発生するならここで行う
# 問題がなさそうなら
git commit
git merge master
git push origin master
push まで完了したら先ほどの pull request のページから取り込み完了したよボタンを押しておきましょう。


■おまけ: 自分が fork しているコードの fork 元リポジトリが更新されたので、こちらも最新にしたい

実はこれは pull request をされたときとあんまり変わりません。対象の相手のブランチを自分の fork しているコードに pull すればよいのです。
git checkout -b merge-master master
git pull http://github.com/parent/parent-repository
# 相手のコミットが自分のブランチに pull されてくるので、この状態で動作を確認する
# merge 作業が発生するならここで行う
# 問題がなさそうなら
git commit
git merge master
git push origin master

2011年2月12日土曜日

Redmine を Debian 5.0 にゼロからインストールしてみた

あらかじめ注意: 下記のメモは、ruby, gem, rails, rack, redmineのいずれかのバージョンが0.0.1でも違うと動作しない可能性が高いので、当てにしないでください。


■顧客が説明した要件
  • 1つのサーバーに複数のプロジェクトのリポジトリとかリソースをおいているので、1プロジェクトにつき1個インスタンスが必要なtracは都合が悪い!
  • っていうかtrac飽きた!!古い!
  • 複数プロジェクト扱えるBTSが欲しい
  • 見た目クールだといいね、カスタマイズとかできるとすごくいい!
  • Wikiは絶対必須
  • Google Appsと連携できると素敵だな!
  • 簡単にインストールしたい、時間かけたくない


■プロジェクトリーダーの理解
  • https://www.gravitydev.com/ はすごくいいんだけれど許可下りなさそうだなぁ。そもそもWikiがないから却下。
  • となるとやっぱりRedmineかな!あれすごくいいよね!
  • Redmineに移行しようかみたいな話も社内で出てたし、先んじて導入してノウハウ作るのはありだな!


■アナリストのデザイン
[11/02/10 9:24:53] akisute: redmineのインストールが超面倒くさいんだけれど
[11/02/10 9:24:54] akisute: なんとかならんのこれ
[11/02/10 9:25:02] wozozo ( ゚Д゚)y─┛~~: rails
[11/02/10 9:25:19] tokibito: rails
[11/02/10 9:25:20] 文 殊堂: まいんちゃん
[11/02/10 9:26:39] akisute: http://redmine.jp/guide/RedmineInstall/
[11/02/10 9:26:43] akisute: これ見てるとアホかと言いたくなってくる
[11/02/10 9:26:50] akisute: Ruby 1.9には対応していません。 上記の表に示したバージョンのRuby 1.8.xをインストールしてください。
RubyGems 1.3.1以上が必要です。
Rake 0.8.3以上が必要です。
Rack 1.0.1が必要です。1.0.1がインストールされていない場合、データベースマイグレーションが失敗します。
[11/02/10 9:27:25] wozozo ( ゚Д゚)y─┛~~: aptでいれたgemをupdateしようとすると、
[11/02/10 9:27:34] wozozo ( ゚Д゚)y─┛~~: おい待てって言われるし
[11/02/10 9:27:49] aodag: Redmineってライトニングなのないの?
[11/02/10 9:27:53] tokibito: rubyはaptで入れたら死亡する可能性
[11/02/10 9:28:04] aodag: rvmっしょ
[11/02/10 9:28:04] tokibito: 自分でビルドしたほうが無難とかいう
[11/02/10 9:28:11] tokibito: rvmで。


■プログラマのコード
  1. redmine:redmine ユーザーを新規に作成する
    • 以下の作業はすべてredmineユーザーで行う
  2. rvmの最新をインストールする
    • http://rvm.beginrescueend.com/rvm/install/
    • curl と git-core のインストールが必要。aptitude経由で実施
    • /home/redmine/.bashrcの追記を忘れないように
    • source ~/.rvm/scripts/rvm も忘れないように
  3. rvmに必要なパッケージをインストールする
    • こんなんデフォルトで用意しろよ・・・いいかげんにしろ・・・
    • rvm package install readline
    • rvm package install iconv
    • rvm package install zlib
    • rvm package install openssl
    • この順番で入れないと依存関係の問題で怒られます (opensslがzlibを使うとか)
  4. ruby 1.8.7 をrvm経由でインストールする
    • 参考は http://d.hatena.ne.jp/masasuz/20100720/1279635055
    • 先に rvm package install しないとgemが使えない, zlibがないので
    • ビルドオプションを付けることでopensslとzlibを有効にすること
    • rvm install 1.8.7 -C --with-openssl-dir=$HOME/.rvm/usr -C --with-zlib-dir=$HOME/.rvm/usr
    • rvm use 1.8.7
    • ruby --version
    • gem --version
  5. gemのバージョンを 1.3.7 に戻す
  6. 本当にopensslとかzlibとかインストールされているかをチェックする
    • ruby -r openssl -e ""
    • エラーになった場合はopensslの再ビルドを行う。opensslを使えるようにしないとのちのちrakeを実行するところでエラーが発生して先に進めなくなる
    • cd ~/.rvm/src/ruby-1.8.7-p330/ext/openssl
    • ruby extconf.rb --with-opt-dir=$HOME/.rvm/usr/
    • make
    • make install
    • ruby -r openssl -e "" を再度実行してエラーにならない事を確認
  7. rails 2.3.5 をgem経由でインストールする
    • gem install rails -v=2.3.5
    • rails 2.3.5をインストールすると自動的にrack 1.0.1が入るが、先にrack 1.0.1をインストールしておいたほうが良いかも
  8. rack 1.0.1 をgem経由でインストールする
    • gem install rack -v=1.0.1
  9. sqlite3-ruby 1.2.3 をgem経由でインストールする
    • 参考は http://d.hatena.ne.jp/modka/20101208
    • sqlite3-devel (sqlite3.h) が見つからないとインストール出来ないので注意
    • 最新のsqlite3-ruby は sqlite3 3.6.3 が必要で、Debianのaptitudeでは3.5.9までしか無いので、バージョンを指定して古いsqlite3-rubyを入れる
    • sudo aptitude install sqlite3
    • sudo aptitude install libsqlite3-dev
    • gem install sqlite3-ruby -v=1.2.3
  10. i18n 0.4.2 をgem経由でインストールする
    • rakeの実行に必要
    • rakeお前依存関係に含めろや・・・アホか・・・><
    • gem install i18n -v=0.4.2
  11. redmine のリリース版の最新をダウンロードする
  12. データベースの設定を行う
    • 参考は http://redmine.jp/guide/RedmineInstall/
    • 今回はsqlite3
    • cd ~/redmine-1.1.1/config
    • cp database.yml.example database.yml
    • vim database.yml
    • cd ~/redmine-1.1.1
    • rake generate_session_store
    • rake db:migrate RAILS_ENV="production"
    • rake redmine:load_default_data RAILS_ENV="production"
  13. メールの送信設定を行う
    • 不要と思われる。メールが飛ばないだけで済む
  14. 起動する
    • cd ~/redmine-1.1.1/
    • ruby script/server webrick -e production
    • http://localhost:3000/ が立ち上がるので、 admin/admin でログインする
    • 適切にadminのパスワードを変更すること
  15. ログの設定を行う
    • やっとかないとログが溜まりまくって死ぬらしいので
    • cd ~/redmine-1.1.1/config
    • cp additional_environment.rb.example additional_environment.rb
    • vim additional_environment.rb
    • http://redmine.jp/guide/RedmineInstall/ のログの設定セクションのとおりに設定しておく
  16. Passengerをインストールする
    • 参考は http://d.hatena.ne.jp/Umeyashiki/20100131/1264948069
    • gem install passenger
    • passenger-install-nginx-module
    • ここまでの手順どおりに進めていると、大体以下のものが足りないはず
      • Curl development headers with SSL support... not found
      • OpenSSL development headers... not found
      • Zlib development headers... not found
    • 一旦abortしてそれぞれインストールすること
      • sudo aptitude install zlib1g-dev
      • sudo aptitude install libssl-dev
      • sudo aptitude install libcurl4-openssl-dev
    • nginxの再ビルド(ないしソースコード)が必要になるので、すでにapt-getしたnginxがある場合には使えない。その場合はpassengerをstandaloneで起動して、そこに対してnginxからproxy-passなりなんなりする。
    • 以下、passengerスタンドアロンで起動し、redmineはすべてpassengerにやらせる場合を考えます。ただしpassengerのスタンドアロンは内部的にはnginxを使っているので、いずれにせよ上記のインストールは必要になります。
    • cd ~/
    • mkdir log run
    • passenger start redmine1.1.1 -d -a 0.0.0.0 -p 3000 -e production --log-file=log/passenger.log --pid-file=run/passenger.pid
    • ってやると何故か/tmp以下にlogファイルをつくろうとしていみわからないエラー吐いて死ぬので中止
    • cd ~/redmine1.1.1
    • passenger start -d -e production
    • 最低限のオプションだけで起動すれば起動できた


■営業の表現、約束
  • お客様、 redmine をお求めですか?ご安心ください! gem install redmine で一発に決まってますよ!簡単です!
    • そんなものはない
  • それなら sudo apt-get install redmine で一発です!猿でもインストールできます!!
    • Debian では無理
  • それなら最初から redmine がインストールされている vm イメージがあります!こちらを使えば一発です!
    • Ubuntu と SUSE しかない
  • Trac Lightning とかゆとり。真のエンジニアは ruby の configure & build から自分でやって当然(キリッ
    • そんな業務と関係ないところに何時間(何万円)使うつもり?
    • アップデートどうすんの?何時間(何万円)使うつもり?


■プロジェクトの書類

http://redmine.jp/guide/


■実装された運用

http://www.redmine.org/projects/redmine


■顧客への請求金額

akisute の実働5時間分 = 数万円 = https://www.gravitydev.com/pricing のスタンダードプラン数年分


■得られたサポート

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


■顧客が本当に必要だったもの

http://twitter.com/shin_no_suke/status/35632371084562433
http://twitter.com/hirokinko/status/36307730025156608
http://twitter.com/hirokinko/status/36310634127695872


■元ネタ

http://ryonoda.wordpress.com/2008/09/26/


■一応補足

Redmine自体はすごく良いアプリだと思います。ええ。いま使ってますが、とっても助かってます。

bitnamiの配布しているパッケージが対話環境でもインストールできるというのは知りませんでした。っていうかbitnamiのページのどこにも書いてないんですが・・・><
wget http://bitnami.org/files/stacks/redmine/1.1.1-0/bitnami-redmine-1.1.1-0-linux-installer.bin
chmod +x bitnami-redmine-1.1.1-0-linux-installer.bin
./bitnami-redmine-1.1.1-0-linux-installer.bin --mode text
でうまくいくようです。

しかしこの方法を使うと勝手にApache, MySQL, Ruby, Subversionをインストールされてしまうみたいなので、きちんと管理したいとなるとちょっと不向きかなと。

2011年2月9日水曜日

UITableView の cell の中に UITextView を配置したとき発生する問題とその対処方法

たとえば Twitter クライアントや SMS クライアントのように、短い文章を入力させるような画面を作りたいとき, Grouped Style な UITableView の cell の中に UITextView を配置して画面を作る事が良くあるかと思います。通常、この作りでほとんど問題はありませんが、特定の条件下で問題が発生することがわかりましたので、回避策をメモしておきます。


■問題

この問題が発生するのは、以下の条件を満たしたときです。
  1. UITableView の cell の中に UITextView を配置する。
  2. UITextView に、縦スクロールが発生するぐらい長い文字列を入力する。
  3. UITextView の中ほどにカーソルを移動する。
  4. UITableView と UITextView の scrollEnabled プロパティを NO に設定する。
  5. UITextView の text プロパティを変更する。
すると, UITextView および UITableView の scrollEnabled プロパティを NO に設定しているにもかかわらず、勝手に UITableView がスクロールを起こしてしまいます。 UITextView の text プロパティを書き換えたら勝手に UITextView が一番下までスクロールしてしまうのはデフォルトの挙動であり、これは問題ありません. UITextView を単品で使っているときは, scrollEnabled プロパティを NO に設定することでスクロールを発生させずに text を書き換えることが可能なのですが, UITextView を UITableView の中に含めたときのみ, scrollEnabled プロパティが無視されてしまい、この問題が発生してしまうようです。

カスタムキーボードを用意したり、本文中のURLを短縮して差し替えたりなど、結構 UITextView の text プロパティを直接書き換えたい要件があったりするので、このままでは困ります。


■解決方法

そこで、相当な荒技ですが、以下のようにして解決を図ることが可能です。
  1. UITableView の cell の中に UITextView を配置する。
  2. UITextView をいったん removeFromSuperview する。
  3. UITextView をいったん UITableView 以外の場所に addSubview する。
    • UIWindow の直下などがおすすめ。
  4. UITextView の scrollEnabled プロパティを NO に設定する。
  5. UITextView の text プロパティを変更する。
  6. UITextView の scrollEnabled プロパティを YES に設定する。
  7. UITextView を元の view に addSubview する。
  8. UITextView を first responder にする。
コードにすると以下のようになります:
UIView *parentView = textView.superview;
[self.view.window addSubview:textView];
textView.scrollEnabled = NO;

textView.text = [currentText stringByReplacingCharactersInRange:selectedRange withString:shrunkenURLString];
textView.selectedRange = NSMakeRange(selectedRange.location + [shrunkenURLString length], 0);

textView.scrollEnabled = YES;
[parentView addSubview:textView];
[textView becomeFirstResponder];
こうすることで, UITableView が勝手にスクロールしてしまう問題を回避することが可能です。