Cabal - Rebuild on file change - haskell

Is there a cabal option to rebuild (or even run the tests and do other stuff) on every source file change? With Stack there is the --file-watch option, anything similar for Cabal? Or do people just use ghcid for that?

Related

How to make Stack rebuild the Cabal file when `package.yaml` has changed?

When I use stack I have the following files in the root:
stack.yaml
package.yaml
myProject.cabal
The last one is built automatically by stack build, based on the other two. Accordingly, I expect myProject.cabal to be updated when the other two files change, but that is not the case. As far as I can tell one must delete the cabal file for a new one to be generated.
First obvious question is: Why? Why doens't Stack rebuild the cabal if obviously needs to be changed?
Second question: How do I tell Stack to rebuild the cabal file? I don't want to manually delete the cabal file every time I do a version change or tweak package.yaml.
What I've tried:
One option is to manually delete the cabal file manually, which just seems like a terrible workflow. The other option is to always delete the cabal file (with a custom makefile) this seems hacky and would trigger a full rebuild (since the cabal file changed) everytime!

Intero doesn't find Paths-module when using cabal data files

When I use the data-files feature of cabal, it generates a Paths_pkgname.hs module that lives in the dist/ folder.
However, intero is unable to find this file (or generate it on its own), and I can't find any means to pass an option to hint at its position.
Note: Somewhere else (on SO?) I picked up the trick when using ghci to make a dummy only-for-ghci/Paths_.hs that is only brought into scope through :set -ionly-for-ghci being set in .ghci. This won't apply for intero though, as its invocation in intero.el specificcally instructs it to ignore the .ghci file.
I was only building my project using cabal and nix. It turns out that because Intero is stack-centric, building the project with stack build does indeed put a Paths_.. module in a place where Intero searches.

(haskell) stack init does not finish. how to ignore all bounds in existing cabal files?

I am converting a project (consisting of several cabalized packages) to stack. "stack init" does not seem to be able to "calculate a build plan" (it takes ages).
Perhaps this gets easier when all version bounds are ignored. But how can I do this - other than actually removing them from the cabal files manually?
EDIT: there is "allow-newer" in http://docs.haskellstack.org/en/stable/yaml_configuration/ but this only helps if the initial stack.yaml file is already there.
Anyway, I could work around my particular problem by manually removing some packages (that is, subdirs) to be built.
My actual comand line was
stack init --verbose --resolver=lts-5 $(cat DIRS) --solver

How to add documentation after packages have already been installed?

I have installed a bunch of packages to the snapshot database. I would now like a local copy of their documentation (even better if it's with hyperlinked source). Is there a way I can tell stack to run haddock on all of them?
EDIT (copied from my answer):
It seems that the obvious stack haddock package will install haddock for the package, so
$ cd ~/.stack/snapshots/x86_64-linux/lts-3.0/7.10.2/doc
$ stack haddock *
seems to do what I want, with two downsides:
I'll still need to remember to pass the --haddock flag to every build (there isn't a ~/.stack/config file, is there?)
It seems to rebuild them; is there a way to avoid that?
It seems that the obvious stack haddock package will install haddock for the package, so
$ cd ~/.stack/snapshots/x86_64-linux/lts-3.0/7.10.2/doc
$ stack haddock *
seems to do what I want, with two downsides:
I'll still need to remember to pass the --haddock flag to every build (there isn't a ~/.stack/config file, is there?)
It seems to rebuild them; is there a way to avoid that?
Step 1. Download and build the newest haddock. The build instructions are
in README.md.
git clone https://github.com/haskell/haddock.git
cd haddock
cabal sandbox init
cabal sandbox add-source haddock-library
cabal sandbox add-source haddock-api
cabal install --dependencies-only
cabal build
Then install the new haddock as haddock.real
cp dist/build/haddock/haddock /some/bin/dir/haddock.real
Step 2. Create a wrapper script named haddock:
#!/bin/sh
/some/bin/dir/haddock.real --hyperlinked-source "$#"
Don't forget to make it executable and put it in your path.
Step 3. Download and build standalone-haddock:
mkdir build-standalone-haddock
git clone https://github.com/feuerbach/standalone-haddock.git
cd standalone-haddock
cabal build
cp dist/build/standalone-haddock/standalone-haddock /some/bin/dir/
An example of how to use standalone-haddock:
mkdir temp
cd temp
cabal get heredoc-0.2.0.0
standalone-haddock -o doc heredoc-0.2.0.0
Then open doc/heredoc/index.html in your browser.
When you navigate to a type definition you should see a Source link on the right and that will bring you to the new hyperlinked source.

