aboutsummaryrefslogtreecommitdiffstats
path: root/app/History/Issues.hs
blob: 49bb893b058d2ceb0381de6caac5a7763e018a77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
module History.Issues
  ( Issues (..),
  )
where

import Backend qualified
import Data.Binary (Binary)
import Data.Function (on)
import Data.List (nub)
import Data.Map qualified as M
import Data.Proxy (Proxy)
import Data.Text qualified as T
import GHC.Generics (Generic)
import History.Plan (Id, Planable, Proto, assume, propagate, protoOf)
import History.Scramble (Scramble (..), getScrambleOf)
import Issue qualified as I

data Issues = Issues
  { commitHash :: Backend.CommitHash,
    issues :: M.Map T.Text I.Issue,
    filesSeen :: [FilePath]
  }
  deriving (Show, Generic, Binary)

instance Planable Issues where
  type Id Issues = Backend.CommitHash
  type Proto Issues = Scramble
  protoOf :: Proxy Issues -> Backend.CommitHash -> IO Scramble
  protoOf _ = getScrambleOf

  assume :: Scramble -> Issues
  assume (Scramble {..}) = Issues {filesSeen = filesChanged, ..}

  propagate :: [Id Issues] -> Issues -> Scramble -> Issues
  propagate _ topIssues bottomScramble =
    Issues
      { commitHash = topIssues.commitHash,
        issues =
          M.mergeWithKey
            ( \_ topIssue bottomIssue ->
                Just $
                  topIssue
                    { I.provenance =
                        I.Provenance
                          { first = bottomIssue.provenance.first,
                            last =
                              if ((/=) `on` (.rawTextHash)) topIssue bottomIssue
                                then topIssue.provenance.last
                                else bottomIssue.provenance.last
                          }
                    }
            )
            (\topIssues -> topIssues)
            ( \bottomIssues ->
                M.map
                  ( \bottomIssue ->
                      if bottomIssue.file `elem` topIssues.filesSeen
                        then bottomIssue {I.closed = True}
                        else bottomIssue
                  )
                  bottomIssues
            )
            topIssues.issues
            bottomScramble.issues,
        filesSeen = nub (topIssues.filesSeen ++ bottomScramble.filesChanged)
      }