summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorDuncan Coutts <duncan@well-typed.com>2015-02-09 13:46:06 -0600
committerAustin Seipp <austin@well-typed.com>2015-02-09 21:07:26 -0600
commita1db53cc6ea03d80f097c550bae277141b03ac30 (patch)
tree494961cd3fa846354040561f7d40bbd9672ede90 /utils
parentde9a836cd920722a4c28dcb464ff2c8d5905acb9 (diff)
downloadhaskell-a1db53cc6ea03d80f097c550bae277141b03ac30.tar.gz
Add a workaround to allow older cabal-install to use ghc-7.10
Summary: This should smooth the upgrade process for people and help with testing the 7.10 RCs. Otherwise people need to first install cabal-install-1.22 before they can use 7.10. The problem is that older cabal still used file-style package dbs for the inplace package db when building packages. The workaround is that both ghc and ghc-pkg will notice when cabal tells them to use a file style db e.g. "dist/package.conf.inplace" and, so long as that db is empty (ie content is []) then they'll instead us a dir style db with the same name but ".d" appended, so in this example that would be "dist/package.conf.inplace.d". We have to use a separate dir rather than transparently upgrading because old Cabal really assumes the path is a file, and if it encounters a dir it will fail. This seems to be enough for older Cabal to work, and may well be enough for other scripts that create dbs using "echo [] > package.conf". Test Plan: validate and check new and old cabal can sucessfully install things, including packages that have internal deps (ie using the inplace db) Reviewers: hvr, tibbe, austin Reviewed By: tibbe, austin Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D628
Diffstat (limited to 'utils')
-rw-r--r--utils/ghc-pkg/Main.hs82
1 files changed, 76 insertions, 6 deletions
diff --git a/utils/ghc-pkg/Main.hs b/utils/ghc-pkg/Main.hs
index 0493866e32..b2815b80a5 100644
--- a/utils/ghc-pkg/Main.hs
+++ b/utils/ghc-pkg/Main.hs
@@ -680,10 +680,18 @@ readParseDatabase verbosity mb_user_conf modify use_cache path
= do e <- tryIO $ getDirectoryContents path
case e of
Left err
- | ioeGetErrorType err == InappropriateType ->
- die ("ghc no longer supports single-file style package databases "
- ++ "(" ++ path ++ ") use 'ghc-pkg init' to create the database "
- ++ "with the correct format.")
+ | ioeGetErrorType err == InappropriateType -> do
+ -- We provide a limited degree of backwards compatibility for
+ -- old single-file style db:
+ mdb <- tryReadParseOldFileStyleDatabase verbosity
+ mb_user_conf modify use_cache path
+ case mdb of
+ Just db -> return db
+ Nothing ->
+ die $ "ghc no longer supports single-file style package "
+ ++ "databases (" ++ path ++ ") use 'ghc-pkg init'"
+ ++ "to create the database with the correct format."
+
| otherwise -> ioError err
Right fs
| not use_cache -> ignore_cache (const $ return ())
@@ -823,6 +831,67 @@ mungePackagePaths top_dir pkgroot pkg =
-- -----------------------------------------------------------------------------
+-- Workaround for old single-file style package dbs
+
+-- Single-file style package dbs have been deprecated for some time, but
+-- it turns out that Cabal was using them in one place. So this code is for a
+-- workaround to allow older Cabal versions to use this newer ghc.
+
+-- We check if the file db contains just "[]" and if so, we look for a new
+-- dir-style db in path.d/, ie in a dir next to the given file.
+-- We cannot just replace the file with a new dir style since Cabal still
+-- assumes it's a file and tries to overwrite with 'writeFile'.
+
+-- ghc itself also cooperates in this workaround
+
+tryReadParseOldFileStyleDatabase :: Verbosity -> Maybe (FilePath, Bool)
+ -> Bool -> Bool -> FilePath
+ -> IO (Maybe PackageDB)
+tryReadParseOldFileStyleDatabase verbosity mb_user_conf modify use_cache path = do
+ -- assumes we've already established that path exists and is not a dir
+ content <- readFile path `catchIO` \_ -> return ""
+ if take 2 content == "[]"
+ then do
+ path_abs <- absolutePath path
+ let path_dir = path <.> "d"
+ warn $ "Warning: ignoring old file-style db and trying " ++ path_dir
+ direxists <- doesDirectoryExist path_dir
+ if direxists
+ then do db <- readParseDatabase verbosity mb_user_conf
+ modify use_cache path_dir
+ -- but pretend it was at the original location
+ return $ Just db {
+ location = path,
+ locationAbsolute = path_abs
+ }
+ else return $ Just PackageDB {
+ location = path,
+ locationAbsolute = path_abs,
+ packages = []
+ }
+
+ -- if the path is not a file, or is not an empty db then we fail
+ else return Nothing
+
+adjustOldFileStylePackageDB :: PackageDB -> IO PackageDB
+adjustOldFileStylePackageDB db = do
+ -- assumes we have not yet established if it's an old style or not
+ mcontent <- liftM Just (readFile (location db)) `catchIO` \_ -> return Nothing
+ case fmap (take 2) mcontent of
+ -- it is an old style and empty db, so look for a dir kind in location.d/
+ Just "[]" -> return db {
+ location = location db <.> "d",
+ locationAbsolute = locationAbsolute db <.> "d"
+ }
+ -- it is old style but not empty, we have to bail
+ Just _ -> die $ "ghc no longer supports single-file style package "
+ ++ "databases (" ++ location db ++ ") use 'ghc-pkg init'"
+ ++ "to create the database with the correct format."
+ -- probably not old style, carry on as normal
+ Nothing -> return db
+
+
+-- -----------------------------------------------------------------------------
-- Creating a new package DB
initPackageDB :: FilePath -> Verbosity -> [Flag] -> IO ()
@@ -941,8 +1010,9 @@ data DBOp = RemovePackage InstalledPackageInfo
changeDB :: Verbosity -> [DBOp] -> PackageDB -> IO ()
changeDB verbosity cmds db = do
let db' = updateInternalDB db cmds
- createDirectoryIfMissing True (location db)
- changeDBDir verbosity cmds db'
+ db'' <- adjustOldFileStylePackageDB db'
+ createDirectoryIfMissing True (location db'')
+ changeDBDir verbosity cmds db''
updateInternalDB :: PackageDB -> [DBOp] -> PackageDB
updateInternalDB db cmds = db{ packages = foldl do_cmd (packages db) cmds }