haskell / haskell-language-server

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

support for cabal/stack scripts #111

Open georgefst opened 4 years ago

georgefst commented 4 years ago

Certain upcoming features (repl, runghc) are likely to make cabal scripts a much more attractive option.

I, for one, would like to switch all of my turtle scripts to use them, rather than (as at present) having them all in a single cabal project. But I wouldn't want to lose the IDE support...

Would there be any major difficulty in supporting these? Is this actually more of a question for hie-bios?

fendor commented 4 years ago

Supporting cabal script is a matter of implementing the issue: https://github.com/haskell/cabal/issues/6149

That is why stack scripts are already supported via hie-bios.

I started to implement it, but there are a few roadbumps that makes it not as easy as hoped.

jneira commented 3 years ago

As commented in https://github.com/haskell/ghcide/issues/162 and here, there is a workaround to make stack scripts work:

Stack scripts work in a "hacky" way. You have to add an explicit hie.yaml file with the contents:

cradle:
  stack:
    component: "File.hs" # your local stack script

Works fine for loading and modifying the stack script. However, if you modify the script section, these changes wont be detected, e.g. you have to restart ghcide/hls.

The reason this works is that you can do stack repl File.hs and the session is loaded correctly.

by @fendor

jneira commented 3 years ago

Related issue in hi-bios: https://github.com/mpickering/hie-bios/issues/217

fendor commented 3 years ago

Afaik, stack repl File.hs ceased to work for stack scripts, therefore it does not work anymore with HLS :( I dont remember in which stack version it used to work (before 1.9.3?) and I cant find any related stack issues for it

georgefst commented 3 years ago

FWIW, I have been making a lot of use of Cabal scripts, using cabal install --package-env . --lib [...]. It's not ideal, but I can live with it for now. Doesn't even require a cradle (EDIT: an explicit hie.yaml - you know what I mean). I don't think this worked when I opened the issue, but I can't remember why.

If it weren't for haskell/cabal#6999 things would actually be rather nice.

jneira commented 3 years ago

@Ailrun this one would be related with #692? (so it would be included for gsoc as well in the same pack)

Ailrun commented 3 years ago

Would it be better to create a new combined issue for GSOC?

jneira commented 3 years ago

Mmm not sure being only 2, it is clear in each one that are related

jneira commented 3 years ago

I ve just see the stack issue linked by @Martinsos, afaik it would enable again the workaround

rihardsk commented 2 years ago

https://github.com/haskell/cabal/issues/6149 has just landed (there hasn't been a release yet, though). Does that mean support for Cabal scripts could be added now?

fendor commented 2 years ago

@rihardsk we have to look into it, but depending on the actual implementation, it could work now out of the box, assuming you have a hie.yaml with the contents:

cradle:
  cabal:

right next to it.

You can help checking it out, by installing cabal HEAD and adding the aforementioned hie.yaml. If it works, hooray, otherwise feel free to provide log messages :)

rihardsk commented 2 years ago

@fendor it doesn't seem to work out of the box. I built cabal HEAD and prepended it to $PATH. I also created the hie.yaml as you suggested. When i open the cabal script with

#! /usr/bin/env cabal        
{- cabal:                    
build-depends:               
    base ^>= 4.14            
  , random-fu ^>= 0.2.7.7    
  , mwc-random ^>= 0.15.0.2  
  , split ^>= 0.2.3.4        
  , pipes ^>= 4.3.16         
-}                           

-- ...

in the header, hls fails to start and i get the following output in the *lsp-haskell::stderr* buffer in emacs:

Found "/home/rihards/darbs/exp/adaptive-marian/code/hie.yaml" for "/home/rihards/darbs/exp/adaptive-marian/code/a"                                                                                                                             
Run entered for haskell-language-server-wrapper(haskell-language-server-wrapper) Version 1.5.1.0, Git revision 745ef26f406dbdd5e4a538585f8519af9f1ccb09 (dirty) x86_64 ghc-8.10.7                                                              
Current directory: /home/rihards/darbs/exp/adaptive-marian/code                                                                                                                                                                                
Operating system: linux                                                                                                                                                                                                                        
Arguments: ["--lsp","-d","-l","/tmp/hls.log"]                                                                                                                                                                                                  
Cradle directory: /home/rihards/darbs/exp/adaptive-marian/code                                                                                                                                                                                 
Cradle type: Cabal                                                                                                                                                                                                                             

Tool versions found on the $PATH                                                                                                                                                                                                               
cabal:    3.7                                                                                                                                                                                                                                  
stack:    2.7.3                                                                                                                                                                                                                                
ghc:    8.10.7                                                                                                                                                                                                                                 

