{-# OPTIONS_GHC -fno-warn-orphans #-} module IssueEvent ( IssueEvent (..), ) where import Control.Monad (join) import Data.Binary (Binary (..)) import Data.Function ((&)) import Data.Text qualified as T import Data.Text.IO qualified as T import Data.Text.Lazy qualified as LT import Data.Text.Lazy.Encoding qualified as LT import GHC.Generics (Generic) import GHC.Records (HasField (..)) import Git.CommitHash (CommitHash) import Issue (Issue (..)) import Issue.Render qualified as I import Patch (Patch) import Patch qualified as A import Process (sh) import Render ((<<<)) import Render qualified as P import System.FilePath (()) import System.IO.Temp (withSystemTempDirectory) import System.Process.Typed (setWorkingDir) data IssueEvent = IssueCreated { hash :: CommitHash, issue :: Issue } | IssueChanged { hash :: CommitHash, oldIssue :: Issue, issue :: Issue } | IssueDeleted { hash :: CommitHash, issue :: Issue } deriving (Show, Generic, Binary) instance HasField "patch" IssueEvent (IO Patch) where getField (IssueCreated {..}) = join $ (diff "" <$> issue.rawText) getField (IssueChanged {..}) = join $ (diff <$> oldIssue.rawText <*> issue.rawText) getField (IssueDeleted {..}) = join $ (flip diff "" <$> issue.rawText) diff :: T.Text -> T.Text -> IO A.Patch diff old new = withSystemTempDirectory "diff" $ \tmp -> do let cwd = tmp T.writeFile (tmp "old") old T.writeFile (tmp "new") new A.parse . LT.toStrict . LT.decodeUtf8 <$> sh ("git diff --no-index -- old new || :" & setWorkingDir cwd) instance P.Render IssueEvent where render = P.render . P.Detailed instance P.Render (P.Detailed IssueEvent) where render (P.Detailed issueEvent) = P.Summarized issueEvent <<< P.hardline @P.AnsiStyle <<< issueEvent.patch instance P.Render (P.Summarized IssueEvent) where render (P.Summarized issueEvent) = P.Summarized issueEvent.hash <<< ( case issueEvent of IssueCreated {} -> P.styled [P.color P.Blue] "created" IssueChanged {} -> P.styled [P.color P.Blue] "changed" IssueDeleted {} -> P.styled [P.color P.Blue] "deleted" ) <<< I.IssueTitle issueEvent.issue