タグ「GitHub」が付けられているもの

当然のことながら普段コーディングはPCで行っています。 ところが、電車の中などちょっとした隙間時間にコーディングができるといいなと思うことがあります。 ちょっとアイデアを思いついた時や、バグに気づいて修正したいときなどがしばしばあります。 もしかしたら、ゼロからプロジェクトを作りたいこともあるかもしれません。

iPhoneアプリで、GitHubのクライアントはいくつかあります。 そのうちのいくつかはエディタ機能を備えているものもあります。 しかし、試した範囲ではとても使いたくなるようなエディタではありませんでした。 やはり、iPhoneで楽しくコーディングしたいものです。 iPhoneのような小さい画面でも楽しくコーディングできるようなインタフェースはありえるのではないでしょうか。

無いものは自分で作ろうの精神で作ってみました。 今のところ、GitHub限定です。 色々なライブラリを組み合わせて、Webアプリとして作りました。 特に、ace editorの恩恵が大きいです。 aceは、基本的にはiPhone/iPadでも動くようになっています。 それをさらに使いやすくするため、表示領域を大きくしたり(パフォーマンスの問題は残るのですが) 「コマンドモード」を導入して、vimのようにカーソル移動ができるようにしました。 カーソルキー問題は、Androidではないでしょうから、iPhone特有の問題かもしれません。

作ったWebアプリの名称は、CodeOnMobileです。 mobile codingにしてしまうと、モバイル向けアプリのコーディングの意味になることが多いので、 coding on mobile (devices)から命名しました。

Webアプリは、

http://codeonmobile.axlight.com/

からアクセスしてください。

その前に、GitHubのプロジェクトページ

https://github.com/dai-shi/codeonmobile

を見てみるとよいでしょう。簡単なスクリーンキャストを載せてあります。 ちょっと長いですが、辛抱強く見ていただけるとうれしいです。

それでは、モバイルでのコーディングを楽しみましょう。

プレゼン資料の公開にgistを使ってみる

  • 投稿日:
  • by

最近、簡単なスライドをWebにアップするときにgistを使っているので、紹介します。

gistを使うと、スライド内のテキストをちょっといじるときなどにブラウザで作業できるので便利かなと思いました。実際はそれほどでもないのですが。

gistを使ってプレゼン資料を作るコツは二つです。

  • reveal.jsを使って1つのHTMLファイルだけで完結させる
  • http://rawgit.com/を使ってブラウザから開けるようにする

reveal.jsは以前紹介したので省略します。

rawgitはgithubのraw fileにcontent-typeをつけたり、cdnでキャッシュしてくれるサービスです。すばらしいですが、永続性は不明です。しかし、代替サービスがあれば乗り換えればよいだけとも言えます。

具体的なサンプルを見た方が早いかもしれません。以下に示すサンプルは、1つのHTMLファイルで、reveal.jsを読み込んで、そのHTML内でJavaScriptを書いて、Markdownを書いています。

まず、ソースはこちらのgistです。

次に、rawgitで開けるようにしたものがこちらです。

「実際はそれほどでもない」と言った理由は、gistを編集するとリビジョンが上がり、rawgitのURLも変わるからです。キャッシュされるのでそうでないと困るのですが。

なんか時代に逆行している感じなので、あまり受けないかもしれません。

GitHub便利です。その一つが、Compare ViewのDiffです。Pull Requestを確認するときもよく見ます。コマンドラインでgit diffと普通にやるより見やすいです。

さて、背景は省略しますが、HTMLでdiffを表示したいと思いました。AngularJSでの利用を想定しているので、JavaScriptのライブラリが欲しいです。

ところが探してもあまり見つかりません。よくまとまっているのはこちら。

http://stackoverflow.com/questions/3053587/javascript-based-diff-utility

ちょっと古い投稿ですが。一番人気なのは、これです。

https://github.com/cemerick/jsdifflib

