module Language.Haskell.Modules.Util.Test ( repoModules , logicModules , diff , diff' , rsync , findHsModules , findHsFiles ) where import Control.Monad (foldM) import Data.List as List (filter, isPrefixOf, isSuffixOf, map) import System.Directory (doesDirectoryExist, doesFileExist, getDirectoryContents) import System.Exit (ExitCode) import System.FilePath (()) import System.Process (readProcess, readProcessWithExitCode) repoModules :: [String] repoModules = [ "Debian.Repo.Sync" , "Debian.Repo.Slice" , "Debian.Repo.SourcesList" , "Debian.Repo.PackageIndex" , "Debian.Repo.Types" , "Debian.Repo.Types.Slice" , "Debian.Repo.Types.Repository" , "Debian.Repo.Types.PackageIndex" , "Debian.Repo.Types.Release" , "Debian.Repo.Types.AptImage" , "Debian.Repo.Types.Repo" , "Debian.Repo.Types.AptBuildCache" , "Debian.Repo.Types.EnvPath" , "Debian.Repo.Types.AptCache" , "Debian.Repo.Orphans" , "Debian.Repo.Types" , "Debian.Repo.AptImage" , "Debian.Repo.Package" , "Debian.Repo.Monads.Top" , "Debian.Repo.Monads.Apt" , "Debian.Repo.AptCache" , "Tmp.File" , "Text.Format" ] logicModules :: [String] logicModules = [ "Data.Boolean.SatSolver" , "Data.Boolean" , "Data.Logic.Resolution" , "Data.Logic.KnowledgeBase" , "Data.Logic.Types.FirstOrder" , "Data.Logic.Types.Common" , "Data.Logic.Types.Harrison.Formulas.FirstOrder" , "Data.Logic.Types.Harrison.Formulas.Propositional" , "Data.Logic.Types.Harrison.Prop" , "Data.Logic.Types.Harrison.Equal" , "Data.Logic.Types.Harrison.FOL" , "Data.Logic.Types.Propositional" , "Data.Logic.Types.FirstOrderPublic" , "Data.Logic.Harrison.Unif" , "Data.Logic.Harrison.Meson" , "Data.Logic.Harrison.Herbrand" , "Data.Logic.Harrison.Formulas.FirstOrder" , "Data.Logic.Harrison.Formulas.Propositional" -- , "Data.Logic.Harrison.Tests" , "Data.Logic.Harrison.Resolution" , "Data.Logic.Harrison.DefCNF" , "Data.Logic.Harrison.Skolem" , "Data.Logic.Harrison.Prop" , "Data.Logic.Harrison.DP" , "Data.Logic.Harrison.Lib" , "Data.Logic.Harrison.PropExamples" , "Data.Logic.Harrison.Prolog" , "Data.Logic.Harrison.Tableaux" , "Data.Logic.Harrison.Equal" , "Data.Logic.Harrison.Normal" , "Data.Logic.Harrison.FOL" , "Data.Logic.Failing" , "Data.Logic.Instances.SatSolver" -- , "Data.Logic.Instances.TPTP" , "Data.Logic.Instances.Chiou" , "Data.Logic.Instances.PropLogic" , "Data.Logic.Normal.Clause" , "Data.Logic.Normal.Implicative" , "Data.Logic.Classes.FirstOrder" , "Data.Logic.Classes.Variable" , "Data.Logic.Classes.Apply" , "Data.Logic.Classes.Negate" , "Data.Logic.Classes.Pretty" , "Data.Logic.Classes.Arity" , "Data.Logic.Classes.Skolem" , "Data.Logic.Classes.Combine" , "Data.Logic.Classes.Constants" , "Data.Logic.Classes.Equals" , "Data.Logic.Classes.Propositional" , "Data.Logic.Classes.Atom" , "Data.Logic.Classes.Formula" , "Data.Logic.Classes.ClauseNormalForm" , "Data.Logic.Classes.Term" , "Data.Logic.Classes.Literal" , "Data.Logic.Satisfiable" ] diff :: FilePath -> FilePath -> IO (ExitCode, String, String) diff a b = do (code, out, err) <- readProcessWithExitCode "diff" ["-ru", "--exclude=*~", "--exclude=*.imports", a, b] "" let out' = unlines (List.filter (not . isPrefixOf "Binary files") . List.map (takeWhile (/= '\t')) $ (lines out)) return (code, out', err) -- | Like diff, but ignores extra files in b. diff' :: FilePath -> FilePath -> IO (ExitCode, String, String) diff' a b = do (code, out, err) <- readProcessWithExitCode "diff" ["-ru", "--unidirectional-new-file", "--exclude=*~", "--exclude=*.imports", a, b] "" let out' = unlines (List.filter (not . isPrefixOf "Binary files") . List.map (takeWhile (/= '\t')) $ (lines out)) return (code, out', err) rsync :: FilePath -> FilePath -> IO () rsync a b = readProcess "rsync" ["-aHxS", "--delete", a ++ "/", b] "" >> return () -- | Find the paths of all the files below the directory @top@. findHsFiles :: [FilePath] -> IO [FilePath] findHsFiles tops = foldM doPath [] tops where doPath r path = do dir <- doesDirectoryExist path reg <- doesFileExist path case () of _ | dir -> doDirectory r path _ | reg && isSuffixOf ".hs" path -> return (path : r) _ -> return r doDirectory r path = getDirectoryContents path >>= foldM doPath r . List.map (path ) . filter (\ x -> x /= "." && x /= "..") -- | Convenience function for building the moduVerse, searches for -- modules in a directory hierarchy. FIXME: This should be in -- MonadClean and use the value of sourceDirs to remove prefixes from -- the module paths. And then it should look at the module text to -- see what the module name really is. findHsModules :: [FilePath] -> IO [String] findHsModules tops = findHsFiles tops >>= return . List.map asModuleName where asModuleName path = List.map (\ c -> if c == '/' then '.' else c) (take (length path - 3) path)