Andreas Klebinger pushed to branch wip/andreask/hadrian_race at Glasgow Haskell Compiler / GHC
Commits:
-
1b7bcd0d
by Andreas Klebinger at 2026-02-06T21:01:35+01:00
3 changed files:
Changes:
| ... | ... | @@ -160,6 +160,13 @@ Cmm |
| 160 | 160 | the recompilation checker will look at to determine if a module needs to be
|
| 161 | 161 | recompiled.
|
| 162 | 162 | |
| 163 | +``ghc-pkg`` utility
|
|
| 164 | +~~~~~~~~~~~~~~~~~~~
|
|
| 165 | + |
|
| 166 | +- A slight rework how package databases are being locked should make ghc-pkg more
|
|
| 167 | + reliable when multiple invocations try to read/modify a package database at the
|
|
| 168 | + same time.
|
|
| 169 | + |
|
| 163 | 170 | Included libraries
|
| 164 | 171 | ~~~~~~~~~~~~~~~~~~
|
| 165 | 172 |
| ... | ... | @@ -58,6 +58,9 @@ module GHC.Unit.Database |
| 58 | 58 | , DbMode(..)
|
| 59 | 59 | , DbOpenMode(..)
|
| 60 | 60 | , isDbOpenReadMode
|
| 61 | + , dbMode
|
|
| 62 | + , modeWithLock
|
|
| 63 | + |
|
| 61 | 64 | , readPackageDbForGhc
|
| 62 | 65 | , readPackageDbForGhcPkg
|
| 63 | 66 | , writePackageDb
|
| ... | ... | @@ -65,6 +68,7 @@ module GHC.Unit.Database |
| 65 | 68 | , PackageDbLock
|
| 66 | 69 | , lockPackageDb
|
| 67 | 70 | , unlockPackageDb
|
| 71 | + , withLockedPackageDb
|
|
| 68 | 72 | -- * Misc
|
| 69 | 73 | , mkMungePathUrl
|
| 70 | 74 | , mungeUnitInfoPaths
|
| ... | ... | @@ -313,6 +317,22 @@ data DbInstUnitId |
| 313 | 317 | -- | Represents a lock of a package db.
|
| 314 | 318 | newtype PackageDbLock = PackageDbLock Handle
|
| 315 | 319 | |
| 320 | +-- | Run the action under a lock, then return the result.
|
|
| 321 | +-- If the mode is R/W the *caller* needs to either free the lock or pass it
|
|
| 322 | +-- on to code that will.
|
|
| 323 | +--
|
|
| 324 | +-- If an exception is raised the lock is released.
|
|
| 325 | +withLockedPackageDb :: DbOpenMode m t -> FilePath -> (PackageDbLock -> IO a) -> IO a
|
|
| 326 | +withLockedPackageDb mode file act = do
|
|
| 327 | + lock <- lockPackageDbWith (lock_mode mode) file
|
|
| 328 | + r <- act lock `onException` unlockPackageDb lock
|
|
| 329 | + when (isDbOpenReadMode mode ) $ unlockPackageDb lock
|
|
| 330 | + pure r
|
|
| 331 | + where
|
|
| 332 | + lock_mode :: DbOpenMode m t -> LockMode
|
|
| 333 | + lock_mode DbOpenReadOnly = SharedLock
|
|
| 334 | + lock_mode DbOpenReadWrite{} = ExclusiveLock
|
|
| 335 | + |
|
| 316 | 336 | -- | Acquire an exclusive lock related to package DB under given location.
|
| 317 | 337 | lockPackageDb :: FilePath -> IO PackageDbLock
|
| 318 | 338 | |
| ... | ... | @@ -362,12 +382,13 @@ lockPackageDbWith mode file = do |
| 362 | 382 | return $ PackageDbLock hnd
|
| 363 | 383 | |
| 364 | 384 | lockPackageDb = lockPackageDbWith ExclusiveLock
|
| 385 | + |
|
| 365 | 386 | unlockPackageDb (PackageDbLock hnd) = do
|
| 366 | 387 | hUnlock hnd
|
| 367 | 388 | hClose hnd
|
| 368 | 389 | |
| 369 | 390 | -- | Mode to open a package db in.
|
| 370 | -data DbMode = DbReadOnly | DbReadWrite
|
|
| 391 | +data DbMode = DbReadOnly | DbReadWrite deriving Eq
|
|
| 371 | 392 | |
| 372 | 393 | -- | 'DbOpenMode' holds a value of type @t@ but only in 'DbReadWrite' mode. So
|
| 373 | 394 | -- it is like 'Maybe' but with a type argument for the mode to enforce that the
|
| ... | ... | @@ -380,6 +401,14 @@ deriving instance Functor (DbOpenMode mode) |
| 380 | 401 | deriving instance F.Foldable (DbOpenMode mode)
|
| 381 | 402 | deriving instance F.Traversable (DbOpenMode mode)
|
| 382 | 403 | |
| 404 | +dbMode :: DbOpenMode m t -> DbMode
|
|
| 405 | +dbMode DbOpenReadOnly = DbReadOnly
|
|
| 406 | +dbMode DbOpenReadWrite{} = DbReadWrite
|
|
| 407 | + |
|
| 408 | +modeWithLock :: PackageDbLock -> DbOpenMode m t -> DbOpenMode m PackageDbLock
|
|
| 409 | +modeWithLock _ DbOpenReadOnly = DbOpenReadOnly
|
|
| 410 | +modeWithLock l DbOpenReadWrite{} = DbOpenReadWrite l
|
|
| 411 | + |
|
| 383 | 412 | isDbOpenReadMode :: DbOpenMode mode t -> Bool
|
| 384 | 413 | isDbOpenReadMode = \case
|
| 385 | 414 | DbOpenReadOnly -> True
|
| ... | ... | @@ -388,9 +417,11 @@ isDbOpenReadMode = \case |
| 388 | 417 | -- | Read the part of the package DB that GHC is interested in.
|
| 389 | 418 | --
|
| 390 | 419 | readPackageDbForGhc :: FilePath -> IO [DbUnitInfo]
|
| 391 | -readPackageDbForGhc file =
|
|
| 392 | - decodeFromFile file DbOpenReadOnly getDbForGhc >>= \case
|
|
| 393 | - (pkgs, DbOpenReadOnly) -> return pkgs
|
|
| 420 | +readPackageDbForGhc file = do
|
|
| 421 | + hPutStrLn stderr $ "readPackageDbForGhc:" ++ show file
|
|
| 422 | + withLockedPackageDb DbOpenReadOnly file $ \_ -> do
|
|
| 423 | + decodeFromFile file DbOpenReadOnly getDbForGhc >>= \case
|
|
| 424 | + (pkgs, DbOpenReadOnly) -> return pkgs
|
|
| 394 | 425 | where
|
| 395 | 426 | getDbForGhc = do
|
| 396 | 427 | _version <- getHeader
|
| ... | ... | @@ -405,11 +436,13 @@ readPackageDbForGhc file = |
| 405 | 436 | -- is not defined in this package. This is because ghc-pkg uses Cabal types
|
| 406 | 437 | -- (and Binary instances for these) which this package does not depend on.
|
| 407 | 438 | --
|
| 439 | +-- The incoming mode carries the exclusive lock if we are in R/W mode.
|
|
| 440 | +--
|
|
| 408 | 441 | -- If we open the package db in read only mode, we get its contents. Otherwise
|
| 409 | 442 | -- we additionally receive a PackageDbLock that represents a lock on the
|
| 410 | 443 | -- database, so that we can safely update it later.
|
| 411 | 444 | --
|
| 412 | -readPackageDbForGhcPkg :: Binary pkgs => FilePath -> DbOpenMode mode t ->
|
|
| 445 | +readPackageDbForGhcPkg :: Binary pkgs => FilePath -> DbOpenMode mode PackageDbLock ->
|
|
| 413 | 446 | IO (pkgs, DbOpenMode mode PackageDbLock)
|
| 414 | 447 | readPackageDbForGhcPkg file mode =
|
| 415 | 448 | decodeFromFile file mode getDbForGhcPkg
|
| ... | ... | @@ -496,26 +529,19 @@ headerMagic = BS.Char8.pack "\0ghcpkg\0" |
| 496 | 529 | |
| 497 | 530 | -- | Feed a 'Get' decoder with data chunks from a file.
|
| 498 | 531 | --
|
| 499 | -decodeFromFile :: FilePath -> DbOpenMode mode t -> Get pkgs ->
|
|
| 532 | +-- The file is already locked when we call this. We only need to pass it on
|
|
| 533 | +-- if we are in R/W mode.
|
|
| 534 | +decodeFromFile :: FilePath -> DbOpenMode mode PackageDbLock -> Get pkgs ->
|
|
| 500 | 535 | IO (pkgs, DbOpenMode mode PackageDbLock)
|
| 501 | 536 | decodeFromFile file mode decoder = case mode of
|
| 502 | 537 | DbOpenReadOnly -> do
|
| 503 | - -- Note [Locking package database on Windows]
|
|
| 504 | - -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 505 | - -- When we open the package db in read only mode, there is no need to acquire
|
|
| 506 | - -- shared lock on non-Windows platform because we update the database with an
|
|
| 507 | - -- atomic rename, so readers will always see the database in a consistent
|
|
| 508 | - -- state.
|
|
| 509 | -#if defined(mingw32_HOST_OS)
|
|
| 510 | - bracket (lockPackageDbWith SharedLock file) unlockPackageDb $ \_ -> do
|
|
| 511 | -#endif
|
|
| 512 | 538 | (, DbOpenReadOnly) <$> decodeFileContents
|
| 513 | 539 | DbOpenReadWrite{} -> do
|
| 514 | - -- When we open the package db in read/write mode, acquire an exclusive lock
|
|
| 515 | - -- on the database and return it so we can keep it for the duration of the
|
|
| 540 | + -- When we open the package db in read/write mode, we receive an exclusive lock
|
|
| 541 | + -- on the database via the mode and return it so we can keep it for the duration of the
|
|
| 516 | 542 | -- update.
|
| 517 | - bracketOnError (lockPackageDb file) unlockPackageDb $ \lock -> do
|
|
| 518 | - (, DbOpenReadWrite lock) <$> decodeFileContents
|
|
| 543 | + -- If an exception is raised the caller releases the lock.
|
|
| 544 | + (, mode) <$> decodeFileContents
|
|
| 519 | 545 | where
|
| 520 | 546 | decodeFileContents = withBinaryFile file ReadMode $ \hnd ->
|
| 521 | 547 | feed hnd (runGetIncremental decoder)
|
| ... | ... | @@ -8,6 +8,7 @@ |
| 8 | 8 | {-# LANGUAGE DataKinds #-}
|
| 9 | 9 | {-# LANGUAGE TupleSections #-}
|
| 10 | 10 | {-# LANGUAGE ScopedTypeVariables #-}
|
| 11 | +{-# LANGUAGE PartialTypeSignatures #-}
|
|
| 11 | 12 | {-# OPTIONS_GHC -Wno-orphans -Wno-x-partial #-}
|
| 12 | 13 | |
| 13 | 14 | -- Fine if this comes from make/Hadrian or the pre-built base.
|
| ... | ... | @@ -872,6 +873,23 @@ lookForPackageDBIn dir = do |
| 872 | 873 | exists_file <- doesFileExist path_file
|
| 873 | 874 | if exists_file then return (Just path_file) else return Nothing
|
| 874 | 875 | |
| 876 | +{- Note [ghc-pkg database locking]
|
|
| 877 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 878 | +We differentiate the read only (RO) and read write (R/W) cases.
|
|
| 879 | + |
|
| 880 | +The general idea is we use `withLockedPackageDb` to lock an already existing
|
|
| 881 | +database in both modes. In RO mode we simply unlock the DB once we read it.
|
|
| 882 | +The unlocking is also handled by withLockedPackageDb.
|
|
| 883 | + |
|
| 884 | +For the R/W case withLockedPackageDb will *lock* the database, and handle unlocking
|
|
| 885 | +in the case of exceptions. But rather than unlocking it once the argument has been
|
|
| 886 | +executed without error we simply pass along the lock inside either a `DbOpenMode` or `PackageDB`
|
|
| 887 | +so we can keep holding while doing one or more modifications.
|
|
| 888 | + |
|
| 889 | +The alternative would be to rewrite much of this in a CPS/bracket style and I couldn't
|
|
| 890 | +quite bring myself to do so.
|
|
| 891 | + |
|
| 892 | +-}
|
|
| 875 | 893 | readParseDatabase :: forall mode t. Verbosity
|
| 876 | 894 | -> Maybe (FilePath,Bool)
|
| 877 | 895 | -> GhcPkg.DbOpenMode mode t
|
| ... | ... | @@ -889,83 +907,79 @@ readParseDatabase verbosity mb_user_conf mode use_cache path |
| 889 | 907 | = do e <- tryIO $ getDirectoryContents path
|
| 890 | 908 | case e of
|
| 891 | 909 | Left err
|
| 892 | - | ioeGetErrorType err == InappropriateType -> do
|
|
| 893 | - -- We provide a limited degree of backwards compatibility for
|
|
| 894 | - -- old single-file style db:
|
|
| 895 | - mdb <- tryReadParseOldFileStyleDatabase verbosity
|
|
| 896 | - mb_user_conf mode use_cache path
|
|
| 897 | - case mdb of
|
|
| 898 | - Just db -> return db
|
|
| 899 | - Nothing ->
|
|
| 900 | - die $ "ghc no longer supports single-file style package "
|
|
| 901 | - ++ "databases (" ++ path ++ ") use 'ghc-pkg init'"
|
|
| 902 | - ++ "to create the database with the correct format."
|
|
| 903 | - |
|
| 910 | + | ioeGetErrorType err == InappropriateType -> dieOnSingleFileDb path
|
|
| 904 | 911 | | otherwise -> ioError err
|
| 905 | - Right fs
|
|
| 906 | - | not use_cache -> ignore_cache (const $ return ())
|
|
| 907 | - | otherwise -> do
|
|
| 908 | - e_tcache <- tryIO $ getModificationTime cache
|
|
| 909 | - case e_tcache of
|
|
| 910 | - Left ex -> do
|
|
| 911 | - whenReportCacheErrors $
|
|
| 912 | - if isDoesNotExistError ex
|
|
| 913 | - then
|
|
| 914 | - -- It's fine if the cache is not there as long as the
|
|
| 915 | - -- database is empty.
|
|
| 916 | - when (not $ null confs) $ do
|
|
| 917 | - warn ("WARNING: cache does not exist: " ++ cache)
|
|
| 918 | - warn ("ghc will fail to read this package db. " ++
|
|
| 919 | - recacheAdvice)
|
|
| 920 | - else do
|
|
| 921 | - warn ("WARNING: cache cannot be read: " ++ show ex)
|
|
| 922 | - warn "ghc will fail to read this package db."
|
|
| 923 | - ignore_cache (const $ return ())
|
|
| 924 | - Right tcache -> do
|
|
| 925 | - when (verbosity >= Verbose) $ do
|
|
| 926 | - warn ("Timestamp " ++ show tcache ++ " for " ++ cache)
|
|
| 927 | - -- If any of the .conf files is newer than package.cache, we
|
|
| 928 | - -- assume that cache is out of date.
|
|
| 929 | - cache_outdated <- (`anyM` confs) $ \conf ->
|
|
| 930 | - (tcache <) <$> getModificationTime conf
|
|
| 931 | - if not cache_outdated
|
|
| 932 | - then do
|
|
| 933 | - when (verbosity > Normal) $
|
|
| 934 | - infoLn ("using cache: " ++ cache)
|
|
| 935 | - GhcPkg.readPackageDbForGhcPkg cache mode
|
|
| 936 | - >>= uncurry mkPackageDB
|
|
| 937 | - else do
|
|
| 938 | - whenReportCacheErrors $ do
|
|
| 939 | - warn ("WARNING: cache is out of date: " ++ cache)
|
|
| 940 | - warn ("ghc will see an old view of this " ++
|
|
| 941 | - "package db. " ++ recacheAdvice)
|
|
| 942 | - ignore_cache $ \file -> do
|
|
| 943 | - when (verbosity >= Verbose) $ do
|
|
| 944 | - tFile <- getModificationTime file
|
|
| 945 | - let rel = case tcache `compare` tFile of
|
|
| 946 | - LT -> " (NEWER than cache)"
|
|
| 947 | - GT -> " (older than cache)"
|
|
| 948 | - EQ -> " (same as cache)"
|
|
| 949 | - warn ("Timestamp " ++ show tFile
|
|
| 950 | - ++ " for " ++ file ++ rel)
|
|
| 951 | - where
|
|
| 952 | - confs = map (path </>) $ filter (".conf" `isSuffixOf`) fs
|
|
| 953 | - |
|
| 954 | - ignore_cache :: (FilePath -> IO ()) -> IO (PackageDB mode)
|
|
| 955 | - ignore_cache checkTime = do
|
|
| 956 | - -- If we're opening for modification, we need to acquire a
|
|
| 957 | - -- lock even if we don't open the cache now, because we are
|
|
| 958 | - -- going to modify it later.
|
|
| 959 | - lock <- F.mapM (const $ GhcPkg.lockPackageDb cache) mode
|
|
| 960 | - let doFile f = do checkTime f
|
|
| 961 | - parseSingletonPackageConf verbosity f
|
|
| 962 | - pkgs <- mapM doFile confs
|
|
| 963 | - mkPackageDB pkgs lock
|
|
| 964 | - |
|
| 965 | - -- We normally report cache errors for read-only commands,
|
|
| 966 | - -- since modify commands will usually fix the cache.
|
|
| 967 | - whenReportCacheErrors = when $ verbosity > Normal
|
|
| 968 | - || verbosity >= Normal && GhcPkg.isDbOpenReadMode mode
|
|
| 912 | + -- Take a lock to use while we read the DB
|
|
| 913 | + Right fs -> withLockedPackageDb mode cache $ \lock -> do
|
|
| 914 | + if not use_cache
|
|
| 915 | + then ignore_cache (lock) (const $ return ())
|
|
| 916 | + else do
|
|
| 917 | + e_tcache <- tryIO $ getModificationTime cache
|
|
| 918 | + case e_tcache of
|
|
| 919 | + Left ex -> do
|
|
| 920 | + whenReportCacheErrors $
|
|
| 921 | + if isDoesNotExistError ex
|
|
| 922 | + then
|
|
| 923 | + -- It's fine if the cache is not there as long as the
|
|
| 924 | + -- database is empty.
|
|
| 925 | + when (not $ null confs) $ do
|
|
| 926 | + warn ("WARNING: cache does not exist: " ++ cache)
|
|
| 927 | + warn ("ghc will fail to read this package db. " ++
|
|
| 928 | + recacheAdvice)
|
|
| 929 | + else do
|
|
| 930 | + warn ("WARNING: cache cannot be read: " ++ show ex)
|
|
| 931 | + warn "ghc will fail to read this package db."
|
|
| 932 | + ignore_cache (lock) (const $ return ())
|
|
| 933 | + Right tcache -> do
|
|
| 934 | + when (verbosity >= Verbose) $ do
|
|
| 935 | + warn ("Timestamp " ++ show tcache ++ " for " ++ cache)
|
|
| 936 | + -- If any of the .conf files is newer than package.cache, we
|
|
| 937 | + -- assume that cache is out of date.
|
|
| 938 | + cache_outdated <- (`anyM` confs) $ \conf ->
|
|
| 939 | + (tcache <) <$> getModificationTime conf
|
|
| 940 | + if not cache_outdated
|
|
| 941 | + then do
|
|
| 942 | + when (verbosity > Normal) $
|
|
| 943 | + infoLn ("using cache: " ++ cache)
|
|
| 944 | + GhcPkg.readPackageDbForGhcPkg cache (modeWithLock lock mode)
|
|
| 945 | + >>= uncurry mkPackageDB
|
|
| 946 | + else do
|
|
| 947 | + whenReportCacheErrors $ do
|
|
| 948 | + warn ("WARNING: cache is out of date: " ++ cache)
|
|
| 949 | + warn ("ghc will see an old view of this " ++
|
|
| 950 | + "package db. " ++ recacheAdvice)
|
|
| 951 | + ignore_cache (lock) $ \file -> do
|
|
| 952 | + when (verbosity >= Verbose) $ do
|
|
| 953 | + tFile <- getModificationTime file
|
|
| 954 | + let rel = case tcache `compare` tFile of
|
|
| 955 | + LT -> " (NEWER than cache)"
|
|
| 956 | + GT -> " (older than cache)"
|
|
| 957 | + EQ -> " (same as cache)"
|
|
| 958 | + warn ("Timestamp " ++ show tFile
|
|
| 959 | + ++ " for " ++ file ++ rel)
|
|
| 960 | + where
|
|
| 961 | + confs = map (path </>) $ filter (".conf" `isSuffixOf`) fs
|
|
| 962 | + |
|
| 963 | + -- Read the package db, potentially locking the .cache file for r/w mode.
|
|
| 964 | + ignore_cache :: PackageDbLock -> (FilePath -> IO ()) -> IO (PackageDB mode)
|
|
| 965 | + ignore_cache lock checkTime = do
|
|
| 966 | + -- If we're opening for modification, we need to acquire a
|
|
| 967 | + -- lock even if we don't open the cache now, because we are
|
|
| 968 | + -- going to modify it later.
|
|
| 969 | + |
|
| 970 | + -- mode' <- F.mapM (const $ GhcPkg.lockPackageDb cache) mode
|
|
| 971 | + |
|
| 972 | + let doFile f = do checkTime f
|
|
| 973 | + parseSingletonPackageConf verbosity f
|
|
| 974 | + pkgs <- mapM doFile confs
|
|
| 975 | + |
|
| 976 | + -- mkPackageDB pkgs mode'
|
|
| 977 | + mkPackageDB pkgs (modeWithLock lock mode)
|
|
| 978 | + |
|
| 979 | + -- We normally report cache errors for read-only commands,
|
|
| 980 | + -- since modify commands will usually fix the cache.
|
|
| 981 | + whenReportCacheErrors = when $ verbosity > Normal
|
|
| 982 | + || verbosity >= Normal && GhcPkg.isDbOpenReadMode mode
|
|
| 969 | 983 | where
|
| 970 | 984 | cache = path </> cachefilename
|
| 971 | 985 | |
| ... | ... | @@ -1060,75 +1074,16 @@ mkMungePathUrl top_dir pkgroot = (munge_path, munge_url) |
| 1060 | 1074 | Just cs@(c : _) | isPathSeparator c -> Just cs
|
| 1061 | 1075 | _ -> Nothing
|
| 1062 | 1076 | |
| 1063 | --- -----------------------------------------------------------------------------
|
|
| 1064 | --- Workaround for old single-file style package dbs
|
|
| 1065 | - |
|
| 1066 | --- Single-file style package dbs have been deprecated for some time, but
|
|
| 1067 | --- it turns out that Cabal was using them in one place. So this code is for a
|
|
| 1068 | --- workaround to allow older Cabal versions to use this newer ghc.
|
|
| 1069 | - |
|
| 1070 | --- We check if the file db contains just "[]" and if so, we look for a new
|
|
| 1071 | --- dir-style db in path.d/, ie in a dir next to the given file.
|
|
| 1072 | --- We cannot just replace the file with a new dir style since Cabal still
|
|
| 1073 | --- assumes it's a file and tries to overwrite with 'writeFile'.
|
|
| 1074 | - |
|
| 1075 | --- ghc itself also cooperates in this workaround
|
|
| 1076 | - |
|
| 1077 | -tryReadParseOldFileStyleDatabase :: Verbosity -> Maybe (FilePath, Bool)
|
|
| 1078 | - -> GhcPkg.DbOpenMode mode t -> Bool -> FilePath
|
|
| 1079 | - -> IO (Maybe (PackageDB mode))
|
|
| 1080 | -tryReadParseOldFileStyleDatabase verbosity mb_user_conf
|
|
| 1081 | - mode use_cache path = do
|
|
| 1082 | - -- assumes we've already established that path exists and is not a dir
|
|
| 1083 | - content <- readFile path `catchIO` \_ -> return ""
|
|
| 1084 | - if take 2 content == "[]"
|
|
| 1085 | - then do
|
|
| 1086 | - path_abs <- absolutePath path
|
|
| 1087 | - let path_dir = adjustOldDatabasePath path
|
|
| 1088 | - warn $ "Warning: ignoring old file-style db and trying " ++ path_dir
|
|
| 1089 | - direxists <- doesDirectoryExist path_dir
|
|
| 1090 | - if direxists
|
|
| 1091 | - then do
|
|
| 1092 | - db <- readParseDatabase verbosity mb_user_conf mode use_cache path_dir
|
|
| 1093 | - -- but pretend it was at the original location
|
|
| 1094 | - return $ Just db {
|
|
| 1095 | - location = path,
|
|
| 1096 | - locationAbsolute = path_abs
|
|
| 1097 | - }
|
|
| 1098 | - else do
|
|
| 1099 | - lock <- F.forM mode $ \_ -> do
|
|
| 1100 | - createDirectoryIfMissing True path_dir
|
|
| 1101 | - GhcPkg.lockPackageDb $ path_dir </> cachefilename
|
|
| 1102 | - return $ Just PackageDB {
|
|
| 1103 | - location = path,
|
|
| 1104 | - locationAbsolute = path_abs,
|
|
| 1105 | - packageDbLock = lock,
|
|
| 1106 | - packages = []
|
|
| 1107 | - }
|
|
| 1108 | - |
|
| 1109 | - -- if the path is not a file, or is not an empty db then we fail
|
|
| 1110 | - else return Nothing
|
|
| 1111 | - |
|
| 1077 | +-- | Just preserved to give a more informative error
|
|
| 1112 | 1078 | adjustOldFileStylePackageDB :: PackageDB mode -> IO (PackageDB mode)
|
| 1113 | 1079 | adjustOldFileStylePackageDB db = do
|
| 1114 | 1080 | -- assumes we have not yet established if it's an old style or not
|
| 1115 | 1081 | mcontent <- liftM Just (readFile (location db)) `catchIO` \_ -> return Nothing
|
| 1116 | - case fmap (take 2) mcontent of
|
|
| 1082 | + case mcontent of
|
|
| 1117 | 1083 | -- it is an old style and empty db, so look for a dir kind in location.d/
|
| 1118 | - Just "[]" -> return db {
|
|
| 1119 | - location = adjustOldDatabasePath $ location db,
|
|
| 1120 | - locationAbsolute = adjustOldDatabasePath $ locationAbsolute db
|
|
| 1121 | - }
|
|
| 1122 | - -- it is old style but not empty, we have to bail
|
|
| 1123 | - Just _ -> die $ "ghc no longer supports single-file style package "
|
|
| 1124 | - ++ "databases (" ++ location db ++ ") use 'ghc-pkg init'"
|
|
| 1125 | - ++ "to create the database with the correct format."
|
|
| 1126 | - -- probably not old style, carry on as normal
|
|
| 1084 | + Just _ -> dieOnSingleFileDb (location db)
|
|
| 1127 | 1085 | Nothing -> return db
|
| 1128 | 1086 | |
| 1129 | -adjustOldDatabasePath :: FilePath -> FilePath
|
|
| 1130 | -adjustOldDatabasePath = (<.> "d")
|
|
| 1131 | - |
|
| 1132 | 1087 | -- -----------------------------------------------------------------------------
|
| 1133 | 1088 | -- Creating a new package DB
|
| 1134 | 1089 | |
| ... | ... | @@ -2289,3 +2244,9 @@ removeFileSafe fn = |
| 2289 | 2244 | -- absolute path.
|
| 2290 | 2245 | absolutePath :: FilePath -> IO FilePath
|
| 2291 | 2246 | absolutePath path = return . normalise . (</> path) =<< getCurrentDirectory
|
| 2247 | + |
|
| 2248 | +dieOnSingleFileDb :: FilePath -> IO a
|
|
| 2249 | +dieOnSingleFileDb path =
|
|
| 2250 | + die $ "ghc no longer supports single-file style package "
|
|
| 2251 | + ++ "databases (" ++ path ++ ") use 'ghc-pkg init'"
|
|
| 2252 | + ++ "to create the database with the correct format." |
|
| \ No newline at end of file |