add file-io to build-depends when building with OsPath flag
Partly converted code to use functions from it, though more remain unconverted. Most of withFile and openFile now use it.
This commit is contained in:
parent
85efc13e3a
commit
1faa3af9cd
20 changed files with 178 additions and 68 deletions
|
@ -12,6 +12,11 @@
|
|||
|
||||
module Utility.Directory where
|
||||
|
||||
#ifdef WITH_OSPATH
|
||||
import System.Directory.OsPath
|
||||
#else
|
||||
import Utility.SystemDirectory
|
||||
#endif
|
||||
import Control.Monad
|
||||
import System.PosixCompat.Files (isDirectory, isSymbolicLink)
|
||||
import Control.Applicative
|
||||
|
@ -20,40 +25,24 @@ import qualified System.FilePath.ByteString as P
|
|||
import Data.Maybe
|
||||
import Prelude
|
||||
|
||||
import Utility.OsPath
|
||||
import Utility.Exception
|
||||
import Utility.Monad
|
||||
import Utility.FileSystemEncoding
|
||||
import qualified Utility.RawFilePath as R
|
||||
|
||||
#ifdef WITH_OSPATH
|
||||
import Utility.OsPath
|
||||
import qualified System.Directory.OsPath as OP
|
||||
#else
|
||||
import Utility.SystemDirectory
|
||||
#endif
|
||||
|
||||
dirCruft :: R.RawFilePath -> Bool
|
||||
dirCruft "." = True
|
||||
dirCruft ".." = True
|
||||
dirCruft _ = False
|
||||
|
||||
dirCruft' :: R.RawFilePath -> Bool
|
||||
dirCruft' "." = True
|
||||
dirCruft' ".." = True
|
||||
dirCruft' _ = False
|
||||
|
||||
{- Lists the contents of a directory.
|
||||
- Unlike getDirectoryContents, paths are not relative to the directory. -}
|
||||
dirContents :: RawFilePath -> IO [RawFilePath]
|
||||
#ifdef WITH_OSPATH
|
||||
dirContents d = map (\p -> d P.</> fromOsPath p)
|
||||
<$> OP.listDirectory (toOsPath d)
|
||||
#else
|
||||
dirContents d =
|
||||
map (\p -> d P.</> toRawFilePath p)
|
||||
. filter (not . dirCruft . toRawFilePath)
|
||||
<$> getDirectoryContents (fromRawFilePath d)
|
||||
#endif
|
||||
map (\p -> d P.</> fromOsPath p)
|
||||
. filter (not . dirCruft . fromOsPath)
|
||||
<$> getDirectoryContents (toOsPath d)
|
||||
|
||||
{- Gets files in a directory, and then its subdirectories, recursively,
|
||||
- and lazily.
|
||||
|
@ -102,11 +91,7 @@ dirContentsRecursiveSkipping skipdir followsubdirsymlinks topdir
|
|||
(Just s)
|
||||
| isDirectory s -> recurse
|
||||
| isSymbolicLink s && followsubdirsymlinks ->
|
||||
#ifdef WITH_OSPATH
|
||||
ifM (OP.doesDirectoryExist (toOsPath entry))
|
||||
#else
|
||||
ifM (doesDirectoryExist (fromRawFilePath entry))
|
||||
#endif
|
||||
ifM (doesDirectoryExist (toOsPath entry))
|
||||
( recurse
|
||||
, skip
|
||||
)
|
||||
|
|
103
Utility/FileIO.hs
Normal file
103
Utility/FileIO.hs
Normal file
|
@ -0,0 +1,103 @@
|
|||
{- File IO on OsPaths.
|
||||
-
|
||||
- Since Prelude exports many of these as well, this needs to be imported
|
||||
- qualified.
|
||||
-
|
||||
- Copyright 2025 Joey Hess <id@joeyh.name>
|
||||
-
|
||||
- License: BSD-2-clause
|
||||
-}
|
||||
|
||||
{-# OPTIONS_GHC -fno-warn-tabs #-}
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE NoImplicitPrelude #-}
|
||||
|
||||
module Utility.FileIO
|
||||
(
|
||||
withFile,
|
||||
openFile,
|
||||
readFile,
|
||||
readFile',
|
||||
writeFile,
|
||||
writeFile',
|
||||
appendFile,
|
||||
appendFile',
|
||||
) where
|
||||
|
||||
#ifdef WITH_OSPATH
|
||||
|
||||
#ifndef mingw32_HOST_OS
|
||||
import System.File.OsPath
|
||||
#else
|
||||
-- On Windows, System.File.OsPath does not handle UNC-style conversion itself,
|
||||
-- so that has to be done when calling it. See
|
||||
-- https://github.com/haskell/file-io/issues/39
|
||||
import Utility.Path.Windows
|
||||
import Utility.OsPath
|
||||
import System.IO (IO, Handle, IOMode)
|
||||
import System.OsPath (OsPath)
|
||||
import qualified System.File.OsPath as O
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.ByteString.Lazy as L
|
||||
import Control.Applicative
|
||||
|
||||
withFile :: OsPath -> IOMode -> (Handle -> IO r) -> IO r
|
||||
withFile f m a = do
|
||||
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
|
||||
O.withFile f' m a
|
||||
|
||||
openFile :: OsPath -> IOMode -> IO Handle
|
||||
openFile f m = do
|
||||
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
|
||||
O.openFile f' m
|
||||
|
||||
readFile :: OsPath -> IO L.ByteString
|
||||
readFile f = do
|
||||
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
|
||||
O.readFile f'
|
||||
|
||||
readFile' :: OsPath -> IO B.ByteString
|
||||
readFile' f = do
|
||||
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
|
||||
O.readFile' f'
|
||||
|
||||
writeFile :: OsPath -> L.ByteString -> IO ()
|
||||
writeFile f b = do
|
||||
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
|
||||
O.writeFile f' b
|
||||
|
||||
writeFile' :: OsPath -> B.ByteString -> IO ()
|
||||
writeFile' f b = do
|
||||
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
|
||||
O.writeFile' f' b
|
||||
|
||||
appendFile :: OsPath -> L.ByteString -> IO ()
|
||||
appendFile f b = do
|
||||
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
|
||||
O.appendFile f' b
|
||||
|
||||
appendFile' :: OsPath -> B.ByteString -> IO ()
|
||||
appendFile' f b = do
|
||||
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
|
||||
O.appendFile' f' b
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
-- When not building with OsPath, export FilePath versions
|
||||
-- instead. However, functions still use ByteString for the
|
||||
-- file content in that case, unlike the Strings used by the Prelude.
|
||||
import Utility.OsPath
|
||||
import System.IO (withFile, openFile, IO)
|
||||
import Data.ByteString.Lazy (readFile, writeFile, appendFile)
|
||||
import qualified Data.ByteString as B
|
||||
|
||||
readFile' :: OsPath -> IO B.ByteString
|
||||
readFile' = B.readFile
|
||||
|
||||
writeFile' :: OsPath -> B.ByteString -> IO ()
|
||||
writeFile' = B.writeFile
|
||||
|
||||
appendFile' :: OsPath -> B.ByteString -> IO ()
|
||||
appendFile' = B.appendFile
|
||||
#endif
|
|
@ -27,6 +27,8 @@ import Control.Monad.Catch
|
|||
import Utility.Exception
|
||||
import Utility.FileSystemEncoding
|
||||
import qualified Utility.RawFilePath as R
|
||||
import qualified Utility.FileIO as F
|
||||
import Utility.OsPath
|
||||
|
||||
{- Applies a conversion function to a file's mode. -}
|
||||
modifyFileMode :: RawFilePath -> (FileMode -> FileMode) -> IO ()
|
||||
|
@ -178,7 +180,7 @@ writeFileProtected' :: RawFilePath -> (Handle -> IO ()) -> IO ()
|
|||
writeFileProtected' file writer = bracket setup cleanup writer
|
||||
where
|
||||
setup = do
|
||||
h <- protectedOutput $ openFile (fromRawFilePath file) WriteMode
|
||||
h <- protectedOutput $ F.openFile (toOsPath file) WriteMode
|
||||
void $ tryIO $ modifyFileMode file $ removeModes otherGroupModes
|
||||
return h
|
||||
cleanup = hClose
|
||||
|
|
|
@ -18,6 +18,8 @@ module Utility.FileSize (
|
|||
import Control.Exception (bracket)
|
||||
import System.IO
|
||||
import Utility.FileSystemEncoding
|
||||
import qualified Utility.FileIO as F
|
||||
import Utility.OsPath
|
||||
#else
|
||||
import System.PosixCompat.Files (fileSize)
|
||||
#endif
|
||||
|
@ -36,7 +38,7 @@ getFileSize :: R.RawFilePath -> IO FileSize
|
|||
#ifndef mingw32_HOST_OS
|
||||
getFileSize f = fmap (fromIntegral . fileSize) (R.getFileStatus f)
|
||||
#else
|
||||
getFileSize f = bracket (openFile (fromRawFilePath f) ReadMode) hClose hFileSize
|
||||
getFileSize f = bracket (F.openFile (toOsPath f) ReadMode) hClose hFileSize
|
||||
#endif
|
||||
|
||||
{- Gets the size of the file, when its FileStatus is already known.
|
||||
|
|
|
@ -13,6 +13,9 @@ module Utility.HtmlDetect (
|
|||
) where
|
||||
|
||||
import Author
|
||||
import qualified Utility.FileIO as F
|
||||
import Utility.RawFilePath
|
||||
import Utility.OsPath
|
||||
|
||||
import Text.HTML.TagSoup
|
||||
import System.IO
|
||||
|
@ -57,8 +60,8 @@ isHtmlBs = isHtml . B8.unpack
|
|||
-- It would be equivalent to use isHtml <$> readFile file,
|
||||
-- but since that would not read all of the file, the handle
|
||||
-- would remain open until it got garbage collected sometime later.
|
||||
isHtmlFile :: FilePath -> IO Bool
|
||||
isHtmlFile file = withFile file ReadMode $ \h ->
|
||||
isHtmlFile :: RawFilePath -> IO Bool
|
||||
isHtmlFile file = F.withFile (toOsPath file) ReadMode $ \h ->
|
||||
isHtmlBs <$> B.hGet h htmlPrefixLength
|
||||
|
||||
-- | How much of the beginning of a html document is needed to detect it.
|
||||
|
|
|
@ -11,10 +11,9 @@
|
|||
|
||||
module Utility.OsPath where
|
||||
|
||||
import Utility.FileSystemEncoding
|
||||
|
||||
#ifdef WITH_OSPATH
|
||||
|
||||
import Utility.RawFilePath
|
||||
|
||||
import System.OsPath
|
||||
import "os-string" System.OsString.Internal.Types
|
||||
import qualified Data.ByteString.Short as S
|
||||
|
@ -36,4 +35,15 @@ fromOsPath = S.fromShort . getWindowsString . getOsString
|
|||
fromOsPath = S.fromShort . getPosixString . getOsString
|
||||
#endif
|
||||
|
||||
#endif /* WITH_OSPATH */
|
||||
#else
|
||||
{- When not building with WITH_OSPATH, use FilePath. This allows
|
||||
- using functions from legacy FilePath libraries interchangeably with
|
||||
- newer OsPath libraries.
|
||||
- -}
|
||||
type OsPath = FilePath
|
||||
toOsPath :: RawFilePath -> OsPath
|
||||
toOsPath = fromRawFilePath
|
||||
|
||||
fromOsPath :: OsPath -> RawFilePath
|
||||
fromOsPath = toRawFilePath
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue