// toInternalRepresentation converts the given release notes to an internal
// representation that is easily serializable any typical encoder.
func toInternalRepresentation(notes *common.ReleaseNotes) *releaseNotes {
	// Sort the sections.
	// The sections are most probably already sorted, but just to be sure.
	sortedSections := make([]*common.ReleaseNotesSection, len(notes.Sections))
	copy(sortedSections, notes.Sections)
	sort.Sort(common.ReleaseNotesSections(sortedSections))

	// Generate sections.
	var sections []*releaseNotesSection
	for _, section := range sortedSections {
		// Sort stories. What this means is specified to each issue tracker.
		sort.Sort(common.Stories(section.Stories))

		// Generate the story section.
		var stories []*story
		for _, s := range section.Stories {
			stories = append(stories, &story{
				Id:    s.ReadableId(),
				Title: s.Title(),
				URL:   s.URL(),
			})
		}
		sections = append(sections, &releaseNotesSection{
			StoryType: strings.Title(section.StoryType),
			Stories:   stories,
		})
	}

	// Return the new internal representation.
	return &releaseNotes{
		Version:  notes.Version.BaseString(),
		Sections: sections,
	}
}
Beispiel #2
0
func GenerateReleaseNotes(v *version.Version, stories []common.Story) *common.ReleaseNotes {
	// Sort the stories. The following steps retain the order, so we can sort here.
	// We copy the slice so that we don't change the argument. Slices are references.
	sortedStories := make([]common.Story, len(stories))
	copy(sortedStories, stories)
	sort.Sort(common.Stories(sortedStories))

	// Group stories by their type into sections.
	// sectionMap: story.Type() -> *releaseNotesSection
	sectionMap := make(map[string]*common.ReleaseNotesSection)

	for _, story := range sortedStories {
		t := story.Type()
		s, ok := sectionMap[t]
		// In case the section is there, append.
		if ok {
			s.Stories = append(s.Stories, story)
			continue
		}
		// Otherwise create a new section.
		sectionMap[t] = &common.ReleaseNotesSection{
			StoryType: t,
			Stories:   []common.Story{story},
		}
	}

	// Collect sections into a slice.
	sections := make([]*common.ReleaseNotesSection, 0, len(sectionMap))
	for _, v := range sectionMap {
		sections = append(sections, v)
	}

	// Sort the sections alphabetically.
	sort.Sort(common.ReleaseNotesSections(sections))

	// Return the new internal representation.
	return &common.ReleaseNotes{
		Version:  v,
		Sections: sections,
	}
}