All my projects are now gaining .ghci files in the root directory. For example, the CmdArgs project has:
:set -w -fwarn-unused-binds -fwarn-unused-imports
let cmdTest _ = return ":main test"
:def test cmdTest
The first line sets some additional warnings. I usually develop my projects in GHCi with lots of useful warnings turned on. I could include these warnings in the .cabal file, but I'd rather have them when developing, and not display them when other people are installing.
The second line loads the Main.hs file, which for CmdArgs is the where I've put the main tests.
The last two lines define a command :test which when invoked just runs :main test, which is how I run the test for CmdArgs.
To load GHCi with this configuration file I simply change to the directory, and type ghci. It automatically loads the right files, and provides a :test command to run the test suite.
I've also converted the HLint project to use a .ghci file. This time the .ghci file is slightly different, but the way I load/test my project is identical:
:set -fno-warn-overlapping-patterns -w -fwarn-unused-binds -fwarn-unused-imports
let cmdTest _ = return ":main --test"
:def test cmdTest
let cmdHpc _ = return $ unlines [":!ghc --make -isrc -i. src/Main.hs -w -fhpc -odir .hpc -hidir .hpc -threaded -o .hpc/hlint-test",":!del hlint-test.tix",":!.hpc\\hlint-test --help",":!.hpc\\hlint-test --test",":!.hpc\\hlint-test src --report=.hpc\\hlint-test-report.html +RTS -N3",":!.hpc\\hlint-test data --report=.hpc\\hlint-test-report.html +RTS -N3",":!hpc.exe markup hlint-test.tix --destdir=.hpc",":!hpc.exe report hlint-test.tix",":!del hlint-test.tix",":!start .hpc\\hpc_index_fun.html"]
:def hpc cmdHpc
The first section turns on/off the appropriate warnings, then sets the include path and loads the main module.
The second section defines a command named :test, which runs the tests.
The final section defines a command named :hpc which runs hpc and pops up a web browser with the result. Unfortunately GHC requires definitions entered in a .ghci file to be on one line, so the formatting isn't ideal, but it's just a list of commands to run at the shell.
Using a .ghci file for all my projects has a number of advantages:
- I have a consistent interface for all my projects.
- Typing :def at the GHCi prompt says which definitions are in scope, and thus which commands exist for this project.
- I've eliminated the Windows specific .bat files.
- The .ghci file mechanism is quite powerful - I've yet to explore it fully, but could imagine much more complex commands.
Update: For a slight improvement on this technique see this post.
Thanks to Gwern Branwen for submitting a .ghci file for running HLint, and starting my investigation of .ghci files.