@@ -19,6 +19,9 @@ import qualified Distribution.Package as Cabal
19import qualified Distribution.PackageDescription as Cabal
19import qualified Distribution.PackageDescription as Cabal
20import qualified Distribution.PackageDescription.Parse as Cabal
20import qualified Distribution.PackageDescription.Parse as Cabal
22+import qualified Distribution.Compat.Exception as Compat
23+import qualified Distribution.ParseUtils as ParseUtils
22data Package = Package
25data Package = Package
23 { source :: DerivationSource
26 { source :: DerivationSource
24 , cabal :: Cabal.GenericPackageDescription
27 , cabal :: Cabal.GenericPackageDescription
@@ -36,7 +39,8 @@ fetchOrFromDB optHackageDB src
36 | otherwise = do
39 | otherwise = do
37 r <- fetch cabalFromPath src
40 r <- fetch cabalFromPath src
39− Nothing -> hPutStrLn stderr "*** failed to fetch source. Does the URL exist?" >> exitFailure
43+ hPutStrLn stderr "*** failed to fetch source. Does the URL exist?" >> exitFailure
40 Just (derivSource, (externalSource, pkgDesc)) ->
44 Just (derivSource, (externalSource, pkgDesc)) ->
41 return (derivSource <$ guard externalSource, pkgDesc)
45 return (derivSource <$ guard externalSource, pkgDesc)
@@ -75,7 +79,7 @@ sourceFromHackage :: Maybe String -> String -> IO DerivationSource
75sourceFromHackage optHash pkgId = do
79sourceFromHackage optHash pkgId = do
76 cacheFile <- hashCachePath pkgId
80 cacheFile <- hashCachePath pkgId
77 let cachedHash = MaybeT $ maybe (readFileMay cacheFile) (return . Just) optHash
81 let cachedHash = MaybeT $ maybe (readFileMay cacheFile) (return . Just) optHash
78− let url = "mirror://hackage/" ++ pkgId ++ ".tar.gz"
82+ url = "mirror://hackage/" ++ pkgId ++ ".tar.gz"
80 -- Use the cached hash (either from cache file or given on cmdline via sha256 opt)
84 -- Use the cached hash (either from cache file or given on cmdline via sha256 opt)
81 -- if available, otherwise download from hackage to compute hash.
85 -- if available, otherwise download from hackage to compute hash.
@@ -109,19 +113,25 @@ cabalFromPath :: FilePath -> MaybeT IO (Bool, Cabal.GenericPackageDescription)
109cabalFromPath path = do
113cabalFromPath path = do
110 d <- liftIO $ doesDirectoryExist path
114 d <- liftIO $ doesDirectoryExist path
111 (,) d <$> if d
115 (,) d <$> if d
112− then cabalFromDirectory path
116+ then cabalFromDirectory path
113− else cabalFromFile path
117+ else cabalFromFile False path
115cabalFromDirectory :: FilePath -> MaybeT IO Cabal.GenericPackageDescription
119cabalFromDirectory :: FilePath -> MaybeT IO Cabal.GenericPackageDescription
116cabalFromDirectory dir = do
120cabalFromDirectory dir = do
117 cabals <- liftIO $ getDirectoryContents dir >>= filterM doesFileExist . map (dir </>) . filter (".cabal" `isSuffixOf`)
121 cabals <- liftIO $ getDirectoryContents dir >>= filterM doesFileExist . map (dir </>) . filter (".cabal" `isSuffixOf`)
118 case cabals of
122 case cabals of
119− [cabalFile] -> cabalFromFile cabalFile
123+ [cabalFile] -> cabalFromFile True cabalFile
120 _ -> liftIO $ hPutStrLn stderr "*** found zero or more than one cabal file. Exiting." >> exitFailure
124 _ -> liftIO $ hPutStrLn stderr "*** found zero or more than one cabal file. Exiting." >> exitFailure
122−cabalFromFile :: FilePath -> MaybeT IO Cabal.GenericPackageDescription
126+cabalFromFile :: Bool -> FilePath -> MaybeT IO Cabal.GenericPackageDescription
123−cabalFromFile file = do
127+cabalFromFile failHard file = do
124− content <- liftIO $ readFile file
128+ content <- MaybeT $ either (const Nothing) Just <$> Compat.tryIO (readFile file)
125 case Cabal.parsePackageDescription content of
129 case Cabal.parsePackageDescription content of
126− Cabal.ParseFailed _ -> mzero
130+ Cabal.ParseFailed e -> do
133+ let (line, err) = ParseUtils.locatedErrorMsg e
134+ msg = maybe "" ((++ ": ") . show) line ++ err
135+ putStrLn $ "*** error parsing cabal file: " ++ msg
127 Cabal.ParseOk _ a -> return a
137 Cabal.ParseOk _ a -> return a