Open simonmichael opened 8 years ago
This hack makes it work for me.
my-ghc-mod.hs:
#!/usr/bin/env stack
-- stack runghc --verbosity info --package directory --package filepath --package process
-- A temporary workaround for https://github.com/DanielG/ghc-mod/issues/787
-- (make ghc-mod work in multi-package stack projects).
-- Ensures check commands are run inside the first directory of the path argument.
-- Setup: compile (stack ghc my-ghc-mod.hs) and install this in your path,
-- configure it as haskell-ghc-mod's Ghc Mod Path, uncheck Enable Ghc Modi.
import Data.List
import Control.Monad
import System.Directory
import System.Environment
import System.FilePath
import System.Process
main :: IO ()
main = do
args <- getArgs
when ("check" `elem` takeWhile (/="--") args) $ do
wd <- getCurrentDirectory
let wdparts = splitDirectories wd
_:patharg:_ = dropWhile (/="check") args
pathparts = splitDirectories patharg
when (wdparts `isPrefixOf` pathparts) $ do
case take 1 $ init $ drop (length wdparts) pathparts of
[subdir] -> setCurrentDirectory $ wd </> subdir
_ -> return ()
callProcess "ghc-mod" args
+1
thanks @simonmichael
@DanielG @lierdakil integrating that would be great !
PS the workaround above is not robust, ie does not handle all cases.
This is more or less intended behavior, the project detection is based on the CWD, not the path you pass in for the simple reason that not all commands have a FILE argument but all of them still need the project detection to work. I think with some refactoring it should be possible to support this but I'm not sure how best to do it.
Essentially there's two internal run*
functions that most commands are implemented in terms of :
runGmlTWith :: IOish m => [Either FilePath ModuleName] -> _ -> _ -> GmlT m a -> GhcModT m b
andrunGmPkgGhc :: (IOish m, Gm m) => LightGhc a -> m a
(Gm
should be read as MonadGhcMod
)that correspond to commands that have file or module arguments and ones that only need access to GHC's package databases.
Unfortunately both of these rely on the "Cradle" (i.e. project environment) to already have been resolved and just get it from the monadic environment. The resolution happens in the withGhcModEnv'
wrapper used by runGhcModT
which these run functions have to be run in.
The problem is that we have to support ghc-modi as well which does the "Cradle" resolution at startup based solely on the CWD so we can't easily delay it until we actually get a command that has a FILE argument.
ghc-mod was just never designed to handle superprojects to begin with :( I'm very much open to redesiging this core functionality though, so if anyone wants to work on this I'd be happy to help.
As for a workaround, how about:
#!/bin/sh
cd "$(cd $(dirname "$1"); ghc-mod root)"
ghc-mod check "$@"
but that of course only works for check.
ghc-mod check FILE
in the root of a multi-package stack project doesn't detect the stack package db.It works if I cd into any of the package directories.