// Helper function to fetch a group of versions and their associated builds. // Returns the versions themselves, as well as a map of version id -> the // builds that are a part of the version (unsorted). func fetchVersionsAndAssociatedBuilds(project *model.Project, skip int, numVersions int) ([]version.Version, map[string][]build.Build, error) { // fetch the versions from the db versionsFromDB, err := version.Find(version.ByProjectId(project.Identifier). WithFields( version.RevisionKey, version.ErrorsKey, version.WarningsKey, version.IgnoredKey, version.MessageKey, version.AuthorKey, version.RevisionOrderNumberKey, version.CreateTimeKey, ).Sort([]string{"-" + version.RevisionOrderNumberKey}).Skip(skip).Limit(numVersions)) if err != nil { return nil, nil, fmt.Errorf("error fetching versions from database: %v", err) } // create a slice of the version ids (used to fetch the builds) versionIds := make([]string, 0, len(versionsFromDB)) for _, v := range versionsFromDB { versionIds = append(versionIds, v.Id) } // fetch all of the builds (with only relevant fields) buildsFromDb, err := build.Find( build.ByVersions(versionIds). WithFields(build.BuildVariantKey, build.TasksKey, build.VersionKey)) if err != nil { return nil, nil, fmt.Errorf("error fetching builds from database: %v", err) } // group the builds by version buildsByVersion := map[string][]build.Build{} for _, build := range buildsFromDb { buildsByVersion[build.Version] = append(buildsByVersion[build.Version], build) } return versionsFromDB, buildsByVersion, nil }
// Returns a JSON response of an array with the NumRecentVersions // most recent versions (sorted on commit order number descending). func (restapi restAPI) getRecentVersions(w http.ResponseWriter, r *http.Request) { projectId := mux.Vars(r)["project_id"] versions, err := version.Find(version.ByMostRecentForRequester(projectId, evergreen.RepotrackerVersionRequester).Limit(10)) if err != nil { msg := fmt.Sprintf("Error finding recent versions of project '%v'", projectId) evergreen.Logger.Logf(slogger.ERROR, "%v: %v", msg, err) restapi.WriteJSON(w, http.StatusInternalServerError, responseError{Message: msg}) return } // Create a slice of version ids to find all relevant builds versionIds := make([]string, 0, len(versions)) // Cache the order of versions in a map for lookup by their id versionIdx := make(map[string]int, len(versions)) for i, version := range versions { versionIds = append(versionIds, version.Id) versionIdx[version.Id] = i } // Find all builds corresponding the set of version ids builds, err := build.Find( build.ByVersions(versionIds). WithFields(build.BuildVariantKey, build.DisplayNameKey, build.TasksKey, build.VersionKey)) if err != nil { msg := fmt.Sprintf("Error finding recent versions of project '%v'", projectId) evergreen.Logger.Logf(slogger.ERROR, "%v: %v", msg, err) restapi.WriteJSON(w, http.StatusInternalServerError, responseError{Message: msg}) return } result := recentVersionsContent{ Project: projectId, Versions: make([]versionLessInfo, 0, len(versions)), } for _, version := range versions { versionInfo := versionLessInfo{ Id: version.Id, Author: version.Author, Revision: version.Revision, Message: version.Message, Builds: make(versionByBuild), } result.Versions = append(result.Versions, versionInfo) } for _, build := range builds { buildInfo := versionBuildInfo{ Id: build.Id, Name: build.DisplayName, Tasks: make(versionByBuildByTask, len(build.Tasks)), } for _, task := range build.Tasks { buildInfo.Tasks[task.DisplayName] = versionStatus{ Id: task.Id, Status: task.Status, TimeTaken: task.TimeTaken, } } versionInfo := result.Versions[versionIdx[build.Version]] versionInfo.Builds[build.BuildVariant] = buildInfo } restapi.WriteJSON(w, http.StatusOK, result) return }