アプリケーションの機能自体には直接関係ないlintのgemの管理

tl;dr

管理したい。

変更したファイルにrubocopやjscsを実行して pull requestに自動でコメントする – Saddler – checkstyle to anywhere
定期的にライブラリの依存関係をアップデートしてPull Requestする – Saddler – checkstyle to anywhere

このへんのエントリでは話のスコープから外した。
スクリプトの序盤で

gem install --no-document git_httpsable-push pull_request-create

とさらっとすませている。

好みではない方法

このやり方はそんなに好みではない。
lintに使うgemだろうとなんだろうと、入る環境を固定したい。
入るバージョンを固定したい。たとえlocalでも。
ちょっと結果がおかしいのをローカルで確認したい、時にとても困る。CircleCIみたいにsshで入れれば多少はマシ。多少。
cleanなciサーバー上ではグローバルに入れて使い捨てていいけど、ローカルでグローバルに入れるのはちょっと…

とぼんやり考えている。
普通に使いたい人(使って欲しい人)にはイミフすぎるので、話のスコープから外している。

好みの方法

rubyプロジェクトの場合は普通にアプリのGemfileのdevelopmentに追加するのがいい。

もしくは

lint.gemfile
lint.gemfile.lock

にしておいて、

bundle --gemfile lint.gemfile --path vendor/lint-bundle

にする。別gemfileを指定して、別pathにinstall。

bundle installはgemfile指定できるけど、
bundle updateやbundle execはgemfile指定できないので、
こうしている間は、元のアプリのbundle exec出来なくて、元のアプリのするときは再度

bundle --path vendor/bundle

なりして、.bundle/config のpathの向き先変えてからbundle execする必要がある。
スクリプト一枚ごとに小分けにしていくのは、これはこれでbundle updateなどメンテが辛くなるので、
ある程度まとめたい、ただある程度まとめると、結局、というループ。

golang自分はまだ書けないんだけど、golangならこの問題に関しては解決するんだよなあ。

広告

compare_linkerにcliつけたcompare_linker_wrapper作った

cli、ただしくはcompare_linkerにフィードバックすべきなんだろうけど、いろいろ煮詰めてないのと、(おそらく)思想的にやりたいことがちょっとずれるので、wrapperのgemにした。

compare_linker とは
(GitHubのhookを受けて) Gemfile.lockにdiffがあったら、diffとGitHubのtagを比較して、GitHubのcompare viewのlinkを作り、commentにpostする。
compare_linkercompare linker example

wrapperでは、内部をガチャガチャっと変更してる。

  • 外からオプションでformatter指定できるなどのcli機能、出力は標準出力
  • 変更前/変更後のdiffをGitHub APIから取ってくるところを localのgit repositoryから取るようにした
    ここが思想的に違うところで、compare_linkerはherokuないしjenkinsでhookを受けて起動する意図で作っているのに対し、wrapperはciサーバーのpost testで実行するイメージ。いかにcloneせずにapi操作だけで実現するか vs CIサーバーならコードはもうあるじゃない
  • 名前はGemfile.lock 決め打ちじゃない(オマケ), –fileオプションか引数にpathを渡す
compare-linker-wrapper 'example/Gemfile.lock' \
  --base origin/master \
  --formatter CompareLinker::Formatter::Markdown

* [octokit](https://github.com/octokit/octokit.rb): 3.8.0 => 3.8.1

compare-linker-wrapper 'example/Gemfile.lock' \
  --base origin/master \
  --formatter CompareLinker::Formatter::Text

octokit: https://github.com/octokit/octokit.rb 3.8.0 => 3.8.1

こんな出力になる。

実際の使い方は こんなふうにしようかなあと。

git diff --name-only origin/master \
 | grep ".*[gG]emfile.lock$" || RETURN_CODE=$?

case "$RETURN_CODE" in
 "" ) echo "found" ;;
 "1" )
   echo "not found"
   exit 0 ;;
 * )
   echo "Error"
   exit $RETURN_CODE ;;
esac

git diff --name-only origin/master \
 | grep ".*[gG]emfile.lock$" \
 | xargs compare-linker-wrapper --base origin/master \
    --formatter CompareLinker::Formatter::Markdown \
 | text-to-checkstyle \
 | saddler report \
    --require saddler/reporter/github \
    --reporter Saddler::Reporter::Github::PullRequestComment

