haskell / haskell-language-server

Official haskell ide support via language server (LSP). Successor of ghcide & haskell-ide-engine.
Apache License 2.0
2.66k stars 355 forks source link

Loading Setup.hs into HLS #3735

Open fendor opened 1 year ago

fendor commented 1 year ago

Problem

Setup.hs is the build Script used by Cabal to actually build a cabal or stack package. It usually takes the trivial form of

import Distribution.Simple
main = defaultMain

where it can be omitted.

However, there exists a number of Custom Setup.hs files that are far more complex, see for example this Setup.hs from cabal-testsuite

Presently, it is impossible to load Setup.hs into HLS, neither the trivial Setup.hs nor the custom Setup.hs. Users are bombarded with intrusive and impossible to decipher error messages such as:

Multi Cradle: No prefixes matched
pwd: /home/hugin/Documents/haskell/hie-bios
filepath: /home/hugin/Documents/haskell/hie-bios/Setup.hs
prefixes:
("./src",Cabal {component = Just "lib:hie-bios"})
("./exe/Main.hs",Cabal {component = Just "hie-bios:exe:hie-bios"})
("./exe/Paths_hie_bios.hs",Cabal {component = Just "hie-bios:exe:hie-bios"})
("./tests/",Cabal {component = Just "hie-bios:test:parser-tests"})
("./tests/",Cabal {component = Just "hie-bios:test:bios-tests"})
cradle

and

Failed to run ["cabal","v2-repl","/home/hugin/Documents/haskell/cabal/cabal-testsuite/Setup.hs"] in directory "/home/hugin/Documents/haskell/cabal". Consult the logs for full command and error.
Failed command: cabal --builddir=/home/hugin/.cache/hie-bios/dist-cabal-6feed062e565a5220d2d16ac7598fdb5 v2-repl --with-compiler /home/hugin/.cache/hie-bios/wrapper-b54f81dea4c0e6d1626911c526bc4e36 --with-hc-pkg /home/hugin/.cache/hie-bios/ghc-pkg-582c31b3f45642fb349d02d1e6665c7b /home/hugin/Documents/haskell/cabal/cabal-testsuite/Setup.hs

Error: cabal: Failed extracting script block: `{- cabal:` start marker not
found

Solution

To properly load Setup.hs, build tools, such as cabal and stack, need to be able to tell us what compilation options we need to build Setup.hs files.

We could also ignore any Setup.hs files using some heuristics, so that users are not greeted with the horrible error messages shown above:

Workarounds

There exists one known workaround by exploiting the cabal repl Scriptfile.hs feature on recent cabal versions only. Requires a cabal.project file in the project.

Example:

#!/usr/bin/env cabal
{- cabal:
build-depends: base, Cabal
-}
import Distribution.Simple
main = defaultMain

in combination with the following hie.yaml

cradle:
  cabal:

Ignoring the Setup.hs can be achieved with a custom hie.yaml file at the root of the project, such as:

cradle:
  multi:
    - path: "./Setup.hs"
      config: 
        cradle:
          none:
    - path: "./"
      config: 
        cradle: 
          cabal:

This is a meta-issue and should subsume all Setup.hs related issues.

michaelpj commented 1 year ago

I guess this also very much relates to the error message issue. If the error message said "Can't load Setup.hs as there is no way to get the compilation options needed for a Setup.hs file, see ", then that would be much better. Not sure if that's reasonable.

xiyuzhai commented 3 months ago

I came across exactly the same issue. Problems like this really turn people away and leave a very bad impression.