func bulkEditStart(issues []*github.Issue) (*github.Issue, []byte) { common := new(github.Issue) for i, issue := range issues { if i == 0 { common.State = issue.State common.Assignee = issue.Assignee common.Labels = issue.Labels common.Milestone = issue.Milestone continue } if common.State != nil && getString(common.State) != getString(issue.State) { common.State = nil } if common.Assignee != nil && getUserLogin(common.Assignee) != getUserLogin(issue.Assignee) { common.Assignee = nil } if common.Milestone != nil && getMilestoneTitle(common.Milestone) != getMilestoneTitle(issue.Milestone) { common.Milestone = nil } common.Labels = commonLabels(common.Labels, issue.Labels) } var buf bytes.Buffer fmt.Fprintf(&buf, "State: %s\n", getString(common.State)) fmt.Fprintf(&buf, "Assignee: %s\n", getUserLogin(common.Assignee)) fmt.Fprintf(&buf, "Labels: %s\n", strings.Join(getLabelNames(common.Labels), " ")) fmt.Fprintf(&buf, "Milestone: %s\n", getMilestoneTitle(common.Milestone)) fmt.Fprintf(&buf, "\n<optional comment here>\n") fmt.Fprintf(&buf, "%s\n", bulkHeader) for _, issue := range issues { fmt.Fprintf(&buf, "%d\t%s\n", getInt(issue.Number), getString(issue.Title)) } return common, buf.Bytes() }
func labelIssue(label string, issue *github.Issue) *github.Issue { l := github.Label{ Name: stringPtr(label), } issue.Labels = append(issue.Labels, l) return issue }
func bulkWriteIssue(old *github.Issue, updated []byte, status func(string)) (ids []int, err error) { i := bytes.Index(updated, []byte(bulkHeader)) if i < 0 { return nil, fmt.Errorf("cannot find bulk edit issue list") } ids = readBulkIDs(updated[i:]) if len(ids) == 0 { return nil, fmt.Errorf("found no issues in bulk edit issue list") } // Make a copy of the issue to modify. x := *old old = &x // Try a write to issue -1, checking for formatting only. old.Number = new(int) *old.Number = -1 if _, err := writeIssue(old, updated, true); err != nil { return nil, err } // Apply to all issues in list. suffix := "" if len(ids) != 1 { suffix = "s" } status(fmt.Sprintf("updating %d issue%s", len(ids), suffix)) failed := false for index, number := range ids { if index%10 == 0 && index > 0 { status(fmt.Sprintf("updated %d/%d issues", index, len(ids))) } // Check rate limits here (in contrast to everywhere else in this program) // to avoid needless failure halfway through the loop. // for client.Rate.Limit > 0 && client.Rate.Remaining == 0 { // delta := (client.Rate.Reset.Sub(time.Now())/time.Minute + 2) * time.Minute { delta := time.Duration(0) if delta < 0 { delta = 2 * time.Minute } status(fmt.Sprintf("updated %d/%d issues; pausing %d minutes to respect GitHub rate limit", index, len(ids), int(delta/time.Minute))) time.Sleep(delta) if _, _, err := client.RateLimit(); err != nil { status(fmt.Sprintf("reading rate limit: %v", err)) } } *old.Number = number if _, err := writeIssue(old, updated, true); err != nil { status(fmt.Sprintf("writing #%d: %s", number, strings.Replace(err.Error(), "\n", "\n\t", -1))) failed = true } } if failed { return ids, fmt.Errorf("failed to update all issues") } return ids, nil }
// Mark issue as open. func OpenIssue(repo string, issue *github.Issue) (*github.Issue, error) { temp := "open" issue.State = &temp closedIssue, err := EditIssue(repo, issue) return closedIssue, err }