func (story *story) SetAssignees(users []common.User) error { task := fmt.Sprintf("Set owners for story %v", story.Story.Id) ownerIds := make([]int, len(users)) for i, user := range users { id, err := strconv.Atoi(user.Id()) if err != nil { return errs.NewError(task, err) } ownerIds[i] = id } var ( config = story.tracker.config client = pivotal.NewClient(config.UserToken) projectId = config.ProjectId ) updateRequest := &pivotal.StoryRequest{OwnerIds: &ownerIds} updatedStory, _, err := client.Stories.Update(projectId, story.Story.Id, updateRequest) if err != nil { return errs.NewError(task, err) } story.Story = updatedStory return nil }
func (release *nextRelease) Start() (action.Action, error) { // In case there are no additional stories, we are done. if len(release.additionalStories) == 0 { return action.Noop, nil } // Add release labels to the relevant stories. var ( config = release.tracker.config client = pivotal.NewClient(config.UserToken) projectId = config.ProjectId ) task := "Label the stories with the release label" log.Run(task) releaseLabel := getReleaseLabel(release.trunkVersion) stories, err := addLabel(client, projectId, release.additionalStories, releaseLabel) if err != nil { return nil, errs.NewError(task, err) } release.additionalStories = nil // Return the rollback action, which removes the release labels that were appended. return action.ActionFunc(func() error { log.Rollback(task) _, err := removeLabel(client, projectId, stories, releaseLabel) if err != nil { return errs.NewError("Remove the release label from the stories", err) } return nil }), nil }
func (tracker *issueTracker) searchStories( queryFormat string, v ...interface{}, ) ([]*pivotal.Story, error) { // Get the client. var ( client = pivotal.NewClient(tracker.config.UserToken) projectId = tracker.config.ProjectId ) // Generate the query. query := fmt.Sprintf(queryFormat, v...) // Automatically limit the story type. query = fmt.Sprintf("(type:%v OR type:%v) AND (%v)", pivotal.StoryTypeFeature, pivotal.StoryTypeBug, query) // Send the query to PT. stories, err := client.Stories.List(projectId, query) // Filter stories by the component label when necessary. if label := tracker.config.ComponentLabel; label != "" { stories = filterStories(stories, func(story *pivotal.Story) bool { return labeled(story, label) }) } return stories, err }
func (tracker *issueTracker) CurrentUser() (common.User, error) { client := pivotal.NewClient(tracker.config.UserToken) me, _, err := client.Me.Get() if err != nil { return nil, err } return &user{me}, nil }
func (tracker *issueTracker) updateStories( stories []*pivotal.Story, updateFunc storyUpdateFunc, rollbackFunc storyUpdateFunc, ) ([]*pivotal.Story, error) { var ( client = pivotal.NewClient(tracker.config.UserToken) projectId = tracker.config.ProjectId ) return updateStories(client, projectId, stories, updateFunc, rollbackFunc) }
func (story *story) Start() error { task := fmt.Sprintf("Start Pivotal Tracker story %v", story.Story.Id) if s := story.Story; s.Type == pivotal.StoryTypeFeature && s.Estimate == nil { panic(errors.New("story not estimated")) } var ( config = story.tracker.config client = pivotal.NewClient(config.UserToken) projectId = config.ProjectId ) updateRequest := &pivotal.StoryRequest{State: pivotal.StoryStateStarted} updatedStory, _, err := client.Stories.Update(projectId, story.Story.Id, updateRequest) if err != nil { return errs.NewError(task, err) } story.Story = updatedStory return nil }
func (story *story) MarkAsImplemented() (action.Action, error) { // Make sure the story is started. switch story.Story.State { case pivotal.StoryStateStarted: // Continue further to set the state to finished. case pivotal.StoryStateFinished: // Nothing to do here. return nil, nil default: // Foobar, an unexpected story state encountered. return nil, fmt.Errorf("unexpected story state: %v", story.State) } // Set the story state to finished. var ( config = story.tracker.config client = pivotal.NewClient(config.UserToken) projectId = config.ProjectId ) updateTask := fmt.Sprintf("Update Pivotal Tracker story (id = %v)", story.Story.Id) updateRequest := &pivotal.StoryRequest{State: pivotal.StoryStateFinished} updatedStory, _, err := client.Stories.Update(projectId, story.Story.Id, updateRequest) if err != nil { return nil, errs.NewError(updateTask, err) } originalStory := story.Story story.Story = updatedStory return action.ActionFunc(func() error { log.Rollback(updateTask) updateRequest := &pivotal.StoryRequest{State: originalStory.State} updatedStory, _, err := client.Stories.Update(projectId, story.Story.Id, updateRequest) if err != nil { return err } story.Story = updatedStory return nil }), nil }
// PromptUserForConfig is a part of loader.ConfigContainer interface. func (local *LocalConfig) PromptUserForConfig() error { c := LocalConfig{spec: local.spec} // Prompt for the project ID. task := "Fetch available Pivotal Tracker projects" log.Run(task) client := pivotal.NewClient(local.spec.global.UserToken) projects, _, err := client.Projects.List() if err != nil { return errs.NewError(task, err) } sort.Sort(ptProjects(projects)) fmt.Println() fmt.Println("Available Pivotal Tracker projects:") fmt.Println() for i, project := range projects { fmt.Printf(" [%v] %v\n", i+1, project.Name) } fmt.Println() fmt.Println("Choose the project to associate this repository with.") index, err := prompt.PromptIndex("Project number: ", 1, len(projects)) if err != nil { if err == prompt.ErrCanceled { prompt.PanicCancel() } return err } fmt.Println() c.ProjectId = projects[index-1].Id // Prompt for the labels. promptForLabel := func(dst *string, labelName, defaultValue string) { if err != nil { return } question := fmt.Sprintf("%v label", labelName) var label string label, err = prompt.PromptDefault(question, defaultValue) if err == nil { *dst = label } } var componentLabel string promptForLabel(&componentLabel, "Component", "") c.ComponentLabel = &componentLabel promptForLabel(&c.Labels.PointMeLabel, "Point me", DefaultPointMeLabel) promptForLabel(&c.Labels.ReviewedLabel, "Reviewed", DefaultReviewedLabel) promptForLabel(&c.Labels.SkipReviewLabel, "Skip review", DefaultSkipReviewLabel) promptForLabel(&c.Labels.TestedLabel, "Testing passed", DefaultTestedLabel) promptForLabel(&c.Labels.SkipTestingLabel, "Skip testing", DefaultSkipTestingLabel) if err != nil { return err } // Prompt for the release skip check labels. skipCheckLabelsString, err := prompt.Prompt(fmt.Sprintf( "Skip check labels, comma-separated (%v always included): ", strings.Join(DefaultSkipCheckLabels, ", "))) if err != nil { if err != prompt.ErrCanceled { return err } } // Append the new labels to the default ones. // Make sure there are no duplicates and empty strings. var ( insertedLabels = strings.Split(skipCheckLabelsString, ",") lenDefault = len(DefaultSkipCheckLabels) lenInserted = len(insertedLabels) ) // Save a few allocations. skipCheckLabels := make([]string, lenDefault, lenDefault+lenInserted) copy(skipCheckLabels, DefaultSkipCheckLabels) LabelLoop: for _, insertedLabel := range insertedLabels { // Trim spaces. insertedLabel = strings.TrimSpace(insertedLabel) // Skip empty strings. if insertedLabel == "" { continue } // Make sure there are no duplicates. for _, existingLabel := range skipCheckLabels { if insertedLabel == existingLabel { continue LabelLoop } } // Append the label. skipCheckLabels = append(skipCheckLabels, insertedLabel) } c.Labels.SkipCheckLabels = skipCheckLabels // Success! *local = c return nil }