aboutsummaryrefslogtreecommitdiffstats
path: root/app/History/Issues.hs
blob: 08ad7724272882298c077069fe05926c5dd6cb85 (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
67
68
69
70
71
72
module History.Issues
  ( Issues (..),
  )
where

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

data Issues = Issues
  { commitHash :: Git.CommitHash,
    issues :: M.Map T.Text I.Issue
  }
  deriving (Show, Generic, Binary)

instance Planable Issues where
  type Id Issues = Git.CommitHash
  type Proto Issues = Scramble
  protoOf :: Proxy Issues -> Git.CommitHash -> IO Scramble
  protoOf _ commitHash = do
    filesChanged <- Git.getChangedFilesOf commitHash
    issues <- concat <$> mapM (getIssuesOfFile commitHash) filesChanged
    pure $
      Scramble
        { issues =
            M.unions
              [ M.singleton issue.id issue | issue <- issues
              ],
          ..
        }

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

  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 ->
                      bottomIssue {I.closed = True}
                  )
                  bottomIssues
            )
            topIssues.issues
            bottomScramble.issues
      }