Chanko の unit を削除した後の後片付け忘れ防止メモ

# 動機

1. chanko の unit で発動条件をコントロールしつつ機能を開発
2. 実装が安定してもう unit から本体に取り込んでもいい状態になる
3. unit を外す
4. app/assets/{images,javascripts,stylesheets}/units/ 以下の symbolic link を消し忘れる
5. deploy 時の `bundle exec rake assets:precompile` がエラーを吐いて deploy 失敗
6. 悲劇

この消し忘れを早目に気付きたい

# 悲劇の再現

```
% ln -snf dark-side app/assets/images/units/gate
% bundle exec rake assets:precompile
rake aborted!
NoMethodError: undefined method `directory?' for nil:NilClass
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/base.rb:307:in `block in each_entry'
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/base.rb:303:in `each'
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/base.rb:303:in `each_entry'
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/base.rb:308:in `block in each_entry'
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/base.rb:303:in `each'
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/base.rb:303:in `each_entry'
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/base.rb:322:in `block in each_file'
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/base.rb:321:in `each'
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/base.rb:321:in `each_file'
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/base.rb:335:in `each_logical_path'
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/manifest.rb:115:in `each'
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/manifest.rb:115:in `to_a'
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/manifest.rb:115:in `compile'
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-rails-2.3.2/lib/sprockets/rails/task.rb:70:in `block (3 levels) in define'
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/rake/sprocketstask.rb:146:in `with_logger'
/Users/ice/myapp/vendor/bundle/ruby/2.1.0/gems/sprockets-rails-2.3.2/lib/sprockets/rails/task.rb:69:in `block (2 levels) in define'
Tasks: TOP => assets:precompile
(See full trace by running task with --trace)
```

死んだ symbolic link を消すのを忘れない
```
% rm -f app/assets/images/units/gate
```

# (今回の)対策

* `rails server` や `rspec` を実行したタイミングで app/assets/*/units/ 以下の死んだ symbolic link をチェック
* 死んだ symbolic link があったらその旨を表示して rails を即終了

config/initializers/chanko.rb を以下の内容で追加。

```rb
chanko_assets_dead_symlinks = []
%w(images javascripts stylesheets).each do |sub_dirname|
  Dir.glob(File.join(Rails.root, "app/assets/#{sub_dirname}/units/*")).each do |path|
    unless File.exists?(path)
      chanko_assets_dead_symlinks << path
    end
  end
end
unless chanko_assets_dead_symlinks.blank?
  $stderr.puts "Maybe you removed chanko unit and forgot to remove its symbolic links."
  $stderr.puts "So remove or fix following dead symbolic links."
  $stderr.puts
  $stderr.puts "Following app/assets/* symbolic links are dead:"
  chanko_assets_dead_symlinks.each do |path|
    $stderr.puts "  #{path}"
  end
  exit 1
end
```

## 機能してるか確認

```
% ln -snf dark-side app/assets/images/units/gate
% bundle exec rake assets:precompile
Maybe you removed chanko unit and forgot to remove its symbolic links.
So remove or fix following dead symbolic links.

Following app/assets/* symbolic links are dead:
  /Users/ice/myapp/app/assets/images/units/gate
```

死んだ symbolic link を消すのを忘れない
```
% rm -f app/assets/images/units/gate
```

## 最後に死んだ symbolic link がない状態でも動作することを確認

```
% bundle exec rake assets:precompile
% bundle exec rake assets:clobber
```