From c7cca43ab0b7a37543217195026565b97cdeec87 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 20 Jan 2025 14:50:08 -0400 Subject: [PATCH] RawFilePath conversion for Utility.Directory.Stream --- Annex/Branch.hs | 8 ++++---- Annex/Journal.hs | 8 +++----- Utility/Directory.hs | 5 +++++ Utility/Directory/Stream.hs | 33 +++++++++++++++++---------------- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/Annex/Branch.hs b/Annex/Branch.hs index 2474b2ae13..bf81830001 100644 --- a/Annex/Branch.hs +++ b/Annex/Branch.hs @@ -752,12 +752,12 @@ stageJournal jl commitindex = withIndex $ withOtherTmp $ \tmpdir -> do genstream dir h jh jlogh streamer = readDirectory jh >>= \case Nothing -> return () Just file -> do - let path = dir P. toRawFilePath file - unless (dirCruft (toRawFilePath file)) $ whenM (isfile path) $ do + let path = dir P. file + unless (dirCruft file) $ whenM (isfile path) $ do sha <- Git.HashObject.hashFile h path - hPutStrLn jlogh file + B.hPutStr jlogh (file <> "\n") streamer $ Git.UpdateIndex.updateIndexLine - sha TreeFile (asTopFilePath $ fileJournal $ toRawFilePath file) + sha TreeFile (asTopFilePath $ fileJournal file) genstream dir h jh jlogh streamer isfile file = isRegularFile <$> R.getFileStatus file -- Clean up the staged files, as listed in the temp log file. diff --git a/Annex/Journal.hs b/Annex/Journal.hs index 8eb1dc880f..72582b6f88 100644 --- a/Annex/Journal.hs +++ b/Annex/Journal.hs @@ -243,17 +243,15 @@ withJournalHandle getjournaldir a = do where -- avoid overhead of creating the journal directory when it already -- exists - opendir d = liftIO (openDirectory (fromRawFilePath d)) + opendir d = liftIO (openDirectory d) `catchIO` (const (createAnnexDirectory d >> opendir d)) {- Checks if there are changes in the journal. -} journalDirty :: (BranchState -> Git.Repo -> RawFilePath) -> Annex Bool journalDirty getjournaldir = do st <- getState - d <- fromRawFilePath <$> fromRepo (getjournaldir st) - liftIO $ - (not <$> isDirectoryEmpty d) - `catchIO` (const $ doesDirectoryExist d) + d <- fromRepo (getjournaldir st) + liftIO $ isDirectoryPopulated d {- Produces a filename to use in the journal for a file on the branch. - The filename does not include the journal directory. diff --git a/Utility/Directory.hs b/Utility/Directory.hs index 20908108f0..70b8f60aa5 100644 --- a/Utility/Directory.hs +++ b/Utility/Directory.hs @@ -37,6 +37,11 @@ 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] diff --git a/Utility/Directory/Stream.hs b/Utility/Directory/Stream.hs index 726f884dd1..509abb68de 100644 --- a/Utility/Directory/Stream.hs +++ b/Utility/Directory/Stream.hs @@ -1,6 +1,6 @@ -{- streaming directory traversal +{- streaming directory reading - - - Copyright 2011-2018 Joey Hess + - Copyright 2011-2025 Joey Hess - - License: BSD-2-clause -} @@ -14,19 +14,20 @@ module Utility.Directory.Stream ( openDirectory, closeDirectory, readDirectory, - isDirectoryEmpty, + isDirectoryPopulated, ) where import Control.Monad -import System.FilePath import Control.Concurrent +import qualified Data.ByteString as B import Data.Maybe import Prelude #ifdef mingw32_HOST_OS import qualified System.Win32 as Win32 +import System.FilePath #else -import qualified System.Posix as Posix +import qualified System.Posix.Directory.ByteString as Posix #endif import Utility.Directory @@ -41,14 +42,14 @@ data DirectoryHandle = DirectoryHandle IsOpen Win32.HANDLE Win32.FindData (MVar type IsOpen = MVar () -- full when the handle is open -openDirectory :: FilePath -> IO DirectoryHandle +openDirectory :: RawFilePath -> IO DirectoryHandle openDirectory path = do #ifndef mingw32_HOST_OS dirp <- Posix.openDirStream path isopen <- newMVar () return (DirectoryHandle isopen dirp) #else - (h, fdat) <- Win32.findFirstFile (path "*") + (h, fdat) <- Win32.findFirstFile (fromRawFilePath path "*") -- Indicate that the fdat contains a filename that readDirectory -- has not yet returned, by making the MVar be full. -- (There's always at least a "." entry.) @@ -76,11 +77,11 @@ closeDirectory (DirectoryHandle isopen h _ alreadyhave) = -- | Reads the next entry from the handle. Once the end of the directory -- is reached, returns Nothing and automatically closes the handle. -readDirectory :: DirectoryHandle -> IO (Maybe FilePath) +readDirectory :: DirectoryHandle -> IO (Maybe RawFilePath) #ifndef mingw32_HOST_OS readDirectory hdl@(DirectoryHandle _ dirp) = do e <- Posix.readDirStream dirp - if null e + if B.null e then do closeDirectory hdl return Nothing @@ -103,18 +104,18 @@ readDirectory hdl@(DirectoryHandle _ h fdat mv) = do where getfn = do filename <- Win32.getFindDataFileName fdat - return (Just filename) + return (Just (toRawFilePath filename)) #endif --- | True only when directory exists and contains nothing. --- Throws exception if directory does not exist. -isDirectoryEmpty :: FilePath -> IO Bool -isDirectoryEmpty d = bracket (openDirectory d) closeDirectory check +-- | True only when directory exists and is not empty. +isDirectoryPopulated :: RawFilePath -> IO Bool +isDirectoryPopulated d = bracket (openDirectory d) closeDirectory check + `catchIO` const (return False) where check h = do v <- readDirectory h case v of - Nothing -> return True + Nothing -> return False Just f - | not (dirCruft (toRawFilePath f)) -> return False + | not (dirCruft f) -> return True | otherwise -> check h