How to install/use a local version of package using Stack? - haskell

The situation is, I am trying to install Netwire using Stack. However, there is a problem in the latest netwire 5.0.1, as reported by dhobbs: http://hub.darcs.net/ertes/netwire/issue/13
Since I don't know when the problem will ever be fixed, I downloaded the repo and made the change myself. However, I don't understand how to install such a locally patched version. stack install does not install that into ~/.stack. Does anyone have an idea?
Update
Now I am developing some other libraries using Stack. How do I make another project use that libraries? Hard coding a relative path looks incredibly ugly.

So you have a project where you want to use your locally patched Netwire version and in your project you have a stack.yml, as an example:
flags: {}
packages:
- '.'
extra-deps: {}
resolver: lts-3.7
You also have an dependency on netwire declared in your cabal file.
To use you patched Netwire in this project of yours you simply put the patched Netwire package in a subdirectory of your project, perhaps called netwire, and update your stack.yml as such:
flags: {}
packages:
- '.'
- netwire
extra-deps: {}
resolver: lts-3.7
Now stack build will build your project with the patched Netwire version.
You can also put the modified source online (if the license permits) and refer to the source using either a tarball URL
- https://example.com/netwire.tar.gz
or a git repository and commit reference:
- location:
git: git#example.com/netwire
commit: 6a86ee32e5b869a877151f74064572225e1a0398
(Check out the documentation for more info: https://docs.haskellstack.org/en/stable/yaml_configuration/#packages-and-extra-deps)

Related

Install package that is not on stackage but on hackage

I'm trying to use a library that's on hackage, but not on stackage.
Currently, the code doesn't seem to be hosted on git anywhere (although I could "fork" it).
Are there any better ways than to just download the library locally and tell stack.yaml where to find it?
The library is parse-dimacs by the way.
stack allows you to specify dependencies that are not included in the (Stackage) snapshot as extra-deps in your stack.yaml.
To use parse-dimacs in your project, you'd add this stanza to your stack.yaml:
extra-deps:
- parse-dimacs-1.3

Prevent rebuilding external dependency

I'm new to Haskell.
I cloned a Haskell project (pandoc) from github, and compiled it with:
stack setup
stack install --test
After a while, the project is built.
Now I want to build another project (pandoc-crossref), an extension to the first one and which depends on it.
There is an extra-deps entry for pandoc in stack.yaml:
extra-deps:
...
- pandoc-2.0.1.1
...
In the README.md of the pandoc-crossref project I can see:
Pandoc will also be built, if it's not installed as a Haskell library system-wide.
But when I try to build pandoc-crossref, pandoc is built again.
What does installed as a Haskell library system-wide mean? Is it possible to prevent the first project being built again? Maybe by using the --extra-lib-dirs option?

How can I use my own build of a package with stack?

The bigger picture is that I'm trying to use the sdl2 package from Stackage (lts 8.1). Though, I'm having a bit of an issue; The package is missing a compiler flag, as detailed in this issue on GitHub. As such, it doesn't build properly.
However, if I clone the repository, I can add the missing compiler flag to the .cabal file and build it myself, which solves the issue. I now have a working build of the package.
So my question is: How can I, in a separate project, use my own working build of the sdl2 package, instead of the one from Stackage?
There are a few ways of doing that with Stack. The one I like the most, and which sounds like a good fit for your scenario, is uploading the repository with your fork to GitHub (or wherever else you find appropriate) and then adding a reference to the online repository as an extra-dep to the packages section of stack.yaml. For the sake of illustration, here is the packages section for a project of mine in which I had to do that:
packages:
- '.'
- location:
git: https://github.com/duplode/threepenny-gui
commit: 7e4e3a41cbb5e55312d4375612790d633ccf1e7a
extra-dep: true

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.

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.

Resources