Which stackage snapshot does stack install use? - haskell

Trying to run
stack install git-mediate
(per git-mediate's instructions)
I get an error message regarding dependent package versions:
Error: While constructing the build plan, the following exceptions were encountered:
In the dependencies for git-mediate-1.0.8:
Diff-0.3.4 from stack configuration does not match >=0.4 (latest matching version is 0.4.0)
needed since git-mediate is a build target.
Some different approaches to resolving this:
* Set 'allow-newer: true' in /Users/yairchu/.stack/config.yaml to ignore all version constraints and build anyway.
* Recommended action: try adding the following to your extra-deps in /Users/yairchu/.stack/global-project/stack.yaml:
- Diff-0.4.0#sha256:b5cfbeed498f555a18774ffd549bbeff7a24bdfe5984154dcfc9f4328a3c2847,1275
Plan construction failed.
It's odd that the stack configuration has Diff-0.3.4, as currently both LTS and nightly stackage snapshots currently contain Diff-0.4.0 (lts-16.8 and nightly-2020-10-13).
What is this stack configuration thing and why is it pinned to old versions of libraries?

stack install is an alias for stack build --copy-bins, so it's really just stack build plus the additional step of copying the built executables to ~/.local/bin.
So, the real question is "how does stack build decide what resolver to use?" Well, if you provide it on the command line, it uses that one, as in:
stack install --resolver lts-16.18 git-mediate
If you don't give an explicit resolver, the default depends on where the build command is run. If you run it inside a stack project, it'll default to the resolver specified in the project's stack.yaml file. For example:
stack new --resolver lts-16.0 exampleproject # create project with lts-16.0 resolver
cd exampleproject
stack build git-mediate # this will build git-mediate using lts-16.0
If you build it outside of any project, then it uses the global project setting, which will be whatever resolver is set in ~/.stack/global-project/stack.yaml, as mentioned in the comments / other answer.
Note that the stack install alias will always copy the executable into the "global" ~/.local/bin, regardless of where it was built. So, if you run stack install git-mediate in the exampleproject directory, as above, you'll get the version built with lts-16.0 as the globally installed version.
Soooo... be careful where you run stack install!
Note that, with respect to git-mediate specfically, there was recently a buggy version published to Stackage, as documented here. The error message is slightly different than the one you got, but the underlying problem might have been the same. So, it's possible that just running stack update without having to modify the resolver setting would work to fix your build problem, if you haven't already fixed it.

stack is implicitly using it's "global project" defined in ~/.stack/global-project/stack.yaml. To control the stackage snapshot being used this file can be edited (or just deleted to use the latest LTS)

Related

Find the package a Haskell module belongs to

I'm new to Haskell stack and wondering how to find out the name of the package that contains a particular module.
Currently, I want to use Data.Tuple.Extra(fst3) ( https://hackage.haskell.org/package/extra-1.7.9/docs/Data-Tuple-Extra.html ) and want to know what I should write below
$ stack install ????
I've already installed the tuple package, which, however, doesn't seem to include the Extra part.
All the Internet resources about the installation of a package I've found so far say something along the lines of "To use Blahblah.Anything.Something, you need to install the foofoo package" . . . How can one know? I searched Stackage but it shows only the documentation of Data.Tuple.Extra and I still fail to find the name of the package.
Edit: As K.A.Buhr notes in her/his answer, stack install is the wrong command for the above case. Use stack build instead.
When browsing package documentation in Hackage, the top-left portion of the page header will always give the package, version number, and description. On the page you link, it's here:
You can also use the "Contents" link in the top-right to go to the main page for the extra package, which gives its full list of modules, licensing, links to the package home page and bug tracker, and so on.
As a side note, stack install extra is technically the wrong command to "install" this package. If you want to make the extra package available for use within the Stack global project, the correct command is stack build extra. If you want to use extra within a stack project, then you want to add extra to the dependencies in your package's xxx.cabal or package.yaml file instead and run stack build (no arguments) to build and install it for use in your project.
In contrast, the stack install command is equivalent to stack build --copy-bins which copies any executables in the package to ~/.local/bin so they'll be in your path. See the Stack docs. It's intended to be used for installing programs written in Haskell that are distributed via Stack, so you can do stack install hlint to install the hlint linter, for example.
In this case, because the extra package has no executables, stack install extra and stack build extra will do the same thing, but it's better to get into the habit of using stack build when you aren't intending to install any package binaries, to avoid surprises.

Stack: 'hdevtools is a library dependency, but the package provides no library needed since my-app is a build target.'

I was trying to add hdevtools to my stack project, so I ran stack build hdevtools. The install seemed to work successfully, and my text editor stopped reporting imported libraries installed via stack (like aeson and tasty) as missing.
However, things went wrong when I added this line to the dependencies section of my package.yaml file:
- hdevtools >= 0.1 && < 1
And then tried to run stack build again. I received the following error output:
Error: While constructing the build plan, the following exceptions were encountered:
In the dependencies for my-app-name-0.1.0.0:
hdevtools is a library dependency, but the package provides no library
needed since my-app-name is a build target.
Some different approaches to resolving this:
* Consider trying 'stack solver', which uses the cabal-install solver to attempt
to find some working build configuration. This can be convenient when dealing
with many complicated constraint errors, but results may be unpredictable.
Plan construction failed.
I tried running stack solver, but that threw the exception documented here.
How can I declare hdevtools as a dependency of my project?
#alexis-king recommends using stack build --copy-compiler-tool hdevtools in this guide, in the section titled Setting up editor integration.
This works for the current project, and other projects using the same GHC version, but you will need to run it again when you upgrade to a new GHC version.
More context from King's guide:
As mentioned above, stack install is not what you want. Tools like ghc-mod, hlint, hoogle, weeder, and intero work best when installed as part of the sandbox, not globally, since that ensures they will match the current GHC version your project is using.
How can I declare hdevtools as a dependency of my project?
hdevtool is an executable and cabal doesn't have a concept of development dependencies (like in other package managers like npm etc). So, all you can do is install hdevtools globally and make it work.

Recommended approach to use Stack as global package manager

I would like to install some Haskell libraries globally, for example hindent which is used by my editor's Haskell integration. What is the recommended way to do this?
I thought that stack install hindent was the correct way to do this. However, then I wanted to update my packages and found that there was no way to do this. According to the GitHub issue report I found,
stack is concerned with managing a local build sandbox for a project. It isn't intended to be a global package manager.
There appear to be workarounds such as maintaining a dummy project with artificial dependencies on the packages I would like installed. This sounds like a terrible hack, and I have been unable to find any official documentation on what approach should actually be taken.
Installing Haskell packages using my system package manager (Homebrew) is not an option since they are not packaged.
I would have opened an issue report against Stack, however the contribution guidelines requested that I instead ask a question here under the haskell-stack tag.
Well, stack install in any project will install to ~/.local/bin therefore making whatever executable you install be globally accessible.
The global project is used when running stack without a project, it is located in ~/.stack/global-project/stack.yaml.
If you want all of your globally accessible tools to have the same dependencies (perhaps to ensure that the ghc version matches or something), then you could make a project intended to build all of these tools. It's up to you whether or not it is the "global project" - there's not much special about it, it's just a default if you run stack and aren't in a project.
In order to record "what haskell executables do I want installed globally", you might consider creating a shell file like
#!/bin/sh
stack install hindent
And then running this whenever you change the versions of the installed tools.
Also, for tools like intero that need to match the ghc version, you can do stack install --copy-compiler-tool intero, and it will be available on the PATH when stack is used with that ghc version.

Is there a declarative way to specify packages to be installed into global-project using Haskell stack?

Stack allows global installation of packages using stack install <packagename> outside of a project directory.
Stack also has a ~/.stack/global-project/stack.yaml file that allows configuration of the global-project. However I can't see a way to "install" packages declaratively. The extra-deps and packages key in the yaml file don't seem to work for this method.
Instead I just have to run stack install <...> <...> each time the snapshot version gets updated for my global-project.

Failure to install hsev on Windows 10 via `stack install hsdev`

I get this error when running stack install hsdev outside and inside of a project:
λ stack install hsdev
Run from outside a project, using implicit global project config
Using resolver: lts-5.11 from implicit global project's config file: C:\Users\atc\AppData\Roaming\stack\global-project\stack.yaml
While constructing the BuildPlan the following exceptions were encountered:
-- While attempting to add dependency,
Could not find package hformat in known packages
-- Failure when adding dependencies:
hformat: needed (>=0.1), stack configuration has no specified version (latest applicable is 0.1.0.0)
simple-log: needed (>=0.3.4), stack configuration has no specified version (latest applicable is 0.3.4)
text-region: needed (>=0.1), stack configuration has no specified version (latest applicable is 0.1.0.0)
needed for package hsdev-0.1.8.2
-- While attempting to add dependency,
Could not find package simple-log in known packages
-- While attempting to add dependency,
Could not find package text-region in known packages
Recommended action: try adding the following to your extra-deps in C:\Users\atc\AppData\Roaming\stack\global-project\stack.yaml
- hformat-0.1.0.0
- simple-log-0.3.4
- text-region-0.1.0.0
I have run stack update prior to attempting this. I want to install hsdev so I can use SublimeHaskell.
stack solver gives:
λ stack solver
Run from outside a project, using implicit global project config
Using resolver: lts-5.11 from implicit global project's config file: C:\Users\atc\AppData\Roaming\stack\global-project\stack.yaml
Using configuration file: AppData\Roaming\stack\global-project\stack.yaml
The following packages are missing from the config:
<snip long list of references to directories in AppData\Local\Temp\stack14228\>
No cabal packages found in AppData\Roaming\stack\global-project\stack.yaml. Please add at least one directory containing a .cabal file. You can also use 'stack init' to automatically generate the config file.
Relevant stack info:
λ stack --version
Version 1.0.4, Git revision cf18703b1392a96a5a4896a560309e501af63260 (3220 commits) x86_6
I got hsdev installed on my windows machine by the following steps.
Run stack unpack hsdev to download the source of hsdev to the working directory.
Move into the directory, run stack init --solver to create a proper stack.yaml build config.
Run stack install to build and copy the executables to your local bin directory. If stack reports an error about a missing LICENSE file create an empty LICENSE file under ./tests/test-package.

Resources