texbuilder-0.1.0.1: TexBuilder/Utils/File.hs
module TexBuilder.Utils.File where
import Control.Monad
import Control.Monad.Extra
import System.Directory
import System.FilePath
import System.Exit
import Numeric.Natural
import Data.Semigroup
import Data.Maybe
listDirAbsolute :: FilePath -> IO [FilePath]
listDirAbsolute dir = do
dir' <- makeAbsolute dir
map (dir'</>) <$> listDirectory dir'
listSubdirs :: Natural -> FilePath -> IO [FilePath]
listSubdirs = walkSubdirs (const pure)
walkSubdirs :: (Natural -> FilePath -> IO a)
-> Natural -> FilePath
-> IO [a]
walkSubdirs f 0 dir = fmap pure $ f 0 dir
walkSubdirs f depth dir = do
paths <- listDirAbsolute dir
dirs <- filterM doesDirectoryExist paths
results <- forM dirs $ walkSubdirs f (depth-1)
(:join results) <$> f depth dir
searchFilesWith :: (FilePath -> Bool) -> [FilePath] -> IO [FilePath]
searchFilesWith f dirs = do
paths <- join <$> forM dirs listDirAbsolute
pure $ filter f paths
-- | Copy file /file/ from dir1 to dir2, creating
-- directories as needed. The path of the resulting
-- copy relative to dir2 will be the same as the path
-- of the original file relative dir1
copyRelative :: FilePath -> FilePath -> FilePath -> IO ()
copyRelative dir1 dir2 file = do
dir1' <- makeAbsolute dir1
let relFile = makeRelative dir1' file
let destFile = dir2 </> relFile
let destDir = takeDirectory destFile
createDirectoryIfMissing True destDir
copyFile file destFile
assertFileEx :: FilePath -> IO ()
assertFileEx file =
unlessM (doesFileExist file) $ do
putStrLn (file <> " does not exist.")
exitFailure
haveExe :: String -> IO Bool
haveExe name = isJust <$> findExecutable name