オンラインデモはこちら。

http://cemerick.github.io/jsdifflib/demo.html

だいぶ求めているもののイメージに近いです。 コードも枯れているらしい。 HTMLが出力されるので、Angularで使うならdirectiveを書かなければいけないですが、それは仕方ないですね。

これで行こうかと思ったところでしたが、なにか物足りません。 なんというか、見た目がワクワクしないのです。 改めてGitHubのDiffと比較してみると、全体的に色が濃すぎる。 あと、単語の差分がハイライトされない。色については自分でcssを書いて調整すればよいでしょうが、単語のハイライトはそれでは済みません。

というわけで、もう一度検索しました。見つけたのがこちらです。

https://github.com/rtfpessoa/diff2html

オンラインデモはこちら。

http://rtfpessoa.github.io/diff2html/

おお、おしゃれ。これですよこれ。なんとStar数は3でした。まったく注目されていません。コードも枯れていないでしょう。まだ不具合もあります。でも、魅力的です。これを使いましょう。

ところが、使うには一つ問題がありました。diff2htmlはdiffの出力を入力としているのです。例えば、

diff --git a/foo.txt b/foo.txt
---
+++
@@ -1,4 +1,5 @@
+zero
 one
 two
-three
+tree
 four

このようなものです。つまり、次はこれを出力するライブラリを探しました。いくつかありそうでしたが、比較的すんなり結合できたのはこちらです。

https://github.com/qiao/difflib.js

入力の行が配列になることと、出力の一行目のヘッダが付かないことなど不足点はありまして、それらは自力で対応しました。

最後にこれらを全部つなげて、angular.jsのdirectiveを書いてできあがりです。下記のような感じで使えるようになりました。

<my-diff path="foo.txt" old-content="one\ntwo\nthree\nfour\n" new-content="zero\none\ntwo\n\tree\nfour\n">

便利です。ちょっと気になることと言えば、依存javascriptが3ファイルもあって、グローバルに関数を定義するようなものであることです。なにかうまく隠蔽する方法があるのでしょうか。

夏ごろに「暑さをみんなでふっとばせ!」というアプリを作りました。

1bitで使い捨てで匿名のコミュニケーションツールを作ってみた

に経緯が書いてあります。

当時は、Famo.usやF/Aのライブラリに手を入れないといけなかったのですが、その後バージョンアップして不具合が解消されました。 新しいバージョンでは読み込み速度なども改善しています。

せっかくなので、GitHubにソースをアップロードしました。 Famo.us/Angularとsocket.ioの組み合わせでこんなことができるというサンプルによいかと思います。

ついでに、「暑」を「寒」に変更する機能もつけました。タイトルはそのままですが。

GitHubのページはこちらです。

https://github.com/dai-shi/atsufut

実際に動作しているアプリのページはこちらです。

http://atsufut.axlight.com/#?color=blue&label=%E5%AF%92

突然ですが、例えば、githubにリポジトリを置いて、herokuにデプロイするというケースは多いのではないでしょうか? そういうときは大抵、

$ git push master origin
$ git push master heroku

と2つコマンドを打つことになると思います。 それぞれ、git remoteでoriginとherokuが設定されているとして。

これが、一発で済むと楽ではないですか? もちろんローカルでshell scriptを書いてもいいかもしれませんが、 例えば、githubにはPUSH権限があるけど、herokuにはPUSH権限がないような ユーザがいるケースでは、どうでしょう? そういう場合に、githubからherokuに自動でデプロイできたら便利でしょう。

いくつか解決法はあるようですが、CodeShipというのを使ってみました。

http://blog.codeship.io/2013/10/02/how-to-deploy-a-ruby-on-rails-app-from-bitbucket-to-heroku.html

