more OsPath conversion

About 1/10th done with this I think.
This commit is contained in:
Joey Hess 2025-01-24 13:40:09 -04:00
parent 8021d22955
commit c412c59ecd
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
16 changed files with 152 additions and 142 deletions

View file

@ -48,7 +48,7 @@ copyFileExternal :: CopyMetaData -> FilePath -> FilePath -> IO Bool
copyFileExternal meta src dest = do
-- Delete any existing dest file because an unwritable file
-- would prevent cp from working.
void $ tryIO $ removeFile dest
void $ tryIO $ removeFile (toOsPath dest)
boolSystem "cp" $ params ++ [File src, File dest]
where
params
@ -76,7 +76,7 @@ copyCoW meta src dest
-- When CoW is not supported, cp creates the destination
-- file but leaves it empty.
unless ok $
void $ tryIO $ removeFile dest
void $ tryIO $ removeFile $ toOsPath dest
return ok
| otherwise = return False
where

View file

@ -30,18 +30,14 @@ import Utility.Exception
import Utility.Monad
import qualified Utility.RawFilePath as R
dirCruft :: R.RawFilePath -> Bool
dirCruft "." = True
dirCruft ".." = True
dirCruft _ = False
dirCruft :: [OsPath]
dirCruft = [literalOsPath ".", literalOsPath ".."]
{- Lists the contents of a directory.
- Unlike getDirectoryContents, paths are not relative to the directory. -}
dirContents :: RawFilePath -> IO [RawFilePath]
dirContents d =
map (\p -> d P.</> fromOsPath p)
. filter (not . dirCruft . fromOsPath)
<$> getDirectoryContents (toOsPath d)
dirContents :: OsPath -> IO [OsPath]
dirContents d = map (d </>) . filter (`notElem` dirCruft)
<$> getDirectoryContents d
{- Gets files in a directory, and then its subdirectories, recursively,
- and lazily.
@ -53,13 +49,13 @@ dirContents d =
- be accessed (the use of unsafeInterleaveIO would make it difficult to
- trap such exceptions).
-}
dirContentsRecursive :: RawFilePath -> IO [RawFilePath]
dirContentsRecursive :: OsPath -> IO [OsPath]
dirContentsRecursive = dirContentsRecursiveSkipping (const False) True
{- Skips directories whose basenames match the skipdir. -}
dirContentsRecursiveSkipping :: (RawFilePath -> Bool) -> Bool -> RawFilePath -> IO [RawFilePath]
dirContentsRecursiveSkipping :: (OsPath -> Bool) -> Bool -> OsPath -> IO [OsPath]
dirContentsRecursiveSkipping skipdir followsubdirsymlinks topdir
| skipdir (P.takeFileName topdir) = return []
| skipdir (takeFileName topdir) = return []
| otherwise = do
-- Get the contents of the top directory outside of
-- unsafeInterleaveIO, which allows throwing exceptions if
@ -71,26 +67,26 @@ dirContentsRecursiveSkipping skipdir followsubdirsymlinks topdir
where
go [] = return []
go (dir:dirs)
| skipdir (P.takeFileName dir) = go dirs
| skipdir (takeFileName dir) = go dirs
| otherwise = unsafeInterleaveIO $ do
(files, dirs') <- collect [] []
=<< catchDefaultIO [] (dirContents dir)
files' <- go (dirs' ++ dirs)
return (files ++ files')
collect :: [RawFilePath] -> [RawFilePath] -> [RawFilePath] -> IO ([RawFilePath], [RawFilePath])
collect :: [OsPath] -> [OsPath] -> [OsPath] -> IO ([OsPath], [OsPath])
collect files dirs' [] = return (reverse files, reverse dirs')
collect files dirs' (entry:entries)
| dirCruft entry = collect files dirs' entries
| entry `elem` dirCruft = collect files dirs' entries
| otherwise = do
let skip = collect (entry:files) dirs' entries
let recurse = collect files (entry:dirs') entries
ms <- catchMaybeIO $ R.getSymbolicLinkStatus entry
ms <- catchMaybeIO $ R.getSymbolicLinkStatus (fromOsPath entry)
case ms of
(Just s)
| isDirectory s -> recurse
| isSymbolicLink s && followsubdirsymlinks ->
ifM (doesDirectoryExist (toOsPath entry))
ifM (doesDirectoryExist entry)
( recurse
, skip
)
@ -105,22 +101,22 @@ dirContentsRecursiveSkipping skipdir followsubdirsymlinks topdir
- be accessed (the use of unsafeInterleaveIO would make it difficult to
- trap such exceptions).
-}
dirTreeRecursiveSkipping :: (RawFilePath -> Bool) -> RawFilePath -> IO [RawFilePath]
dirTreeRecursiveSkipping :: (OsPath -> Bool) -> OsPath -> IO [OsPath]
dirTreeRecursiveSkipping skipdir topdir
| skipdir (P.takeFileName topdir) = return []
| skipdir (takeFileName topdir) = return []
| otherwise = do
subdirs <- filterM isdir =<< dirContents topdir
go [] subdirs
where
go c [] = return c
go c (dir:dirs)
| skipdir (P.takeFileName dir) = go c dirs
| skipdir (takeFileName dir) = go c dirs
| otherwise = unsafeInterleaveIO $ do
subdirs <- go []
=<< filterM isdir
=<< catchDefaultIO [] (dirContents dir)
go (subdirs++dir:c) dirs
isdir p = isDirectory <$> R.getSymbolicLinkStatus p
isdir p = isDirectory <$> R.getSymbolicLinkStatus (fromOsPath p)
{- When the action fails due to the directory not existing, returns []. -}
emptyWhenDoesNotExist :: IO [a] -> IO [a]

