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

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!

Related

Cabal - Rebuild on file change

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?

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

Alex, Happy, Cabal, and Re-preprocessing

I am using Alex 3.0.5, Happy 1.18.10, Cabal 1.16.0.2
I have a small compiler project that is built using Cabal. I am exposing the compiler's internals as a library, so I have in the exposed modules section, MyLangLex and MyLangPar. If I delete the .hs files that are generated by Alex and Happy, then running cabal configure, and then cabal build will run Alex and Happy first, generate the files, and then proceed with the build, and everything works as expected. However, if I do not delete these files, Alex and Happy either do not build the files, or they don't put them in the right place. I think Happy runs, because I see a message from Happy; however, when I look at the .hs file that should be generated it is incorrect (doesn't have a change in it), and I can tell for sure that the version of the .hs file that Cabal uses in the build is the wrong one because the behaviour that should have changed does not. I.e. The change to the .y file does not get incorporated into the built program, so I suspect that while Happy is run, Cabal places this file in some temp directory, and then uses the old .hs file, which is still there for the build. But I am not sure about this.
Is the error on my part or is one of the tools misbehaving?
It sounds like you need a "other-modules:" directive in your library section for Lex.x and Par.y:
library
...
build-tools: alex, happy
other-modules: Compiler.RSL.Syntax.Lex, Compiler.RSL.Syntax.Par
The other-modules directive together with build-tools will instruct cabal to use alex and to create Compiler/RSL/Syntax/Lex.hs from the .x file if it doesn't exist (and the same for Par.hs).
Alternatively, add Compiler.RSL.Syntax.Lex to your 'exposed-modules' list. This tells cabal that the Lex.hs file should exist, and so if it doesn't cabal will look for ways to build it using the tools in the build-tools line.

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