text-to-checkstyle はこれから作る。
Edited: 2015-03-17 3:37 text_to_checkstyle 作ってリリースした。

Tachikoma.io が第七回フクオカRuby大賞でHeroku賞を受賞

TL;DR

Tachikoma.ioのRubyやRailsを使うプログラマーの定形作業を減らす、バージョンアップを簡単に習慣化する試み、というところが評価されました。
「第7回フクオカRuby大賞」結果発表! – 福岡県Ruby・コンテンツビジネス振興会議

リハーサル時に壇上より。

IMG_3482

Interval Bundle update

githubのpublic repositoryは無料で提供しているのでTachikoma.ioを使うと手間がなくて良くて、private repositoryは月額課金制なので、Tachikoma.ioを使ってくれると手間がなくて良い上にぼくもhappyで、とはいえコードをTachikoma.ioに預けるのはキビシイ、ということであれば、定期的にライブラリの依存関係をアップデートしてPull Requestする – Saddler – checkstyle to anywhere
このあたり参考にどうぞ。

受賞展示では、Rubyのどんなバージョンを使っているか、Railsのどんなバージョンを使っているか、コードホスティングSaas, コード関係のSaaSの利用状況を、来訪者にマークしてもらってコンテンツにしました。

IMG_3496IMG_3498

下記は事前にAsakusa.rbで素振りをしたコンテンツです。

IMG_3465IMG_3466

バイアス強すぎるのでは、という指摘は当然。ただ、AsakusaでRuby2.1, Rails4.1が多いのはこれから上げるところなのかなーとか、フクオカでRuby1.9, 1.8がいらっしゃったのは、が、頑張れといったところとか、着目するといろいろあります。

コードのホスティングは、GitHub/GH:e 文化圏が圧倒的で、次がbitbucketなのかなと思い込んでいたのだけど、GitHubの次に(GH:eでなく)Gitlab勢力が無視できないぐらいいるなーというのが収穫でした。Gitlab文化圏はGitHubエコシステムに乗れないのがボディブローで効いてきそう。heroku経由でheroku addonに乗るのかな? herokuも使わないのかな。

ふーむ。

ssh protocol形式のgit のurlをparse/buildするuri-ssh_git書いた

ssh protocol形式のgit のurlをparse/buildするuri-ssh_git書いた。

経緯

GitHubのclone url表現には3つある。

それぞれ、git protocol, ssh protocol, https protocolだ。gitとhttpsはいいんだけど、ssh形式は、これはurl的には

ssh://git@github.com:22/kyanny/hello.git

Git における SSH オプション指定方法あれこれ – Qiita

だそうだ。で、ssh形式をparseするのにURI.parse や Addressable.parse でparseできてた、つもりだったんだけど、これはいままでAddressableでpathだけ使ってたからであって、これがたまたまparseしてただけっぽい。

# URI
url = URI.parse('git@github.com:schacon/ticgit.git')
URI::InvalidURIError: bad URI(is not URI?): git@github.com:schacon/ticgit.git

# Addressable
url = Addressable::URI.parse('git@github.com:schacon/ticgit.git')
#=> #<Addressable::URI:0x3fedf48fb430 URI:git@github.com:schacon/ticgit.git>
url.path #=> "schacon/ticgit.git"
url.scheme #=> "git@github.com"

で、ssh形式のurlどうパースするんだ…ってググったりnet-ssh見たりしたけど、見つからなくて取り急ぎgem書いた。Addressableのuri.schemeを分割するのは無し。偶然parseできてるだけな気がするので。@と:でぱっと見区切れるようにみえるんだけど、portとか相対パス絶対パスとかどうなるんだ、っていうので検索、検索。なお最終的にはぱっと区切って終わりにした。

Usage

url = URI::SshGit.parse('git@github.com:packsaddle/ruby-uri-ssh_git.git')
# #<URI::SshGit::Generic git@github.com:packsaddle/ruby-uri-ssh_git.git>

