Lastik 0.2 → 0.3
raw patch · 7 files changed
+223/−16 lines, 7 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Lastik.Compile: environmentCommand :: String -> String -> IO String
+ Lastik.Find: (&&?) :: (Applicative f) => f Bool -> f Bool -> f Bool
+ Lastik.Find: (/==>) :: (Applicative f1, Applicative f2) => f1 (f2 Bool) -> f1 (f2 Bool) -> f1 (f2 Bool)
+ Lastik.Find: (/=>) :: (Applicative f) => f Bool -> f Bool -> f Bool
+ Lastik.Find: (/=?) :: (Eq a, Functor f) => f a -> a -> f Bool
+ Lastik.Find: (<?>) :: FilePather a -> FilePath -> a
+ Lastik.Find: (===>) :: (Applicative f1, Applicative f2) => f1 (f2 Bool) -> f1 (f2 Bool) -> f1 (f2 Bool)
+ Lastik.Find: (==>) :: (Applicative f) => f Bool -> f Bool -> f Bool
+ Lastik.Find: (==?) :: (Eq a, Functor f) => f a -> a -> f Bool
+ Lastik.Find: (?&&?) :: (Applicative f1, Applicative f2) => f1 (f2 Bool) -> f1 (f2 Bool) -> f1 (f2 Bool)
+ Lastik.Find: (?||?) :: (Applicative f1, Applicative f2) => f1 (f2 Bool) -> f1 (f2 Bool) -> f1 (f2 Bool)
+ Lastik.Find: (||?) :: (Applicative f) => f Bool -> f Bool -> f Bool
+ Lastik.Find: Directory :: FileType
+ Lastik.Find: File :: FileType
+ Lastik.Find: FilePather :: (FilePath -> a) -> FilePather a
+ Lastik.Find: Unknown :: FileType
+ Lastik.Find: always :: FilePather Bool
+ Lastik.Find: always' :: FilePather (a -> Bool)
+ Lastik.Find: baseName :: FilePather FilePath
+ Lastik.Find: baseName' :: FilePather (a -> FilePath)
+ Lastik.Find: constant :: (Functor f) => f a -> f (t -> a)
+ Lastik.Find: data FileType
+ Lastik.Find: directory :: FilePather FilePath
+ Lastik.Find: directory' :: FilePather (a -> FilePath)
+ Lastik.Find: extension :: FilePather FilePath
+ Lastik.Find: extension' :: FilePather (a -> FilePath)
+ Lastik.Find: fileName :: FilePather FilePath
+ Lastik.Find: fileName' :: FilePather (a -> FilePath)
+ Lastik.Find: filePath :: FilePather FilePath
+ Lastik.Find: filePather :: (FilePath -> a) -> FilePather a
+ Lastik.Find: find :: RecursePredicate -> FilterPredicate -> FilePath -> IO [FilePath]
+ Lastik.Find: hasExtension :: FilePather Bool
+ Lastik.Find: hasExtension' :: FilePather (a -> Bool)
+ Lastik.Find: hasTrailingPathSeparator :: FilePather Bool
+ Lastik.Find: hasTrailingPathSeparator' :: FilePather (a -> Bool)
+ Lastik.Find: instance (Monoid a) => Monoid (FilePather a)
+ Lastik.Find: instance Applicative FilePather
+ Lastik.Find: instance Eq FileType
+ Lastik.Find: instance Functor FilePather
+ Lastik.Find: instance Monad FilePather
+ Lastik.Find: instance Show FileType
+ Lastik.Find: isAbsolute :: FilePather Bool
+ Lastik.Find: isAbsolute' :: FilePather (a -> Bool)
+ Lastik.Find: isDirectory :: (Applicative f) => f (FileType -> Bool)
+ Lastik.Find: isFile :: (Applicative f) => f (FileType -> Bool)
+ Lastik.Find: isRelative :: FilePather Bool
+ Lastik.Find: isRelative' :: FilePather (a -> Bool)
+ Lastik.Find: isUnknown :: (Applicative f) => f (FileType -> Bool)
+ Lastik.Find: isValid :: FilePather Bool
+ Lastik.Find: isValid' :: FilePather (a -> Bool)
+ Lastik.Find: makeValid :: FilePather FilePath
+ Lastik.Find: makeValid' :: FilePather (a -> FilePath)
+ Lastik.Find: never :: FilePather Bool
+ Lastik.Find: never' :: FilePather (a -> Bool)
+ Lastik.Find: newtype FilePather a
+ Lastik.Find: normalise :: FilePather FilePath
+ Lastik.Find: normalise' :: FilePather (a -> FilePath)
+ Lastik.Find: not' :: (Functor f) => f Bool -> f Bool
+ Lastik.Find: splitDirectories :: FilePather [FilePath]
+ Lastik.Find: splitDirectories' :: FilePather (a -> [FilePath])
+ Lastik.Find: splitExtension :: FilePather (String, String)
+ Lastik.Find: splitExtension' :: FilePather (a -> (String, String))
+ Lastik.Find: type FilterPredicate = FilePather (FileType -> Bool)
+ Lastik.Find: type RecursePredicate = FilePather Bool
+ Lastik.Util: ifM :: (Monad f) => f Bool -> f a -> f a -> f a
- Lastik.Directory: archiveDirectories :: [(FilePath, FilePath)] -> RecursionPredicate -> FilterPredicate -> [ZipOption] -> IO Archive
+ Lastik.Directory: archiveDirectories :: [(FilePath, FilePath)] -> RecursePredicate -> FilterPredicate -> [ZipOption] -> IO Archive
- Lastik.Directory: copyDir :: RecursionPredicate -> FilterPredicate -> Int -> FilePath -> FilePath -> IO ()
+ Lastik.Directory: copyDir :: RecursePredicate -> FilterPredicate -> Int -> FilePath -> FilePath -> IO ()
- Lastik.Directory: writeArchive :: [(FilePath, FilePath)] -> RecursionPredicate -> FilterPredicate -> [ZipOption] -> FilePath -> IO ()
+ Lastik.Directory: writeArchive :: [(FilePath, FilePath)] -> RecursePredicate -> FilterPredicate -> [ZipOption] -> FilePath -> IO ()
- Lastik.Directory: writeHashArchive :: [(FilePath, FilePath)] -> RecursionPredicate -> FilterPredicate -> [ZipOption] -> FilePath -> IO ()
+ Lastik.Directory: writeHashArchive :: [(FilePath, FilePath)] -> RecursePredicate -> FilterPredicate -> [ZipOption] -> FilePath -> IO ()
Files
- Lastik.cabal +3/−2
- Lastik/Compile.hs +9/−1
- Lastik/Directory.hs +7/−8
- Lastik/Find.hs +192/−0
- Lastik/Output.hs +2/−2
- Lastik/Runner.hs +2/−2
- Lastik/Util.hs +8/−1
Lastik.cabal view
@@ -1,5 +1,5 @@ Name: Lastik-Version: 0.2+Version: 0.3 License: BSD3 License-File: LICENSE Author: Tony Morris <code@tmorris.net>@@ -16,7 +16,7 @@ Library if flag(small_base)- Build-Depends: base < 4 && >= 3, bytestring, directory, filepath, process, FileManip, zip-archive, pureMD5, SHA+ Build-Depends: base < 4 && >= 3, bytestring, directory, filepath, process, zip-archive, pureMD5, SHA else Build-Depends: base < 3, filepath, process, FileManip, zip-archive, pureMD5, SHA @@ -25,6 +25,7 @@ Lastik.Compile, Lastik.Directory, Lastik.Extension,+ Lastik.Find, Lastik.Output, Lastik.Runner, Lastik.Util,
Lastik/Compile.hs view
@@ -3,14 +3,18 @@ -- | A module for representing data types that can be compiled by taking a list of files. module Lastik.Compile ( Compile,- compile+ compile,+ environmentCommand ) where import Control.Monad import Data.List+import Data.Maybe import System.Directory import System.Cmd import System.Exit+import System.Environment+import System.FilePath -- | A class of compilable data types. class Compile c where@@ -21,3 +25,7 @@ instance Compile ([FilePath] -> String) where compile = id++environmentCommand :: String -> String -> IO String+environmentCommand v c = (\e -> (case lookup v e of Nothing -> c+ Just k -> k </> c) ++ " ") `fmap` getEnvironment
Lastik/Directory.hs view
@@ -13,7 +13,7 @@ import System.Directory import System.FilePath-import System.FilePath.Find+import Lastik.Find import Codec.Archive.Zip import qualified Data.ByteString.Lazy as B import Control.Monad@@ -29,7 +29,7 @@ -- | 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.+ -> RecursePredicate -- ^ 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. -> IO Archive -- ^ The constructed archive.@@ -38,7 +38,7 @@ -- | 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.+ -> RecursePredicate -- ^ 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.@@ -46,9 +46,9 @@ writeArchive dirs rp fp opts f = do a <- archiveDirectories dirs rp fp opts B.writeFile f (fromArchive a) --- | Writes a zip archive to a file then computes a MD5 and SHA1 hash and writes them to files with @".MD5"@ and @".SHA"@ extensions.+-- | Writes a zip archive to a file then computes a MD5 and SHA1 hash and writes them to files with @".md5"@ and @".sha1"@ 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.+ -> RecursePredicate -- ^ 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.@@ -56,11 +56,10 @@ writeHashArchive dirs rp fp opts f = do a <- archiveDirectories dirs rp fp opts let s = fromArchive a B.writeFile f s- writeFile (f <.> "MD5") (show (md5 s))- writeFile (f <.> "SHA") (show (sha1 s))+ forM_ [(show . md5, "md5"), (show . sha1, "sha1")] (\(k, a) -> writeFile (f <.> a) (k s)) -- | 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.+copyDir :: RecursePredicate -- ^ 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.
+ Lastik/Find.hs view
@@ -0,0 +1,192 @@+module Lastik.Find where++import Control.Applicative+import Control.Monad+import Control.Monad.Instances+import Data.Monoid+import System.FilePath+import System.Directory+import qualified System.FilePath as P+import Lastik.Util++newtype FilePather a = FilePather {+ (<?>) :: FilePath -> a+}++instance Functor FilePather where+ fmap f (FilePather k) = FilePather (f . k)++instance Applicative FilePather where+ FilePather f <*> FilePather a = FilePather (f <*> a)+ pure = FilePather . const++instance Monad FilePather where+ FilePather f >>= k = FilePather (f >>= (<?>) . k)+ return = pure++instance (Monoid a) => Monoid (FilePather a) where+ mempty = return mempty+ FilePather x `mappend` FilePather y = FilePather (x `mappend` y)++filePather :: (FilePath -> a) -> FilePather a+filePather = FilePather++filePath :: FilePather FilePath+filePath = filePather id++always :: FilePather Bool+always = filePather (\_ -> True)++always' :: FilePather (a -> Bool)+always' = constant always++never :: FilePather Bool+never = filePather (\_ -> False)++never' :: FilePather (a -> Bool)+never' = constant never++extension :: FilePather FilePath+extension = filePather takeExtension++extension' :: FilePather (a -> FilePath)+extension' = constant extension++directory :: FilePather FilePath+directory = filePather takeDirectory++directory' :: FilePather (a -> FilePath)+directory' = constant directory++hasExtension :: FilePather Bool+hasExtension = filePather P.hasExtension++hasExtension' :: FilePather (a -> Bool)+hasExtension' = constant Lastik.Find.hasExtension++splitExtension :: FilePather (String, String)+splitExtension = filePather P.splitExtension++splitExtension' :: FilePather (a -> (String, String))+splitExtension' = constant Lastik.Find.splitExtension++splitDirectories :: FilePather [FilePath]+splitDirectories = filePather P.splitDirectories++splitDirectories' :: FilePather (a -> [FilePath])+splitDirectories' = constant Lastik.Find.splitDirectories++hasTrailingPathSeparator :: FilePather Bool+hasTrailingPathSeparator = filePather P.hasTrailingPathSeparator++hasTrailingPathSeparator' :: FilePather (a -> Bool)+hasTrailingPathSeparator' = constant Lastik.Find.hasTrailingPathSeparator++fileName :: FilePather FilePath+fileName = filePather takeFileName++fileName' :: FilePather (a -> FilePath)+fileName' = constant fileName++baseName :: FilePather FilePath+baseName = filePather takeBaseName++baseName' :: FilePather (a -> FilePath)+baseName' = constant baseName++normalise :: FilePather FilePath+normalise = filePather P.normalise++normalise' :: FilePather (a -> FilePath)+normalise' = constant Lastik.Find.normalise++makeValid :: FilePather FilePath+makeValid = filePather P.makeValid++makeValid' :: FilePather (a -> FilePath)+makeValid' = constant Lastik.Find.makeValid++isRelative :: FilePather Bool+isRelative = filePather P.isRelative++isRelative' :: FilePather (a -> Bool)+isRelative' = constant Lastik.Find.isRelative++isAbsolute :: FilePather Bool+isAbsolute = filePather P.isAbsolute++isAbsolute' :: FilePather (a -> Bool)+isAbsolute' = constant Lastik.Find.isAbsolute++isValid :: FilePather Bool+isValid = filePather P.isValid++isValid' :: FilePather (a -> Bool)+isValid' = constant Lastik.Find.isValid++not' :: (Functor f) => f Bool -> f Bool+not' = fmap not++constant :: (Functor f) => f a -> f (t -> a)+constant p = fmap const p++(==?) :: (Eq a, Functor f) => f a -> a -> f Bool+p ==? a = fmap (a ==) p++(/=?) :: (Eq a, Functor f) => f a -> a -> f Bool+p /=? a = fmap (a /=) p++(==>) :: (Applicative f) => f Bool -> f Bool -> f Bool+(==>) = liftA2 (\p q -> not p || q)++(===>) :: (Applicative f1, Applicative f2) => f1 (f2 Bool) -> f1 (f2 Bool) -> f1 (f2 Bool)+(===>) = liftA2 (==>)++(/=>) :: (Applicative f) => f Bool -> f Bool -> f Bool+(/=>) = liftA2 (\p q -> not q && p)++(/==>) :: (Applicative f1, Applicative f2) => f1 (f2 Bool) -> f1 (f2 Bool) -> f1 (f2 Bool)+(/==>) = liftA2 (/=>)++(&&?) :: (Applicative f) => f Bool -> f Bool -> f Bool+(&&?) = liftA2 (&&)++(?&&?) :: (Applicative f1, Applicative f2) => f1 (f2 Bool) -> f1 (f2 Bool) -> f1 (f2 Bool)+(?&&?) = liftA2 (&&?)++(||?) :: (Applicative f) => f Bool -> f Bool -> f Bool+(||?) = liftA2 (||)++(?||?) :: (Applicative f1, Applicative f2) => f1 (f2 Bool) -> f1 (f2 Bool) -> f1 (f2 Bool)+(?||?) = liftA2 (||?)++data FileType = File | Directory | Unknown deriving (Eq, Show)++type RecursePredicate = FilePather Bool+type FilterPredicate = FilePather (FileType -> Bool)++isFile :: (Applicative f) => f (FileType -> Bool)+isFile = pure (== File)++isDirectory :: (Applicative f) => f (FileType -> Bool)+isDirectory = pure (== Directory)++isUnknown :: (Applicative f) => f (FileType -> Bool)+isUnknown = pure (== Unknown)++find :: RecursePredicate -> FilterPredicate -> FilePath -> IO [FilePath]+find = find' []+ where+ find' :: FilePath -> RecursePredicate -> FilterPredicate -> FilePath -> IO [FilePath]+ find' k r f p = let z = if null k then p else k </> p+ z' t = if f <?> z $ t then [z] else []+ in ifM (doesFileExist z)+ (return (z' File)) $+ do e <- doesDirectoryExist z+ if e+ then if r <?> z+ then do c <- getDirectoryContents z+ t <- fmap join $ forM (filter (`notElem` [".", ".."]) c) (find' k r f . (z </>))+ return (z' Directory ++ t)+ else return (z' Directory)+ else return (z' Unknown)
Lastik/Output.hs view
@@ -17,7 +17,7 @@ import Control.Monad.Instances import Data.Maybe import System.Directory-import System.FilePath.Find+import Lastik.Find -- | A class of data types that have a potential output target. class Output o where@@ -86,5 +86,5 @@ d <===> s = case output d of Nothing -> return s Just k -> do e <- doesDirectoryExist k if e- then find always always k >>= (\t -> t <==> s)+ then find always always' k >>= (\t -> t <==> s) else return s
Lastik/Runner.hs view
@@ -22,7 +22,7 @@ import System.Cmd import System.Directory import System.Exit-import System.FilePath.Find+import Lastik.Find import Lastik.Compile import Lastik.Extension import Lastik.Output@@ -86,7 +86,7 @@ pathTransform' :: (Extension e) => e -> Runner r -> Runner r pathTransform' = pathTransform . recurse where- recurse c p = fmap concat $ find always (extension ==? ext' c) `mapM` p+ recurse c p = fmap concat $ find always (constant $ extension ==? ext' c) `mapM` p -- | Execute the compile result as a system command. (!!!) :: (Compile c) => Runner c
Lastik/Util.hs view
@@ -16,7 +16,8 @@ (^^^), space, space',- uncons+ uncons,+ ifM ) where import System.Exit@@ -132,3 +133,9 @@ uncons x _ [] = x uncons _ f (h:t) = f h t +-- | if/then/else with a lifted predicate.+ifM :: (Monad f) => f Bool -> f a -> f a -> f a+ifM c t f = do c' <- c+ t' <- t+ f' <- f+ return (if c' then t' else f')