outdated な port の依存関係を考慮して upgrade する

MacPorts は apt-get に比べるとちょっと依存関係の解決のあたりがプアな感じなので*1、更新する時は port outdated で古くなったものを調べて、port deps で依存関係をチェックして依存するパッケージが outdated になっていないものを upgrade という作業をするようにしました。
だけど手動でやるのは面倒なので自動的にこれをやってくれる Rubyスクリプトを書いてみたので貼ってみます。
実行すると、依存している port が outdated に含まれていない port を調べてそれらを port -fun upgrade で更新します。1パスしか実行しないので、依存のある port は再度実行しないと更新されません。一気にやったほうがいいかも。

outdated = `port outdated`.split("\n")
if /No installed ports are outdated./ =~ outdated[0]
  puts outdated[0]
  exit 0
end

unless /The following installed ports are outdated:/ =~ outdated[0]
  $stderr.puts "port outdated failed, maybe..."
  $stderr.puts *outdated
  exit 1
end

outdated.shift
outdated.map!{|l| l.split(/\s/,2).first }
ports = {}
outdated.each{|port|
  ports[port] = `port deps #{port}`.split("\n").select do |l|
    /^\t/ =~ l
  end.map{|l| l.split("\t")[1]}
}

nodeps = ports.select do |port, deps|
  not deps.any?{|dp| ports.include?(dp)}
end

nodeps = nodeps.map{|ndp| ndp[0] }

if nodeps.empty?
  puts "Program Logic Error: no outdated port."
  exit 1
end

puts "upgrade deps #{nodeps.join(" ")}"
system("sudo port -fun upgrade #{nodeps.join(" ")}")

あーこういうのを貼るために gist というのを使えばいいのかも。まだ GitHub をちゃんと使えてない。まだSSH鍵も未登録。

*1:わたしが正しい使い方を知らないだけの可能性大