Konstantine Rybnikov avatar Konstantine Rybnikov committed e1c3c4c

implement most things ready for grouping by content, except for groupsFromMap

Comments (0)

Files changed (2)

 
 *_flymake*
 *.hi
+*.o
+duplicates
-import System.Environment
-import System.Directory
+import System.Environment (getArgs)
+import System.Directory (getDirectoryContents, doesDirectoryExist, doesFileExist)
+import System.IO (openFile, IOMode(ReadMode))
+import Control.Monad (foldM)
+import Data.ByteString.Lazy (hGetContents)
+import qualified Data.Map as Map
+
+data DuplicateReason = SameContents deriving (Show)
+data DuplicateGroup = DuplicateGroup { getFiles :: [FilePath]
+                                     , getReasons :: [DuplicateReason]
+                                     } deriving (Show)
 
 safeHead :: [a] -> Maybe a
 safeHead [] = Nothing
 
 mainWithValidPath :: FilePath -> IO ()
 mainWithValidPath path = do
-  let duplicateGroups = getDuplicateGroups path
+  duplicateGroups <- getDuplicateGroups path
   printDuplicateGroups duplicateGroups
   return ()
 
-data DuplicateGroup = DuplicateGroup deriving (Show)
-
-getDuplicateGroups :: FilePath -> [DuplicateGroup]
-getDuplicateGroups = undefined
+getDuplicateGroups :: FilePath -> IO [DuplicateGroup]
+getDuplicateGroups path = do
+  paths <- allPossibleFiles path
+  getDuplicateFiles paths
 
 printDuplicateGroups :: [DuplicateGroup] -> IO ()
 printDuplicateGroups groups = do
   let showedGroups = (map show groups)
   putStrLn (concat showedGroups)
   return ()
+
+getDuplicateFiles :: [FilePath] -> IO [DuplicateGroup]
+getDuplicateFiles paths = getDuplicatesBySameContents paths
+
+allPossibleFiles :: FilePath -> IO [FilePath]
+allPossibleFiles path = do
+  dirEntries <- getDirectoryContents path
+  (files, dirs) <- splitOnFilesAndDirs dirEntries
+  return []
+
+splitOnFilesAndDirs :: [FilePath] -> IO ([FilePath], [FilePath])
+splitOnFilesAndDirs paths = do
+  foldM f ([], []) (reverse paths)
+  where f (files, dirs) x = do
+          xExist <- doesFileExist x
+          if xExist
+            then return (x:files, dirs)
+            else return (files, x:dirs)
+
+getDuplicatesBySameContents :: [FilePath] -> IO [DuplicateGroup]
+getDuplicatesBySameContents paths = do
+  hs <- mapM (\path -> openFile path ReadMode) paths
+  contents <- mapM hGetContents hs
+  let pairs = zip paths contents
+  return (getDuplicateGroupsByFilepathAndIdentityData pairs)
+
+getDuplicateGroupsByFilepathAndIdentityData ::
+  (Eq a, Ord a) => [(FilePath, a)] -> [DuplicateGroup]
+getDuplicateGroupsByFilepathAndIdentityData pairs =
+  let resM = foldr f Map.empty pairs
+        where f p m = Map.insertWith (++) (snd p) (fst p) m
+  in groupsFromMap resM
+
+groupsFromMap :: (Eq a, Ord a) => Map.Map a FilePath -> [DuplicateGroup]
+groupsFromMap = undefined
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.