Haskell Stack Ghci test-suite - haskell

I'm trying to use stack to load my test-suite in ghci and have it load the QuickCheck and hspec dependency.
How can I do this?
I'm using the franklinchen template.
https://github.com/commercialhaskell/stack-templates/blob/master/franklinchen.hsfiles
I have tried
stack ghci spec
stack ghci test-suite
stack ghci --main-is spec
I modified the test-suite spec to target the main-is: LibSpec.hs file
test-suite spec
default-language: Haskell2010
ghc-options: -Wall
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: LibSpec.hs
build-depends: base
, chapterexercises
, hspec
, QuickCheck

stack ghci --test
Note that this will only work if there's a single test suite and no other executable. Otherwise it will give you a warning:
* * * * * * * *
The main module to load is ambiguous. Candidates are:
Package `project' component exe:project-exe with main-is file: T:\project\app\Main.hs
Package `project' component test:project-test with main-is file: T:\project\test\Spec.hs
None will be loaded. You can specify which one to pick by:
1) Specifying targets to stack ghci e.g. stack ghci project:exe:project-exe
2) Specifying what the main is e.g. stack ghci --main-is project:exe:project-exe
* * * * * * * *
In this case you have to use
stack ghci --test chapterexercises:test:spec
Without --test stack is going to ignore the tests. That's why you don't get the ambiguity error in the first place.

Related

Multiple files use the same module name:

when I type stack run I get no error message but when I type stack ghci I get this error about multiple files use the same name , how I can solve it ?
(base) wejden#wejdenaydi:~/wejden$ stack ghci
Using main module: 1. Package `wejden' component wejden:exe:wejden-exe with main-is file: /home/wejden/wejden/app/Main.hs
Building all executables for `wejden' once. After a successful build of all of them, only specified executables will be rebuilt.
wejden> configure (lib + exe)
Configuring wejden-0.1.0.0...
wejden> initial-build-steps (lib + exe)
The following GHC options are incompatible with GHCi and have not been passed to it: -threaded
Configuring GHCi with the following packages: wejden
* * * * * * * *
Warning: Multiple files use the same module name:
* Paths_wejden found at the following paths
* /home/wejden/wejden/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build/autogen/Paths_wejden.hs (wejden:lib)
* /home/wejden/wejden/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build/wejden-exe/autogen/Paths_wejden.hs (wejden:exe:wejden-exe)
* * * * * * * *
GHCi, version 8.10.4: https://www.haskell.org/ghc/ :? for help
[1 of 3] Compiling Lib ( /home/wejden/wejden/src/Lib.hs, interpreted )
[2 of 3] Compiling Main ( /home/wejden/wejden/app/Main.hs, interpreted )
[3 of 3] Compiling Paths_wejden ( /home/wejden/wejden/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build/autogen/Paths_wejden.hs, interpreted )
Ok, three modules loaded.
Loaded GHCi configuration from /tmp/haskell-stack-ghci/f99925e2/ghci-script
*Main Lib Paths_wejden>
For those who, like me, need very specific instructions, here it goes:
executables:
mypkgname-exe:
main: Main.hs
source-dirs: app
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- stocks
when:
- condition: false
other-modules: Paths_mypkgname
where mypkgname needs to be replaced with your package name. I'm posting this because on my first attempt I had put the when clause in the wrong place.
This is a known issue with hpack: https://github.com/commercialhaskell/stack/issues/5439
In short, add this in your package.yaml, to your executable(s) or your library:
when:
- condition: false
other-modules: Paths_wejden # your package name here

Adding dependencies to stack project

I am very new to Haskell and I am trying to add the graphics package gloss to my stack project but I am encountering problems when doing stack build.
I have created my stack project as follows:
LICENSE package.yaml stack.yaml
README.md package.yaml~ stack.yaml.lock
Setup.hs project39.cabal stack.yaml~
TAGS project39.cabal~ test
and edited the stack.yamland the cabal file as follows:
# extra-deps:
# - acme-missiles-0.3
# - git: https://github.com/commercialhaskell/stack.git
# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
# - gloss-1.13.2.1
executable project39-exe
main-is: Main.hs
other-modules:
Paths_project39
hs-source-dirs:
app
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends:
base >=4.7 && <5
, project39
, gloss
default-language: Haskell2010
In the src file Lib.hs I have added a Import Graphics.Gloss to test if it works:
module Lib
( someFunc
) where
import Graphics.Gloss
but when I then do stack build I get the following error:
Could not load module ‘Graphics.Gloss’
It is a member of the hidden package ‘gloss-1.13.2.1’.
Perhaps you need to add ‘gloss’ to the build-depends in your .cabal file.
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
4 | import Graphics.Gloss
| ^^^^^^^^^^^^^^^^^^^^^
I am unsure what the problem here is and how to solve it.
You have a separate library stanza in your package.yaml. You need to add the gloss dependency there.

Compile only one target from a stack project with multiple targets in the cabal file

