event.go

  1package gitlab
  2
  3import (
  4	"fmt"
  5	"sort"
  6	"strings"
  7	"time"
  8
  9	"github.com/MichaelMure/git-bug/util/text"
 10	"github.com/xanzy/go-gitlab"
 11)
 12
 13// Event represents a unified GitLab event (note, label or state event).
 14type Event interface {
 15	ID() string
 16	UserID() int
 17	Kind() EventKind
 18	CreatedAt() time.Time
 19}
 20
 21type EventKind int
 22
 23const (
 24	EventUnknown EventKind = iota
 25	EventError
 26	EventComment
 27	EventTitleChanged
 28	EventDescriptionChanged
 29	EventClosed
 30	EventReopened
 31	EventLocked
 32	EventUnlocked
 33	EventChangedDuedate
 34	EventRemovedDuedate
 35	EventAssigned
 36	EventUnassigned
 37	EventChangedMilestone
 38	EventRemovedMilestone
 39	EventAddLabel
 40	EventRemoveLabel
 41	EventMentionedInIssue
 42	EventMentionedInMergeRequest
 43)
 44
 45type NoteEvent struct{ gitlab.Note }
 46
 47func (n NoteEvent) ID() string           { return fmt.Sprintf("%d", n.Note.ID) }
 48func (n NoteEvent) UserID() int          { return n.Author.ID }
 49func (n NoteEvent) CreatedAt() time.Time { return *n.Note.CreatedAt }
 50func (n NoteEvent) Kind() EventKind {
 51
 52	switch {
 53	case !n.System:
 54		return EventComment
 55
 56	case n.Body == "closed":
 57		return EventClosed
 58
 59	case n.Body == "reopened":
 60		return EventReopened
 61
 62	case n.Body == "changed the description":
 63		return EventDescriptionChanged
 64
 65	case n.Body == "locked this issue":
 66		return EventLocked
 67
 68	case n.Body == "unlocked this issue":
 69		return EventUnlocked
 70
 71	case strings.HasPrefix(n.Body, "changed title from"):
 72		return EventTitleChanged
 73
 74	case strings.HasPrefix(n.Body, "changed due date to"):
 75		return EventChangedDuedate
 76
 77	case n.Body == "removed due date":
 78		return EventRemovedDuedate
 79
 80	case strings.HasPrefix(n.Body, "assigned to @"):
 81		return EventAssigned
 82
 83	case strings.HasPrefix(n.Body, "unassigned @"):
 84		return EventUnassigned
 85
 86	case strings.HasPrefix(n.Body, "changed milestone to %"):
 87		return EventChangedMilestone
 88
 89	case strings.HasPrefix(n.Body, "removed milestone"):
 90		return EventRemovedMilestone
 91
 92	case strings.HasPrefix(n.Body, "mentioned in issue"):
 93		return EventMentionedInIssue
 94
 95	case strings.HasPrefix(n.Body, "mentioned in merge request"):
 96		return EventMentionedInMergeRequest
 97
 98	default:
 99		return EventUnknown
100	}
101
102}
103
104func (n NoteEvent) Title() string {
105	if n.Kind() == EventTitleChanged {
106		return getNewTitle(n.Body)
107	}
108	return text.CleanupOneLine(n.Body)
109}
110
111type LabelEvent struct{ gitlab.LabelEvent }
112
113func (l LabelEvent) ID() string           { return fmt.Sprintf("%d", l.LabelEvent.ID) }
114func (l LabelEvent) UserID() int          { return l.User.ID }
115func (l LabelEvent) CreatedAt() time.Time { return *l.LabelEvent.CreatedAt }
116func (l LabelEvent) Kind() EventKind {
117	switch l.Action {
118	case "add":
119		return EventAddLabel
120	case "remove":
121		return EventRemoveLabel
122	default:
123		return EventUnknown
124	}
125}
126
127type StateEvent struct{ gitlab.StateEvent }
128
129func (s StateEvent) ID() string           { return fmt.Sprintf("%d", s.StateEvent.ID) }
130func (s StateEvent) UserID() int          { return s.User.ID }
131func (s StateEvent) CreatedAt() time.Time { return *s.StateEvent.CreatedAt }
132func (s StateEvent) Kind() EventKind {
133	switch s.State {
134	case "closed":
135		return EventClosed
136	case "opened", "reopened":
137		return EventReopened
138	default:
139		return EventUnknown
140	}
141}
142
143type ErrorEvent struct {
144	Err  error
145	Time time.Time
146}
147
148func (e ErrorEvent) ID() string           { return "" }
149func (e ErrorEvent) UserID() int          { return -1 }
150func (e ErrorEvent) CreatedAt() time.Time { return e.Time }
151func (e ErrorEvent) Kind() EventKind      { return EventError }
152
153// SortedEvents consumes an Event-channel and returns an event slice, sorted by creation date, using CreatedAt-method.
154func SortedEvents(c <-chan Event) []Event {
155	var events []Event
156	for e := range c {
157		events = append(events, e)
158	}
159	sort.Sort(eventsByCreation(events))
160	return events
161}
162
163type eventsByCreation []Event
164
165func (e eventsByCreation) Len() int {
166	return len(e)
167}
168
169func (e eventsByCreation) Less(i, j int) bool {
170	return e[i].CreatedAt().Before(e[j].CreatedAt())
171}
172
173func (e eventsByCreation) Swap(i, j int) {
174	e[i], e[j] = e[j], e[i]
175}
176
177// getNewTitle parses body diff given by gitlab api and return it final form
178// examples: "changed title from **fourth issue** to **fourth issue{+ changed+}**"
179//           "changed title from **fourth issue{- changed-}** to **fourth issue**"
180// because Gitlab
181func getNewTitle(diff string) string {
182	newTitle := strings.Split(diff, "** to **")[1]
183	newTitle = strings.Replace(newTitle, "{+", "", -1)
184	newTitle = strings.Replace(newTitle, "+}", "", -1)
185	return strings.TrimSuffix(newTitle, "**")
186}