Haskell stack not building test executable - haskell

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.

Related

How do I import a text file in a cabal project?

In app/Main.hs, I want to open a text file, "foo.txt". I know how to open a text file in a plain Haskell program. In my cabal project,
import System.IO
Main = do
contents <- readFile "foo.txt"
print $ Main.lex contents
return contents
type Keyword = String
lex :: String -> [Keyword]
lex "" = []
lex x = words x
gives the error
openFile: does not exist (No such file or directory)
What do I need to change in my cabal file, or the file path or location to be able to open the file? I've tried putting it next to the output binary, and that doesn't work either.
This is my cabal file:
-- This file has been generated from package.yaml by hpack version 0.28.2.
--
-- see: https://github.com/sol/hpack
--
-- hash: baf2fc7e230f4b4937dfd918a13fefb55b66c7a4468b24d0e3e90cad675b26d5
name: CCompiler
version: 0.1.0.0
description: Please see the README on GitHub at <https://github.com/githubuser/CCompiler#readme>
homepage: https://github.com/githubuser/CCompiler#readme
bug-reports: https://github.com/githubuser/CCompiler/issues
author: Author name here
maintainer: example#example.com
copyright: 2018 Author name here
license: BSD3
license-file: LICENSE
build-type: Simple
cabal-version: >= 1.10
extra-source-files:
ChangeLog.md
README.md
source-repository head
type: git
location: https://github.com/githubuser/CCompiler
library
exposed-modules:
Lib
other-modules:
Paths_CCompiler
hs-source-dirs:
src
build-depends:
base >=4.7 && <5
default-language: Haskell2010
executable CCompiler-exe
main-is: Main.hs
other-modules:
Paths_CCompiler
hs-source-dirs:
app
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends:
CCompiler
, base >=4.7 && <5
default-language: Haskell2010
test-suite CCompiler-test
type: exitcode-stdio-1.0
main-is: Spec.hs
other-modules:
Paths_CCompiler
hs-source-dirs:
test
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends:
CCompiler
, base >=4.7 && <5
default-language: Haskell2010
add
data-dir: data
in the top section of the cabal file.
create the directory 'data' next to src and app, and put all files in there.
Make sure your cabal file also has this line
other-modules:
Paths_CCompiler
with your project's name instead of CCompiler.
My main function is now this
module Main where
import Lib
import System.IO
import Paths_CCompiler
main = do
filepath <- getDataFileName "return_2.c"
contents <- readFile filepath
print $ Lib.lex contents
return contents
Thanks to this blog post.
I understand your question to be about finding files at runtime, which you want to process and aren't packaged with your package.
Where are severals ways, how you could find files at runtime, which aren't packaged.
Either add an command line flag and call your executable with the absolute path of the file you want to process.
Or implement a file chooser dialog, with e.g. gi-gtk.
Or hard coding relative paths which isn't advisable, as they are interpreted relative to the current working directory of your process, which can be different, depending on how the program did get started.
If you want to determine, which current working directory your program runs in, if started with cabal run, just do a litte test project with the following cabal file:
name: test2
build-type: Simple
cabal-version: >= 1.10
version: 0.0.0.1
executable test2
hs-source-dirs: .
main-is: test2.hs
build-depends:
base
, directory
and the following test2.hs:
module Main where
import System.Directory
main :: IO ()
main = do
cwd <- getCurrentDirectory
putStrLn cwd

stack build results in "output was redirected with -o, but no output will be generated because there is no Main module."

Didn't see any relevant result when google searching for this error so thought I'd post it.
stack build
Building all executables for `gitchapter' once. After a successful build of all of them, only specified executables will be rebuilt.
gitchapter-0.1.0.0: build (exe)
Preprocessing executable 'app' for gitchapter-0.1.0.0..
Building executable 'app' for gitchapter-0.1.0.0..
Preprocessing executable 'test' for gitchapter-0.1.0.0..
Warning: Enabling workaround for Main module 'Main' listed in 'other-modules'
Building executable 'test' for gitchapter-0.1.0.0..
illegaly!
<no location info>: error:
output was redirected with -o, but no output will be generated
because there is no Main module.
-- While building custom Setup.hs for package gitchapter-0.1.0.0 using:
/home/chris/.stack/setup-exe-cache/x86_64-linux-nopie/Cabal-simple_mPHDZzAJ_2.0.1.0_ghc-8.2.2 --builddir=.stack-work/dist/x86_64-linux-nopie/Cabal-2.0.1.0 build exe:app exe:test --ghc-options " -ddump-hi -ddump-to-file -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
It definitely is related to the 'test' executable definition - as if I remove this, it completes the stack build successfully - but without the required test executable.
gitchapter.cabal
-- This file has been generated from package.yaml by hpack version 0.28.2.
--
-- see: https://github.com/sol/hpack
--
-- hash: a3e4a735ee8304dd50f5af53a64d7b639894cbcc24ba01d0171a588e67455018
name: gitchapter
version: 0.1.0.0
author: Chris Stryczynski
maintainer: Chris Stryczynski
license: BSD3
license-file: LICENSE
build-type: Simple
cabal-version: >= 1.10
executable app
main-is: Main.hs
other-modules:
BlogLiterately
Example
FileSection
GHCi
GHCiSession
Git
GitTextPartial
Hart
Operations
Operations.Parsers
QuasiText
Render
Section
Test
Paths_gitchapter
hs-source-dirs:
src
build-depends:
HUnit
, QuickCheck
, base >=4.9 && <4.11
, directory
, extra
, filepath
, foldl
, mtl
, optparse-applicative
, pandoc-include-code
, parsec
, pretty-simple
, process
, regex-pcre
, regex-posix
, safe
, string-conversions
, system-filepath
, template-haskell
, text
, transformers
, turtle
, unix
, unordered-containers
default-language: Haskell2010
executable test
main-is: Test.hs
other-modules:
BlogLiterately
Example
FileSection
GHCi
GHCiSession
Git
GitTextPartial
Hart
Main
Operations
Operations.Parsers
QuasiText
Render
Section
Paths_gitchapter
hs-source-dirs:
src
build-depends:
HUnit
, QuickCheck
, base >=4.9 && <4.11
, directory
, extra
, filepath
, foldl
, mtl
, optparse-applicative
, pandoc-include-code
, parsec
, pretty-simple
, process
, regex-pcre
, regex-posix
, safe
, string-conversions
, system-filepath
, template-haskell
, text
, transformers
, turtle
, unix
, unordered-containers
default-language: Haskell2010
You need to set
executable test
ghc-options: -main-is Test
in your cabal file.

How to make Stack only build one executable? stack build :exe1 doesn't work?

I have multiple executables in one of my Stack projects:
executable m1
hs-source-dirs: src
main-is: Main1.hs
default-language: Haskell2010
build-depends: base >= 4.7 && < 5
executable m2
hs-source-dirs: src
main-is: Main2.hs
default-language: Haskell2010
build-depends: base >= 4.7 && < 5
I would like to build only one of them at a time. From the documentation and this other question, it would seem that the following command should work:
stack build :m2
but what actually happens is that both executables, m1 and m2, are always built regardless of whether I include the package name, the package type, etc.
What could be causing this?
It's not possible at the moment. See https://github.com/commercialhaskell/stack/issues/1406

Issues running tests with cabal and HUnit in haskell ('builds-depends' failed.)

I trying to run my first haskell program using cabal and HUnit. I seem to have trouble with my .cabal as I get the error:
λ cabal test
.\haskell.cabal has been changed. Re-configuring with most recently used
options. If this fails, please run configure manually.
cabal: haskell.cabal:21: Parse of field 'build-depends' failed.
Here is the .cabal file
name: haskell
version: 0.1.0.0
synopsis: fibonacci functions
category: Testing
build-type: Simple
cabal-version: >=1.10
executable haskell
main-is: Main.hs
build-depends: base >=4.8 && <4.9
hs-source-dirs: src
default-language: Haskell2010
test-suite Tests
build-depends: Test.HUnit
hs-source-dirs: test
main-is: tests.hs
Type: exitcode-stdio-1.0
test file:
import Test.HUnit
test1 = TestCase (assert True)
This is the problem:
build-depends: Test.HUnit
Perhaps you wanted build-depends: hunit ?

Shared cabal "build-depends" (Haskell) [duplicate]

Here's a .cabal file:
Name: myprogram
Version: 0.1
-- blah blah blah
Cabal-version: >=1.9.2
Executable myprogram
HS-source-dirs: src
Main-is: Main.hs
Build-depends: attoparsec == 0.10.*,
base == 4.3.*,
-- long long list of packages
Test-Suite test
HS-source-dirs: test, src
Type: exitcode-stdio-1.0
Main-is: Main.hs
Build-depends: attoparsec == 0.10.*,
base == 4.3.*,
-- long long list of packages
QuickCheck == 2.4.*
Is there any way I can replace the long list of build-depends packages for the test suite with "same as for the executable, plus QuickCheck"?
Edit: version information.
cabal-dev 0.9
cabal-install 0.10.2
Cabal library 1.10.2.0
GHC 7.0.4
Haskell Platform 2011.4.0.0
NOTE: superseded by phadej's answer suggesting common stanzas.
Is there any way I can replace the long list of build-depends packages for the test suite with "same as for the executable, plus QuickCheck"?
Not that I know of. However, there is a way to only mention the list of build-depends packages once, by structuring your project into three targets:
a library that contains all your code, and needs the long build-depends list.
an executable that consists of only one file, and depends on base and the library from above.
a test-suite that depends on the library from above, and the testing packages you are using.
Maybe this approach is what indygemma's answer proposes, but the Cabal file proposed there will not quite achieve it, as Norman Ramsey points out in a comment. Here's the main points of what you need in a Cabal file. For a full example that works for me, you can look at this Cabal file.
name: my-program
version: ...
library
hs-source-dirs: src-lib
build-depends: base, containers, ...
exposed-modules: My.Program.Main, ...
executable my-program
hs-source-dirs: src-exec
main-is: my-program.hs
Build-depends: base, my-program
test-suite tests
type: exitcode-stdio-1.0
hs-source-dirs: src-test
main-is: tests.hs
other-modules: ...
build-depends: base, my-program, test-framework, ...
Important points:
There are three separate source directories for the three targets. This is necessary to stop GHC from recompiling library files when building the other targets.
All of the application code is in the library. The executable is just a wrapper, like this:
import My.Program.Main (realMain)
main = realMain
The library exposes all modules that are necessary for testing.
The last point highlights the drawback of this approach: You end up having to expose internal modules. The main benefit of this approach is that you have less duplication in the Cabal file, and maybe more importantly, less duplication in the build process: The library code will be built only once, and then linked into both the executable and the test-suite.
Since version 2.2 Cabal supports common stanzas, to dedup build info fields:
https://cabal.readthedocs.io/en/latest/developing-packages.html#common-stanzas
cabal-version: 2.2
name: myprogram
version: 0.1
-- blah blah blah
common deps
build-depends: base ^>= 4.11,
-- long long list of packages
ghc-options: -Wall
library
import: deps
exposed-modules: Foo
test-suite tests
import: deps
type: exitcode-stdio-1.0
main-is: Tests.hs
build-depends: foo
You could also consider using hpack instead of writing the .cabal file by hand:
In hpack's package.yaml format, you can specify a common dependencies field whose entries are added to every components' build-depends field when generating the .cabal file.
For example, see hpack's own package.yaml and the generated hpack.cabal.
To start using hpack with an existing package, you can use hpack-convert which will generate the package.yaml from an existing .cabal file.
To create a new package that uses hpack, you can use stack's simple-hpack template like so: stack new mypkg simple-hpack.
If you use stack for development, you don't have to call hpack manually to regenerate the .cabal file from an updated package.yaml – stack will do that automatically.
No easy way:
you can use m4 and specify your dependencies once, but then you will need to reprocess your Cabal file through m4 whenever you change it.
you can move the code you are testing out to a library, and then specify the library in your Build-depends for the test. That requires you to install a library even just to run the test.
You can just not put the test in the cabal file at all. Build it with ghc --make, which will pull in dependencies. But then you lose cabal integration.
There is an optional library section for .cabal files, which solves your problem.
name: myprogram
version: 0.1
-- blah blah blah
cabal-version: >=1.9.2
library
build-depends: attoparsec == 0.10.*
, base == 4.3.*
-- long long list of packages
executable myprogram
hs-source-dirs: src
main-is: Main.hs
test-suite test
hs-source-dirs: test, src
type: exitcode-stdio-1.0
main-is: Main.hs
build-depends: QuickCheck == 2.4.*

Resources