diff options
author | Duncan Coutts <duncan@well-typed.com> | 2015-02-09 13:46:06 -0600 |
---|---|---|
committer | Austin Seipp <austin@well-typed.com> | 2015-02-09 21:07:26 -0600 |
commit | a1db53cc6ea03d80f097c550bae277141b03ac30 (patch) | |
tree | 494961cd3fa846354040561f7d40bbd9672ede90 /utils | |
parent | de9a836cd920722a4c28dcb464ff2c8d5905acb9 (diff) | |
download | haskell-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.hs | 82 |
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 } |