-- | A module for performing operations on directories.moduleLastik.Directory(chdir,archiveDirectories,writeArchive,writeHashArchive,copyDir,dropRoot,dropRoot',mkdir,rmdir)whereimportSystem.DirectoryimportSystem.FilePathimportSystem.FilePath.FindimportCodec.Archive.ZipimportqualifiedData.ByteString.LazyasBimportControl.MonadimportControl.ExceptionimportData.Digest.Pure.MD5importData.Digest.Pure.SHA-- | Change to the given directory, then execute the given action, then change back to the original directory.chdir::FilePath-- ^ The directory to change to.->IOa-- ^ The action to execute in the given directory.->IOa-- ^ The result of executing the given action.chdirda=bracketgetCurrentDirectorysetCurrentDirectory(\_->setCurrentDirectoryd>>a)-- | Create a zip archive by changing into directories and archiving the contents.archiveDirectories::[(FilePath,FilePath)]-- ^ A list of base directories to change to and contents of that directory to archive.->RecursionPredicate-- ^ The recursion predicate to search for files to archive.->FilterPredicate-- ^ The filter predicate to search for files to archive.->[ZipOption]-- ^ The options during the creation of the archive.->IOArchive-- ^ The constructed archive.archiveDirectoriesdirsrpfpopts=foldM(\a(d,f)->chdird$doj<-findrpfpfaddFilesToArchiveoptsaj)emptyArchivedirs-- | Writes a zip archive to a file.writeArchive::[(FilePath,FilePath)]-- ^ A list of base directories to change to and contents of that directory to archive.->RecursionPredicate-- ^ The recursion predicate to search for files to archive.->FilterPredicate-- ^ The filter predicate to search for files to archive.->[ZipOption]-- ^ The options during the creation of the archive.->FilePath-- ^ The file to write the archive to.->IO()writeArchivedirsrpfpoptsf=doa<-archiveDirectoriesdirsrpfpoptsB.writeFilef(fromArchivea)-- | Writes a zip archive to a file then computes a MD5 and SHA1 hash and writes them to files with @".MD5"@ and @".SHA"@ extensions.writeHashArchive::[(FilePath,FilePath)]-- ^ A list of base directories to change to and contents of that directory to archive.->RecursionPredicate-- ^ The recursion predicate to search for files to archive.->FilterPredicate-- ^ The filter predicate to search for files to archive.->[ZipOption]-- ^ The options during the creation of the archive.->FilePath-- ^ The file to write the archive to and the prefix name of the files containing the hashes.->IO()writeHashArchivedirsrpfpoptsf=doa<-archiveDirectoriesdirsrpfpoptslets=fromArchiveaB.writeFilefswriteFile(f<.>"MD5")(show(md5s))writeFile(f<.>"SHA")(show(sha1s))-- | Copy the contents of a directory to another, perhaps trimming parent directories.copyDir::RecursionPredicate-- ^ The recursion predicate to search for files in the source directory.->FilterPredicate-- ^ The filter predicate to search for files in the source directory.->Int-- ^ The number of parent directories to drop before copying to the target directory.->FilePath-- ^ The source directory.->FilePath-- ^ The target directory.->IO()copyDirrpfplevelsfromto=dos<-findrpfpfromforM_s(\f->letd=dropRoot'levelsfindomkdir(to</>dropFileNamed)copyFilef(to</>d))-- | Drops the parent directory of a given file path.---- > dropRoot "/foo/bar" == "/bar"-- > dropRoot "foo/bar" == "bar"-- > dropRoot "foo" == ""-- > dropRoot "" == ""dropRoot::FilePath-- ^ The file path to drop the parent directory from.->String-- ^ The file path without a parent directory.dropRoot[]=[]dropRoot(x:xs)=(ifx==pathSeparatorthenidelsedrop1)(dropWhile(/=pathSeparator)xs)-- | Drops the parent directory ('dropRoot') of a given file path multiple times.---- > dropRoot' 0 "/foo/bar" == "/foo/bar"-- > dropRoot' 1 "/foo/bar" == "/bar"-- > dropRoot' 1 "foo/bar" == "bar"-- > dropRoot' 2 "foo/bar" == ""-- > dropRoot' 10 "foo/bar" == ""dropRoot'::Int-- ^ The number of times to drop the parent directory.->FilePath-- ^ The file path to drop parent directories from.->FilePath-- ^ Te file path without parent directories.dropRoot'nk=(iteratedropRootk)!!(ifn<0then0elsen)-- | Creates the given directory and its parents if it doesn't exist.mkdir::FilePath-- ^ The directory to create.->IO()mkdir=createDirectoryIfMissingTrue-- | Removes the given directory recursively if it exists.rmdir::FilePath-- ^ The directory to remove.->IO()rmdird=doesDirectoryExistd>>=flipwhen(removeDirectoryRecursived)