func storyTags(tracker common.IssueTracker, commits []*git.Commit) (tags []string) { var ( storyTagSet = make(map[string]struct{}, 1) storyTagList = make([]string, 0, 1) ) for _, commit := range commits { tag := commit.StoryIdTag // Skip empty tags. if tag == "" { continue } // Skip unassigned stories. if _, err := tracker.StoryTagToReadableStoryId(tag); err != nil { continue } // Otherwise register the tag, unless already registered. if _, ok := storyTagSet[tag]; ok { continue } storyTagSet[tag] = struct{}{} storyTagList = append(storyTagList, tag) } return storyTagList }
// ListStoryIdsToBeAssigned lists the story IDs that are associated with // the commits that modified trunk since the last release, i.e. with the commits // as returned by ListNewTrunkCommits. // // Only the story IDs matching the issue tracker that is passed in are returned. func ListStoryIdsToBeAssigned(tracker common.IssueTracker) ([]string, error) { // Get the commits that modified trunk. task := "Get the commits that modified trunk" commits, err := ListNewTrunkCommits() if err != nil { return nil, errs.NewError(task, err) } // Collect the story IDs. idSet := make(map[string]struct{}, len(commits)) for _, commit := range commits { // Skip empty tags. if commit.StoryIdTag == "" { continue } // Parse the tag to get the story ID. storyId, err := tracker.StoryTagToReadableStoryId(commit.StoryIdTag) if err != nil { continue } // Add the ID to the set. idSet[storyId] = struct{}{} } // Convert the set to a list. idList := make([]string, 0, len(idSet)) for id := range idSet { idList = append(idList, id) } // Return the final list of story IDs. return idList, nil }
// DumpStoryChanges writes a nicely formatted output to the io.Writer passed in. // // In case the porcelain argument is true, the output is printed in a more machine-friendly way. func DumpStoryChanges( writer io.Writer, groups []*StoryChangeGroup, tracker common.IssueTracker, porcelain bool, ) error { tw := tabwriter.NewWriter(writer, 0, 8, 2, '\t', 0) if !porcelain { _, err := io.WriteString(tw, "Story\tChange\tCommit SHA\tCommit Source\tCommit Title\n") if err != nil { return err } _, err = io.WriteString(tw, "=====\t======\t==========\t=============\t============\n") if err != nil { return err } } for _, group := range groups { storyId, err := tracker.StoryTagToReadableStoryId(group.StoryIdTag) if err != nil { return err } for _, change := range group.Changes { changeId := change.ChangeIdTag // Print the first line. var ( commit = change.Commits[0] commitMessageTitle = prompt.ShortenCommitTitle(commit.MessageTitle) ) printChange := func(commit *git.Commit) error { _, err := fmt.Fprintf(tw, "%v\t%v\t%v\t%v\t%v\n", storyId, changeId, commit.SHA, commit.Source, commitMessageTitle) return err } if err := printChange(commit); err != nil { return err } // Make some of the columns empty in case we are not porcelain. if !porcelain { storyId = "" changeId = "" } // Print the rest with the chosen columns being empty. for _, commit := range change.Commits[1:] { if err := printChange(commit); err != nil { return err } } } } return tw.Flush() }