From b759787dd9534a4f764c11503823ee6f957019dd Mon Sep 17 00:00:00 2001 From: Sean Hess Date: Tue, 11 Jul 2023 14:17:00 -0600 Subject: [PATCH 1/2] User-friendly error message when modules aren't listed in other-modules or exposed-modules + only show if isCabaltype + show prefixes --- .../session-loader/Development/IDE/Session.hs | 82 ++++++++++++++++++- 1 file changed, 78 insertions(+), 4 deletions(-) diff --git a/ghcide/session-loader/Development/IDE/Session.hs b/ghcide/session-loader/Development/IDE/Session.hs index cfc9796c33..b98e170eec 100644 --- a/ghcide/session-loader/Development/IDE/Session.hs +++ b/ghcide/session-loader/Development/IDE/Session.hs @@ -35,12 +35,14 @@ import Data.Bifunctor import qualified Data.ByteString.Base16 as B16 import qualified Data.ByteString.Char8 as B import Data.Default +import Data.Char (isLower) import Data.Either.Extra import Data.Function import Data.Hashable import qualified Data.HashMap.Strict as HM import Data.IORef import Data.List +import Data.List.Extra (dropPrefix, split) import qualified Data.Map.Strict as Map import Data.Maybe import Data.Proxy @@ -75,6 +77,7 @@ import Development.IDE.Types.Logger (Pretty (pretty), import Development.IDE.Types.Options import GHC.Check import qualified HIE.Bios as HieBios +import qualified HIE.Bios.Cradle as HieBios import HIE.Bios.Environment hiding (getCacheDir) import HIE.Bios.Types hiding (Log) import qualified HIE.Bios.Types as HieBios @@ -662,7 +665,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do Left err -> do dep_info <- getDependencyInfo (maybeToList hieYaml) let ncfp = toNormalizedFilePath' cfp - let res = (map (renderCradleError ncfp) err, Nothing) + let res = (map (renderCradleError cradle ncfp) err, Nothing) void $ modifyVar' fileToFlags $ Map.insertWith HM.union hieYaml (HM.singleton ncfp (res, dep_info)) void $ modifyVar' filesMap $ HM.insert ncfp hieYaml @@ -905,9 +908,80 @@ setCacheDirs recorder CacheDirs{..} dflags = do & maybe id setODir oCacheDir -renderCradleError :: NormalizedFilePath -> CradleError -> FileDiagnostic -renderCradleError nfp (CradleError _ _ec t) = - ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Error) nfp (T.unlines (map T.pack t)) +renderCradleError :: Cradle a -> NormalizedFilePath -> CradleError -> FileDiagnostic +renderCradleError cradle nfp (CradleError _ _ec ms) = + ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Error) nfp $ T.unlines $ map T.pack userFriendlyMessage + where + + userFriendlyMessage :: [String] + userFriendlyMessage + | HieBios.isCabalCradle cradle = fromMaybe ms fileMissingMessage + | otherwise = ms + + fileMissingMessage :: Maybe [String] + fileMissingMessage = + multiCradleErrMessage <$> parseMultiCradleErr ms + +-- | Information included in Multi Cradle error messages +data MultiCradleErr = MultiCradleErr + { mcPwd :: FilePath + , mcFilePath :: FilePath + , mcPrefixes :: [(FilePath, String)] + } deriving (Show) + +-- | Attempt to parse a multi-cradle message +parseMultiCradleErr :: [String] -> Maybe MultiCradleErr +parseMultiCradleErr ms = do + _ <- lineAfter "Multi Cradle: " + wd <- lineAfter "pwd: " + fp <- lineAfter "filepath: " + ps <- prefixes + pure $ MultiCradleErr wd fp ps + + where + lineAfter :: String -> Maybe String + lineAfter pre = listToMaybe $ mapMaybe (stripPrefix pre) ms + + prefixes :: Maybe [(FilePath, String)] + prefixes = do + pure $ mapMaybe tuple ms + + tuple :: String -> Maybe (String, String) + tuple line = do + line' <- surround '(' line ')' + [f, s] <- pure $ split (==',') line' + pure (f, s) + + -- extracts the string surrounded by required characters + surround :: Char -> String -> Char -> Maybe String + surround start s end = do + guard (listToMaybe s == Just start) + guard (listToMaybe (reverse s) == Just end) + pure $ drop 1 $ take (length s - 1) s + + + + + + +multiCradleErrMessage :: MultiCradleErr -> [String] +multiCradleErrMessage e = + [ "Loading the module '" <> moduleFileName <> "' failed. It seems that it is not listed in your .cabal file!" + , "Perhaps you need to add `"<> moduleName <> "` to other-modules or exposed-modules" -- named 'example' in example.cabal." + , "For more information, visit: https://cabal.readthedocs.io/en/3.4/developing-packages.html#modules-included-in-the-package" + , "" + ] <> map prefix (mcPrefixes e) + where + localFilePath f = dropWhile (==pathSeparator) $ dropPrefix (mcPwd e) f + moduleFileName = localFilePath $ mcFilePath e + moduleName = intercalate "." $ map dropExtension $ dropWhile isSourceFolder $ splitDirectories moduleFileName + isSourceFolder p = all isLower $ take 1 p + prefix (f, r) = f <> " - " <> r + + + + + -- See Note [Multi Cradle Dependency Info] type DependencyInfo = Map.Map FilePath (Maybe UTCTime) From 91adfab6d1d4bcf21e3e7dcd8968f12f232e1dcb Mon Sep 17 00:00:00 2001 From: Fendor Date: Tue, 1 Aug 2023 12:28:16 +0200 Subject: [PATCH 2/2] Fix formatting --- .../session-loader/Development/IDE/Session.hs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/ghcide/session-loader/Development/IDE/Session.hs b/ghcide/session-loader/Development/IDE/Session.hs index b98e170eec..6d28727016 100644 --- a/ghcide/session-loader/Development/IDE/Session.hs +++ b/ghcide/session-loader/Development/IDE/Session.hs @@ -34,8 +34,8 @@ import Data.Aeson hiding (Error) import Data.Bifunctor import qualified Data.ByteString.Base16 as B16 import qualified Data.ByteString.Char8 as B -import Data.Default import Data.Char (isLower) +import Data.Default import Data.Either.Extra import Data.Function import Data.Hashable @@ -924,7 +924,7 @@ renderCradleError cradle nfp (CradleError _ _ec ms) = -- | Information included in Multi Cradle error messages data MultiCradleErr = MultiCradleErr - { mcPwd :: FilePath + { mcPwd :: FilePath , mcFilePath :: FilePath , mcPrefixes :: [(FilePath, String)] } deriving (Show) @@ -959,15 +959,10 @@ parseMultiCradleErr ms = do guard (listToMaybe (reverse s) == Just end) pure $ drop 1 $ take (length s - 1) s - - - - - multiCradleErrMessage :: MultiCradleErr -> [String] multiCradleErrMessage e = - [ "Loading the module '" <> moduleFileName <> "' failed. It seems that it is not listed in your .cabal file!" - , "Perhaps you need to add `"<> moduleName <> "` to other-modules or exposed-modules" -- named 'example' in example.cabal." + [ "Loading the module '" <> moduleFileName <> "' failed. It may not be listed in your .cabal file!" + , "Perhaps you need to add `"<> moduleName <> "` to other-modules or exposed-modules." , "For more information, visit: https://cabal.readthedocs.io/en/3.4/developing-packages.html#modules-included-in-the-package" , "" ] <> map prefix (mcPrefixes e) @@ -978,11 +973,6 @@ multiCradleErrMessage e = isSourceFolder p = all isLower $ take 1 p prefix (f, r) = f <> " - " <> r - - - - - -- See Note [Multi Cradle Dependency Info] type DependencyInfo = Map.Map FilePath (Maybe UTCTime) type HieMap = Map.Map (Maybe FilePath) (HscEnv, [RawComponentInfo])