Is it possible to specify a `stack.yaml` file for a haskell script? - haskell

Let's say I have the following script inside my haskell project directory:
#!/usr/bin/env stack
-- stack --resolver lts-12.5 script
-- some imports here
main :: IO ()
main = do
-- some code here
I'd like to use the stack.yaml file that exists inside the project directory, in order to get the required packages, as I want to get them from a specific git commit instead of lts-12.5.
I've tried adding --stack-yaml stack.yaml after --resolver lts-12.5 but I'm getting this warning when I run the script: Ignoring override stack.yaml file for script command: stack.yaml.
Is it possible to use my stack.yaml file for the script? or is it possible to specify the git commit from which I want to get the package (like using location with commit and git inside stack.yaml)?

You can achieve this using custom snapshot files. For example, in snapshot.yaml:
resolver: ghc-8.4.3
name: has-acme-missiles
packages:
- acme-missiles-0.3
In Main.hs:
#!/usr/bin/env stack
-- stack --resolver snapshot.yaml script
import Acme.Missiles
main :: IO ()
main = launchMissiles
Results in:
$ ./Main.hs
Nuclear launch detected.

Related

Haskell stack script with a dependency from Github?

Is there a way to run a stack script (https://docs.haskellstack.org/en/stable/GUIDE/#script-interpreter) with a dependency from Github? I would like to run a script with the dependency somePackageFromGithub, so e.g.:
#!/usr/bin/env stack
-- stack --resolver lts-18.0 script --package somePackageFromGithub
module Main where
main :: IO ()
main = putStrLn "Hello World!"
Usually I would put this in the stack.yaml file as an extra dependency:
extra-deps:
- git: https://github.com/user/somePackageFromGithub.git
commit: "some hash"
But the stack script subcommand does not allow to specify a stack.yaml file (v.2.7.1): Ignoring override stack.yaml file for script command. Is there a way around this limitation of the stack cli interface?

Force Haskell Stack build to use the Resolver Specified after Shebang

I'm trying to use haskell for scripting in the pattern specified here on the "Script interpreter" section:
https://haskell-lang.org/tutorial/stack-script
When I have comments like this in my script after the shebang:
#!/usr/bin/env stack
{- stack
--resolver nightly-2016-11-26
--install-ghc
runghc
--package http-conduit
-}
{-# LANGUAGE OverloadedStrings #-}
I know I can safely say run:
$ stack myfile.hs
And it correctly picks up the resolver version I specified I need.
However, if I also try to build my script, to have the best of both worlds in scripting for development while I figure things out, and compilation once I'm more sure...
username#myhost:~/$ stack exec -- ghc myfile.hs && ./myfile
Run from outside a project, using implicit global project config
Using resolver: lts-7.10 from implicit global project's config file: /home/username/.stack/global-project/stack.yaml
That will error out because it's using resolver 'lts-7.10' from my global config instead of 'nightly-2016-11-26' even though my comments after the shebang specify a specific, non-global resolver to use.
While I know I could run ghc above and explicitly call --resolver on the command line, I would prefer if this were picked up from what's within the file itself. Is this possible?

How to load tests in ghci with stack

I created a very simple project with stack. It contains: an executable, a library and test targets in the associated cabal file. When I load the code to ghci via stack ghci, I can't access test there, even if they are in separate module. Is there any way to use it in such a way?
Try stack ghci (your project name):(the test suite name). Then you should be able to enter main and your tests will run.
Example:
If your .cabal project file had the following values:
name: ExampleProject
...
test-suite Example-test
Then the command to run would be stack ghci ExampleProject:Example-test
(edit suggested by #Chris Stryczynski)
To watch the test and src directories so they are updated when you reload with :r, run:
stack ghci --ghci-options -isrc --ghci-options -itest ExampleProduct:Example-test

ghc-mod under stack complaining about hidden main package

I have following problem with ghc-mod which prevents me from using ide for some files in a yesod app project.
I install template app as follows:
/tmp$ stack new demo yesod-sqlite && cd demo
/tmp/demo$ stack setup && stack build && stack install ghc-mod
Which yields following stack.yaml (commented lines removed):
resolver: lts-5.6
packages:
- '.'
extra-deps: []
flags: {}
extra-package-dbs: []
And this is a demo.cabal: http://pastebin.com/i4n1TR6W.
Then, running stack exec -- ghc-mod check app/main.hs does not produce errors, but stack exec -- ghc-mod check app/devel.hs has this to say:
app/devel.hs:2:1:Failed to load interface for ‘Application’It is a member of the hidden package ‘demo-0.0.0’.Perhaps you need to add ‘demo’ to the build-depends in your .cabal file.
So the ghc-mod somehow thinks this package is itself hidden? But any other place where project's files are imported by another checks fine, and the application builds and works successfully. The only specifics about this file is using PackageImports language extension:
{-# LANGUAGE PackageImports #-}
import "demo" Application (develMain)
I tried googling the error message but it seems to only come up with regard to external packages and not the one being debugged.
These two files devel.hs and DevelMain.hs are quite special: they are marked as a module of demo in .cabal but they are importing demo as a compiled package, i.e. recursive dependency.
They are not exposed from library demo nor imported anywhere else so won't get compiled when you run stack build, but when you run ghc-mod check on them, they are interpreted in the context of the current project, therefore the recursive dependency will be an issue.
The only purpose of these two otherwise meaningless files is to debug your yesod website in ghci, as the comment in DevelMain.hs stated:
-- | Running your app inside GHCi.
--
-- To start up GHCi for usage with Yesod, first make sure you are in dev mode:
--
-- > cabal configure -fdev
--
-- Note that #yesod devel# automatically sets the dev flag.
-- Now launch the repl:
--
-- > cabal repl --ghc-options="-O0 -fobject-code"
--
-- To start your app, run:
--
-- > :l DevelMain
-- > DevelMain.update
--
-- You can also call #DevelMain.shutdown# to stop the app
--
-- You will need to add the foreign-store package to your .cabal file.
-- It is very light-weight.
--
-- If you don't use cabal repl, you will need
-- to run the following in GHCi or to add it to
-- your .ghci file.
--
-- :set -DDEVELOPMENT
--
-- There is more information about this approach,
-- on the wiki: https://github.com/yesodweb/yesod/wiki/ghci
cabal repl and stack ghci will compile the project beforehand so these two files won't cause any error there.

Stack interpreter option - Add an external dependency

I'm making a script with Turtle and I need a dependency from GitHub. I saw that you can add such a dependency when you make a project by putting this in your stack.yaml:
packages:
- location:
git: https://github.com/githubuser/reponame.git
commit: somecommitID
But is it possible to add it via the command line?
This is the command line used to run the script:
stack --resolver lts-3.2 --install-ghc runghc --package turtle
Edit:
These are the first lines of my script:
#!/usr/bin/env stack
-- stack --resolver lts-3.1 --install-ghc runghc --package turtle
import Turtle
...
We do not support all of stack.yaml options on the commandline. I recommend putting a stack.yaml somewhere. If you don't want to just put it in the same folder as the script, use "--stack-yaml"

Resources