Hannes Siebenhandl pushed to branch wip/fendor/ghc-pkg-ospath at Glasgow Haskell Compiler / GHC

Commits:

5 changed files:

Changes:

  • compiler/GHC/Unit/State.hs
    ... ... @@ -802,7 +802,7 @@ readUnitDatabase logger cfg conf_file = do
    802 802
           if cache_exists
    
    803 803
             then do
    
    804 804
               debugTraceMsg logger 2 $ text "Using binary package database:" <+> ppr filename
    
    805
    -          readPackageDbForGhc (OsPath.unsafeDecodeUtf filename)
    
    805
    +          readPackageDbForGhc filename
    
    806 806
             else do
    
    807 807
               -- If there is no package.cache file, we check if the database is not
    
    808 808
               -- empty by inspecting if the directory contains any .conf file. If it
    

  • libraries/ghc-boot/GHC/Unit/Database.hs
    ... ... @@ -68,6 +68,7 @@ module GHC.Unit.Database
    68 68
        -- * Misc
    
    69 69
        , mkMungePathUrl
    
    70 70
        , mungeUnitInfoPaths
    
    71
    +   , writeFileAtomic
    
    71 72
        )
    
    72 73
     where
    
    73 74
     
    
    ... ... @@ -86,10 +87,10 @@ import Data.Binary.Get as Bin
    86 87
     import Data.List (intersperse)
    
    87 88
     import Control.Exception as Exception
    
    88 89
     import Control.Monad (when)
    
    89
    -import System.FilePath as FilePath
    
    90
    +import qualified System.FilePath as FilePath
    
    90 91
     #if !defined(mingw32_HOST_OS)
    
    91 92
     import Data.Bits ((.|.))
    
    92
    -import System.Posix.Files
    
    93
    +import System.Posix.Files.PosixString
    
    93 94
     import System.Posix.Types (FileMode)
    
    94 95
     #endif
    
    95 96
     import System.IO
    
    ... ... @@ -97,7 +98,12 @@ import System.IO.Error
    97 98
     import GHC.IO.Exception (IOErrorType(InappropriateType))
    
    98 99
     import qualified GHC.Data.ShortText as ST
    
    99 100
     import GHC.IO.Handle.Lock
    
    100
    -import System.Directory
    
    101
    +import System.OsPath (OsPath)
    
    102
    +import System.OsString.Internal.Types (getOsString)
    
    103
    +import qualified System.OsPath as OsPath
    
    104
    +import qualified System.Directory.OsPath as OsPath
    
    105
    +import qualified System.Directory.Internal as OsPath.Internal
    
    106
    +import qualified System.File.OsPath as FileIO
    
    101 107
     
    
    102 108
     -- | @ghc-boot@'s UnitInfo, serialized to the database.
    
    103 109
     type DbUnitInfo      = GenericUnitInfo BS.ByteString BS.ByteString BS.ByteString BS.ByteString DbModule
    
    ... ... @@ -314,13 +320,13 @@ data DbInstUnitId
    314 320
     newtype PackageDbLock = PackageDbLock Handle
    
    315 321
     
    
    316 322
     -- | Acquire an exclusive lock related to package DB under given location.
    
    317
    -lockPackageDb :: FilePath -> IO PackageDbLock
    
    323
    +lockPackageDb :: OsPath -> IO PackageDbLock
    
    318 324
     
    
    319 325
     -- | Release the lock related to package DB.
    
    320 326
     unlockPackageDb :: PackageDbLock -> IO ()
    
    321 327
     
    
    322 328
     -- | Acquire a lock of given type related to package DB under given location.
    
    323
    -lockPackageDbWith :: LockMode -> FilePath -> IO PackageDbLock
    
    329
    +lockPackageDbWith :: LockMode -> OsPath -> IO PackageDbLock
    
    324 330
     lockPackageDbWith mode file = do
    
    325 331
       -- We are trying to open the lock file and then lock it. Thus the lock file
    
    326 332
       -- needs to either exist or we need to be able to create it. Ideally we
    
    ... ... @@ -350,10 +356,10 @@ lockPackageDbWith mode file = do
    350 356
         (lockFileOpenIn ReadWriteMode)
    
    351 357
         (const $ lockFileOpenIn ReadMode)
    
    352 358
       where
    
    353
    -    lock = file <.> "lock"
    
    359
    +    lock = file OsPath.<.> OsPath.Internal.os "lock"
    
    354 360
     
    
    355 361
         lockFileOpenIn io_mode = bracketOnError
    
    356
    -      (openBinaryFile lock io_mode)
    
    362
    +      (FileIO.openBinaryFile lock io_mode)
    
    357 363
           hClose
    
    358 364
           -- If file locking support is not available, ignore the error and proceed
    
    359 365
           -- normally. Without it the only thing we lose on non-Windows platforms is
    
    ... ... @@ -387,7 +393,7 @@ isDbOpenReadMode = \case
    387 393
     
    
    388 394
     -- | Read the part of the package DB that GHC is interested in.
    
    389 395
     --
    
    390
    -readPackageDbForGhc :: FilePath -> IO [DbUnitInfo]
    
    396
    +readPackageDbForGhc :: OsPath -> IO [DbUnitInfo]
    
    391 397
     readPackageDbForGhc file =
    
    392 398
       decodeFromFile file DbOpenReadOnly getDbForGhc >>= \case
    
    393 399
         (pkgs, DbOpenReadOnly) -> return pkgs
    
    ... ... @@ -409,7 +415,7 @@ readPackageDbForGhc file =
    409 415
     -- we additionally receive a PackageDbLock that represents a lock on the
    
    410 416
     -- database, so that we can safely update it later.
    
    411 417
     --
    
    412
    -readPackageDbForGhcPkg :: Binary pkgs => FilePath -> DbOpenMode mode t ->
    
    418
    +readPackageDbForGhcPkg :: Binary pkgs => OsPath -> DbOpenMode mode t ->
    
    413 419
                               IO (pkgs, DbOpenMode mode PackageDbLock)
    
    414 420
     readPackageDbForGhcPkg file mode =
    
    415 421
         decodeFromFile file mode getDbForGhcPkg
    
    ... ... @@ -425,7 +431,7 @@ readPackageDbForGhcPkg file mode =
    425 431
     
    
    426 432
     -- | Write the whole of the package DB, both parts.
    
    427 433
     --
    
    428
    -writePackageDb :: Binary pkgs => FilePath -> [DbUnitInfo] -> pkgs -> IO ()
    
    434
    +writePackageDb :: Binary pkgs => OsPath -> [DbUnitInfo] -> pkgs -> IO ()
    
    429 435
     writePackageDb file ghcPkgs ghcPkgPart = do
    
    430 436
       writeFileAtomic file (runPut putDbForGhcPkg)
    
    431 437
     #if !defined(mingw32_HOST_OS)
    
    ... ... @@ -446,10 +452,10 @@ writePackageDb file ghcPkgs ghcPkgPart = do
    446 452
             ghcPart    = encode ghcPkgs
    
    447 453
     
    
    448 454
     #if !defined(mingw32_HOST_OS)
    
    449
    -addFileMode :: FilePath -> FileMode -> IO ()
    
    455
    +addFileMode :: OsPath -> FileMode -> IO ()
    
    450 456
     addFileMode file m = do
    
    451
    -  o <- fileMode <$> getFileStatus file
    
    452
    -  setFileMode file (m .|. o)
    
    457
    +  o <- fileMode <$> getFileStatus (getOsString file)
    
    458
    +  setFileMode (getOsString file) (m .|. o)
    
    453 459
     #endif
    
    454 460
     
    
    455 461
     getHeader :: Get (Word32, Word32)
    
    ... ... @@ -496,7 +502,7 @@ headerMagic = BS.Char8.pack "\0ghcpkg\0"
    496 502
     
    
    497 503
     -- | Feed a 'Get' decoder with data chunks from a file.
    
    498 504
     --
    
    499
    -decodeFromFile :: FilePath -> DbOpenMode mode t -> Get pkgs ->
    
    505
    +decodeFromFile :: OsPath -> DbOpenMode mode t -> Get pkgs ->
    
    500 506
                       IO (pkgs, DbOpenMode mode PackageDbLock)
    
    501 507
     decodeFromFile file mode decoder = case mode of
    
    502 508
       DbOpenReadOnly -> do
    
    ... ... @@ -517,7 +523,7 @@ decodeFromFile file mode decoder = case mode of
    517 523
         bracketOnError (lockPackageDb file) unlockPackageDb $ \lock -> do
    
    518 524
           (, DbOpenReadWrite lock) <$> decodeFileContents
    
    519 525
       where
    
    520
    -    decodeFileContents = withBinaryFile file ReadMode $ \hnd ->
    
    526
    +    decodeFileContents = FileIO.withBinaryFile file ReadMode $ \hnd ->
    
    521 527
           feed hnd (runGetIncremental decoder)
    
    522 528
     
    
    523 529
         feed hnd (Partial k)  = do chunk <- BS.hGet hnd BS.Lazy.defaultChunkSize
    
    ... ... @@ -527,21 +533,21 @@ decodeFromFile file mode decoder = case mode of
    527 533
         feed _ (Done _ _ res) = return res
    
    528 534
         feed _ (Fail _ _ msg) = ioError err
    
    529 535
           where
    
    530
    -        err = mkIOError InappropriateType loc Nothing (Just file)
    
    536
    +        err = mkIOError InappropriateType loc Nothing (Just $ OsPath.Internal.so file)
    
    531 537
                   `ioeSetErrorString` msg
    
    532 538
             loc = "GHC.Unit.Database.readPackageDb"
    
    533 539
     
    
    534 540
     -- Copied from Cabal's Distribution.Simple.Utils.
    
    535
    -writeFileAtomic :: FilePath -> BS.Lazy.ByteString -> IO ()
    
    541
    +writeFileAtomic :: OsPath -> BS.Lazy.ByteString -> IO ()
    
    536 542
     writeFileAtomic targetPath content = do
    
    537
    -  let (targetDir, targetFile) = splitFileName targetPath
    
    543
    +  let (targetDir, targetFile) = OsPath.splitFileName targetPath
    
    538 544
       Exception.bracketOnError
    
    539
    -    (openBinaryTempFileWithDefaultPermissions targetDir $ targetFile <.> "tmp")
    
    540
    -    (\(tmpPath, handle) -> hClose handle >> removeFile tmpPath)
    
    545
    +    (FileIO.openBinaryTempFileWithDefaultPermissions targetDir $ targetFile OsPath.<.> OsPath.Internal.os "tmp")
    
    546
    +    (\(tmpPath, handle) -> hClose handle >> OsPath.removeFile tmpPath)
    
    541 547
         (\(tmpPath, handle) -> do
    
    542 548
             BS.Lazy.hPut handle content
    
    543 549
             hClose handle
    
    544
    -        renameFile tmpPath targetPath)
    
    550
    +        OsPath.renameFile tmpPath targetPath)
    
    545 551
     
    
    546 552
     instance Binary DbUnitInfo where
    
    547 553
       put (GenericUnitInfo
    
    ... ... @@ -711,7 +717,7 @@ mkMungePathUrl top_dir pkgroot = (munge_path, munge_url)
    711 717
         -- rather than letting FilePath change it to use \ as the separator
    
    712 718
         stripVarPrefix var path = case ST.stripPrefix var path of
    
    713 719
                                   Just "" -> Just ""
    
    714
    -                              Just cs | isPathSeparator (ST.head cs) -> Just cs
    
    720
    +                              Just cs | FilePath.isPathSeparator (ST.head cs) -> Just cs
    
    715 721
                                   _ -> Nothing
    
    716 722
     
    
    717 723
     
    

  • libraries/ghc-boot/ghc-boot.cabal.in
    ... ... @@ -81,6 +81,8 @@ Library
    81 81
                        containers >= 0.5 && < 0.9,
    
    82 82
                        directory  >= 1.2 && < 1.4,
    
    83 83
                        filepath   >= 1.3 && < 1.6,
    
    84
    +                   file-io,
    
    85
    +                   os-string,
    
    84 86
                        deepseq    >= 1.4 && < 1.6,
    
    85 87
                        ghc-platform  >= 0.1,
    
    86 88
                        ghc-toolchain >= 0.1
    

  • utils/ghc-pkg/Main.hs
    ... ... @@ -47,12 +47,19 @@ import Distribution.Types.UnqualComponentName
    47 47
     import Distribution.Types.LibraryName
    
    48 48
     import Distribution.Types.MungedPackageName
    
    49 49
     import Distribution.Types.MungedPackageId
    
    50
    -import Distribution.Simple.Utils (toUTF8BS, writeUTF8File, readUTF8File)
    
    50
    +import Distribution.Simple.Utils (ignoreBOM, toUTF8BS, toUTF8LBS, fromUTF8LBS)
    
    51 51
     import qualified Data.Version as Version
    
    52
    -import System.FilePath as FilePath
    
    52
    +import System.OsPath as OsPath
    
    53
    +import qualified System.FilePath as FilePath
    
    53 54
     import qualified System.FilePath.Posix as FilePath.Posix
    
    54
    -import System.Directory ( getXdgDirectory, createDirectoryIfMissing, getAppUserDataDirectory,
    
    55
    -                          getModificationTime, XdgDirectory ( XdgData ) )
    
    55
    +import System.Directory.OsPath
    
    56
    +  ( getXdgDirectory, createDirectoryIfMissing, getAppUserDataDirectory,
    
    57
    +    getModificationTime, XdgDirectory ( XdgData ),
    
    58
    +    doesDirectoryExist, getDirectoryContents,
    
    59
    +    doesFileExist, removeFile,
    
    60
    +    getCurrentDirectory )
    
    61
    +import System.Directory.Internal (os, so)
    
    62
    +import qualified System.File.OsPath as FileIO
    
    56 63
     import Text.Printf
    
    57 64
     
    
    58 65
     import Prelude hiding (Foldable(..))
    
    ... ... @@ -65,9 +72,6 @@ import Data.Bifunctor
    65 72
     
    
    66 73
     import Data.Char ( toLower )
    
    67 74
     import Control.Monad
    
    68
    -import System.Directory ( doesDirectoryExist, getDirectoryContents,
    
    69
    -                          doesFileExist, removeFile,
    
    70
    -                          getCurrentDirectory )
    
    71 75
     import System.Exit ( exitWith, ExitCode(..) )
    
    72 76
     import System.Environment ( getArgs, getProgName, getEnv )
    
    73 77
     import System.IO
    
    ... ... @@ -430,7 +434,7 @@ runit verbosity cli nonopts = do
    430 434
             glob filename >>= print
    
    431 435
     #endif
    
    432 436
         ["init", filename] ->
    
    433
    -        initPackageDB filename verbosity cli
    
    437
    +        initPackageDB (os filename) verbosity cli
    
    434 438
         ["register", filename] ->
    
    435 439
             registerPackage filename verbosity cli
    
    436 440
                             multi_instance
    
    ... ... @@ -538,7 +542,7 @@ readPackageArg AsDefault str = Id <$> readGlobPkgId str
    538 542
     
    
    539 543
     data PackageDB (mode :: GhcPkg.DbMode)
    
    540 544
       = PackageDB {
    
    541
    -      location, locationAbsolute :: !FilePath,
    
    545
    +      location, locationAbsolute :: !OsPath,
    
    542 546
           -- We need both possibly-relative and definitely-absolute package
    
    543 547
           -- db locations. This is because the relative location is used as
    
    544 548
           -- an identifier for the db, so it is important we do not modify it.
    
    ... ... @@ -570,14 +574,14 @@ allPackagesInStack = concatMap packages
    570 574
     -- specified package DB can depend on, since dependencies can only extend
    
    571 575
     -- down the stack, not up (e.g. global packages cannot depend on user
    
    572 576
     -- packages).
    
    573
    -stackUpTo :: FilePath -> PackageDBStack -> PackageDBStack
    
    577
    +stackUpTo :: OsPath -> PackageDBStack -> PackageDBStack
    
    574 578
     stackUpTo to_modify = dropWhile ((/= to_modify) . location)
    
    575 579
     
    
    576
    -readFromSettingsFile :: FilePath
    
    577
    -                      -> (FilePath -> RawSettings -> Either String b)
    
    580
    +readFromSettingsFile :: OsPath
    
    581
    +                      -> (OsPath -> RawSettings -> Either String b)
    
    578 582
                           -> IO (Either String b)
    
    579 583
     readFromSettingsFile settingsFile f = do
    
    580
    -  settingsStr <- readFile settingsFile
    
    584
    +  settingsStr <- readUtf8File settingsFile
    
    581 585
       pure $ do
    
    582 586
         mySettings <- case maybeReadFuzzy settingsStr of
    
    583 587
           Just s -> pure $ Map.fromList s
    
    ... ... @@ -586,11 +590,11 @@ readFromSettingsFile settingsFile f = do
    586 590
           Nothing -> Left $ "Can't parse settings file " ++ show settingsFile
    
    587 591
         f settingsFile mySettings
    
    588 592
     
    
    589
    -readFromTargetFile :: FilePath
    
    593
    +readFromTargetFile :: OsPath
    
    590 594
                        -> (Target -> b)
    
    591 595
                        -> IO (Either String b)
    
    592 596
     readFromTargetFile targetFile f = do
    
    593
    -  targetStr <- readFile targetFile
    
    597
    +  targetStr <- readUtf8File targetFile
    
    594 598
       pure $ do
    
    595 599
         target <- case maybeReadFuzzy targetStr of
    
    596 600
           Just t -> Right t
    
    ... ... @@ -626,33 +630,33 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    626 630
          case [ f | FlagGlobalConfig f <- my_flags ] of
    
    627 631
             -- See Note [Base Dir] for more information on the base dir / top dir.
    
    628 632
             [] -> do mb_dir <- getBaseDir
    
    629
    -                 case mb_dir of
    
    633
    +                 case fmap os mb_dir of
    
    630 634
                        Nothing  -> die err_msg
    
    631 635
                        Just dir -> do
    
    632 636
                          -- Look for where it is given in the settings file, if marked there.
    
    633 637
                          -- See Note [Settings file] about this file, and why we need GHC to share it with us.
    
    634
    -                     let settingsFile = dir </> "settings"
    
    638
    +                     let settingsFile = dir </> os "settings"
    
    635 639
                          exists_settings_file <- doesFileExist settingsFile
    
    636 640
                          erel_db <-
    
    637 641
                           if exists_settings_file
    
    638
    -                          then readFromSettingsFile settingsFile getGlobalPackageDb
    
    639
    -                          else pure (Left ("Settings file doesn't exist: " ++ settingsFile))
    
    642
    +                          then readFromSettingsFile settingsFile (\ ospath -> getGlobalPackageDb (so ospath))
    
    643
    +                          else pure (Left ("Settings file doesn't exist: " ++ show settingsFile))
    
    640 644
     
    
    641 645
                          case erel_db of
    
    642
    -                      Right rel_db -> return (dir, dir </> rel_db)
    
    646
    +                      Right rel_db -> return (dir, dir </> os rel_db)
    
    643 647
                           -- If the version of GHC doesn't have this field or the settings file
    
    644 648
                           -- doesn't exist for some reason, look in the libdir.
    
    645 649
                           Left err -> do
    
    646 650
                             r <- lookForPackageDBIn dir
    
    647 651
                             case r of
    
    648
    -                          Nothing -> die (unlines [err, ("Fallback: Can't find package database in " ++ dir)])
    
    652
    +                          Nothing -> die (unlines [err, ("Fallback: Can't find package database in " ++ show dir)])
    
    649 653
                               Just path -> return (dir, path)
    
    650 654
             fs -> do
    
    651 655
               -- The value of the $topdir variable used in some package descriptions
    
    652 656
               -- Note that the way we calculate this is slightly different to how it
    
    653 657
               -- is done in ghc itself. We rely on the convention that the global
    
    654 658
               -- package db lives in ghc's libdir.
    
    655
    -          let pkg_db = last fs
    
    659
    +          let pkg_db = os $ last fs
    
    656 660
               top_dir <- absolutePath (takeDirectory pkg_db)
    
    657 661
               return (top_dir, pkg_db)
    
    658 662
     
    
    ... ... @@ -662,10 +666,10 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    662 666
       -- getXdgDirectory can fail (e.g. if $HOME isn't set)
    
    663 667
     
    
    664 668
       mb_user_conf <-
    
    665
    -    case [ f | FlagUserConfig f <- my_flags ] of
    
    669
    +    case [ os f | FlagUserConfig f <- my_flags ] of
    
    666 670
           _ | no_user_db -> return Nothing
    
    667 671
           [] -> do
    
    668
    -        let targetFile = top_dir </> "targets" </> "default.target"
    
    672
    +        let targetFile = top_dir </> os "targets" </> os "default.target"
    
    669 673
             exists_settings_file <- doesFileExist targetFile
    
    670 674
             targetArchOS <- case exists_settings_file of
    
    671 675
               False -> do
    
    ... ... @@ -694,15 +698,15 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    694 698
             -- otherwise we use $XDG_DATA_HOME/$UNIQUE_SUBDIR
    
    695 699
             --
    
    696 700
             -- UNIQUE_SUBDIR is typically a combination of the target platform and GHC version
    
    697
    -        m_appdir <- getFirstSuccess $ map (fmap (</> subdir))
    
    698
    -          [ getAppUserDataDirectory "ghc"  -- this is ~/.ghc/
    
    699
    -          , getXdgDirectory XdgData "ghc"  -- this is $XDG_DATA_HOME/
    
    701
    +        m_appdir <- getFirstSuccess $ map (fmap (</> os subdir))
    
    702
    +          [ getAppUserDataDirectory $ os "ghc"  -- this is ~/.ghc/
    
    703
    +          , getXdgDirectory XdgData $ os "ghc"  -- this is $XDG_DATA_HOME/
    
    700 704
               ]
    
    701 705
             case m_appdir of
    
    702 706
               Nothing -> return Nothing
    
    703 707
               Just dir -> do
    
    704 708
                 lookForPackageDBIn dir >>= \case
    
    705
    -              Nothing -> return (Just (dir </> "package.conf.d", False))
    
    709
    +              Nothing -> return (Just (dir </> os "package.conf.d", False))
    
    706 710
                   Just f  -> return (Just (f, True))
    
    707 711
           fs -> return (Just (last fs, True))
    
    708 712
     
    
    ... ... @@ -716,11 +720,11 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    716 720
     
    
    717 721
       e_pkg_path <- tryIO (System.Environment.getEnv "GHC_PACKAGE_PATH")
    
    718 722
       let env_stack =
    
    719
    -        case e_pkg_path of
    
    723
    +        case fmap os e_pkg_path of
    
    720 724
                     Left  _ -> sys_databases
    
    721 725
                     Right path
    
    722
    -                  | not (null path) && isSearchPathSeparator (last path)
    
    723
    -                  -> splitSearchPath (init path) ++ sys_databases
    
    726
    +                  | hasTrailingPathSeparator path
    
    727
    +                  -> splitSearchPath (dropTrailingPathSeparator path) <> sys_databases
    
    724 728
                       | otherwise
    
    725 729
                       -> splitSearchPath path
    
    726 730
     
    
    ... ... @@ -733,7 +737,7 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    733 737
                           | Just (user_conf, _user_exists) <- mb_user_conf
    
    734 738
                           = Just user_conf
    
    735 739
                    is_db_flag FlagGlobal     = Just virt_global_conf
    
    736
    -               is_db_flag (FlagConfig f) = Just f
    
    740
    +               is_db_flag (FlagConfig f) = Just $ os f
    
    737 741
                    is_db_flag _              = Nothing
    
    738 742
     
    
    739 743
       let flag_db_names | null db_flags = env_stack
    
    ... ... @@ -748,7 +752,7 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    748 752
       -- stack, unless any of them are present in the stack
    
    749 753
       -- already.
    
    750 754
       let final_stack = filter (`notElem` env_stack)
    
    751
    -                     [ f | FlagConfig f <- reverse my_flags ]
    
    755
    +                     [ os f | FlagConfig f <- reverse my_flags ]
    
    752 756
                          ++ env_stack
    
    753 757
     
    
    754 758
           top_db = if null db_flags
    
    ... ... @@ -764,7 +768,7 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    764 768
       when (verbosity > Normal) $ do
    
    765 769
         infoLn ("db stack: " ++ show (map location db_stack))
    
    766 770
         F.forM_ db_to_operate_on $ \db ->
    
    767
    -      infoLn ("modifying: " ++ (location db))
    
    771
    +      infoLn ("modifying: " ++ show (location db))
    
    768 772
         infoLn ("flag db stack: " ++ show (map location flag_db_stack))
    
    769 773
     
    
    770 774
       return (db_stack, db_to_operate_on, flag_db_stack)
    
    ... ... @@ -843,12 +847,12 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    843 847
     
    
    844 848
             return (db_stack, GhcPkg.DbOpenReadWrite to_modify)
    
    845 849
           where
    
    846
    -        couldntOpenDbForModification :: FilePath -> IOError -> IO a
    
    850
    +        couldntOpenDbForModification :: OsPath -> IOError -> IO a
    
    847 851
             couldntOpenDbForModification db_path e = die $ "Couldn't open database "
    
    848
    -          ++ db_path ++ " for modification: " ++ show e
    
    852
    +          ++ show db_path ++ " for modification: " ++ show e
    
    849 853
     
    
    850 854
             -- Parse package db in read-only mode.
    
    851
    -        readDatabase :: FilePath -> IO (PackageDB 'GhcPkg.DbReadOnly)
    
    855
    +        readDatabase :: OsPath -> IO (PackageDB 'GhcPkg.DbReadOnly)
    
    852 856
             readDatabase db_path = do
    
    853 857
               db <- readParseDatabase verbosity mb_user_conf
    
    854 858
                                       GhcPkg.DbOpenReadOnly use_cache db_path
    
    ... ... @@ -863,20 +867,20 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
    863 867
           (as, s'') <- stateSequence s' ms
    
    864 868
           return (a : as, s'')
    
    865 869
     
    
    866
    -lookForPackageDBIn :: FilePath -> IO (Maybe FilePath)
    
    870
    +lookForPackageDBIn :: OsPath -> IO (Maybe OsPath)
    
    867 871
     lookForPackageDBIn dir = do
    
    868
    -  let path_dir = dir </> "package.conf.d"
    
    872
    +  let path_dir = dir </> os "package.conf.d"
    
    869 873
       exists_dir <- doesDirectoryExist path_dir
    
    870 874
       if exists_dir then return (Just path_dir) else do
    
    871
    -    let path_file = dir </> "package.conf"
    
    875
    +    let path_file = dir </> os "package.conf"
    
    872 876
         exists_file <- doesFileExist path_file
    
    873 877
         if exists_file then return (Just path_file) else return Nothing
    
    874 878
     
    
    875 879
     readParseDatabase :: forall mode t. Verbosity
    
    876
    -                  -> Maybe (FilePath,Bool)
    
    880
    +                  -> Maybe (OsPath,Bool)
    
    877 881
                       -> GhcPkg.DbOpenMode mode t
    
    878 882
                       -> Bool -- use cache
    
    879
    -                  -> FilePath
    
    883
    +                  -> OsPath
    
    880 884
                       -> IO (PackageDB mode)
    
    881 885
     readParseDatabase verbosity mb_user_conf mode use_cache path
    
    882 886
       -- the user database (only) is allowed to be non-existent
    
    ... ... @@ -898,7 +902,7 @@ readParseDatabase verbosity mb_user_conf mode use_cache path
    898 902
                     Just db -> return db
    
    899 903
                     Nothing ->
    
    900 904
                       die $ "ghc no longer supports single-file style package "
    
    901
    -                     ++ "databases (" ++ path ++ ") use 'ghc-pkg init'"
    
    905
    +                     ++ "databases (" ++ show path ++ ") use 'ghc-pkg init'"
    
    902 906
                          ++ "to create the database with the correct format."
    
    903 907
     
    
    904 908
                | otherwise -> ioError err
    
    ... ... @@ -914,7 +918,7 @@ readParseDatabase verbosity mb_user_conf mode use_cache path
    914 918
                             -- It's fine if the cache is not there as long as the
    
    915 919
                             -- database is empty.
    
    916 920
                             when (not $ null confs) $ do
    
    917
    -                            warn ("WARNING: cache does not exist: " ++ cache)
    
    921
    +                            warn ("WARNING: cache does not exist: " ++ show cache)
    
    918 922
                                 warn ("ghc will fail to read this package db. " ++
    
    919 923
                                       recacheAdvice)
    
    920 924
                           else do
    
    ... ... @@ -923,7 +927,7 @@ readParseDatabase verbosity mb_user_conf mode use_cache path
    923 927
                       ignore_cache (const $ return ())
    
    924 928
                     Right tcache -> do
    
    925 929
                       when (verbosity >= Verbose) $ do
    
    926
    -                      warn ("Timestamp " ++ show tcache ++ " for " ++ cache)
    
    930
    +                      warn ("Timestamp " ++ show tcache ++ " for " ++ show cache)
    
    927 931
                       -- If any of the .conf files is newer than package.cache, we
    
    928 932
                       -- assume that cache is out of date.
    
    929 933
                       cache_outdated <- (`anyM` confs) $ \conf ->
    
    ... ... @@ -931,12 +935,12 @@ readParseDatabase verbosity mb_user_conf mode use_cache path
    931 935
                       if not cache_outdated
    
    932 936
                           then do
    
    933 937
                               when (verbosity > Normal) $
    
    934
    -                             infoLn ("using cache: " ++ cache)
    
    938
    +                             infoLn ("using cache: " ++ show cache)
    
    935 939
                               GhcPkg.readPackageDbForGhcPkg cache mode
    
    936 940
                                 >>= uncurry mkPackageDB
    
    937 941
                           else do
    
    938 942
                               whenReportCacheErrors $ do
    
    939
    -                              warn ("WARNING: cache is out of date: " ++ cache)
    
    943
    +                              warn ("WARNING: cache is out of date: " ++ show cache)
    
    940 944
                                   warn ("ghc will see an old view of this " ++
    
    941 945
                                         "package db. " ++ recacheAdvice)
    
    942 946
                               ignore_cache $ \file -> do
    
    ... ... @@ -947,11 +951,11 @@ readParseDatabase verbosity mb_user_conf mode use_cache path
    947 951
                                         GT -> " (older than cache)"
    
    948 952
                                         EQ -> " (same as cache)"
    
    949 953
                                   warn ("Timestamp " ++ show tFile
    
    950
    -                                ++ " for " ++ file ++ rel)
    
    954
    +                                ++ " for " ++ show file ++ rel)
    
    951 955
                 where
    
    952
    -                 confs = map (path </>) $ filter (".conf" `isSuffixOf`) fs
    
    956
    +                 confs = map (path </>) $ filter (os ".conf" `OsPath.isExtensionOf`) fs
    
    953 957
     
    
    954
    -                 ignore_cache :: (FilePath -> IO ()) -> IO (PackageDB mode)
    
    958
    +                 ignore_cache :: (OsPath -> IO ()) -> IO (PackageDB mode)
    
    955 959
                      ignore_cache checkTime = do
    
    956 960
                          -- If we're opening for modification, we need to acquire a
    
    957 961
                          -- lock even if we don't open the cache now, because we are
    
    ... ... @@ -987,15 +991,16 @@ readParseDatabase verbosity mb_user_conf mode use_cache path
    987 991
               packages = pkgs
    
    988 992
             }
    
    989 993
     
    
    990
    -parseSingletonPackageConf :: Verbosity -> FilePath -> IO InstalledPackageInfo
    
    994
    +parseSingletonPackageConf :: Verbosity -> OsPath -> IO InstalledPackageInfo
    
    991 995
     parseSingletonPackageConf verbosity file = do
    
    992
    -  when (verbosity > Normal) $ infoLn ("reading package config: " ++ file)
    
    993
    -  BS.readFile file >>= fmap fst . parsePackageInfo
    
    996
    +  when (verbosity > Normal) $ infoLn ("reading package config: " ++ show file)
    
    997
    +  FileIO.readFile file >>= fmap fst . parsePackageInfo . BS.toStrict
    
    994 998
     
    
    995
    -cachefilename :: FilePath
    
    996
    -cachefilename = "package.cache"
    
    997 999
     
    
    998
    -mungePackageDBPaths :: FilePath -> PackageDB mode -> PackageDB mode
    
    1000
    +cachefilename :: OsPath
    
    1001
    +cachefilename = os "package.cache"
    
    1002
    +
    
    1003
    +mungePackageDBPaths :: OsPath -> PackageDB mode -> PackageDB mode
    
    999 1004
     mungePackageDBPaths top_dir db@PackageDB { packages = pkgs } =
    
    1000 1005
         db { packages = map (mungePackagePaths top_dir pkgroot) pkgs }
    
    1001 1006
       where
    
    ... ... @@ -1012,7 +1017,7 @@ mungePackageDBPaths top_dir db@PackageDB { packages = pkgs } =
    1012 1017
     -- Also perform a similar substitution for the older GHC-specific
    
    1013 1018
     -- "$topdir" variable. The "topdir" is the location of the ghc
    
    1014 1019
     -- installation (obtained from the -B option).
    
    1015
    -mungePackagePaths :: FilePath -> FilePath
    
    1020
    +mungePackagePaths :: OsPath -> OsPath
    
    1016 1021
                       -> InstalledPackageInfo -> InstalledPackageInfo
    
    1017 1022
     mungePackagePaths top_dir pkgroot pkg =
    
    1018 1023
        -- TODO: similar code is duplicated in GHC.Unit.Database
    
    ... ... @@ -1031,25 +1036,26 @@ mungePackagePaths top_dir pkgroot pkg =
    1031 1036
         munge_urls  = map munge_url
    
    1032 1037
         (munge_path,munge_url) = mkMungePathUrl top_dir pkgroot
    
    1033 1038
     
    
    1034
    -mkMungePathUrl :: FilePath -> FilePath -> (FilePath -> FilePath, FilePath -> FilePath)
    
    1039
    +mkMungePathUrl :: OsPath -> OsPath -> (FilePath -> FilePath, FilePath -> FilePath)
    
    1035 1040
     mkMungePathUrl top_dir pkgroot = (munge_path, munge_url)
    
    1036 1041
        where
    
    1037 1042
         munge_path p
    
    1038
    -      | Just p' <- stripVarPrefix "${pkgroot}" p = pkgroot ++ p'
    
    1039
    -      | Just p' <- stripVarPrefix "$topdir"    p = top_dir ++ p'
    
    1043
    +      | Just p' <- stripVarPrefix "${pkgroot}" p = so pkgroot ++ p'
    
    1044
    +      | Just p' <- stripVarPrefix "$topdir"    p = so top_dir ++ p'
    
    1040 1045
           | otherwise                                = p
    
    1041 1046
     
    
    1042 1047
         munge_url p
    
    1043
    -      | Just p' <- stripVarPrefix "${pkgrooturl}" p = toUrlPath pkgroot p'
    
    1044
    -      | Just p' <- stripVarPrefix "$httptopdir"   p = toUrlPath top_dir p'
    
    1048
    +      | Just p' <- stripVarPrefix "${pkgrooturl}" p = toUrlPath (so pkgroot) p'
    
    1049
    +      | Just p' <- stripVarPrefix "$httptopdir"   p = toUrlPath (so top_dir) p'
    
    1045 1050
           | otherwise                                   = p
    
    1046 1051
     
    
    1052
    +    toUrlPath :: FilePath -> FilePath -> FilePath
    
    1047 1053
         toUrlPath r p = "file:///"
    
    1048 1054
                      -- URLs always use posix style '/' separators:
    
    1049 1055
                      ++ FilePath.Posix.joinPath
    
    1050 1056
                             (r : -- We need to drop a leading "/" or "\\"
    
    1051 1057
                                  -- if there is one:
    
    1052
    -                             dropWhile (all isPathSeparator)
    
    1058
    +                             dropWhile (all FilePath.isPathSeparator)
    
    1053 1059
                                            (FilePath.splitDirectories p))
    
    1054 1060
     
    
    1055 1061
         -- We could drop the separator here, and then use </> above. However,
    
    ... ... @@ -1057,7 +1063,7 @@ mkMungePathUrl top_dir pkgroot = (munge_path, munge_url)
    1057 1063
         -- rather than letting FilePath change it to use \ as the separator
    
    1058 1064
         stripVarPrefix var path = case stripPrefix var path of
    
    1059 1065
                                   Just [] -> Just []
    
    1060
    -                              Just cs@(c : _) | isPathSeparator c -> Just cs
    
    1066
    +                              Just cs@(c : _) | FilePath.isPathSeparator c -> Just cs
    
    1061 1067
                                   _ -> Nothing
    
    1062 1068
     
    
    1063 1069
     -- -----------------------------------------------------------------------------
    
    ... ... @@ -1074,18 +1080,18 @@ mkMungePathUrl top_dir pkgroot = (munge_path, munge_url)
    1074 1080
     
    
    1075 1081
     -- ghc itself also cooperates in this workaround
    
    1076 1082
     
    
    1077
    -tryReadParseOldFileStyleDatabase :: Verbosity -> Maybe (FilePath, Bool)
    
    1078
    -                                 -> GhcPkg.DbOpenMode mode t -> Bool -> FilePath
    
    1083
    +tryReadParseOldFileStyleDatabase :: Verbosity -> Maybe (OsPath, Bool)
    
    1084
    +                                 -> GhcPkg.DbOpenMode mode t -> Bool -> OsPath
    
    1079 1085
                                      -> IO (Maybe (PackageDB mode))
    
    1080 1086
     tryReadParseOldFileStyleDatabase verbosity mb_user_conf
    
    1081 1087
                                      mode use_cache path = do
    
    1082 1088
       -- assumes we've already established that path exists and is not a dir
    
    1083
    -  content <- readFile path `catchIO` \_ -> return ""
    
    1089
    +  content <- readUtf8File path `catchIO` \_ -> return ""
    
    1084 1090
       if take 2 content == "[]"
    
    1085 1091
         then do
    
    1086 1092
           path_abs <- absolutePath path
    
    1087 1093
           let path_dir = adjustOldDatabasePath path
    
    1088
    -      warn $ "Warning: ignoring old file-style db and trying " ++ path_dir
    
    1094
    +      warn $ "Warning: ignoring old file-style db and trying " ++ show path_dir
    
    1089 1095
           direxists <- doesDirectoryExist path_dir
    
    1090 1096
           if direxists
    
    1091 1097
             then do
    
    ... ... @@ -1112,7 +1118,7 @@ tryReadParseOldFileStyleDatabase verbosity mb_user_conf
    1112 1118
     adjustOldFileStylePackageDB :: PackageDB mode -> IO (PackageDB mode)
    
    1113 1119
     adjustOldFileStylePackageDB db = do
    
    1114 1120
       -- assumes we have not yet established if it's an old style or not
    
    1115
    -  mcontent <- liftM Just (readFile (location db)) `catchIO` \_ -> return Nothing
    
    1121
    +  mcontent <- liftM Just (readUtf8File (location db)) `catchIO` \_ -> return Nothing
    
    1116 1122
       case fmap (take 2) mcontent of
    
    1117 1123
         -- it is an old style and empty db, so look for a dir kind in location.d/
    
    1118 1124
         Just "[]" -> return db {
    
    ... ... @@ -1121,20 +1127,20 @@ adjustOldFileStylePackageDB db = do
    1121 1127
           }
    
    1122 1128
         -- it is old style but not empty, we have to bail
    
    1123 1129
         Just  _   -> die $ "ghc no longer supports single-file style package "
    
    1124
    -                    ++ "databases (" ++ location db ++ ") use 'ghc-pkg init'"
    
    1130
    +                    ++ "databases (" ++ show (location db) ++ ") use 'ghc-pkg init'"
    
    1125 1131
                         ++ "to create the database with the correct format."
    
    1126 1132
         -- probably not old style, carry on as normal
    
    1127 1133
         Nothing   -> return db
    
    1128 1134
     
    
    1129
    -adjustOldDatabasePath :: FilePath -> FilePath
    
    1130
    -adjustOldDatabasePath = (<.> "d")
    
    1135
    +adjustOldDatabasePath :: OsPath -> OsPath
    
    1136
    +adjustOldDatabasePath = (<.> os "d")
    
    1131 1137
     
    
    1132 1138
     -- -----------------------------------------------------------------------------
    
    1133 1139
     -- Creating a new package DB
    
    1134 1140
     
    
    1135
    -initPackageDB :: FilePath -> Verbosity -> [Flag] -> IO ()
    
    1141
    +initPackageDB :: OsPath -> Verbosity -> [Flag] -> IO ()
    
    1136 1142
     initPackageDB filename verbosity _flags = do
    
    1137
    -  let eexist = die ("cannot create: " ++ filename ++ " already exists")
    
    1143
    +  let eexist = die ("cannot create: " ++ show filename ++ " already exists")
    
    1138 1144
       b1 <- doesFileExist filename
    
    1139 1145
       when b1 eexist
    
    1140 1146
       b2 <- doesDirectoryExist filename
    
    ... ... @@ -1148,7 +1154,7 @@ initPackageDB filename verbosity _flags = do
    1148 1154
           packageDbLock = GhcPkg.DbOpenReadWrite lock,
    
    1149 1155
           packages = []
    
    1150 1156
         }
    
    1151
    -    -- We can get away with passing an empty stack here, because the new DB is
    
    1157
    +    -- We can get away with passing an empty stack here,FilePath because the new DB is
    
    1152 1158
         -- going to be initially empty, so no dependencies are going to be actually
    
    1153 1159
         -- looked up.
    
    1154 1160
         []
    
    ... ... @@ -1183,7 +1189,7 @@ registerPackage input verbosity my_flags multi_instance
    1183 1189
           f   -> do
    
    1184 1190
             when (verbosity >= Normal) $
    
    1185 1191
                 info ("Reading package info from " ++ show f ++ " ... ")
    
    1186
    -        readUTF8File f
    
    1192
    +        readUtf8File $ os f
    
    1187 1193
     
    
    1188 1194
       expanded <- if expand_env_vars then expandEnvVars s force
    
    1189 1195
                                      else return s
    
    ... ... @@ -1274,13 +1280,13 @@ changeDBDir verbosity cmds db db_stack = do
    1274 1280
       updateDBCache verbosity db db_stack
    
    1275 1281
      where
    
    1276 1282
       do_cmd (RemovePackage p) = do
    
    1277
    -    let file = location db </> display (installedUnitId p) <.> "conf"
    
    1278
    -    when (verbosity > Normal) $ infoLn ("removing " ++ file)
    
    1283
    +    let file = location db </> os (display (installedUnitId p)) <.> os "conf"
    
    1284
    +    when (verbosity > Normal) $ infoLn ("removing " ++ show file)
    
    1279 1285
         removeFileSafe file
    
    1280 1286
       do_cmd (AddPackage p) = do
    
    1281
    -    let file = location db </> display (installedUnitId p) <.> "conf"
    
    1282
    -    when (verbosity > Normal) $ infoLn ("writing " ++ file)
    
    1283
    -    writeUTF8File file (showInstalledPackageInfo p)
    
    1287
    +    let file = location db </> os (display (installedUnitId p)) <.> os "conf"
    
    1288
    +    when (verbosity > Normal) $ infoLn ("writing " ++ show file)
    
    1289
    +    writeUtf8File file (showInstalledPackageInfo p)
    
    1284 1290
       do_cmd (ModifyPackage p) =
    
    1285 1291
         do_cmd (AddPackage p)
    
    1286 1292
     
    
    ... ... @@ -1338,13 +1344,13 @@ updateDBCache verbosity db db_stack = do
    1338 1344
                 warn $ "    " ++ pkg
    
    1339 1345
     
    
    1340 1346
       when (verbosity > Normal) $
    
    1341
    -      infoLn ("writing cache " ++ filename)
    
    1347
    +      infoLn ("writing cache " ++ show filename)
    
    1342 1348
     
    
    1343 1349
       let d = fmap (fromPackageCacheFormat . fst) pkgsGhcCacheFormat
    
    1344 1350
       GhcPkg.writePackageDb filename d pkgsCabalFormat
    
    1345 1351
         `catchIO` \e ->
    
    1346 1352
           if isPermissionError e
    
    1347
    -      then die $ filename ++ ": you don't have permission to modify this file"
    
    1353
    +      then die $ show filename ++ ": you don't have permission to modify this file"
    
    1348 1354
           else ioError e
    
    1349 1355
     
    
    1350 1356
       case packageDbLock db of
    
    ... ... @@ -1583,7 +1589,7 @@ listPackages verbosity my_flags mPackageName mModuleName = do
    1583 1589
           broken = map installedUnitId (brokenPackages pkg_map)
    
    1584 1590
     
    
    1585 1591
           show_normal PackageDB{ location = db_name, packages = pkg_confs } =
    
    1586
    -          do hPutStrLn stdout db_name
    
    1592
    +          do hPutStrLn stdout (show db_name)
    
    1587 1593
                  if null pkg_confs
    
    1588 1594
                      then hPutStrLn stdout "    (no packages)"
    
    1589 1595
                      else hPutStrLn stdout $ unlines (map ("    " ++) (map pp_pkg pkg_confs))
    
    ... ... @@ -1610,7 +1616,7 @@ listPackages verbosity my_flags mPackageName mModuleName = do
    1610 1616
     #else
    
    1611 1617
         let
    
    1612 1618
           show_colour PackageDB{ location = db_name, packages = pkg_confs } =
    
    1613
    -          do hPutStrLn stdout db_name
    
    1619
    +          do hPutStrLn stdout (show db_name)
    
    1614 1620
                  if null pkg_confs
    
    1615 1621
                      then hPutStrLn stdout "    (no packages)"
    
    1616 1622
                      else hPutStrLn stdout $ unlines (map ("    " ++) (map pp_pkg pkg_confs))
    
    ... ... @@ -1698,7 +1704,7 @@ dumpUnits verbosity my_flags expand_pkgroot = do
    1698 1704
       doDump expand_pkgroot [ (pkg, locationAbsolute db)
    
    1699 1705
                             | db <- flag_db_stack, pkg <- packages db ]
    
    1700 1706
     
    
    1701
    -doDump :: Bool -> [(InstalledPackageInfo, FilePath)] -> IO ()
    
    1707
    +doDump :: Bool -> [(InstalledPackageInfo, OsPath)] -> IO ()
    
    1702 1708
     doDump expand_pkgroot pkgs = do
    
    1703 1709
       -- fix the encoding to UTF-8, since this is an interchange format
    
    1704 1710
       hSetEncoding stdout utf8
    
    ... ... @@ -1731,7 +1737,7 @@ findPackagesByDB db_stack pkgarg
    1731 1737
     
    
    1732 1738
     cannotFindPackage :: PackageArg -> Maybe (PackageDB mode) -> IO a
    
    1733 1739
     cannotFindPackage pkgarg mdb = die $ "cannot find package " ++ pkg_msg pkgarg
    
    1734
    -  ++ maybe "" (\db -> " in " ++ location db) mdb
    
    1740
    +  ++ maybe "" (\db -> " in " ++ show (location db)) mdb
    
    1735 1741
       where
    
    1736 1742
         pkg_msg (Id pkgid)           = displayGlobPkgId pkgid
    
    1737 1743
         pkg_msg (IUId ipid)          = display ipid
    
    ... ... @@ -1944,7 +1950,7 @@ checkPackageConfig pkg verbosity db_stack
    1944 1950
       checkExposedModules db_stack pkg
    
    1945 1951
       checkOtherModules pkg
    
    1946 1952
       let has_code = Set.null (openModuleSubstFreeHoles (Map.fromList (instantiatedWith pkg)))
    
    1947
    -  when has_code $ mapM_ (checkHSLib verbosity (libraryDirs pkg ++ libraryDynDirs pkg)) (hsLibraries pkg)
    
    1953
    +  when has_code $ mapM_ (checkHSLib verbosity (fmap os $ libraryDirs pkg ++ libraryDynDirs pkg)) (hsLibraries pkg)
    
    1948 1954
       -- ToDo: check these somehow?
    
    1949 1955
       --    extra_libraries :: [String],
    
    1950 1956
       --    c_includes      :: [String],
    
    ... ... @@ -2011,20 +2017,20 @@ checkPath url_ok is_dir warn_only thisfield d
    2011 2017
                || "https://" `isPrefixOf` d) = return ()
    
    2012 2018
     
    
    2013 2019
      | url_ok
    
    2014
    - , Just d' <- stripPrefix "file://" d
    
    2015
    - = checkPath False is_dir warn_only thisfield d'
    
    2020
    + , Just f <- stripPrefix "file://" d
    
    2021
    + = checkPath False is_dir warn_only thisfield f
    
    2016 2022
     
    
    2017 2023
        -- Note: we don't check for $topdir/${pkgroot} here. We rely on these
    
    2018 2024
        -- variables having been expanded already, see mungePackagePaths.
    
    2019 2025
     
    
    2020
    - | isRelative d = verror ForceFiles $
    
    2021
    -                     thisfield ++ ": " ++ d ++ " is a relative path which "
    
    2026
    + | isRelative d' = verror ForceFiles $
    
    2027
    +                     thisfield ++ ": " ++ show d ++ " is a relative path which "
    
    2022 2028
                       ++ "makes no sense (as there is nothing for it to be "
    
    2023 2029
                       ++ "relative to). You can make paths relative to the "
    
    2024 2030
                       ++ "package database itself by using ${pkgroot}."
    
    2025 2031
             -- relative paths don't make any sense; #4134
    
    2026 2032
      | otherwise = do
    
    2027
    -   there <- liftIO $ if is_dir then doesDirectoryExist d else doesFileExist d
    
    2033
    +   there <- liftIO $ if is_dir then doesDirectoryExist d' else doesFileExist d'
    
    2028 2034
        when (not there) $
    
    2029 2035
            let msg = thisfield ++ ": " ++ d ++ " doesn't exist or isn't a "
    
    2030 2036
                                             ++ if is_dir then "directory" else "file"
    
    ... ... @@ -2032,6 +2038,8 @@ checkPath url_ok is_dir warn_only thisfield d
    2032 2038
            if warn_only
    
    2033 2039
               then vwarn msg
    
    2034 2040
               else verror ForceFiles msg
    
    2041
    +  where
    
    2042
    +   d' = os d
    
    2035 2043
     
    
    2036 2044
     checkDep :: PackageDBStack -> UnitId -> Validate ()
    
    2037 2045
     checkDep db_stack pkgid
    
    ... ... @@ -2050,24 +2058,25 @@ checkDuplicateDepends deps
    2050 2058
       where
    
    2051 2059
            dups = [ p | (p:_:_) <- group (sort deps) ]
    
    2052 2060
     
    
    2053
    -checkHSLib :: Verbosity -> [String] -> String -> Validate ()
    
    2061
    +checkHSLib :: Verbosity -> [OsPath] -> String -> Validate ()
    
    2054 2062
     checkHSLib _verbosity dirs lib = do
    
    2055
    -  let filenames = ["lib" ++ lib ++ ".a",
    
    2056
    -                   "lib" ++ lib ++ "_p.a",
    
    2057
    -                   "lib" ++ lib ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".so",
    
    2058
    -                   "lib" ++ lib ++ "_p" ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".so",
    
    2059
    -                   "lib" ++ lib ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dylib",
    
    2060
    -                   "lib" ++ lib ++ "_p" ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dylib",
    
    2061
    -                   lib ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dll",
    
    2062
    -                   lib ++ "_p" ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dll",
    
    2063
    -                   lib ++ ".bytecodelib"
    
    2064
    -                  ]
    
    2063
    +  let filenames = fmap os
    
    2064
    +        [ "lib" ++ lib ++ ".a"
    
    2065
    +        , "lib" ++ lib ++ "_p.a"
    
    2066
    +        , "lib" ++ lib ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".so"
    
    2067
    +        , "lib" ++ lib ++ "_p" ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".so"
    
    2068
    +        , "lib" ++ lib ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dylib"
    
    2069
    +        , "lib" ++ lib ++ "_p" ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dylib"
    
    2070
    +        , lib ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dll"
    
    2071
    +        , lib ++ "_p" ++ "-ghc" ++ GHC.Version.cProjectVersion ++ ".dll"
    
    2072
    +        , lib ++ ".bytecodelib"
    
    2073
    +        ]
    
    2065 2074
       b <- liftIO $ doesFileExistOnPath filenames dirs
    
    2066 2075
       when (not b) $
    
    2067 2076
         verror ForceFiles ("cannot find any of " ++ show filenames ++
    
    2068 2077
                            " on library path")
    
    2069 2078
     
    
    2070
    -doesFileExistOnPath :: [FilePath] -> [FilePath] -> IO Bool
    
    2079
    +doesFileExistOnPath :: [OsPath] -> [OsPath] -> IO Bool
    
    2071 2080
     doesFileExistOnPath filenames paths = anyM doesFileExist fullFilenames
    
    2072 2081
       where fullFilenames = [ path </> filename
    
    2073 2082
                             | filename <- filenames
    
    ... ... @@ -2096,9 +2105,9 @@ checkModuleFile :: InstalledPackageInfo -> ModuleName -> Validate ()
    2096 2105
     checkModuleFile pkg modl =
    
    2097 2106
           -- there's no interface file for GHC.Prim
    
    2098 2107
           unless (modl == ModuleName.fromString "GHC.Prim") $ do
    
    2099
    -      let files = [ ModuleName.toFilePath modl <.> extension
    
    2108
    +      let files = [ os (ModuleName.toFilePath modl) <.> os extension
    
    2100 2109
                       | extension <- ["hi", "p_hi", "dyn_hi", "p_dyn_hi"] ]
    
    2101
    -      b <- liftIO $ doesFileExistOnPath files (importDirs pkg)
    
    2110
    +      b <- liftIO $ doesFileExistOnPath files (fmap os $ importDirs pkg)
    
    2102 2111
           when (not b) $
    
    2103 2112
              verror ForceFiles ("cannot find any of " ++ show files)
    
    2104 2113
     
    
    ... ... @@ -2280,12 +2289,18 @@ tryIO :: IO a -> IO (Either Exception.IOException a)
    2280 2289
     tryIO = Exception.try
    
    2281 2290
     
    
    2282 2291
     -- removeFileSave doesn't throw an exceptions, if the file is already deleted
    
    2283
    -removeFileSafe :: FilePath -> IO ()
    
    2292
    +removeFileSafe :: OsPath -> IO ()
    
    2284 2293
     removeFileSafe fn =
    
    2285 2294
       removeFile fn `catchIO` \ e ->
    
    2286 2295
         when (not $ isDoesNotExistError e) $ ioError e
    
    2287 2296
     
    
    2288 2297
     -- | Turn a path relative to the current directory into a (normalised)
    
    2289 2298
     -- absolute path.
    
    2290
    -absolutePath :: FilePath -> IO FilePath
    
    2299
    +absolutePath :: OsPath -> IO OsPath
    
    2291 2300
     absolutePath path = return . normalise . (</> path) =<< getCurrentDirectory
    
    2301
    +
    
    2302
    +writeUtf8File :: OsPath -> String -> IO ()
    
    2303
    +writeUtf8File file contents = writeFileAtomic file (toUTF8LBS contents)
    
    2304
    +
    
    2305
    +readUtf8File :: OsPath -> IO String
    
    2306
    +readUtf8File file = (ignoreBOM . fromUTF8LBS) <$> FileIO.readFile file

  • utils/ghc-pkg/ghc-pkg.cabal.in
    ... ... @@ -25,6 +25,7 @@ Executable ghc-pkg
    25 25
                        process    >= 1   && < 1.7,
    
    26 26
                        containers,
    
    27 27
                        filepath,
    
    28
    +                   file-io,
    
    28 29
                        Cabal,
    
    29 30
                        Cabal-syntax,
    
    30 31
                        binary,