# http://docs.ruby-lang.org/ja/2.2.0/class/URI=3a=3aGeneric.html
# :scheme ,:userinfo, :host, :port, :registry, :path, :opaque, :query, :fragment
url.scheme #=> nil
url.userinfo #=> 'git'
url.user #=> 'git'
url.password #=> nil
url.host #=> 'github.com'
url.port #=> nil
url.registry #=> nil
url.path #=> '/packsaddle/ruby-uri-ssh_git.git'
url.opaque #=> nil
url.query #=> nil
url.fragment #=> nil

URI::SshGit.build(
  userinfo: 'git',
  host: 'github.com',
  path: '/packsaddle/ruby-uri-ssh_git.git'
).to_s
#=> 'git@github.com:packsaddle/ruby-uri-ssh_git.git'

# Utility method
ssh_protocol = 'git@github.com:packsaddle/ruby-uri-ssh_git.git'
git_protocol = 'git://github.com/packsaddle/ruby-uri-ssh_git.git'

::URI::SshGit.ssh_protocol?(ssh_protocol) #=> true
::URI::SshGit.git_protocol?(ssh_protocol) #=> false
::URI::SshGit.ssh_protocol?(git_protocol) #=> false
::URI::SshGit.git_protocol?(git_protocol) #=> true

# Usage
git_clone_url = '...'
if URI::SshGit.ssh_protocol?(git_clone_url)
  parsed = URI::SshGit.parse(git_clone_url)
else
  parsed = URI.parse(git_clone_url)
end
parsed.host
parsed.path

感想

追記ここから: 2015-03-06 3:28
バグ作りこんだので, Utility部分は削ってインターフェース変えます。
追記ここまで

うーん… packsaddle/ruby-uri-ssh_git.git を parseするときに /packsaddle/ruby-uri-ssh_git.git に読み替えてるんだけど、ここが1対1のマッピングじゃない時に(foo/bar.gitが/data/foo/bar.gitですとか)情報が欠落してて破綻する。が、ひとまずgithubとbitbucketはこのルールでいいっぽいので良いとしておこう。あとURIがらみの初めて書いたのでhookするぽいんとがよくわからん。クラスとモジュールの構成もうまくないけど、必要なら誰かが直すでしょう… というかssh形式のurlをparse出来る何かがあるはず。

nodejsだとssh-url使うとよさげ
あとssh git url parse で調べてると、npmまわりのfetchしたりのissueがいろいろ出てくるので、普通にparse出来るのかもしれない。未確認。

参照

GitHub statusを簡単に通知するコマンドを作った

GitHub statusとは、TravisCIとかがビルド中は黄色で、成功失敗を赤緑でPull Request上で表してくれるあれ。それを簡単に通知するコマンドとそのgemを作った

2015-02-28-github-status-notifier-pending

詳しい使い方はこっちに書いた。
CI環境からGitHubのPull Requestのstatusを簡単に通知するコマンド – Saddler – checkstyle to anywhere

readmeにもあるとおり、こう使う。

# before your command
$ github-status-notifier notify --state pending

$ SOME_YOUR_COMMAND

# after your command
$ github-status-notifier notify --exit-status $?

branchとかリポジトリとかsha1とか、TravisCI/CircleCIのビルドのURLの生成とか、それなりにいい感じに動いてくれるのが特長。シンプルに実行したいだけならjoker1007/github-commit-status-updater こっちを使うと良い。

これ系のproduct今ガッと作ってpacksaddle プロダクトとしてまとめてる。もうちょっと作る。

静的解析結果をpull requestのコメントにつけるsaddler作った

静的解析結果をpull requestのコメントにつけるsaddlerというrubygemを作った。rubygemだけど、コマンドラインを通して言語中立なので何にでも使える。

git diff --name-only origin/master \
   | grep -e '\.js$' \
   | xargs ./node_modules/gulp-jscs/node_modules/.bin/jscs \
       --reporter checkstyle \
   | checkstyle_filter-git diff origin/master \
   | saddler report \
      --require saddler/reporter/github \
      --reporter Saddler::Reporter::Github::PullRequestReviewComment

こんなイメージで、結果をcheckstyle formatで出力できれば、なんでもpull requestのreview commentに付けられる。これをTravisCI, CircleCI, Jenkinsなどから実行する。

2015-02-27-jscs-comment

導入や各段で何が起きるのかは、こっちに書いた。

