more OsPath conversion
About 1/10th done with this I think.
This commit is contained in:
parent
8021d22955
commit
c412c59ecd
16 changed files with 152 additions and 142 deletions
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue