Thorでコマンドラインスクリプトを作成

mitukiii.jp | Rubyでコマンドラインスクリプト書くならThorが便利そう を見て
Thorを使ってみました。
gistの中身をコマンドラインで見れたら嬉しいなと思っていたので
作ってみることにしました。


作成中にswdyh/gisty - GitHubというcoolなツールがあるのと
試しにbundle gemでgemの雛形作った辺りでdefunkt/gist - GitHubってのも
あると気づいたんだけど。。。

作るもののイメージ

手始めに

・gist listで一覧取得
・gist show id/number で詳細参照
・対象gistユーザは、git config --get user.name もしくは ENV['GIST_USER']から取得

機能として不十分な点(とりあえず後回し)

・local cache(http HEADを使う)
・private gist(認証)
・gistの修正


実行結果

$ ./gist list

  No.    ID       Description
------------------------------------------------------------------------------------------------------------------------
   1.    1565483  extract rails committer
   2.    1346802  oracle memo
   3.    1317257  マルチバイト文字列を2バイトとみなし、指定したバイト数でカット。中途半端は切る。
   4.    1240764  send attached email on tmail
   5.    1224037  creat gem install script from gem list
   6.    1195136  textmate_snippets
   7.    1143577  screen-4.0.3/pty.c for Mac OS 10.7
   8.    1070727  split_file.pl
   9.    1070725  split_file.rb
  10.    1028328  official_notification.rb
  11.     985199  The array of the relationship between a child and his parents is output by the hierarchical display. 
  12.     877337  kill the rails process for windows
  13.     792887  http://d.hatena.ne.jp/rochefort/20110124/p1
  14.     764900  
  15.     761807  http://www.itmedia.co.jp/enterprise/articles/1004/03/news002_2.html
  16.     710693  vbs/open.vbs
  17.     653268  remove_buzzword_from_itunes_lyric
  18.     651402  (gm)display real image size
  19.     572142  capistrano_sample_thinking_sphinx_deploy.rb
$ ./gist show 4

or

$ ./gist show 1240764

file: attached_email.rb
----------------------------------------------------------------------------------------------------
require 'rubygems'
require 'tmail'
require 'net/smtp'
require 'base64'

module MyProject
  class AttachedEmail
    SMTP_HOST = 'localhost'

    def initialize
      @mail = TMail::Mail.new

略


usageも

$ ./gist
Tasks:
  gist help [TASK]     # Describe available tasks or one specific task
  gist list            # List your gists
  gist show ID/NUMBER  # Show your raw gist by id or the listing number

Thor使用個所

usageやコマンドラインオプションの設定が超絶簡単です。
method_optionsを使うと--形式でオプション指定、型指定ができます。
(今回使ってませんが)

    desc 'list', 'List your gists'
    def list
      setup
      write_list_header
      @data.each_with_index do |list, i|
        puts "%4s. %10s  %s" % [i+1, list['id'], list['description']]
      end
      write_footer
    end

    desc 'show [ID/NUMBER]', 'Show your raw gist by id or the listing number'
    def show(arg)
      raise ArgumentError "#{arg} is not numerical" unless numeric?(arg)
      setup
      content = []
      # IDで検索
      @data.each_with_index do |list, i|
        content = get_content(i) and break if list['id'] == arg
      end

      # 番号で検索
      if content.empty? and number_of?(arg.to_i)
        content = get_content(arg.to_i-1)
      end
      puts content
    end

余談

仕様について

gisty使ってみてから気づいたんだけどgit cloneさせる仕様の方が断然いいですね。

open-uriについて

net/httpのheadを使うように修正しようかと思って今回は使ってないんですが
open-uri を使うと 302でもredirectしてくれるんですね。

net/httpについて

canonical_eachでhead正式名称と値が取得できると。

>> res
=> #<Net::HTTPFound 302 Found readbody=true>


>> res.canonical_each{|k,v| puts "#{k} : #{v}"}
Server : nginx/1.0.4
Date : Sun, 29 Jan 2012 05:58:23 GMT
Content-Type : text/html; charset=utf-8
Connection : close
Status : 302 Found
X-Ratelimit-Limit : 100
X-Frame-Options : deny
Location : https://raw.github.com/gist/1565483/5a4074cd72b1c85a607afa5cc1f21566e587ca9a/rails_committers.rb
X-Ratelimit-Remaining : 100
X-Runtime : 3
Content-Length : 162
Cache-Control : no-cache
Strict-Transport-Security : max-age=2592000