aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--anissue.cabal2
-rw-r--r--app/Exception.hs7
-rw-r--r--app/History/CommitInfo.hs3
-rw-r--r--app/History/IssueEvent.hs8
-rw-r--r--app/Main.hs5
-rw-r--r--app/Patch.hs37
6 files changed, 56 insertions, 6 deletions
diff --git a/anissue.cabal b/anissue.cabal
index c60f660..0d6d504 100644
--- a/anissue.cabal
+++ b/anissue.cabal
@@ -87,6 +87,7 @@ executable anissue
Issue.Text
Issue.TypedValue
Parallel
+ Patch
Process
Settings
TreeGrepper.Comment
@@ -106,6 +107,7 @@ executable anissue
bytestring,
cmark,
containers,
+ diff-parse,
directory,
filepath,
optparse-applicative,
diff --git a/app/Exception.hs b/app/Exception.hs
index ddaef5a..49c9cb6 100644
--- a/app/Exception.hs
+++ b/app/Exception.hs
@@ -4,6 +4,7 @@ module Exception
NoCommits (..),
ProcessException (..),
UnknownFileExtension (..),
+ InvalidDiff (..),
)
where
@@ -16,6 +17,7 @@ data AnyException
| NoCommits' NoCommits
| ProcessException' ProcessException
| UnknownFileExtension' UnknownFileExtension
+ | InvalidDiff' InvalidDiff
deriving (Show)
instance Exception AnyException
@@ -43,3 +45,8 @@ data UnknownFileExtension = UnknownFileExtension
deriving (Show)
instance Exception UnknownFileExtension
+
+data InvalidDiff = InvalidDiff String
+ deriving (Show)
+
+instance Exception InvalidDiff
diff --git a/app/History/CommitInfo.hs b/app/History/CommitInfo.hs
index dbb7e20..c5224b2 100644
--- a/app/History/CommitInfo.hs
+++ b/app/History/CommitInfo.hs
@@ -20,6 +20,7 @@ import History.PartialCommitInfo (PartialCommitInfo (..))
import Issue (Issue (..))
import Issue.Provenance qualified as I
import Parallel (parSequence)
+import Patch qualified as P
import Process (sh)
import System.FilePath ((</>))
import System.IO.Temp (withSystemTempDirectory)
@@ -109,7 +110,7 @@ diffCommitInfos maybeOldInfo newInfo =
let cwd = tmp
T.writeFile (tmp </> "old") old
T.writeFile (tmp </> "new") new
- LT.toStrict . LT.decodeUtf8 <$> sh ("git diff --no-index -- old new || :" & setWorkingDir cwd)
+ P.parse . LT.toStrict . LT.decodeUtf8 <$> sh ("git diff --no-index -- old new || :" & setWorkingDir cwd)
mergeListsBy :: (a -> a -> Bool) -> (a -> a -> b) -> (a -> b) -> (a -> b) -> [a] -> [a] -> [b]
mergeListsBy eq onBoth onLeft onRight lefts rights =
diff --git a/app/History/IssueEvent.hs b/app/History/IssueEvent.hs
index 933b047..0900f13 100644
--- a/app/History/IssueEvent.hs
+++ b/app/History/IssueEvent.hs
@@ -1,24 +1,24 @@
module History.IssueEvent (IssueEvent (..)) where
-import Data.Text qualified as T
import History.CommitHash (CommitHash)
import Issue (Issue)
+import Patch (Patch)
data IssueEvent
= IssueCreated
{ hash :: CommitHash,
issue :: Issue,
- patch :: T.Text
+ patch :: Patch
}
| IssueChanged
{ hash :: CommitHash,
oldIssue :: Issue,
issue :: Issue,
- patch :: T.Text
+ patch :: Patch
}
| IssueDeleted
{ hash :: CommitHash,
issue :: Issue,
- patch :: T.Text
+ patch :: Patch
}
deriving (Show)
diff --git a/app/Main.hs b/app/Main.hs
index 6f96aa5..8d785be 100644
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -398,6 +398,7 @@ import Issue.Sort qualified as I
import Issue.Tag qualified as I
import Options.Applicative ((<**>))
import Options.Applicative qualified as O
+import Patch qualified as P
import Prettyprinter ((<+>))
import Prettyprinter qualified as P
import Prettyprinter.Render.Terminal qualified as P
@@ -670,7 +671,9 @@ main = do
IssueDeleted {issue} ->
shortHash <+> kwd "deleted" <+> title issue
)
- <+> if patch then P.pretty e.patch else P.emptyDoc
+ <+> if patch
+ then P.hardline <> P.render e.patch
+ else P.emptyDoc
)
es'
)
diff --git a/app/Patch.hs b/app/Patch.hs
new file mode 100644
index 0000000..f1c547a
--- /dev/null
+++ b/app/Patch.hs
@@ -0,0 +1,37 @@
+module Patch
+ ( Patch,
+ parse,
+ render,
+ )
+where
+
+import Control.Exception (throw)
+import Data.Text qualified as T
+import Exception qualified as E
+import Prettyprinter (pretty)
+import Prettyprinter qualified as P
+import Prettyprinter.Render.Terminal qualified as P
+import Text.Diff.Parse qualified as D
+import Text.Diff.Parse.Types qualified as D
+
+newtype Patch = Patch
+ { fileDeltas :: D.FileDeltas
+ }
+ deriving (Show)
+
+parse :: T.Text -> Patch
+parse = either (throw . E.InvalidDiff) Patch . D.parseDiff
+
+render :: Patch -> P.Doc P.AnsiStyle
+render (Patch {..}) =
+ P.vsep $ map prettyFileDelta fileDeltas
+ where
+ prettyFileDelta (D.FileDelta {..}) = prettyContent fileDeltaContent
+ prettyContent D.Binary = P.emptyDoc
+ prettyContent (D.Hunks hunks) = P.vsep (map prettyHunk hunks)
+ prettyHunk (D.Hunk {..}) = P.vsep $ map prettyLine hunkLines
+ prettyLine (D.Line {..}) =
+ case lineAnnotation of
+ D.Added -> P.annotate (P.color P.Green) $ P.pretty ("+" :: T.Text) <> pretty lineContent
+ D.Removed -> P.annotate (P.color P.Red) $ P.pretty ("-" :: T.Text) <> pretty lineContent
+ D.Context -> P.annotate (P.color P.White) $ P.pretty (" " :: T.Text) <> pretty lineContent