DanielG / ghc-mod

Happy Haskell Hacking for editors. DEPRECATED
Other
677 stars 175 forks source link

Package resolution failure on test executables #635

Open expipiplus1 opened 8 years ago

expipiplus1 commented 8 years ago

Running ghc-mod on its own test code fails, as it doesn't see the correct packages:

Running ghc-mod info src/GHCMod.hs foo has the correct behaviour, but running ghc-mod info test/Main.hs foo fails because the packages aren't being made visible.

As far as I can tell, ghc-mod isn't compiling the files with the packages (and other attributes) they are listed with in the .cabal file, instead it's always using the packages from the primary executable or library.

~/src/ghc-mod
$ git checkout release
Switched to branch 'release'
Your branch is up-to-date with 'origin/release'.

~/src/ghc-mod
$ stack build
ghc-mod-5.4.0.0: build
...snip...
ghc-mod-5.4.0.0: install
Installing library in
C:\Users\jophish\src\ghc-mod\.stack-work\install\x86_64-windows\lts-3.1\7.10.2\lib\x86_64-windows-ghc-7.10.2\ghc-mod-5.4.0.0-EaYZIi1kTQb8WDt3QlxtDc
Installing executable(s) in
C:\Users\jophish\src\ghc-mod\.stack-work\install\x86_64-windows\lts-3.1\7.10.2\bin
Registering ghc-mod-5.4.0.0...
ghc: warning: _tzset from msvcrt is linked instead of __imp__tzset

~/src/ghc-mod
$ stack exec -- ghc-mod info src/GHCMod.hs main
ghc-mod.exe: warning: _tzset from msvcrt is linked instead of __imp__tzset
main :: IO ()   -- Defined at src\GHCMod.hs:395:1

~/src/ghc-mod
$ stack exec -- ghc-mod info test/Main.hs main
EXCEPTION: info:
               Could not find module ‘Spec’
               Use -v to see a list of the files searched for.
               Could not find module ‘Dir’
               Use -v to see a list of the files searched for.
               Could not find module ‘TestUtils’
               Perhaps you meant Test.Util
               Use -v to see a list of the files searched for.
               Could not find module ‘Test.Hspec’
               Use -v to see a list of the files searched for.
Cannot show info

~/src/ghc-mod
$ stack test
...snip...
Installing packages

~/src/ghc-mod
$ stack exec -- ghc-mod info test/Main.hs main
EXCEPTION: info:
               Could not find module ‘Spec’
               Use -v to see a list of the files searched for.
               Could not find module ‘Dir’
               Use -v to see a list of the files searched for.
               Could not find module ‘TestUtils’
               Perhaps you meant Test.Util
               Use -v to see a list of the files searched for.
               Could not find module ‘Test.Hspec’
               It is a member of the hidden package ‘hspec-2.1.10’.
               Perhaps you need to add ‘hspec’ to the build-depends in your .cabal file.
               Use -v to see a list of the files searched for.
Cannot show info
DanielG commented 8 years ago

Yeah we use an ugly workaround to get the tests to work: https://github.com/kazu-yamamoto/ghc-mod/blob/master/Language/Haskell/GhcMod/Cradle.hs#L46

This is because some of the tests assume a plain (i.e. non cabal) environment but since there is a .cabal file up the directory hierarchy for the tests ghc-mod thinks they are part of a cabal project.

expipiplus1 commented 8 years ago

I think it's little more than that. Sometimes tests require their own packages which are spelled out in the .cabal file and not just a plain setup.

For example in an empty project with a test executable which depends on my-package ghc-mod won't be able to process the test executable source because my-package wasn't specified in the .cabal file. In the example below ghc-mod will not be able to resolve import Test.Tasty in Tests.hs

name:                example
version:             0.1.0.0

build-type:          Simple

library
  exposed-modules: 
    Example
  build-depends:       
      base >=4.7 && < 5

test-suite test
  type:
    exitcode-stdio-1.0
  main-is:
    Tests.hs
  build-depends:
    base >= 4 && < 5,
    tasty >= 0.10 && < 0.12
expipiplus1 commented 8 years ago

Aha, this seems to happen only when one is using stack.

Without knowing any of the details, I'd take a guess at the cause being that stack is a little more careful about where it installs packages, and which of them are visible to whom.

hatashiro commented 8 years ago

Any update on this? I have a same issue when using with stack.

expipiplus1 commented 8 years ago

@noraesae, running cabal configure --enable-tests will get ghc-mod using the cabal files again. As far as I can tell there's no way to get this working using just stack.

DanielG commented 8 years ago

How does stack even handle tests? The problem is that in cabal there is a flag to turn them on as @expipiplus1 said but how does stack decide to enable tests in the generated configuration? My guess was always just doing stack test once and if it does it kinda like cabal it would have to then enable test suites implicitly but no-one ever confirmed that to work so my thinking now is maybe stack generates a second cabal configuration next to the non-test one and uses that for tests? After you run stack build and then stack test on a project with an empty .stack-work directory does the later add another directory in there or something?

Alternatively look at the .stack-work/dist/*/Cabal-*/setup-config file to see if the test suite is enabled. Using cabal-helper-wrapper . .stack-work/dist/*/Cabal-*/ print-lbi --human | head -n1 | ppsh you can get a nice pretty printed version of that, see also here: https://github.com/kazu-yamamoto/ghc-mod/issues/673#issuecomment-152777602 (I really need to add a shorthand command for that). The documentation for the datatype is here: http://hackage.haskell.org/package/Cabal-1.22.4.0/docs/Distribution-Simple-LocalBuildInfo.html#t:LocalBuildInfo

I think you'll want to look at componentsConfigs IIRC if the test suites aren't in there they aren't enabled.

DanielG commented 8 years ago

Okay so it looks like this comes down to ghc-mod configuring a stack project using cabal-install when it shouldn't and then sticking to cabal-install once dist/setup-config exists. I managed to get it to work by deleting dist/, doing stack test and then running ghc-mod. I can't reproduce the case where it generates dist/ even though we're in a stack project :/

DanielG commented 8 years ago

In Emacs you can enable verbose logging: (setq ghc-debug-options '("-v7")) if someone can reproduce this the contents of the *GHC Error* buffer would be super helpful.