変更したファイルにrubocopやjscsを実行して pull requestに自動でコメントする – Saddler – checkstyle to anywhere

HoundCIやprontoより柔軟度が格段に高いこと、CI環境だけで完結できること、中間に変なwrapperが不要でメンテナンス性が高いこと、が特長。便利。

travis-ciの設定してたらauthority gemのcollaboratorの一人になった

authority gemのcollaboratorになった

lokka/lokka 以来。あと、若干pundit gem派だったのを今さっき思い出した。

経緯

Help with maintenance? · Issue #94 · nathanl/authority

追加メンテナー探してる。メンション来たので前回travis-ci周りいじったんだよなーとtravis-ciまわりの設定見てた。意図通り書けていないのでpull request送った。タナボタでメンテナーになった!
Screen Shot 2015-01-10 at 2.31.34

抱負

travis-ciでcontainer対応, transpecでrspec v3対応, 依存gemのバージョン整理, rubocopとhoundci入れる(houndciはadminじゃなくて入れられるか分かんね), Tachikoma.io 突っ込む ぐらいいい機会だやろう。ここまで別にメンテナーである必要ない。あとissueに1個答えるのが努力目標。

余談

conventional-changelog

conventional-changelogのCONVENTIONS.md見ながらコミット積んで、pull requestにlistで書いたらめっちゃほめられた。気分いいわ〜

Screen Shot 2015-01-10 at 2.05.56

ただしscopeに何書いていいのかいまだに全然つかめない。

メンテナーの参考

turnip の Collaborator (Maintainer) になりました – Thanks Driven Life

Rubyのコマンドで標準入力と引数ファイル名で同じように扱いたい

$ foo-command ./bar.file

で扱えるものは

$ cat ./bar.file | foo-command

もしくは

$ cat ./bar.file | foo-command -

で扱えてほしいという話。

主にUnix哲学にかぶれるとこういうことを言い出す。

または、parserというruby gemが提供するruby-parse, ruby-rewriteコマンドが標準入力を受けて、というのが出来ないので、ruby-parse-wrapped, ruby-rewrite-wrapped というコマンドを提供するparser-cli_wrapperというruby gemを書いたという話。

やりたいのはreadmeに書いたとおり、

$ cat Gemfile
source 'https://rubygems.org';

gemspec

$ ruby-parse Gemfile
(begin
  (send nil :source
    (str "https://rubygems.org"))
  (send nil :gemspec))

こう動くコマンドがあったら、こうも動いてほしいよね、という。

$ cat Gemfile | ruby-parse -
(begin
  (send nil :source
    (str "https://rubygems.org"))
  (send nil :gemspec))

で、ここまでだったらparserにそういうpull request作って終わりなんだけど、実際はEnable stdin with ruby-parse commitまで作ったけど実装練れてない感じがしたので踏みとどまって、wrapして別のコマンド提供するgem作った。

うーんってなって書いた実装がコレ 標準入力あったら-e で渡す方に詰めとく
https://github.com/sanemat/parser-cli_wrapper/blob/04fbe925f53fc2ed3110ef3588aef7b9a431c62d/bin/ruby-parse-wrapped
もとがこれ
https://github.com/whitequark/parser/blob/c8897941723c9b94000a1065b007ea71caa18c46/bin/ruby-parse

自分で書くなら、そもそも標準入力で渡される方を先に書いて、fileも読み取れるようにする、から、その点は無理なく書いていけそう(その代わり複数ファイルのときに?? ってなりそう)。parserの場合、ruby-parse FILEruby-parse -e 'some ruby code'で出力されるASTがちょっと異なっていて、具体的にはAST側にファイルを囲むbeginってのが出ない、おそらく普通使うときはファイルベースだよね、ってところでむむむってなった。

むむむってなったので、tempfileにひとまず書き出して、それをファイルとして読む、という二度手間することにした。それどこに書くの? というのも迷って、
binの中に
https://github.com/sanemat/parser-cli_wrapper/blob/04fbe925f53fc2ed3110ef3588aef7b9a431c62d/bin/ruby-parse-wrapped
こんなにロジックでうめつくすのはおかしいだろ、って思うから、なんか解決方法はあるだろうけど知らない。どこにどう書いたもんだろう?

