filediff 0.1.0.7 → 0.1.0.8
raw patch · 5 files changed
+100/−31 lines, 5 filesdep +bytestringdep +rainbowPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
Dependencies added: bytestring, rainbow
API changes (from Hackage documentation)
+ Filediff.Printing: printDiff :: Diff -> IO ()
+ Filediff.Printing: printFilediff :: Filediff -> IO ()
+ Filediff.Printing: printSeqdiff :: SeqDiff Line -> IO ()
Files
- filediff.cabal +3/−3
- src/Filediff.hs +5/−3
- src/Filediff/Printing.hs +68/−0
- src/Filediff/Sequence.hs +16/−17
- src/Filediff/Types.hs +8/−8
filediff.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: filediff-version: 0.1.0.7+version: 0.1.0.8 synopsis: Diffing and patching module description: `filediff` is a Haskell library for creating diffs, and applying diffs to files and directories. homepage: https://github.com/bgwines/filediff@@ -20,10 +20,10 @@ location: git://github.com/bgwines/filediff.git library- exposed-modules: Filediff, Filediff.Types, Filediff.Sequence, Filediff.Stats+ exposed-modules: Filediff, Filediff.Types, Filediff.Sequence, Filediff.Stats, Filediff.Printing other-modules: Filediff.Utils -- other-extensions:- build-depends: base >=4.7 && <4.8, mtl, time, directory, either, transformers, data-memocombinators, Zora >=1.1.22, text, data-default, tasty, tasty-hunit+ build-depends: base >=4.7 && <4.8, mtl, time, directory, either, transformers, data-memocombinators, Zora >=1.1.22, text, data-default, tasty, tasty-hunit, rainbow, bytestring hs-source-dirs: src default-language: Haskell2010
src/Filediff.hs view
@@ -156,7 +156,8 @@ shouldIgnore :: [FilePath] -> FilePath -> Bool shouldIgnore toIgnore filepath = any (flip isPrefix $ filepath) toIgnore --- | /O(n)/. Apply a diff to a directory or file+-- | /O(n)/. Apply a diff to a file. Throws an exception if the+-- application fails. applyToFile :: Filediff -> FilePath -> IO [Line]--EitherT Error IO () applyToFile (Filediff _ _ change) filepath = do case change of@@ -176,13 +177,14 @@ -- need, here (because of the write right after) file <- TIO.readFile filepath let result = applySequenceDiff seqdiff . T.lines $ file- TIO.writeFile filepath (safeInit . T.unlines $ result) -- init for trailing \n+ TIO.writeFile filepath (safeInit . T.unlines $ result) -- `init` for trailing \n return result safeInit :: T.Text -> T.Text safeInit x = if T.null x then x else T.init x --- | `True` upon success; `False` upon failure+-- | Applies a `Diff` to a directory. Throws an exception if the+-- application fails. applyToDirectory :: Diff -> FilePath -> IO () applyToDirectory (Diff filediffs) filepath = mapM_ apply filediffs where
+ src/Filediff/Printing.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}++-- | A module for printing 'Filediff' data types to the console.+module Filediff.Printing+( printDiff+, printFilediff+, printSeqdiff+) where++import Rainbow++import Zora.List as ZL (merge_by)++import qualified Data.Text as T+import qualified Data.Text.Encoding as T+import qualified Data.ByteString.Char8 as ByteString++import Filediff.Types+import Filediff.Sequence++-- | Prints a 'SeqDiff Line'. Prints with colors and some formatting.+printSeqdiff :: SeqDiff Line -> IO ()+printSeqdiff (SeqDiff dels adds) = do+ let deletedLines = zip (repeat "del") (zip dels (repeat ""))+ let addedLines = zip (repeat "add") (adds)++ let interleaved = ZL.merge_by mergeCmpFn deletedLines addedLines+ mapM_ printLine interleaved+ where+ mergeCmpFn :: (String, (Int, Line)) -> (String, (Int, Line)) -> Ordering+ mergeCmpFn (_, (i, _)) (_, (j, _)) = i `compare` j++ printLine :: (String, (Int, Line)) -> IO ()+ printLine (t, (i, line)) = do+ putChunkLn $ chunk (T.encodeUtf8 line') & color+ where+ line' :: Line+ line' = if t == "del"+ then T.pack $ "- <Line " ++ (show i) ++ ">"+ else (T.pack "+ ") <> line++ color :: Chunk a -> Chunk a+ color = if t == "del"+ then fore red+ else fore green++-- | Prints a 'Filediff'. Prints with colors and some formatting.+printFilediff :: Filediff -> IO ()+printFilediff (Filediff base comp change) = do+ let diffType :: ByteString = case change of {+ Add _ -> "(file addition)";+ Mod _ -> "(file modification)";+ Del _ -> "(file deletion)"; }+ let diffDescription :: ByteString = "diff a/" <> (ByteString.pack base) <> " b/" <> (ByteString.pack comp) <> " " <> diffType+ putChunkLn $ chunk diffDescription & fore brightWhite & bold++ let delLine :: ByteString = "--- a/" <> (ByteString.pack base)+ let addLine :: ByteString = "+++ b/" <> (ByteString.pack comp)+ putChunkLn $ chunk delLine & fore brightWhite & bold+ putChunkLn $ chunk addLine & fore brightWhite & bold++ printSeqdiff $ seqDiff change+ putChunkLn $ chunk ("" :: ByteString)++-- | Prints a 'Diff'. Prints with colors and some formatting.+printDiff :: Diff -> IO ()+printDiff = mapM_ printFilediff . filediffs
src/Filediff/Sequence.hs view
@@ -114,8 +114,8 @@ -- | returns (to delete, to add) -- --- > diffSequences "abcdefg" "wabxyze"--- SeqDiff {dels = [2,3,5,6], adds = [(0,'w'),(3,'x'),(4,'y'),(5,'z')]}+-- > λ diffSequences "abcdefg" "wabxyze"+-- > SeqDiff {dels = [2,3,5,6], adds = [(0,'w'),(3,'x'),(4,'y'),(5,'z')]} diffSequences :: forall a. (Eq a, MemoTable a) => [a] -> [a] -> SeqDiff a diffSequences a b = SeqDiff (nonSubsequenceIndices common a)@@ -124,27 +124,26 @@ common :: [a] common = longestCommonSubsequence a b - -- | λ add- -- | [(0,"w"),(3,"x"),(4,"y")]- -- | λ common- -- | ["a","b","e"]+ -- | > λ add+ -- > [(0,"w"),(3,"x"),(4,"y")]+ -- > λ common+ -- > ["a","b","e"] getProgressiveIndicesToAdd :: (Eq a) => [a] -> [a] -> [(Int, a)] getProgressiveIndicesToAdd sub super = map (\i -> (i, super !! i)) $ nonSubsequenceIndices sub super --- | > diffSequences "abcdefg" "wabxyze"--- SeqDiff {dels = [2,3,5,6], adds = [(0,'w'),(3,'x'),(4,'y'),(5,'z')]}--- --- > applySequenceDiff it "abcdefg"--- "wabxyze"+-- | > λ diffSequences "abcdefg" "wabxyze"+-- > SeqDiff {dels = [2,3,5,6], adds = [(0,'w'),(3,'x'),(4,'y'),(5,'z')]}+-- > λ applySequenceDiff it "abcdefg"+-- > "wabxyze" applySequenceDiff :: forall a. (Eq a) => SeqDiff a -> [a] -> [a] applySequenceDiff (SeqDiff dels adds) = insertAtProgressiveIndices adds . removeAtIndices dels where -- | Best explained by example: -- |- -- | > insertAtProgressiveIndices [(1,'a'),(3,'b')] "def"- -- | "daebf"+ -- | > λ insertAtProgressiveIndices [(1,'a'),(3,'b')] "def"+ -- | > "daebf" insertAtProgressiveIndices :: [(Int, a)] -> [a] -> [a] insertAtProgressiveIndices = insertAtProgressiveIndices' 0 @@ -190,8 +189,8 @@ -- | When `sub` is a (not necessarily contiguous) subsequence of `super`, -- get the index at which each element of `sub` appears. E.g. -- --- > subsequenceIndices "abe" "abcdefg"--- [0,1,4]+-- > λ subsequenceIndices "abe" "abcdefg"+-- > [0,1,4] subsequenceIndices :: (Eq a) => [a] -> [a] -> [Int] subsequenceIndices [] _ = [] subsequenceIndices _ [] = error "`sub` was not a subsequence of `super`"@@ -203,8 +202,8 @@ -- | When `sub` is a (not necessarily contiguous) subsequence of `super`, -- get the indices at which elements of `sub` do *not* appear. E.g. -- --- > nonSubsequenceIndices "abe" "abcdefg"--- [2,3,5,6]+-- > λ nonSubsequenceIndices "abe" "abcdefg"+-- > [2,3,5,6] nonSubsequenceIndices :: (Eq a) => [a] -> [a] -> [Int] nonSubsequenceIndices sub super = [0..(length super - 1)] \\ (subsequenceIndices sub super)
src/Filediff/Types.hs view
@@ -31,10 +31,9 @@ import Data.MemoCombinators.Class (MemoTable, table, memoize) -- | The basic data type for a difference between two files. The--- `FilePath` is the "base" file in the base-comp comparison, and--- is the file to which the patch will be applied. Deletions: a list--- of indices at which to remove elements. Additions: each line to add--- comes with the index at which it will eventually reside.+-- "base" `FilePath` is the file chose state is being compared against,+-- and the "comp" `FilePath` is the file being compared (the "later"+-- of the two). data Filediff = Filediff { base :: FilePath, comp :: FilePath,@@ -98,9 +97,10 @@ comp = comp fd2, change = change fd1 `mappend` change fd2 } --- | A data type for differences between directories+-- | A data type for differences between directories. `filediffs`+-- stores 'Filediffs` whose filepaths are relative to directories being+-- diffed. data Diff = Diff {- -- relative to directories being diffed filediffs :: [Filediff] } deriving (Show, Generic) @@ -161,8 +161,8 @@ = filter (uncurry f) $ (\x y -> (x,y)) <$> a <*> b --- | Data type for a line+-- | Data type for a line. type Line = T.Text --- | Basic error type+-- | Basic error type. type Error = String