@@ -4,11 +4,12 @@ import (
44 "bufio"
55 "fmt"
66 "regexp"
7- "slices "
7+ "strconv "
88 "strings"
99 "time"
1010
1111 "cl-parse/git"
12+ "cl-parse/origin"
1213)
1314
1415const (
@@ -18,23 +19,25 @@ const (
1819)
1920
2021type ChangelogEntry struct {
21- Version string `json:"version" yaml:"version" toml:"version"`
22- Date time.Time `json:"date" yaml:"date" toml:"date"`
22+ Version string `json:"version" yaml:"version" toml:"version"`
23+ Date time.Time `json:"date" yaml:"date" toml:"date"`
2324 CompareURL string `json:"compareUrl" yaml:"compareUrl" toml:"compareUrl"`
24- Changes map [string ][]Change `json:"changes" yaml:"changes" toml:"changes"`
25+ Changes map [string ][]Change `json:"changes" yaml:"changes" toml:"changes"`
2526}
2627
2728type Change struct {
28- Scope string `json:"scope,omitempty" yaml:"scope,omitempty" toml:"scope,omitempty"`
29- Description string `json:"description" yaml:"description" toml:"description"`
30- Commit string `json:"commit,omitempty" yaml:"commit,omitempty" toml:"commit,omitempty"`
31- CommitBody string `json:"commitBody,omitempty" yaml:"commitBody,omitempty" toml:"commitBody,omitempty"`
32- RelatedItems []string `json:"relatedItems,omitempty" yaml:"relatedItems,omitempty" toml:"relatedItems,omitempty"`
29+ Scope string `json:"scope,omitempty" yaml:"scope,omitempty" toml:"scope,omitempty"`
30+ Description string `json:"description" yaml:"description" toml:"description"`
31+ Commit string `json:"commit,omitempty" yaml:"commit,omitempty" toml:"commit,omitempty"`
32+ CommitBody string `json:"commitBody,omitempty" yaml:"commitBody,omitempty" toml:"commitBody,omitempty"`
33+ RelatedItems []* origin. Issue `json:"relatedItems,omitempty" yaml:"relatedItems,omitempty" toml:"relatedItems,omitempty"`
3334}
3435
3536type Parser struct {
36- entries []ChangelogEntry
37- IncludeBody bool
37+ entries []ChangelogEntry
38+ originUrl string
39+ IncludeBody bool
40+ FetchItemDetails bool
3841}
3942
4043func NewParser () * Parser {
@@ -63,10 +66,18 @@ func (p *Parser) Parse(content string) ([]ChangelogEntry, error) {
6366 scanner := bufio .NewScanner (strings .NewReader (content ))
6467 var currentEntry * ChangelogEntry
6568 var currentSection string
69+ var err error
6670
6771 versionRegex := regexp .MustCompile (versionPattern )
6872 changeRegex := regexp .MustCompile (changePattern )
6973
74+ if p .FetchItemDetails {
75+ p .originUrl , err = git .GetOriginURL ("." )
76+ if err != nil {
77+ return nil , fmt .Errorf ("failed to get origin URL: %w" , err )
78+ }
79+ }
80+
7081 for scanner .Scan () {
7182 line := strings .TrimSpace (scanner .Text ())
7283
@@ -79,7 +90,6 @@ func (p *Parser) Parse(content string) ([]ChangelogEntry, error) {
7990 p .entries = append (p .entries , * currentEntry )
8091 }
8192
82- var err error
8393 currentEntry , err = p .createNewEntry (matches )
8494 if err != nil {
8595 return nil , err
@@ -120,28 +130,40 @@ func (p *Parser) createNewEntry(matches []string) (*ChangelogEntry, error) {
120130 }, nil
121131}
122132
123- func (p * Parser ) parseChange (line string , changeRegex * regexp.Regexp , currentSection string , currentEntry * ChangelogEntry ) error {
133+ func (p * Parser ) parseChange (
134+ line string ,
135+ changeRegex * regexp.Regexp ,
136+ currentSection string ,
137+ currentEntry * ChangelogEntry ,
138+ ) error {
124139 matches := changeRegex .FindStringSubmatch (line )
125140 if matches == nil {
126141 return nil
127142 }
128143
144+ relatedItems , err := extractRelatedItems (matches [2 ], p .originUrl )
145+ if err != nil {
146+ return err
147+ }
148+
129149 change := Change {
130150 Scope : matches [1 ],
131151 Description : matches [2 ],
132- RelatedItems : extractRelatedItems ( matches [ 2 ]), // Extract from description
152+ RelatedItems : relatedItems ,
133153 }
134154
135155 if matches [3 ] != "" {
136156 change .Commit = parseCommitHashFromLink (matches [3 ])
137157 if err := p .addCommitBody (& change ); err != nil {
138158 return err
139159 }
140- // Extract related items from commit body if available
141160 if change .CommitBody != "" {
142- bodyItems := extractRelatedItems (change .CommitBody )
161+ bodyItems , err := extractRelatedItems (change .CommitBody , p .originUrl )
162+ if err != nil {
163+ return err
164+ }
143165 for _ , item := range bodyItems {
144- if ! slices . Contains (change .RelatedItems , item ) {
166+ if ! containsIssue (change .RelatedItems , item ) {
145167 change .RelatedItems = append (change .RelatedItems , item )
146168 }
147169 }
@@ -185,19 +207,37 @@ func parseCommitHashFromLink(link string) string {
185207 return ""
186208}
187209
188- func extractRelatedItems (text string ) [] string {
210+ func extractRelatedItems (text string , repoUrl string ) ([] * origin. Issue , error ) {
189211 regex := regexp .MustCompile (`#(\d+)` )
190212 matches := regex .FindAllStringSubmatch (text , - 1 )
191213
192214 seen := make (map [string ]bool )
193- var items []string
215+ var items []* origin. Issue
194216
195217 for _ , match := range matches {
196218 if ! seen [match [1 ]] {
197- items = append (items , match [1 ])
219+ number , _ := strconv .Atoi (match [1 ])
220+ issue := & origin.Issue {
221+ Number : number ,
222+ }
223+ if repoUrl != "" {
224+ if err := origin .GetIssueDetails (issue , repoUrl , match [1 ]); err != nil {
225+ return nil , fmt .Errorf ("failed to get issue details for #%s: %w" , match [1 ], err )
226+ }
227+ }
228+ items = append (items , issue )
198229 seen [match [1 ]] = true
199230 }
200231 }
201232
202- return items
233+ return items , nil
234+ }
235+
236+ func containsIssue (items []* origin.Issue , item * origin.Issue ) bool {
237+ for _ , existing := range items {
238+ if existing .Number == item .Number {
239+ return true
240+ }
241+ }
242+ return false
203243}
0 commit comments