I have a similar setup like this SO question.
However I'm working with stack and not directoly with cabal:
stack.yaml
Test.cabal
src/FirstExe
src/SecondExe
The stack file is minimal
resolver: lts-8.17
packages:
- '.'
The file Test.cabal has 2 executables:
name: Test
version: 0.1.0.0
build-type: Simple
cabal-version: >=1.8
executable FirstExe
hs-source-dirs: src
main-is: FirstExe.hs
build-depends: base >=4.8 && <4.10
executable SecondExe
hs-source-dirs: src
main-is: SecondExe.hs
build-depends: base >=4.8 && <4.10
The src/FirstExe.hs compiles successfully:
main :: IO ()
main = putStrLn "FirstExe compiles nicely"
The src/SecondExe.hs has an error:
main :: IO ()
main = "SecondExe gives compiler error" -- putStrLn is missing ...
(Note: The goal of this error is to see, when stack builds the SecondExe.)
When I do a stack ide targets I get
Test:exe:FirstExe
Test:exe:SecondExe
Now I want to compile only the first target FirstExe without compiling the second and without changing
the Test.cabal file. In reallity I will switch between the 2 executables.
According to the Haskell Tool Stack documentation it should
be possible
I tried two possibilies:
stack build :FirstExe
stack build Test:exe:FirstExe
In both cases it compiles the second executable too!
Test-0.1.0.0: configure (exe)
Configuring Test-0.1.0.0...
Test-0.1.0.0: build (exe)
Preprocessing executable 'FirstExe' for Test-0.1.0.0...
Preprocessing executable 'SecondExe' for Test-0.1.0.0...
[1 of 1] Compiling Main ( src/SecondExe.hs, .stack-work/dist/x86_64-linux-nopie/Cabal-1.24.2.0/build/SecondExe/SecondExe-tmp/Main.o )
/home/roland/Projekte/HaskellTutorials/Test/src/SecondExe.hs:2:8: error:
* Couldn't match expected type `IO ()' with actual type `[Char]'
* In the expression: "SecondExe gives compiler error"
In an equation for `main': main = "SecondExe gives compiler error"
-- While building package Test-0.1.0.0 using:
/home/roland/.stack/setup-exe-cache/x86_64-linux-nopie/Cabal-simple_mPHDZzAJ_1.24.2.0_ghc-8.0.2 --builddir=.stack-work/dist/x86_64-linux-nopie/Cabal-1.24.2.0 build exe:FirstExe exe:SecondExe --ghc-options " -ddump-hi -ddump-to-file"
Process exited with code: ExitFailure 1
What am I doing wrong?

Haskell Stack build specific executable

How to build an specific stack executable file, ie. those specified in projectname.cabal, like:
executable executable-name
hs-source-dirs: tools
main-is: ExecutableModule.hs
ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, hsass
, hlibsass
I would need to compile executable-name and no other. It would be something like:
stack build --executable executable-name
Stack uses a component based lookup, e.g.
stack build packagename:component-type:component-name
So if your package is called "foo", and your executable is called "bar", you can use
stack build foo:exe:bar
However, if the component-name is unique, you can drop the package's name and the component type. So if your executable is called "exectuable-name", it's
stack build :executable-name

Haskell stack not building test executable

Background
I'm building a logfile parser in Haskell. I'm using stack to build it. Running the stack build command works happily and my project compiles. Running stack test, however, produces the following error:
parser-test: executable not found
I see the the following warning above the error message but I don't know how to avoid the redirect to which it refers.
Warning: output was redirected with -o, but no output will be generated because there is no Main module.
Relevant files
I haven't written any tests yet so the test file is as it was created by stack new. My cabal file looks like this:
...
category: Executable
build-type: Simple
-- extra-source-files:
cabal-version: >=1.10
library
hs-source-dirs: src
exposed-modules: LogParser
build-depends: base >= 4.7 && < 5
, attoparsec
, bytestring
, old-locale
, time
default-language: Haskell2010
executable parser-exe
hs-source-dirs: app
main-is: Main.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, attoparsec
, bytestring
, old-locale
, time
, parser
default-language: Haskell2010
test-suite parser-test
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: Spec.hs
build-depends: base
, attoparsec
, bytestring
, hspec
, hspec-attoparsec
, old-locale
, time
, parser
ghc-options: -threaded -rtsopts -with-rtsopts=-N
default-language: Haskell2010
source-repository head
type: git
...
I presume I'm missing something but I can't find where what I'm missing is documented.
Desired behaviour
I should see the Test suite not yet implemented message outlined in the stack documentation.
The content of the test/Spec.hs file from the template is:
main :: IO ()
main = putStrLn "Test suite not yet implemented"
You can see this content at commercialhaskell/stack-templates in new-template.hsfiles.
I'm not sure where the module ParserSpec where line comes from (as brought up in the Github issue), but it's not part of the template. On my system, stack new bar && cd bar && stack test succeeds.
As to the reason behind the Main module requirement: it comes from the Cabal library, and as I understand it was added due to limitations in other compilers Cabal supports. In other words, GHC could technically allow this code to compile, but Cabal does not pass in those arguments to remain compatible with other compilers.

Resources