チュートリアルに沿って言われたとおりに設定するだけでできるようになりました。 どうやら、双方にアクセスするための鍵を登録して、 さらにPUSH時のhookを登録することで実現しているみたいです。 鍵の元はCodeShipにあるわけなので、CodeShip側に悪意があればいろいろできちゃいそうですが。

CodeShipはデプロイだけではなく、テストもまわせるなど、使いこなせばいろいろできそうです。

ttyrec/jsttyplayがうまくいったので、ちょっと欲が出てきて、GitHubのプロジェクトのREADMEに作ったスクリーンキャストを載せたくなりました。

Markdown自体はHTMLタグを埋め込むことができるのですが、README.mdが表示されるときには全てのタグが使える訳ではありません。

ざっと試したところ、script,canvas,iframeは消えました。たぶん、embedも消えるでしょう。

最後の手段は、画像です。画像は載っているのを見たことがあります。 そこで、スクリーンキャストをGIFアニメーションに変換しようと思いました。

ttyrecは文字情報が記録されているので、そこから直接GIFアニメーションに変換できたら効率的な(サイズの小さい)ファイルが作れるはずだ、と期待したのですが、残念ながらそのようなツールは見つかりませんでした。

仕方ないのでテキストベースはあきらめ、普通に画面キャプチャすることでスクリーンキャストする方式に戻ることにしました。 GIFアニメーションを出力できるスクリーンキャストツールとしては、 Screencast-O-Maticがお手軽そうだったので試してみました。

まず、初めに普通にターミナルを録画して変換してみましたが、GIFファイルが大きくなりすぎました。そこで、フォントを小さくして、さらにttyrecで記録したものを倍速で再生することで時間も半分にしたところ、だいぶ小さくはなりました。それでも時間が長いと大きいですが。

これを、README.mdに埋め込むのですが、ファイルはどこに置くかというと、 GitHub pagesに置きました。

ところが、まだファイルが大きすぎるのかうまくいきません。Not Foundになってしまいました。仕方ないのでraw.github.comを使ってファイルの位置を指定したら、今度はうまく行きました。ちなみに、サイズが大きすぎるとblob is too bigというエラーがでます。

本来はraw.github.comを使ってコンテンツ配信をするのはよろしくないのだと思います。ファイルサイズをもう少し小さくすることができたら、GitHub pagesのリンクも再挑戦することにします。

最近、ブログネタがどんどんマイナー路線に行ってしまっていますが、だれか読者はいるでしょうか。


8/2追記。

4倍速にして時間を圧縮し、fpsを半分にして、ファイルサイズを小さくしたところ、GitHub pagesのリンクでも動くようになりました。 これにより、GitHub pagesを開く際はそのままリンクが使われ、github.comを開く際は、よろしくCDNにコピーされるようになりました。

動画は便利ですね。身体的な技を習得する場合もそうですが、最近ではプログラミングも動画で習得するようですね。自分は使っていませんが、ドットインストールは便利そうです。

さて、本題です。スクリーンキャストをテキストベースで行いたいと思いました。ターミナルだけで手軽にやろうと。

ttyrecというツールを使いました。Ubuntuではaptでインストールできます。

$ apt-get install ttyrec

実行すると新しいシェルが始まるのでそこで一通り作業してexitすると、全て記録されています。とても簡単です。

ttyplayで実行できます。再生中に速度も変えられるので便利。2倍速くらいでもついていけます。

ttyrecで録画したスクリーンキャストをwebにアップする方法を調べました。2つ見つけました。

初めはお手軽なplayterm.orgを使うつもりでしたが、一つだけ難点が。試してないから確かではないのですが、一度アップすると削除ができない様子なのです。もうちょっと自分で制御したくて、jsttyplayを使うことにしました。しかし、jsttyplayはライブラリなのでいろいろ手を入れないと使えません。まずは、Webサイトが必要です。

