画像の圧縮自体はImageOptimと云ふプログラムをコマンドで呼んでゐる丈だ。お終い。
HomebrewではCaskroom/cask/imageoptimに在る。
そこでGitの話に成る。
利用シーンはご想像にお任せするが、gitでpullした後に、其のpullで更新されたPNGファイルをlosslessで最適化する。最適化するコードだけ抜き出すと以下に成る。
#!/usr/bin/env ruby require 'shellwords' targets = ... system "ImageOptim #{Shellwords.shelljoin(targets)}"
targetsに指定すべきファイルを一覧するにはだうしたらいいだらうか。pullした時に更新したコミット番号がわかるので、diffをとり、削除された差分ではないファイルを一覧し、PNGを抽出する。簡単なシェルのスクリプトだ。git diff --name-status
を使へる。
#!/usr/bin/env ruby require 'shellwords' revisions = ARGV[1] || (print 'revisions> '; gets.strip) targets = `git diff --name-status #{revisions}`. each_line. collect(&:strip). reject{|line| line.start_with?('D') }. collect{|line| line.sub(/\A\S+\s+/, '') }. select{|line| line.end_with?('.png') } system "ImageOptim #{Shellwords.shelljoin(targets)}"
此れをImageOptimと云ふ名前で保存しておけば、./ImageOptim -- 64e88f6..2be0234
等と呼び出せる。
餘談だが此の偽のコミット番号はruby -rsecurerandom -e"puts SecureRandom.uuid[0..6]"
で作れる。
上で標準ライブラリのShellwordsを使ってゐるのは、空白を含んだファイル名が沢山転がってゐるからだ。そもそも此れが、bashスクリプトではなく面倒に成ってRubyを書いた理由だった。
次に現れたのは日本語ファイル名だった。OSXのgitはとうに日本語のファイル名を扱へるやうにはなってゐるが、親切にもエスケープして表示してくれる。\001\002…のやうな。
面倒だ。調べると此のエスケープをオフにするオプションがある。git config core.quotepath
だ。此れをfalseにすればUnicodeのまま印字される。常にオフにするのも氣がひけるので、スクリプトの終了時に元の設定に戻すコードを書いた。Ruby的なブロック引數だ。
#!/usr/bin/env ruby require 'shellwords' def git_quotepath? case `git config --local core.quotepath` when "" then nil when "false\n" then false when "true\n" then true end end def set_git_quotepath config case config when nil `git config --local --unset core.quotepath` when false `git config --local core.quotepath false` when true `git config --local core.quotepath true` end end def without_git_quotepath &block config = git_quotepath? set_git_quotepath false block.call ensure set_git_quotepath config end revisions = ARGV[1] || (print 'revisions> '; gets.strip) targets = without_git_quotepath{ `git diff --name-status #{revisions}` }. each_line. collect(&:strip). reject{|line| line.start_with?('D') }. collect{|line| line.sub(/\A\S+\s+/, '') }. select{|line| line.end_with?('.png') } system "ImageOptim #{Shellwords.shelljoin(targets)}" # vim: set ft=ruby:
疲れた。