@@ -52,23 +52,24 @@ findLocalCradle fp = do
52
52
Nothing -> cabalHelperCradle fp
53
53
logm $ " Module \" " ++ fp ++ " \" is loaded by Cradle: " ++ show crdl
54
54
return crdl
55
+
55
56
-- | Check if the given cradle is a stack cradle.
56
57
-- This might be used to determine the GHC version to use on the project.
57
- -- If it is a stack-cradle, we have to use ` stack path --compiler-exe`
58
+ -- If it is a stack-cradle, we have to use @" stack path --compiler-exe"@
58
59
-- otherwise we may ask `ghc` directly what version it is.
59
60
isStackCradle :: Cradle -> Bool
60
61
isStackCradle = (`elem` [" stack" , " Cabal-Helper-Stack" , " Cabal-Helper-Stack-None" ])
61
62
. BIOS. actionName
62
63
. BIOS. cradleOptsProg
63
64
64
- -- | Check if the given cradle is a cabal cradle.
65
+ -- | Check if the given cradle is a cabal cradle.
65
66
-- This might be used to determine the GHC version to use on the project.
66
- -- If it is a stack-cradle, we have to use ` stack path --compiler-exe`
67
- -- otherwise we may ask ` ghc` directly what version it is.
67
+ -- If it is a stack-cradle, we have to use @" stack path --compiler-exe"@
68
+ -- otherwise we may ask @ ghc@ directly what version it is.
68
69
isCabalCradle :: Cradle -> Bool
69
70
isCabalCradle =
70
71
(`elem`
71
- [" cabal"
72
+ [ " cabal"
72
73
, " Cabal-Helper-Cabal-V1"
73
74
, " Cabal-Helper-Cabal-V2"
74
75
, " Cabal-Helper-Cabal-V1-Dir"
@@ -81,10 +82,10 @@ isCabalCradle =
81
82
82
83
-- | Execute @ghc@ that is based on the given cradle.
83
84
-- Output must be a single line. If an error is raised, e.g. the command
84
- -- failed, a @ Nothing@ is returned.
85
+ -- failed, a ' Nothing' is returned.
85
86
-- The exact error is written to logs.
86
87
--
87
- -- E.g. for a stack cradle, we use ` stack ghc` and for a cabal cradle
88
+ -- E.g. for a stack cradle, we use @ stack ghc@ and for a cabal cradle
88
89
-- we are taking the @ghc@ that is on the path.
89
90
execProjectGhc :: Cradle -> [String ] -> IO (Maybe String )
90
91
execProjectGhc crdl args = do
@@ -167,6 +168,8 @@ This guessing has no guarantees and may change at any time.
167
168
=== Example:
168
169
169
170
Assume the following project structure:
171
+
172
+ @
170
173
/
171
174
└── Foo/
172
175
├── Foo.cabal
@@ -178,28 +181,31 @@ Assume the following project structure:
178
181
├── B.cabal
179
182
└── src/
180
183
└── Lib2.hs
184
+ @
181
185
182
- Assume the call @findCabalHelperEntryPoint "/Foo/B /src/Lib2.hs"@.
183
- We now want to know to which project "/Foo/B /src/Lib2.hs" belongs to
186
+ Assume the call @findCabalHelperEntryPoint "\ /Foo\/B\ /src\ /Lib2.hs"@.
187
+ We now want to know to which project "\ /Foo\/B\ /src\ /Lib2.hs" belongs to
184
188
and what the projects root is. If we only do a naive search to find the
185
189
first occurrence of either "B.cabal", "stack.yaml", "cabal.project"
186
190
or "Foo.cabal", we might assume that the location of "B.cabal" marks
187
- the project's root directory of which "/Foo/B /src/Lib2.hs" is part of.
191
+ the project's root directory of which "\ /Foo\/B\ /src\ /Lib2.hs" is part of.
188
192
However, there is also a "cabal.project" and "stack.yaml" in the parent
189
- directory, which add the package "B" as a package.
190
- So, the compilation of the package "B" , and the file "src/Lib2.hs" in it,
193
+ directory, which add the package @B@ as a package.
194
+ So, the compilation of the package @B@ , and the file "src\ /Lib2.hs" in it,
191
195
does not only depend on the definitions in "B.cabal", but also
192
196
on "stack.yaml" and "cabal.project".
193
- The project root is therefore "/Foo/".
197
+ The project root is therefore "\ /Foo\ /".
194
198
Only if there is no "stack.yaml" or "cabal.project" in any of the ancestor
195
199
directories, it is safe to assume that "B.cabal" marks the root of the project.
196
200
197
201
Thus:
202
+
198
203
>>> findCabalHelperEntryPoint "/Foo/B/src/Lib2.hs
199
204
Just (Ex (ProjLocStackYaml { plStackYaml = "/Foo/"}))
200
205
201
206
or
202
- >>> findCabalHelperEntryPoint "/Foo/B/src/Lib2.hs
207
+
208
+ >>> findCabalHelperEntryPoint "/Foo/B/src/Lib2.hs"
203
209
Just (Ex (ProjLocV2File { plProjectDirV2 = "/Foo/"}))
204
210
205
211
In the given example, it is not guaranteed which project type is found,
@@ -340,6 +346,8 @@ required to load and compile the given file.
340
346
=== Mono-Repo
341
347
342
348
Assume the project structure:
349
+
350
+ @
343
351
/
344
352
└── Mono/
345
353
├── cabal.project
@@ -350,21 +358,24 @@ Assume the project structure:
350
358
└── B/
351
359
├── B.cabal
352
360
└── Exe.hs
361
+ @
353
362
354
363
Currently, Haskell IDE Engine needs to know on startup which GHC version is
355
364
needed to compile the project. This information is needed to show warnings to
356
365
the user if the GHC version on the project does not agree with the GHC version
357
366
that was used to compile Haskell IDE Engine.
358
367
359
368
Therefore, the function 'findLocalCradle' is invoked with a dummy FilePath,
360
- such as "/Mono/Lib.hs". Since there will be no package that contains this
369
+ such as "\ /Mono\ /Lib.hs". Since there will be no package that contains this
361
370
dummy FilePath, the result will be a None-cradle.
362
371
363
372
Either
373
+
364
374
>>> findLocalCradle "/Mono/Lib.hs"
365
375
Cradle { cradleRootDir = "/Mono/", CradleAction { actionName = "Cabal-Helper-Stack-None", ..} }
366
376
367
- or:
377
+ or
378
+
368
379
>>> findLocalCradle "/Mono/Lib.hs"
369
380
Cradle { cradleRootDir = "/Mono/", CradleAction { actionName = "Cabal-Helper-Cabal-V2-None", ..} }
370
381
@@ -374,8 +385,9 @@ a 'cabal' project.
374
385
375
386
376
387
If we are trying to load the executable:
388
+
377
389
>>> findLocalCradle "/Mono/B/Exe.hs"
378
- Cradle { cradleRootDir = "/Mono/B/ ", CradleAction { actionName = "Cabal-Helper-Cabal-V2", ..} }
390
+ Cradle { cradleRootDir = "/Mono/", CradleAction { actionName = "Cabal-Helper-Cabal-V2", ..} }
379
391
380
392
we will detect correctly the compiler options, by first finding the appropriate
381
393
package, followed by traversing the units in the package and finding the
@@ -384,6 +396,8 @@ component that exposes the executable by FilePath.
384
396
=== No explicit executable folder
385
397
386
398
Assume the project structure:
399
+
400
+ @
387
401
/
388
402
└── Library/
389
403
├── cabal.project
@@ -392,18 +406,21 @@ Assume the project structure:
392
406
└── src
393
407
├── Lib.hs
394
408
└── Exe.hs
409
+ @
395
410
396
411
There are different dependencies for the library "Lib.hs" and the
397
- executable "Exe.hs". If we are trying to load the executable "src/Exe.hs"
412
+ executable "Exe.hs". If we are trying to load the executable "src\ /Exe.hs"
398
413
we will correctly identify the executable unit, and correctly initialise
399
414
dependencies of "exe:Library".
400
415
It will be correct even if we load the unit "lib:Library" before
401
416
the "exe:Library" because the unit "lib:Library" does not expose
402
- a module "Exe".
417
+ a module @ "Exe"@ .
403
418
404
419
=== Sub package
405
420
406
421
Assume the project structure:
422
+
423
+ @
407
424
/
408
425
└── Repo/
409
426
├── cabal.project
@@ -414,12 +431,13 @@ Assume the project structure:
414
431
└── SubRepo
415
432
├── SubRepo.cabal
416
433
└── Lib2.hs
434
+ @
417
435
418
- When we try to load "/Repo/SubRepo/Lib2.hs", we need to identify root
419
- of the project, which is "/Repo/" but set the root directory of the cradle
420
- responsible to load "/Repo/SubRepo/Lib2.hs" to "/Repo/SubRepo", since
436
+ When we try to load "\ /Repo\ /SubRepo\ /Lib2.hs", we need to identify root
437
+ of the project, which is "\ /Repo\ /" but set the root directory of the cradle
438
+ responsible to load "\ /Repo\ /SubRepo\ /Lib2.hs" to "\ /Repo\ /SubRepo", since
421
439
the compiler options obtained from Cabal-Helper are relative to the package
422
- source directory, which is "/Repo/SubRepo".
440
+ source directory, which is "\ /Repo\ /SubRepo".
423
441
424
442
-}
425
443
cabalHelperCradle :: FilePath -> IO Cradle
@@ -492,60 +510,60 @@ cabalHelperCradle file = do
492
510
fp
493
511
}
494
512
}
495
- where
496
513
497
- -- | Fix occurrences of "-i." to "-i<cradle-root-dir>"
498
- -- Flags obtained from cabal-helper are relative to the package
499
- -- source directory. This is less resilient to using absolute paths,
500
- -- thus, we fix it here.
501
- fixImportDirs :: FilePath -> String -> String
502
- fixImportDirs base_dir arg =
503
- if " -i" `isPrefixOf` arg
504
- then let dir = drop 2 arg
505
- -- the flag "-i" has special meaning.
506
- in if not (null dir) && isRelative dir then (" -i" ++ base_dir </> dir)
507
- else arg
508
- else arg
509
-
510
- -- | Cradle Action to query for the ComponentOptions that are needed
511
- -- to load the given FilePath.
512
- -- This Function is not supposed to throw any exceptions and use
513
- -- 'CradleLoadResult' to indicate errors.
514
- cabalHelperAction :: Ex ProjLoc -- ^ Project location, can be used
515
- -- to present error build-tool
516
- -- agnostic error messages.
517
- -> QueryEnv v -- ^ Query Env created by 'mkQueryEnv'
518
- -- with the appropriate 'distdir'
519
- -> Package v -- ^ Package this cradle is part for.
520
- -> FilePath -- ^ Root directory of the cradle
521
- -- this action belongs to.
522
- -> FilePath -- ^ FilePath to load, expected to be an absolute path.
523
- -> IO (CradleLoadResult ComponentOptions )
524
- cabalHelperAction proj env package root fp = do
525
- -- Get all unit infos the given FilePath may belong to
526
- let units = pUnits package
527
- -- make the FilePath to load relative to the root of the cradle.
528
- let relativeFp = makeRelative root fp
529
- debugm $ " Relative Module FilePath: " ++ relativeFp
530
- getComponent proj env (toList units) relativeFp
531
- >>= \ case
532
- Right comp -> do
533
- let fs' = getFlags comp
534
- let fs = map (fixImportDirs root) fs'
535
- let targets = getTargets comp relativeFp
536
- let ghcOptions = fs ++ targets
537
- debugm $ " Flags for \" " ++ fp ++ " \" : " ++ show ghcOptions
538
- debugm $ " Component Infos: " ++ show comp
539
- return
540
- $ CradleSuccess
541
- ComponentOptions { componentOptions = ghcOptions
542
- , componentDependencies = []
543
- }
544
- Left err -> return
545
- $ CradleFail
546
- $ CradleError
547
- (ExitFailure 2 )
548
- err
514
+ -- | Cradle Action to query for the ComponentOptions that are needed
515
+ -- to load the given FilePath.
516
+ -- This Function is not supposed to throw any exceptions and use
517
+ -- 'CradleLoadResult' to indicate errors.
518
+ cabalHelperAction :: Ex ProjLoc -- ^ Project location, can be used
519
+ -- to present build-tool
520
+ -- agnostic error messages.
521
+ -> QueryEnv v -- ^ Query Env created by 'mkQueryEnv'
522
+ -- with the appropriate 'distdir'
523
+ -> Package v -- ^ Package this cradle is part for.
524
+ -> FilePath -- ^ Root directory of the cradle
525
+ -- this action belongs to.
526
+ -> FilePath -- ^ FilePath to load, expected to be an absolute path.
527
+ -> IO (CradleLoadResult ComponentOptions )
528
+ cabalHelperAction proj env package root fp = do
529
+ -- Get all unit infos the given FilePath may belong to
530
+ let units = pUnits package
531
+ -- make the FilePath to load relative to the root of the cradle.
532
+ let relativeFp = makeRelative root fp
533
+ debugm $ " Relative Module FilePath: " ++ relativeFp
534
+ getComponent proj env (toList units) relativeFp
535
+ >>= \ case
536
+ Right comp -> do
537
+ let fs' = getFlags comp
538
+ let fs = map (fixImportDirs root) fs'
539
+ let targets = getTargets comp relativeFp
540
+ let ghcOptions = fs ++ targets
541
+ debugm $ " Flags for \" " ++ fp ++ " \" : " ++ show ghcOptions
542
+ debugm $ " Component Infos: " ++ show comp
543
+ return
544
+ $ CradleSuccess
545
+ ComponentOptions { componentOptions = ghcOptions
546
+ , componentDependencies = []
547
+ }
548
+ Left err -> return
549
+ $ CradleFail
550
+ $ CradleError
551
+ (ExitFailure 2 )
552
+ err
553
+
554
+ -- | Fix occurrences of "-i." to "-i<cradle-root-dir>"
555
+ -- Flags obtained from cabal-helper are relative to the package
556
+ -- source directory. This is less resilient to using absolute paths,
557
+ -- thus, we fix it here.
558
+ fixImportDirs :: FilePath -> String -> String
559
+ fixImportDirs base_dir arg =
560
+ if " -i" `isPrefixOf` arg
561
+ then let dir = drop 2 arg
562
+ -- the flag "-i" has special meaning.
563
+ in if not (null dir) && isRelative dir then (" -i" ++ base_dir </> dir)
564
+ else arg
565
+ else arg
566
+
549
567
550
568
-- | Get the component the given FilePath most likely belongs to.
551
569
-- Lazily ask units whether the given FilePath is part of one of their
@@ -826,8 +844,8 @@ ancestors dir
826
844
where
827
845
subdir = takeDirectory dir
828
846
829
- -- | Assuming a FilePath "src/Lib/Lib.hs" and a list of directories
830
- -- such as ["src", "app"], returns either the given FilePath
847
+ -- | Assuming a FilePath @ "src\ /Lib\ /Lib.hs"@ and a list of directories
848
+ -- such as @ ["src", "app"]@ , returns either the given FilePath
831
849
-- with a matching directory stripped away.
832
850
-- If there are multiple matches, e.g. multiple directories are a prefix
833
851
-- of the given FilePath, return the first match in the list.
0 commit comments