Run HAppStack app withot cabal

I'm trying out HAppStack. I installed HAppStack and created a project: happstack new project web. New folder 'web' created with project guestbook under it. So now I want to run it. The only way I could do it is run cabal install. But I want to run my app without installing with cabal! Executing run.sh errors: Could not find module 'Paths_guestbook'. How can I do it?
Edit:
In general, is there a way to run HAppStack app without rebuild like in Snap?
In general, you can always build Cabal projects without installing simply by doing:
$ cabal configure
$ cabal build
The resulting executable will usually be called dist/build/<project>/<project>.
The specific error you're getting is because the code must be built with Cabal to get the Paths_guestbook module, which will contain information about the location of data files used by it. (It may be the case that it's unable to find these data files if you run the executable without installing it; in that case, you'll need a more elaborate solution, such as cabal-dev.)
(I'm not a Happstack user, so I don't know if there's an official way to accomplish this, but this should work for basically any Cabal-based project in general. The repository shows that run.sh was last modified in 2009, so I suspect it has simply bit-rotten. It doesn't do anything special, though, so cabal build should work just fine.)
SHORT VERSION:
The run.sh seems to be missing an include paramater. Modify it to look like this:
#!/bin/sh
runghc -isrc -isrc-interactive-only src/Main.hs
I have update the run.sh in darcs to include this change.
LONG VERSION:
Normally that flag is not needed for Happstack applications. You can usually just do, runhaskell Main.hs. But in that particular example the Main.hs explicitly imports:
import Paths_guestbook (version)
which is used in the versionInfo function so that the server can report its own version number. Though version number in src-interactive-only is hardcoded and will generally be out of date. So it is only correct if you actually build with cabal.
The Paths_guestbook module is normally created automatically when cabal build is run. So, another fix would be to change the run.sh to:
#!/bin/sh
runghc -isrc -idist/build/autogen src/Main.hs
And run cabal configure && cabal build once. After that you will be able to use run.sh (until you do a cabal clean).
Another option would be to set a CPP flag in the .cabal file, and only import Paths_guestbook when the application is being built via cabal.
For example in the happstack.com source code:
http://patch-tag.com/r/stepcut/happstackDotCom/snapshot/current/content/pretty/Main.hs
In line 40 (or so) you will see an #ifdef __CABAL__. happstack.com needs to be able to know where to find the static content such as .css files. When doing runhaskell Main.hs in the local directory, it will look for the files in a sub-directory of the local directory. If you do cabal install it will instead look whever cabal installs the data files. Or, you can override the default location with command-line arguments. (Which is what the debian packaging for that app does).
Unfortunately, the happstack new project command is somewhat bitrotten because the author became a parent and has not had time to work on it in a long time. It will likely be removed from the upcoming Happstack release in order to reduce confusion.
In order to be truly useful, I think the command needs to prompt for a bunch of values and then generate a new project from a set of templates. Similar to how 'cabal init' works. But currently, no one has volunteered the time to make that happen.
To see changes to your source appear automatically with out restarting the server you can use the happstack-plugins library. There is an screencast of it here:
http://happstack.blogspot.com/2010/10/recompile-your-haskell-based-templates.html

Resources