github.com/brandonmanuel/git-chglog@v0.0.0-20200903004639-7a62fa08787a/tag_selector.go (about) 1 package chglog 2 3 import ( 4 "strings" 5 ) 6 7 type tagSelector struct{} 8 9 func newTagSelector() *tagSelector { 10 return &tagSelector{} 11 } 12 13 func (s *tagSelector) Select(tags []*Tag, query string) ([]*Tag, string, error) { 14 tokens := strings.Split(query, "..") 15 16 switch len(tokens) { 17 case 1: 18 return s.selectSingleTag(tags, tokens[0]) 19 case 2: 20 old := tokens[0] 21 new := tokens[1] 22 if old == "" && new == "" { 23 return nil, "", nil 24 } else if old == "" { 25 return s.selectBeforeTags(tags, new) 26 } else if new == "" { 27 return s.selectAfterTags(tags, old) 28 } 29 return s.selectRangeTags(tags, tokens[0], tokens[1]) 30 } 31 32 return nil, "", errFailedQueryParse 33 } 34 35 func (s *tagSelector) selectSingleTag(tags []*Tag, token string) ([]*Tag, string, error) { 36 var from string 37 38 for i, tag := range tags { 39 if tag.Name == token { 40 if i+1 < len(tags) { 41 from = tags[i+1].Name 42 } 43 return []*Tag{tag}, from, nil 44 } 45 } 46 47 return nil, "", nil 48 } 49 50 func (*tagSelector) selectBeforeTags(tags []*Tag, token string) ([]*Tag, string, error) { 51 var ( 52 res []*Tag 53 from string 54 enable bool 55 ) 56 57 for i, tag := range tags { 58 if tag.Name == token { 59 enable = true 60 } 61 62 if enable { 63 res = append(res, tag) 64 from = "" 65 if i+1 < len(tags) { 66 from = tags[i+1].Name 67 } 68 } 69 } 70 71 if len(res) == 0 { 72 return res, "", errNotFoundTag 73 } 74 75 return res, from, nil 76 } 77 78 func (*tagSelector) selectAfterTags(tags []*Tag, token string) ([]*Tag, string, error) { 79 var ( 80 res []*Tag 81 from string 82 ) 83 84 for i, tag := range tags { 85 res = append(res, tag) 86 from = "" 87 if i+1 < len(tags) { 88 from = tags[i+1].Name 89 } 90 91 if tag.Name == token { 92 break 93 } 94 } 95 96 if len(res) == 0 { 97 return res, "", errNotFoundTag 98 } 99 100 return res, from, nil 101 } 102 103 func (s *tagSelector) selectRangeTags(tags []*Tag, old string, new string) ([]*Tag, string, error) { 104 var ( 105 res []*Tag 106 from string 107 enable bool 108 ) 109 110 for i, tag := range tags { 111 if tag.Name == new { 112 enable = true 113 } 114 115 if enable { 116 from = "" 117 if i+1 < len(tags) { 118 from = tags[i+1].Name 119 } 120 res = append(res, tag) 121 } 122 123 if tag.Name == old { 124 enable = false 125 } 126 } 127 128 if len(res) == 0 { 129 return res, "", errNotFoundTag 130 } 131 132 return res, from, nil 133 }