Skip to content

Commit 0afdbc2

Browse files
authored
Multi Component cabal support (#409)
* Support for cabal multi-component new versions of cabal-install (>= 3.11) have support for starting multi-component repls which allow us to correctly load multiple components, cruicially including the correct transitive closure of all the components we need for correct HLS support. This works by passing multiple targets to `cabal repl`, i.e. `cabal repl target1 target2 ...` In order to do this, we must know all the previous targets we have loaded, so `runCradle` gets an extra `[FilePath]` argument so that this can be supplied. This is the only externally visible API change in this patch. `hie-bios` sometimes passes raw `FilePath`s as targets, and sometimes actual component names (lib:foo, test:foo, exe:bar ...) The latter happes when we have user configuration in the hie.yaml explicitly specifying component names. As downstream users of hie-bios have no concept of "component names", they only know about files which caused a particular component to be loaded, we must handle mapping back from `FilePath`s when starting a multi-component session. It was not easy to do this with the way the code previously work with multi-cradles and `getCradle` and `multiAction` being mutually recursive. So now we uniformly treat everything as a multi-cradle of sorts, resolving the configuration tree from hie.yaml (which I took care not to change) into a list of `ResolvedCradle`s ordered by prefixes, which can easily be consulted by the cabal multi-component cradle to map `FilePath`s back to component names when needed. * Move Logger into Cradle * Also enable multi repl when starting a multi-component session
1 parent 78d0cd2 commit 0afdbc2

File tree

11 files changed

+383
-284
lines changed

11 files changed

+383
-284
lines changed

exe/Main.hs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,28 +63,28 @@ main = do
6363
hSetEncoding stdout utf8
6464
cwd <- getCurrentDirectory
6565
cmd <- execParser progInfo
66-
cradle <-
67-
-- find cradle does a takeDirectory on the argument, so make it into a file
68-
findCradle (cwd </> "File.hs") >>= \case
69-
Just yaml -> loadCradle yaml
70-
Nothing -> loadImplicitCradle (cwd </> "File.hs")
71-
7266
let
7367
printLog (L.WithSeverity l sev) = "[" ++ show sev ++ "] " ++ show (pretty l)
7468
logger :: forall a . Pretty a => L.LogAction IO (L.WithSeverity a)
7569
logger = L.cmap printLog L.logStringStderr
7670

71+
cradle <-
72+
-- find cradle does a takeDirectory on the argument, so make it into a file
73+
findCradle (cwd </> "File.hs") >>= \case
74+
Just yaml -> loadCradle logger yaml
75+
Nothing -> loadImplicitCradle logger (cwd </> "File.hs")
76+
7777
res <- case cmd of
78-
Check targetFiles -> checkSyntax logger logger cradle targetFiles
78+
Check targetFiles -> checkSyntax logger cradle targetFiles
7979
Debug files -> case files of
80-
[] -> debugInfo logger (cradleRootDir cradle) cradle
81-
fp -> debugInfo logger fp cradle
80+
[] -> debugInfo (cradleRootDir cradle) cradle
81+
fp -> debugInfo fp cradle
8282
Flags files -> case files of
8383
-- TODO force optparse to acquire one
8484
[] -> error "too few arguments"
8585
_ -> do
8686
res <- forM files $ \fp -> do
87-
res <- getCompilerOptions logger fp cradle
87+
res <- getCompilerOptions fp [] cradle
8888
case res of
8989
CradleFail (CradleError _deps _ex err) ->
9090
return $ "Failed to show flags for \""
@@ -97,7 +97,7 @@ main = do
9797
CradleNone -> return $ "No flags/None Cradle: component " ++ fp ++ " should not be loaded"
9898
return (unlines res)
9999
ConfigInfo files -> configInfo files
100-
CradleInfo files -> cradleInfo files
100+
CradleInfo files -> cradleInfo logger files
101101
Root -> rootInfo cradle
102102
Version -> return progVersion
103103
putStr res

src/HIE/Bios/Config.hs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ module HIE.Bios.Config(
1515
pattern StackType,
1616
stackComponent,
1717
stackYaml,
18-
CradleType(..),
18+
CradleTree(..),
1919
Callable(..)
2020
) where
2121

@@ -47,7 +47,7 @@ data CradleConfig a =
4747
-- ^ Dependencies of a cradle.
4848
-- Dependencies are expected to be relative to the root directory.
4949
-- The given files are not required to exist.
50-
, cradleType :: CradleType a
50+
, cradleTree :: CradleTree a
5151
-- ^ Type of the cradle to use. Actions to obtain
5252
-- compiler flags from are dependant on this field.
5353
}
@@ -100,7 +100,7 @@ pattern StackType { stackComponent, stackYaml } = StackType_ (Last stackComponen
100100
instance Show StackType where
101101
show = show . Stack
102102

103-
data CradleType a
103+
data CradleTree a
104104
= Cabal { cabalType :: !CabalType }
105105
| CabalMulti { defaultCabal :: !CabalType, subCabalComponents :: [ (FilePath, CabalType) ] }
106106
| Stack { stackType :: !StackType }
@@ -125,7 +125,7 @@ data CradleType a
125125
| Other { otherConfig :: a, originalYamlValue :: Value }
126126
deriving (Eq, Functor)
127127

128-
instance Show (CradleType a) where
128+
instance Show (CradleTree a) where
129129
show (Cabal comp) = "Cabal {component = " ++ show (cabalComponent comp) ++ "}"
130130
show (CabalMulti d a) = "CabalMulti {defaultCabal = " ++ show d ++ ", subCabalComponents = " ++ show a ++ "}"
131131
show (Stack comp) = "Stack {component = " ++ show (stackComponent comp) ++ ", stackYaml = " ++ show (stackYaml comp) ++ "}"
@@ -154,31 +154,31 @@ readConfig fp = do
154154

155155
fromYAMLConfig :: CradleConfigYAML a -> Config a
156156
fromYAMLConfig cradleYAML = Config $ CradleConfig (fromMaybe [] $ YAML.dependencies cradleYAML)
157-
(toCradleType $ YAML.cradle cradleYAML)
157+
(toCradleTree $ YAML.cradle cradleYAML)
158158

159-
toCradleType :: YAML.CradleComponent a -> CradleType a
160-
toCradleType (YAML.Multi cpts) =
159+
toCradleTree :: YAML.CradleComponent a -> CradleTree a
160+
toCradleTree (YAML.Multi cpts) =
161161
Multi $ (\(YAML.MultiSubComponent fp' cfg) -> (fp', cradle $ fromYAMLConfig cfg)) <$> cpts
162-
toCradleType (YAML.Stack (YAML.StackConfig yaml cpts)) =
162+
toCradleTree (YAML.Stack (YAML.StackConfig yaml cpts)) =
163163
case cpts of
164164
YAML.NoComponent -> Stack $ StackType Nothing yaml
165165
(YAML.SingleComponent c) -> Stack $ StackType (Just c) yaml
166166
(YAML.ManyComponents cs) -> StackMulti (StackType Nothing yaml)
167167
((\(YAML.StackComponent fp' c cYAML) ->
168168
(fp', StackType (Just c) cYAML)) <$> cs)
169-
toCradleType (YAML.Cabal (YAML.CabalConfig prjFile cpts)) =
169+
toCradleTree (YAML.Cabal (YAML.CabalConfig prjFile cpts)) =
170170
case cpts of
171171
YAML.NoComponent -> Cabal $ CabalType Nothing prjFile
172172
(YAML.SingleComponent c) -> Cabal $ CabalType (Just c) prjFile
173173
(YAML.ManyComponents cs) -> CabalMulti (CabalType Nothing prjFile)
174174
((\(YAML.CabalComponent fp' c cPrjFile) ->
175175
(fp', CabalType (Just c) cPrjFile)) <$> cs)
176-
toCradleType (YAML.Direct cfg) = Direct (YAML.arguments cfg)
177-
toCradleType (YAML.Bios cfg) = Bios (toCallable $ YAML.callable cfg)
176+
toCradleTree (YAML.Direct cfg) = Direct (YAML.arguments cfg)
177+
toCradleTree (YAML.Bios cfg) = Bios (toCallable $ YAML.callable cfg)
178178
(toCallable <$> YAML.depsCallable cfg)
179179
(YAML.ghcPath cfg)
180-
toCradleType (YAML.None _) = None
181-
toCradleType (YAML.Other cfg) = Other (YAML.otherConfig cfg)
180+
toCradleTree (YAML.None _) = None
181+
toCradleTree (YAML.Other cfg) = Other (YAML.otherConfig cfg)
182182
(YAML.originalYamlValue cfg)
183183

184184
toCallable :: YAML.Callable -> Callable

0 commit comments

Comments
 (0)