How to update .cabal file using Stack? - haskell

I have an older project that I created with Stack. I want to move my project to the latest LTS set from Stackage.
When I change the resolver in the stack.yaml file, the problem is that the versions in the extra-deps in the .cabal file are still for the old LTS set. Is there a way to automatically update the version numbers in the .cabal file using Stack?

You could simply delete (some of) the (upper) bounds of the build-depends in your cabal file.
When it comes to distributing your package, stack can automatically add dependency bounds if you use the --pvp-bounds flag, e.g. stack sdist --pvp-bounds upper, stack upload --pvp-bounds both etc.
There's a blog post by Michael Snoyman on this feature.

Related

How can I use Stackage's cabal.config files with nix-style cabal?

Stackage provides a cabal.config file with each snapshot, e.g. this one. How can I make cabal new-configure a project with the package versions from that file?
(Alternatively: Is there another way to configure a nix-style cabal project with dependency versions from a specific Stackage snapshot?)
The cabal.config files from Stackage only contain a single huge constraints section with the same syntax that the cabal.project files use.
So you can simply copy these constraints into your cabal.project.local file, delete any constraints for packages in your local project and new-build.

Create hackage package that can be installed with stack

When running stack sdist in my project directory, the stack.yaml file isn't included in the tarball (this seems to be expected).
Consequently, when I upload the tarball to hackage, then stack install mypackage it complains about missing dependencies (extra-deps) which I specified in the stack.yaml file.
$ stack install pandoc-placetable
Run from outside a project, using implicit global project config
Using resolver: lts-5.17 from implicit global project's config file: ~/.stack/global-project/stack.yaml
While constructing the BuildPlan the following exceptions were encountered:
-- Failure when adding dependencies:
spreadsheet: needed (>=0.1.3 && <0.1.4), not present in build plan (latest applicable is 0.1.3.4)
needed for package: pandoc-placetable-0.4
-- While attempting to add dependency,
Could not find package spreadsheet in known packages
Recommended action: try adding the following to your extra-deps in /Users/maurobieg/.stack/global-project/stack.yaml
- spreadsheet-0.1.3.4
Or what's the recommended way to make a hackage package stack-installable if it has further hackage dependencies?
Update: I just added extra-source-files: stack.yaml to the cabal file and the stack.yaml is indeed included in the tarbal of the newly published version. Nevertheless, stack install pandoc-placetable-0.4.1 still comes up with the same error.
I could also just tell people who don't want to install cabal-install on their system to clone from GitHub, then build with stack. Is that the recommended approach for tiny packages? Or should I ask them to include the dependency of pandoc-placetable (i.e. spreadsheet) in their global stack.yaml? Smells like polluting a global file...
As mentioned by #mgsloan in the comments above: There's an open stack issue about using stack.yaml from hackage package.
I guess until it's fixed I'll just tell people to clone from GitHub (or as mentioned by #MichaelSnoyman to stack unpack) and then cd into the newly created directory and stack install there.

How to get stack to save dependencies?

I'm using the stack install command to save dependencies for a new project. How do I get it to save those dependencies into stack.yaml? Unless I'm missing something, I can't see where stack is recording the project dependencies and I can't seem to find anything in a docs about this.
You still keep your dependencies in a .cabal file. From the Stack FAQ:
A .cabal file is provided for each package, and defines all package-level metadata just like it does in the cabal-install world: modules, executables, test suites, etc. No change at all on this front.
A stack.yaml file references 1 or more packages, and provides information on where dependencies come from.
If you need additional versions of dependencies than the LTS Haskell snapshot you're using, you'll add them to the extra-deps portion of the stack.yaml file.

Could I make Stack use my patched Cabal library?

Does anyone know if there exists an easy way to make Stack use specific patched version of Cabal library from my GitHub repository? I'm very pleased with how can I use forked versions of other packages by just putting them into packages: section of stack.yaml, but that doesn't seem to work with Cabal.
What I wanted is some way to specify git repository URL and revision in stack.yaml and have Cabal library built from that source, not from Hackage or whatever upstream repository. Could this be done?
Stack will use the newest version of the Cabal library in your global database, so installing it there (such as by using the Setup.hs script directly) should work.

Stackage inclusive or exclusive usage

I'm attempting to start a new project using the Snap web framework. I used snap init to get my basic skeleton working. I also put http://www.stackage.org/lts/cabal.config next to my .cabal file. I didn't uncomment the line to use Stackage exclusively. So I tried to build and it failed and couldn't find the version of lens required by my .cabal file. The cabal.config file from Stackage specifies a version of lens that is not the same as the one in my .cabal file. So I deleted every constraint from my package list and did the usual cabal install --only-dep -j8 --enable-test and it worked!
However, I have always been told that package versions should be constrained. So when working with Stackage is it okay to leave package versions unconstrained? Should I downgrade my packages to the ones available in Stackage instead?
As far as I understand a cabal.config file specifies a set of dependencies with the specific versions that satisfy dependencies, so how does Stackage work? Is it just a subset of packages from Hackage that are proven to be compatible? Do they host their own packages or rely on Hackage for downloads?
Thanks in advance :)
Both options are available. The default option is what you did, and still goes to hackage to get the packages. You just added a filter to your cabal that prevents you from using any version of a package included in Stackage that was not tested to work together with all of the other packages.
The other option is to simply point your cabal repo to a Stackage url, and then you will download packages directly from the Stackage server. That server will only serve packages that are known to work together, so there is no need for additional constraints in your cabal file. I actually prefer this way of working.
In both cases, if you have additional constraints in your cabal file that are incompatible with the Stackage restrictions, your build will fail. If you use the first option, you will get dependency conflicts. When using the second option, the Stackage server will simply report that it does not have that specific package/version.

Resources