module Static.Resources.Checker (
check,
isStaticResourceFile
) where
import System.IO.HVFS.Utils
import Data.List
import Control.Monad
import Static.Resources.Types
import Data.Functor
import Control.Monad.Error
import System.Directory
check :: String -> ResourceSpec -> IO (Either String ())
check dir spec = do
sysFiles <- mapM canonicalizePath =<< filter isStaticResourceFile <$> recurseDir SystemFS dir
specFiles <- mapM (\r -> canonicalizePath $ dir ++ "/" ++ path r) $ (join $ resources <$> sets spec)
ignoredFiles <- mapM (\p -> canonicalizePath $ dir ++ "/" ++ p) $ ignored spec
let diff a b = fileDiff (sort $ nub a) (sort $ nub b)
runErrorT $ do
when (not $ null $ diff sysFiles (specFiles ++ ignoredFiles)) $
throwError $ "Files from some sets are not availble in FS: \n" ++ (unlines $ diff sysFiles (specFiles ++ ignoredFiles)) ++ "\n\n"
when (not $ null $ diff (specFiles ++ ignoredFiles) sysFiles) $
throwError $ "Some files on filesystem are not listed in any set or ignored: \n" ++ (unlines $ diff (specFiles ++ ignoredFiles) sysFiles) ++ "\n\n"
fileDiff:: [FilePath] -> [FilePath] -> [FilePath]
fileDiff (f1:f1s) (f2:f2s)
| (isDir f1 && f1 `isPrefixOf` f2) = fileDiff (f1:f1s) f2s
| (isDir f2 && f2 `isPrefixOf` f1) = fileDiff f1s (f2 : f2s)
| (f1 == f2) = fileDiff f1s f2s
| (f1 <= f2) && (isDir f1) = fileDiff f1s (f2:f2s)
| (f1 <= f2) = f1 : (fileDiff f1s (f2:f2s))
| otherwise = fileDiff (f1:f1s) f2s
fileDiff [] fs = filter (not . isDir) fs
fileDiff _ _ = []
isDir :: String -> Bool
isDir = not . isStaticResourceFile
isStaticResourceFile :: String -> Bool
isStaticResourceFile fn = any (`isSuffixOf` fn) [".css",".js",".less"]