github.com/Trim21/git-chglog@v0.0.0-20200414013904-db796966b373/commit_extractor.go (about) 1 package chglog 2 3 import ( 4 "sort" 5 "strings" 6 ) 7 8 type commitExtractor struct { 9 opts *Options 10 } 11 12 func newCommitExtractor(opts *Options) *commitExtractor { 13 return &commitExtractor{ 14 opts: opts, 15 } 16 } 17 18 func (e *commitExtractor) Extract(commits []*Commit) ([]*CommitGroup, []*Commit, []*Commit, []*NoteGroup) { 19 commitGroups := []*CommitGroup{} 20 noteGroups := []*NoteGroup{} 21 mergeCommits := []*Commit{} 22 revertCommits := []*Commit{} 23 24 filteredCommits := commitFilter(commits, e.opts.CommitFilters, e.opts.NoCaseSensitive) 25 26 for _, commit := range commits { 27 if commit.Merge != nil { 28 mergeCommits = append(mergeCommits, commit) 29 continue 30 } 31 32 if commit.Revert != nil { 33 revertCommits = append(revertCommits, commit) 34 continue 35 } 36 } 37 38 for _, commit := range filteredCommits { 39 if commit.Merge == nil && commit.Revert == nil { 40 e.processCommitGroups(&commitGroups, commit, e.opts.NoCaseSensitive) 41 } 42 43 e.processNoteGroups(¬eGroups, commit) 44 } 45 46 e.sortCommitGroups(commitGroups) 47 e.sortNoteGroups(noteGroups) 48 49 return commitGroups, mergeCommits, revertCommits, noteGroups 50 } 51 52 func (e *commitExtractor) processCommitGroups(groups *[]*CommitGroup, commit *Commit, noCaseSensitive bool) { 53 var group *CommitGroup 54 55 // commit group 56 raw, ttl := e.commitGroupTitle(commit) 57 58 for _, g := range *groups { 59 rawTitleTmp := g.RawTitle 60 if noCaseSensitive { 61 rawTitleTmp = strings.ToLower(g.RawTitle) 62 } 63 64 rawTmp := raw 65 if noCaseSensitive { 66 rawTmp = strings.ToLower(raw) 67 } 68 if rawTitleTmp == rawTmp { 69 group = g 70 } 71 } 72 73 if group != nil { 74 group.Commits = append(group.Commits, commit) 75 } else if raw != "" { 76 *groups = append(*groups, &CommitGroup{ 77 RawTitle: raw, 78 Title: ttl, 79 Commits: []*Commit{commit}, 80 }) 81 } 82 } 83 84 func (e *commitExtractor) processNoteGroups(groups *[]*NoteGroup, commit *Commit) { 85 if len(commit.Notes) != 0 { 86 for _, note := range commit.Notes { 87 e.appendNoteToNoteGroups(groups, note) 88 } 89 } 90 } 91 92 func (e *commitExtractor) appendNoteToNoteGroups(groups *[]*NoteGroup, note *Note) { 93 exist := false 94 95 for _, g := range *groups { 96 if g.Title == note.Title { 97 exist = true 98 g.Notes = append(g.Notes, note) 99 } 100 } 101 102 if !exist { 103 *groups = append(*groups, &NoteGroup{ 104 Title: note.Title, 105 Notes: []*Note{note}, 106 }) 107 } 108 } 109 110 func (e *commitExtractor) commitGroupTitle(commit *Commit) (string, string) { 111 var ( 112 raw string 113 ttl string 114 ) 115 116 if title, ok := dotGet(commit, e.opts.CommitGroupBy); ok { 117 if v, ok := title.(string); ok { 118 raw = v 119 if t, ok := e.opts.CommitGroupTitleMaps[v]; ok { 120 ttl = t 121 } else { 122 ttl = strings.Title(raw) 123 } 124 } 125 } 126 127 return raw, ttl 128 } 129 130 func (e *commitExtractor) sortCommitGroups(groups []*CommitGroup) { 131 // groups 132 sort.Slice(groups, func(i, j int) bool { 133 var ( 134 a, b interface{} 135 ok bool 136 ) 137 138 a, ok = dotGet(groups[i], e.opts.CommitGroupSortBy) 139 if !ok { 140 return false 141 } 142 143 b, ok = dotGet(groups[j], e.opts.CommitGroupSortBy) 144 if !ok { 145 return false 146 } 147 148 res, err := compare(a, "<", b) 149 if err != nil { 150 return false 151 } 152 return res 153 }) 154 155 // commits 156 for _, group := range groups { 157 sort.Slice(group.Commits, func(i, j int) bool { 158 var ( 159 a, b interface{} 160 ok bool 161 ) 162 163 a, ok = dotGet(group.Commits[i], e.opts.CommitSortBy) 164 if !ok { 165 return false 166 } 167 168 b, ok = dotGet(group.Commits[j], e.opts.CommitSortBy) 169 if !ok { 170 return false 171 } 172 173 res, err := compare(a, "<", b) 174 if err != nil { 175 return false 176 } 177 return res 178 }) 179 } 180 } 181 182 func (e *commitExtractor) sortNoteGroups(groups []*NoteGroup) { 183 // groups 184 sort.Slice(groups, func(i, j int) bool { 185 return strings.ToLower(groups[i].Title) < strings.ToLower(groups[j].Title) 186 }) 187 188 // notes 189 for _, group := range groups { 190 sort.Slice(group.Notes, func(i, j int) bool { 191 return strings.ToLower(group.Notes[i].Title) < strings.ToLower(group.Notes[j].Title) 192 }) 193 } 194 }