今回は、GitHub pagesを使いました。gh-pagesブランチにjsttyplayをコピーして、test.htmlを参考にHTMLを書きました。不具合もいくつかあって、

  • Rewindボタンが動かない(バグ修正した)
  • PlayPauseボタンの動作が不明(非表示にした)
  • fontが相対パスなので、ディレクトリが異なると読み込めず
  • ttyrecordファイルのURLがハードコードされている

などが気になりました。

あと、注意点がいくつかあります。

  • ターミナルのサイズを記録時と再生時で同じにする必要がある。これは、ttyrecの制限。playterm.orgでは80x24を標準としている。
  • TERM=xtermでは途中で固まった。TERM=vt100だと大丈夫。ttyplayは問題ないので、これはjsttyplayの制限。

これらをクリアして見事ttyrecで記録したスクリーンキャストをWebに載せることができました。HTML5 Canvasで動いているようです。ターミナルをエミュレートしている感じでしょうか。かっこいいですね。

jsttyplay_screenshot.png

このシンプルさがいいです。 再生速度変更ボタンはありませんが、簡単に作れそうです。 そのうち暇ができたらちょっと改造してみようかと思いました。

興味がある方はお試しください。

jsdomへのpull request: XHRサポート

  • 投稿日:
  • by

connect-prerendererをちゃんと動かすためにやったjsdomの修正その2をpull requestにしました。

https://github.com/tmpvar/jsdom/pull/654

実はXHR自体は、 node-XMLHttpRequest をそのまま使うだけでほとんど苦労はありませんでした。

大変だったのは、クッキーを引き継ぐところでした。 そもそもXHRを使わない場合も、jsdomはクッキーの引継ぎをサポートしていませんでした。XHRを使わない場合というのは、JavaScriptやCSSや画像ファイルなどを読み込む場合です。

まず、JavaScriptのロード時にもクッキーを引き継ぐようにするコーディングをしてから、XHRでもクッキーを引き継ぐようにしました。XHRはnode-XMLHttpRequestの内部のコードまで理解しなくてはならず、苦労しました。ちょっと強引に実装したため、もしかしたら将来のバージョンのnode-XMLHttpRequestでは動かないかもしれません。

pull requestは無事マージされて、jsdom v0.8.1がリリースされました。興味がある方はお試しください。

https://npmjs.org/package/jsdom

connect-prerenderer もこのバージョンを使うように修正しました。

https://npmjs.org/package/connect-prerenderer

今回は、npm周りのTIPSです。特に新しい知見ではないのですが、メモのために書いておきます。

node.jsのパッケージマネージャであるnpmは依存パッケージの解決をしてくれます。依存パッケージは、package.jsonに書いておきます。

例えば、expressを使う場合、

"dependencies": {
  "express": "*"
}

のように書きます。バージョン番号を指定しておきたい場合もあります。

"dependencies": {
  "express": "3.1.0"
}

のように書きます。他にも不等号やチルダを使ってバージョン番号の範囲を書くこともできます。今回はそのあたりは詳しく書きませんが、package.jsonにはバージョン番号の範囲を書いておくことがおすすめです。node.js関連のパッケージはまだ発展途上で仕様が変わることがよくあるからです。そうでなくても、">=3.0.0"などと書いておけば、"3.0.0"では動いたのだということが分かってよいかもしれません。

さて、本題です。依存パッケージがnpmに登録されていない場合はどうすればよいでしょう? 一つの答えは、登録してしまえばよいのです。が、登録したくない場合もあります。今回そのようなケースがありました。それは、GitHubでforkした場合です。将来的にはPull Requestして取り込んでもらうつもりなら、npmに独自バージョンを登録するのはうまくありません。そこで、npmに登録されていないけれど、依存パッケージとして使いたいときにどうするかという話です。

GitHubを使うとしても方法は2通りあります。一つは、tarballで取得する方法、もう一つは、gitプロトコルで取得する方法です。

前者は、

"dependencies": {
  "jsdom": "https://github.com/dai-shi/jsdom/tarball/3bb5b24c5e"
}

