やりたいこと
いまいち上手く日本語に出来なかったので図解する。
コマンドラインツール等で、実行時に手元のファイルをテンプレートとして利用したり、静的ファイルをディレクトリごとコピったりしたいことが良くある。でもそのままExecutableにするとファイルが付いてこなくてどうしよう、と言う話。上の図で言うと、赤い矢印で示したファイル参照を実現したい。
.cabalファイルの記述
実行時に必要なファイルを.cabal
ファイルに記述する。Data-dir:
に必要なディレクトリ、Data-files:
にそのディレクトリ下のファイルを羅列する。この指定が曲者で拡張子がワイルドカードに出来ない。なので、/**/*
とかにしたいのを我慢しつつ、拡張子をひとつずつ記述する。
foobar.cabal
Data-dir: data Data-files: templates/*.html.tmpl templates/*.js.tmpl assets/*.svg assets/*.ico assets/*.png
Haskellから呼び出す
foobar
というパッケージに付随するファイルは、Paths_foobar.getDataFileName :: FilePath -> IO FilePath
で呼び出せるようにcabalがコンパイルしてくれる。魔法か。
Main.hs
import Paths_foobar main :: IO () main = do path <- Paths_foobar.getDataFileName "templates/app.js.tmpl" putStrLn path -- 絶対パス
どうなっているのか
手元のWindowsで、インストール先はこんな感じになってた。
C:\Users\UserName\AppData\Roaming\cabal ├ bin │ └ foobar.exe └ x86_64-windows-ghc-7.10.2 └ foobar ├ templates └ assets
応用例:インストール時にコンパイルしたファイルを使う
データディレクトリに入れるファイルをインストール時に動的に作りたい場合がある。例えば、配布しているソースは.coffee
で、実際に使うのはコンパイルした.js
という場合。
.cabal
ファイルで、Build-type: Custom
とすると、Setup.hs
ファイルにビルド時に呼ばれるフックを記述できる。内容は略。
foobar.cabal
Build-type: Custom
Setup.hs
(略)
作ったもの
Elmでパッケージを公開する前にドキュメントをプレビューできるツール。
参考用にどうぞ。