View file

@ -20,13 +20,13 @@ import Control.Monad.IO.Class
import Control.Monad.IfElse
import System.IO.Error
import Data.Maybe
import qualified System.FilePath.ByteString as P
import Prelude
import Utility.SystemDirectory
import Utility.Path.AbsRel
import Utility.Exception
import Utility.FileSystemEncoding
import Utility.OsPath
import qualified Utility.RawFilePath as R
import Utility.PartialPrelude
@ -51,39 +51,39 @@ import Utility.PartialPrelude
- Note that, the second FilePath, if relative, is relative to the current
- working directory.
-}
createDirectoryUnder :: [RawFilePath] -> RawFilePath -> IO ()
createDirectoryUnder :: [OsPath] -> OsPath -> IO ()
createDirectoryUnder topdirs dir =
createDirectoryUnder' topdirs dir R.createDirectory
createDirectoryUnder' topdirs dir createDirectory
createDirectoryUnder'
:: (MonadIO m, MonadCatch m)
=> [RawFilePath]
-> RawFilePath
-> (RawFilePath -> m ())
=> [OsPath]
-> OsPath
-> (OsPath -> m ())
-> m ()
createDirectoryUnder' topdirs dir0 mkdir = do
relps <- liftIO $ forM topdirs $ \topdir -> relPathDirToFile topdir dir0
let relparts = map P.splitDirectories relps
let relparts = map splitDirectories relps
-- Catch cases where dir0 is not beneath a topdir.
-- If the relative path between them starts with "..",
-- it's not. And on Windows, if they are on different drives,
-- the path will not be relative.
let notbeneath = \(_topdir, (relp, dirs)) ->
headMaybe dirs /= Just ".." && not (P.isAbsolute relp)
headMaybe dirs /= Just ".." && not (isAbsolute relp)
case filter notbeneath $ zip topdirs (zip relps relparts) of
((topdir, (_relp, dirs)):_)
-- If dir0 is the same as the topdir, don't try to
-- create it, but make sure it does exist.
| null dirs ->
liftIO $ unlessM (doesDirectoryExist (fromRawFilePath topdir)) $
liftIO $ unlessM (doesDirectoryExist topdir) $
ioError $ customerror doesNotExistErrorType $
"createDirectoryUnder: " ++ fromRawFilePath topdir ++ " does not exist"
"createDirectoryUnder: " ++ fromOsPath topdir ++ " does not exist"
| otherwise -> createdirs $
map (topdir P.</>) (reverse (scanl1 (P.</>) dirs))
map (topdir </>) (reverse (scanl1 (</>) dirs))
_ -> liftIO $ ioError $ customerror userErrorType
("createDirectoryUnder: not located in " ++ unwords (map fromRawFilePath topdirs))
("createDirectoryUnder: not located in " ++ unwords (map fromOsPath topdirs))
where
customerror t s = mkIOError t s Nothing (Just (fromRawFilePath dir0))
customerror t s = mkIOError t s Nothing (Just (fromOsPath dir0))
createdirs [] = pure ()
createdirs (dir:[]) = createdir dir (liftIO . ioError)
@ -100,6 +100,6 @@ createDirectoryUnder' topdirs dir0 mkdir = do
Left e
| isDoesNotExistError e -> notexisthandler e
| isAlreadyExistsError e || isPermissionError e ->
liftIO $ unlessM (doesDirectoryExist (fromRawFilePath dir)) $
liftIO $ unlessM (doesDirectoryExist dir) $
ioError e
| otherwise -> liftIO $ ioError e

View file

@ -27,10 +27,11 @@ import Utility.Split
import Utility.FileSystemEncoding
import Utility.Env
import Utility.Exception
import Utility.OsPath
import Utility.RawFilePath
import Data.Maybe
import System.FilePath
import System.Posix.Files
import System.Posix.Files (isSymbolicLink)
import Data.Char
import Control.Monad.IfElse
import Control.Applicative
@ -39,7 +40,7 @@ import Prelude
{- Installs a library. If the library is a symlink to another file,
- install the file it links to, and update the symlink to be relative. -}
installLib :: (FilePath -> FilePath -> IO ()) -> FilePath -> FilePath -> IO (Maybe FilePath)
installLib installfile top lib = ifM (doesFileExist lib)
installLib installfile top lib = ifM (doesFileExist (toOsPath lib))
( do
installfile top lib
checksymlink lib
@ -50,17 +51,17 @@ installLib installfile top lib = ifM (doesFileExist lib)
checksymlink f = whenM (isSymbolicLink <$> getSymbolicLinkStatus (inTop top f)) $ do
l <- readSymbolicLink (inTop top f)
let absl = absPathFrom
(parentDir (toRawFilePath f))
(toRawFilePath l)
target <- relPathDirToFile (toRawFilePath (takeDirectory f)) absl
installfile top (fromRawFilePath absl)
removeWhenExistsWith removeLink (top ++ f)
createSymbolicLink (fromRawFilePath target) (inTop top f)
checksymlink (fromRawFilePath absl)
(parentDir (toOsPath f))
(toOsPath l)
target <- relPathDirToFile (takeDirectory (toOsPath f)) absl
installfile top (fromOsPath absl)
removeWhenExistsWith removeLink (toRawFilePath (top ++ f))
createSymbolicLink (fromOsPath target) (inTop top f)
checksymlink (fromOsPath absl)
-- Note that f is not relative, so cannot use </>
inTop :: FilePath -> FilePath -> FilePath
inTop top f = top ++ f
inTop :: FilePath -> FilePath -> RawFilePath
inTop top f = toRawFilePath $ top ++ f
{- Parse ldd output, getting all the libraries that the input files
- link to. Note that some of the libraries may not exist