hdevtools icon indicating copy to clipboard operation
hdevtools copied to clipboard

Stack compatibility

Open parsonsmatt opened this issue 9 years ago • 13 comments

I'm really excited about stack because it makes building Haskell projects super easy. Right now the only thing blocking me from using it for everything is that the current crop of vim plugins all rely on either ghc-mod (which doesn't appear to be compatible with stack at all) or hdevtools.

Generally, the way to execute a command in the stack context is stack exec. Trying to do stack exec hdevtools check src/Main.hs in a project of mine gives the following error:

Cabal error: Use of GHC's environment variable GHC_PACKAGE_PATH is incompatible with Cabal. Use the flag --package-db to specify a package database (it can be used multiple times).

Stack can output the path to the current package database with stack path. I'd like to try testing to see if we can pass that into hdevtools and it would be able to run in a stack environment, but I'm not sure where in the code it's calling out to cabal or GHC. If anyone could give me some pointers there, that'd help out a lot with integrating with the new tool :smile:

parsonsmatt avatar Jun 25 '15 03:06 parsonsmatt

Interesting - I'd have to do a fair amount of digging to see where that error is coming from.

schell avatar Jun 25 '15 16:06 schell

In my experimentation with ghc-mod and stack, I got a similar error:

$ stack exec ghc-mod check src/Main.hs

cabal: Use of GHC's environment variable GHC_PACKAGE_PATH is incompatible with
Cabal. Use the flag --package-db to specify a package database (it can be used
multiple times).
ghc-mod: readCreateProcess: cabal "configure" "--with-ghc=ghc" "--package-db=clear" "--package-db=global" "--package-db=user" (exit 1): failed

readCreateProcess is not in ghc-mod repository according to ag, or hoogle, so I'm not sure how helpful that is

parsonsmatt avatar Jun 25 '15 16:06 parsonsmatt

I have a feeling it's in System.Process and that ghc-mod is issuing a cabal shell command.

schell avatar Jun 25 '15 16:06 schell

Yup! You're right there.

The hdevtools code for executing the GHC stuff is here:

runCommand :: IORef State -> ClientSend -> Command -> GHC.Ghc ()
runCommand _ clientSend (CmdCheck file) = do
    let noPhase = Nothing
    target <- GHC.guessTarget file noPhase
    GHC.setTargets [target]
    let handler err = GHC.printException err >> return GHC.Failed
    flag <- GHC.handleSourceError handler (GHC.load GHC.LoadAllTargets)
    liftIO $ case flag of
        GHC.Succeeded -> clientSend (ClientExit ExitSuccess)
        GHC.Failed -> clientSend (ClientExit (ExitFailure 1))

(plus other cases)

Looking at the GHC module docs, there's a DynFlags config object, which has a field:

 extraPkgConfs :: [PkgConfRef] -> [PkgConfRef]
-- |The -package-db flags given on the command line, in the order they appeared.

where PkgConfRef can be constructed as PkgConfFile FilePath.

Looking at DynFlags, it seems like it should be possible to do:

dynFlags { extraPkgConfs = (:) (PkgConfFile pathToPkgDb) }

In fact, I bet that could be done just by making the modification here!

let updatedDynFlags = initialDynFlags
        { GHC.log_action = logAction state clientSend
        , GHC.ghcLink = GHC.NoLink
        , GHC.hscTarget = GHC.HscInterpreted
        }
let updatedDynFlags' = if hasDbPath ghcOpts then updateDynFlags { extraPkgConfgs = -- etc...

I'll give this a shot tonight to see if it works.

parsonsmatt avatar Jun 25 '15 18:06 parsonsmatt

Yes please! And thanks :)

schell avatar Jun 25 '15 19:06 schell

Great news! It works :D

https://github.com/parsonsmatt/hdevtools/commit/0a25c74082d4c8841ac3d89d7d8f5a75f0673796

So I built hdevtools with stack, hard coded the output of stack path --local-pkg-db into the file, and rebuilt it with stack. Once it was built, I installed it onto my path, and it doesn't have any issues working in the directory. Naturally it only works in that directory, but... well, it works.

So I can think of two ways to get stack and hdevtools playing a bit nicer together:

  1. Expose a --package-db command line argument that would take precedence. Then hdevtools could use the stack db with:

    hdevtools --package-db "`stack path --local-pkg-db`" check src/Main.hs
    

    which isn't clean, but it would work, be pretty easy to implement.

  2. Check for the presence of a stack.yaml file, and if so, get the local package database information from stack somehow. This would work similarly to the way hdevtools looks for the cabal sandbox file and gets the db info from there.

I've asked the stack mailing list what the easiest way for hdevtools to get the info.

How would you like to proceed with implementing the feature?

parsonsmatt avatar Jun 26 '15 01:06 parsonsmatt

+1

greglearns avatar Jun 30 '15 21:06 greglearns

@parsonsmatt - can you submit a pull request to https://github.com/schell/hdevtools? If not I'll do it by hand :)

schell avatar Jun 30 '15 21:06 schell

@ranjitjhala is actually a bit further along with the changes: https://github.com/ranjitjhala/hdevtools/tree/stack

I exposed a -g --package-db= flag in my branch. With the right combination of package-dbs being passed in, that's probably sufficient to get stack and hdevtools playing nicely for right now. I can take another look and submit a PR if I can verify that it works, for exposing that feature.

There have been a few other packages modified to be compatible with Stack. The most useful one as a comparison for implementing it in other packages is probably the commit to get yesod-devel working with stack. I'd also like to work on getting that integrated but likely won't have time until Thursday.

parsonsmatt avatar Jun 30 '15 22:06 parsonsmatt

Any updates?

seanhess avatar Aug 02 '15 16:08 seanhess

Hi all, sorry was a bit checked out -- I believe this is done and merged into the @schell repo? and in hdevtools 1.1.1.9?

ranjitjhala avatar Aug 03 '15 01:08 ranjitjhala

Yes, over merged your changes into my fork and pushed to hackage. Try it out and tell me if it works for you.

schell avatar Aug 03 '15 18:08 schell

Any progress on this? I'm getting this error on hdevtools version 0.1.2.2 (the latest on hackage).

chris-martin avatar Feb 14 '16 23:02 chris-martin