@@ -13,11 +13,11 @@ import Distribution.Helper (Package, projectPackages, pUnits,
13
13
unChModuleName , Ex (.. ), ProjLoc (.. ),
14
14
QueryEnv , mkQueryEnv , runQuery ,
15
15
Unit , unitInfo , uiComponents ,
16
- ChEntrypoint (.. ))
16
+ ChEntrypoint (.. ), uComponentName )
17
17
import Distribution.Helper.Discover (findProjects , getDefaultDistDir )
18
18
import Data.Char (toLower )
19
19
import Data.Function ((&) )
20
- import Data.List (isPrefixOf , isInfixOf , sortOn , find )
20
+ import Data.List (isPrefixOf , isInfixOf , sortOn , find , intercalate )
21
21
import qualified Data.List.NonEmpty as NonEmpty
22
22
import Data.List.NonEmpty (NonEmpty )
23
23
import qualified Data.Map as M
@@ -45,10 +45,13 @@ import System.Process (readCreateProcessWithExitCode, shell)
45
45
findLocalCradle :: FilePath -> IO Cradle
46
46
findLocalCradle fp = do
47
47
cradleConf <- BIOS. findCradle fp
48
- case cradleConf of
49
- Just yaml -> BIOS. loadCradle yaml
48
+ crdl <- case cradleConf of
49
+ Just yaml -> do
50
+ debugm $ " Found \" " ++ yaml ++ " \" for \" " ++ fp ++ " \" "
51
+ BIOS. loadCradle yaml
50
52
Nothing -> cabalHelperCradle fp
51
-
53
+ logm $ " Module \" " ++ fp ++ " \" is loaded by Cradle: " ++ show crdl
54
+ return crdl
52
55
-- | Check if the given cradle is a stack cradle.
53
56
-- This might be used to determine the GHC version to use on the project.
54
57
-- If it is a stack-cradle, we have to use `stack path --compiler-exe`
@@ -508,7 +511,7 @@ cabalHelperCradle file = do
508
511
debugm $ " Relative Module FilePath: " ++ relativeFp
509
512
getComponent env (toList units) relativeFp
510
513
>>= \ case
511
- Just comp -> do
514
+ Right comp -> do
512
515
let fs' = getFlags comp
513
516
let fs = map (fixImportDirs root) fs'
514
517
let targets = getTargets comp relativeFp
@@ -520,11 +523,11 @@ cabalHelperCradle file = do
520
523
ComponentOptions { componentOptions = ghcOptions
521
524
, componentDependencies = []
522
525
}
523
- Nothing -> return
526
+ Left err -> return
524
527
$ CradleFail
525
528
$ CradleError
526
529
(ExitFailure 2 )
527
- [" Could not obtain flags for " ++ fp ]
530
+ [err ]
528
531
529
532
-- | Get the component the given FilePath most likely belongs to.
530
533
-- Lazily ask units whether the given FilePath is part of one of their
@@ -534,25 +537,59 @@ cabalHelperCradle file = do
534
537
-- The given FilePath must be relative to the Root of the project
535
538
-- the given units belong to.
536
539
getComponent
537
- :: QueryEnv pt -> [Unit pt ] -> FilePath -> IO (Maybe ChComponentInfo )
538
- getComponent _env [] _fp = return Nothing
539
- getComponent env (unit : units) fp =
540
- try (runQuery (unitInfo unit) env) >>= \ case
541
- Left (e :: IOException ) -> do
542
- warningm $ " Catching and swallowing an IOException: " ++ show e
543
- warningm
544
- $ " The Exception was thrown in the context of finding"
545
- ++ " a component for \" "
546
- ++ fp
547
- ++ " \" in the unit: "
548
- ++ show unit
549
- getComponent env units fp
550
- Right ui -> do
551
- let components = M. elems (uiComponents ui)
552
- debugm $ " Unit Info: " ++ show ui
553
- case find (fp `partOfComponent` ) components of
554
- Nothing -> getComponent env units fp
555
- comp -> return comp
540
+ :: forall pt . QueryEnv pt -> [Unit pt ] -> FilePath -> IO (Either String ChComponentInfo )
541
+ getComponent env unitCandidates fp = getComponent' [] [] unitCandidates >>=
542
+ \ case
543
+ (tried, failed, Nothing ) -> return (Left $ buildErrorMsg tried failed)
544
+ (_, _, Just comp) -> return (Right comp)
545
+ where
546
+ getComponent' :: [Unit pt ] -> [Unit pt ] -> [Unit pt ] -> IO ([Unit pt ], [Unit pt ], Maybe ChComponentInfo )
547
+ getComponent' triedUnits failedUnits [] = return (triedUnits, failedUnits, Nothing )
548
+ getComponent' triedUnits failedUnits (unit : units) =
549
+ try (runQuery (unitInfo unit) env) >>= \ case
550
+ Left (e :: IOException ) -> do
551
+ warningm $ " Catching and swallowing an IOException: " ++ show e
552
+ warningm
553
+ $ " The Exception was thrown in the context of finding"
554
+ ++ " a component for \" "
555
+ ++ fp
556
+ ++ " \" in the unit: "
557
+ ++ show unit
558
+ getComponent' triedUnits (unit: failedUnits) units
559
+ Right ui -> do
560
+ let components = M. elems (uiComponents ui)
561
+ debugm $ " Unit Info: " ++ show ui
562
+ case find (fp `partOfComponent` ) components of
563
+ Nothing -> getComponent' (unit: triedUnits) failedUnits units
564
+ comp -> return (triedUnits, failedUnits, comp)
565
+
566
+ buildErrorMsg :: [Unit pt ] -> [Unit pt ] -> String
567
+ buildErrorMsg triedUnits failedUnits = unlines $
568
+ [ " Could not obtain flags for: \" " ++ fp ++ " \" ." ]
569
+ ++
570
+ [ unlines
571
+ [ " The given File was not part of any component."
572
+ , " No component exposes this module, we tried the following:"
573
+ , intercalate " ," (map showUnitInfo triedUnits)
574
+ , " If you dont know how to expose a module take a look at: "
575
+ , " https://www.haskell.org/cabal/users-guide/developing-packages.html"
576
+ ]
577
+ | not ( null triedUnits)
578
+ ]
579
+ ++
580
+ [ unlines
581
+ [ " We could not build all components."
582
+ , " If one of these components exposes the module, make sure these compile."
583
+ , " The following components failed to compile:"
584
+ , intercalate " ," (map showUnitInfo failedUnits)
585
+ ]
586
+ | not (null failedUnits)
587
+ ]
588
+
589
+ -- TODO: this is terrible
590
+ showUnitInfo :: Unit pt -> String
591
+ showUnitInfo unit = maybe (show unit) show (uComponentName unit)
592
+
556
593
557
594
-- | Check whether the given FilePath is part of the Component.
558
595
-- A FilePath is part of the Component if and only if:
0 commit comments