Consulting the cradle to get project GHC version...                                                                                                                                                                                            
Failed to get project GHC version:CradleError {cradleErrorDependencies = [], cradleErrorExitCode = ExitFailure 1, cradleErrorStderr = ["Error when calling cabal --builddir=/home/rihards/.cache/hie-bios/dist-code-b81b1ed796ad78aa090f9ea451b44b34 v2-exec --with-compiler /home/rihards/.cache/hie-bios/wrapper-13a09b18ea883dd377d59db5e821a86b ghc -v0 -- --numeric-version","","No cabal.project file or cabal file matching the default glob './*.cabal' was found.\nPlease create a package description file <pkgname>.cabal or a cabal.project file referencing the packages you want to build.\n\n"]}                                                                                                                            

Process lsp-haskell stderr finished                                                                                                                                                                                                            

/tmp/hls.log doesn't get any new entries as a result of the above, btw.

I checked that the new cabal repl add-tags.hs command does indeed work and brings up a ghci session with my stuff.

fendor commented 2 years ago

Thank you for the report!

Sounds like cabal v2-exec ghc -v0 -- --numeric-version basically fails to run. We need to revive https://github.com/haskell/cabal/pull/7500 and push it over the finish line >_>

dschrempf commented 1 year ago

@rihardsk we have to look into it, but depending on the actual implementation, it could work now out of the box, assuming you have a hie.yaml with the contents:

cradle:
  cabal:

right next to it.

You can help checking it out, by installing cabal HEAD and adding the aforementioned hie.yaml. If it works, hooray, otherwise feel free to provide log messages :)

Thank you!

This actually worked for me wit hls-1.8 and ghc924. It would be great though, if the somewhat useless hie.yaml file could be omitted!

fendor commented 1 year ago

@dschrempf At the current time, the hie.yaml is the way to tell HLS how the project shall be loaded. If there is no cabal.project, no *.cabal file, no stack.yaml, how is it supposed to guess you want to use cabal on it?

EDIT: Also, I amazed to hear it works, awesome!

dschrempf commented 1 year ago

I understand that hls needs this information. But the file could be a fallback or so?

fendor commented 1 year ago

A fallback for what case? It is optional, but for cabal scripts, HLS currently has no way of determining that the given file is a cabal script (we could parse the bang line I suppose) to guess correctly what to use to load the script.

dschrempf commented 1 year ago

Well, I do not know how HLS determines the file type, libraries etc. But from an outsider's point of view it seems pretty stupid that I have to provide a file that has essentially no information in it to make things work :smile:. The only point in having the hie.yaml file I could see is that the file deviates the attention of HLS from another project up on the directory structure to the current directory. Is that so?

fendor commented 1 year ago

has essentially no information in it to make things work

It does have information, namely that it is a file that can be loaded via cabal. You could also have a stack project, a stack script, or a plain Haskell script as well. It is not trivial to know and hie.yaml disambiguates for that case.

Is that so?

No, hie.yaml basically tells HLS exactly how to build a project, the reason it is so small is that we can infer the rest from the context once we know we should use cabal. In fact, every time HLS opens a project, it generates a hie.yaml internally (a cradle, but hie.yaml is a cradle description) and uses it to load the project. Again, maybe we could improve the discovery mechanism, but there are many cases where an explicit hie.yaml is just necessary.

dschrempf commented 1 year ago

I see. In thin case I advocate for improving the discovery mechanism. Thanks for explaining things to me!

georgefst commented 1 year ago

This actually worked for me wit hls-1.8 and ghc924

Not working for me unfortunately, with the same tools (Cabal 3.8.1.0, Linux).

It would be great though, if the somewhat useless hie.yaml file could be omitted!

I think "useless" is an exaggeration, as @fendor has said, but I agree that we should strive to make it unnecessary. I was also going to suggest parsing the bang line. There are potentially a lot of edge cases, but recognising #!/usr/bin/env cabal would be a start.

dschrempf commented 1 year ago

Not working for me unfortunately, with the same tools (Cabal 3.8.1.0, Linux).

It could be that this works for me because the script is within a project that provides the required libraries.

georgefst commented 1 year ago

Just to confirm, no one's actually got this to work properly by specifying a hie.yaml, right? It seems unlikely that it's possible, right now, since HLS runs cabal exec -v0 -- ghc --print-libdir, which complains about not finding a *.cabal or cabal.project file.

So does that mean we're still blocked on haskell/cabal#7500? Or is there, in principal, some easy way to extract the environment information from cabal repl?

fendor commented 1 year ago

The former can be fixed via the linked PR. I don't think there is currently a way to get the options from cabal repl. However, we could tweak hie-bios to have a cli interface to get the options if and only if you specify the ghc version you want to use for scripts. Such a cli interface, could also be used to implement proper support... PRs welcome, won't be able to get to it the next couple of weeks, but I think the POC might be much simpler now.

georgefst commented 11 months ago

I think the reason for the confusion above is that, in addition to the hie.yaml, a cabal.project file is currently required (whose contents don't seem to matter much). @fendor pointed this out in https://github.com/haskell/haskell-language-server/discussions/3572.

So loading scripts does now work, though the workarounds required are quite inconvenient if one has a lot of scripts.