Node.jsに行け、かなあ。

Edited(2014-11-25 2:16): なんでARGFにしなかったんだっけ? 忘れた 標準入力を取りつつ、オプションを活かしつつ、にしたかったからだと思う。ARGV.shiftしてARGF取り出せるようにすると、ARGV壊しちゃわない?あんまり理解できてない
http://stackoverflow.com/questions/20359129/stream-data-through-ruby-script-and-using-parameter-in-argv

Release tachikoma v4.2.1: Strategies with cocoapods and composer

tl;dr

Tachikoma v4.2.1 gets the power against objective-c applications and php applications. Those strategies are cocoapods and composer. You can update library dependencies more easily, you’ll be happy 🙂

Tachikoma v4.2.1 はobjective-cのアプリケーションやphpのアプリケーションに対して使えるようになりました。cocoapodscomposerというストラテジー追加のおかげです。依存ライブラリのアップデートがより簡単になるので、幸せになれるでしょう 🙂

Key features

bundle exec rake tachikoma:run_cocoapods is for objective-c application. You receive interval pull request with pods update.
bundle exec rake tachikoma:run_composer is for php application. You receive interval pull request with composer update.
Deprecate bundle exec rake tachikoma:run_bundle, Use bundle exec rake tachikoma:run_bundler instead. This keeps symmetry between other strategies’ name.

bundle exec rake tachikoma:run_cocoapods はobjective-c アプリケーションのための機能です。あなたは定期的にpods updateしたpull requestを受け取ることが出来ます。
bundle exec rake tachikoma:run_composer はphp アプリケーションのための機能です。あなたは定期的にcomposer updateしたpull requestを受け取ることが出来ます。
bundle exec rake tachikoma:run_bundleは廃止予定です。替わりにbundle exec rake tachikoma:run_bundlerを使ってください。これは他のストラテジーの名前との対称性のためです。

Enjoy programming!

プログラミングを楽しみましょう!

無駄に使ってるgemのname spaceをtransferする

gem-compareをつくろうと思って作る前にリリースしてnamespaceの占有してたんだけど、結局作ってなくて、使ってないならもし良かったらくださいってメールもらったのでtransferした。
https://github.com/sanemat/gem-compare
http://rubygems.org/gems/gem-compare

ググったら2つ方法があった。

  • ownerに突っ込んで、まあよしなにやってもらう
  • 全リリース済みのバージョンをyankする

今回とったのはownerに突っ込む方。

ownerに突っ込んで、まあよしなにやってもらう

rubygems.orgのメールアドレス教えてくださいって返事出す。もらったら追加。

http://guides.rubygems.org/command-reference/#gem-owner

$ gem owner gem-compare -a who-want-trnasfer@example.com
$ open https://rubygems.org/gems/gem-compare

pros
– 確実に名前空間を引渡できる

cons
bundle exec rake releaseではじめ行けないのでgemコマンドググる必要がある
– なんとなくお互いにめんどい

全リリース済みのバージョンをyankする

Removing a published RubyGem / Gemcutter / Knowledge Base – RubyGems.org Support

pros
– 普通のプロセス

cons
– 早い者勝ち
– いつから使えるようになるのかも知らない

あとは参考になればやりとり。

I noticed you have a gem-compare gem registered on RubyGems.org, but I
also see that the gem is not finished for several months.
Will you continue? I am writing a RubyGems plugin for comparing gem's
versions and it would conflict with yours.

Of course that if you wish to have it and work on in I will just
choose another name, but if you know you wouldn't, would you
allow me to use the `gem-compare` name for my gem on RubyGems.org?

You can find mine work-in-progress gem here:
https://github.com/strzibny/gem-compare

Thank you for clarification.
====
Cool, I don't have a plan to build gem-compare gem now, so it's ok.
I'll add you as gem owner, then you can remove me 🙂
Would you give me your email for rubygems.org?
====
thanks a lot! My email is new-owner@example.com
====
I added you as owner. I'm looking forward to your awesome gem!
http://rubygems.org/gems/gem-compare

追記: 2014-08-19 0:37 と、5月に書いてたのがやっと、July 9, 2014 にv0.0.2 リリースしてたようだ。めでたい。Congrats!