のように書き、後者は、

"dependencies": {
  "jsdom": "git://github.com/dai-shi/jsdom.git#3bb5b24c5e"
}

のように書きます。

どちらがいいのでしょう? よく分かりません。 試しに一回だけ、npm installの時間を計測してみました。 結果、前者が11秒、後者が14秒でした。 gitプロトコルの方がオーバヘッドがあるのかもしれません。 httpプロキシしか使えない場合は、前者に決まりですね。 GitHubがtarballのURLを廃止したら(ZIPのURLはリンクがありますが、tarballってどこまでオフィシャルなのでしょう?)、後者に決まりですね。

今のところはどちらでもよいのかもしれません。


10/20追記。

"https://github.com/dai-shi/jsdom/tarball/3bb5b24c5e"

の代わりに、

"https://github.com/dai-shi/jsdom/archive/3bb5b24c5e.tar.gz"

と書く方法もあるようです。こっちの方がオフィシャルな感じがしますね。

jsdomへのpull request: hashchangeイベント対応

  • 投稿日:
  • by

connect-prerendererをちゃんと動かすためにやった 修正をjsdomのpull requestにして欲しいと依頼されました。

unit testを書いて欲しいということなので、書いてみたのですが動かなくて苦労しました。 __defineGetter____defineSetter__を初めて使いました。 ECMAScriptではこれらは入っていない(definePropertyを使う)そうですが、nodeでは__defineGetter____defineSetter__は使えるようです。

結局、当初やっていた修正では全くダメ(なぜconnect-prerendererが動いたのか不明)で、window.locationまわりのコードを全部書き直しました。 おかげで、全体的により仕様に合った動きをするようになり、立派なpull requestができあがりました。

ちゃんとマージされたようで、めでたしめでたし。

https://github.com/tmpvar/jsdom/pull/650

Gunosy RSS はオープンソースで提供されています。ライセンスの範囲内で自由に使うことができます。

慣れている人は説明なしですぐにできると思いますが、どれだけ簡単にできるかを示すため手順を書いておきます。

前提:

  • herokuのアカウントがあること(なければ作る)
  • heroku toolbeltがインストールされ、SSH鍵が登録済であること
  • GitHubのアカウントがあること(なければ作る)
  • gitがインストールされていること

まず、GitHubからソースコードを取得します。

https://github.com/dai-shi/gunosy-rss

にアクセスして、右上のForkボタンを押して、自分のリポジトリにします。自分のリポジトリのページに行ってリポジトリのURLを確認します。 仮に、git@github.com:<username>/gunosy-rss.gitだったとします。

% git clone git@github.com:<username>/gunosy-rss.git

をコマンドラインで実行するとダウンロードされます。

% cd gunosy-rss

でディレクトリを移動します。

次に、herokuにアプリケーションを作ります。

% heroku apps:create <appname>

を実行するだけです。<appname>は省略も可能です。 作ったアプリケーションの情報を確認するため、

% heroku apps:info

とします。そこで表示される、Git URLとWeb URLが重要です。 それぞれ、git@heroku.com:<appname>.githttp://<appname>.herokuapp.com/だったとします。

% heroku config:set SITE_PREFIX=http://<appname>.herokuapp.com/

として、環境変数を登録します。

% git remote add heroku git@heroku.com:<appname>.git

として、リモートリポジトリを登録します。

% git push heroku

として、herokuにアップロードして、完了です。 http://<appname>.herokuapp.com/<gunosyid>.rssでRSSフィードが生成されます。

いかがでしょう?


補足

実は、GitHubのアカウント作らずForkもしなくても、上記のことはできます。ですが、せっかくなのでpull requestが送れるようにForkするのが、GitHubらしいのではないでしょうか。

herokuのアプリケーション情報を表示するところでは、

% heroku apps:info --app <appname>

とする必要があるかもしれません。