github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/model/build_variant_history.go (about) 1 package model 2 3 import ( 4 "github.com/evergreen-ci/evergreen" 5 "github.com/evergreen-ci/evergreen/db" 6 "github.com/evergreen-ci/evergreen/model/task" 7 "github.com/evergreen-ci/evergreen/model/version" 8 "gopkg.in/mgo.v2/bson" 9 ) 10 11 type buildVariantHistoryIterator struct { 12 BuildVariantInTask string 13 BuildVariantInVersion string 14 ProjectName string 15 } 16 17 // Interface around getting task and version history for a given build variant 18 // in a given project. 19 type BuildVariantHistoryIterator interface { 20 GetItems(beforeCommit *version.Version, numCommits int) ([]bson.M, []version.Version, error) 21 } 22 23 // Since version currently uses build variant display name and task uses build variant 24 // name, we need both. 25 func NewBuildVariantHistoryIterator(buildVariantInTask string, buildVariantInVersion string, 26 projectName string) BuildVariantHistoryIterator { 27 return &buildVariantHistoryIterator{buildVariantInTask, buildVariantInVersion, projectName} 28 } 29 30 // Returns versions and tasks grouped by gitspec, newest first (sorted by order number desc) 31 func (self *buildVariantHistoryIterator) GetItems(beforeCommit *version.Version, numRevisions int) ([]bson.M, []version.Version, error) { 32 var versionQuery db.Q 33 if beforeCommit != nil { 34 versionQuery = db.Query(bson.M{ 35 version.RequesterKey: evergreen.RepotrackerVersionRequester, 36 version.RevisionOrderNumberKey: bson.M{"$lt": beforeCommit.RevisionOrderNumber}, 37 version.IdentifierKey: self.ProjectName, 38 version.BuildVariantsKey: bson.M{ 39 "$elemMatch": bson.M{ 40 version.BuildStatusVariantKey: self.BuildVariantInVersion, 41 }, 42 }, 43 }) 44 } else { 45 versionQuery = db.Query(bson.M{ 46 version.RequesterKey: evergreen.RepotrackerVersionRequester, 47 version.IdentifierKey: self.ProjectName, 48 version.BuildVariantsKey: bson.M{ 49 "$elemMatch": bson.M{ 50 version.BuildStatusVariantKey: self.BuildVariantInVersion, 51 }, 52 }, 53 }) 54 } 55 versionQuery = versionQuery.WithFields( 56 version.IdKey, 57 version.RevisionOrderNumberKey, 58 version.RevisionKey, 59 version.MessageKey, 60 version.CreateTimeKey, 61 ).Sort([]string{"-" + version.RevisionOrderNumberKey}).Limit(numRevisions) 62 63 //Get the next numCommits 64 versions, err := version.Find(versionQuery) 65 66 if err != nil { 67 return nil, nil, err 68 } 69 70 if len(versions) == 0 { 71 return nil, []version.Version{}, nil 72 } 73 74 //versionEndBoundary is the *earliest* version which should be included in results 75 versionEndBoundary := versions[len(versions)-1] 76 77 matchFilter := bson.M{ 78 task.RequesterKey: evergreen.RepotrackerVersionRequester, 79 task.BuildVariantKey: self.BuildVariantInTask, 80 task.ProjectKey: self.ProjectName, 81 } 82 83 if beforeCommit != nil { 84 matchFilter[task.RevisionOrderNumberKey] = bson.M{ 85 "$gte": versionEndBoundary.RevisionOrderNumber, 86 "$lt": beforeCommit.RevisionOrderNumber, 87 } 88 } else { 89 matchFilter[task.RevisionOrderNumberKey] = bson.M{ 90 "$gte": versionEndBoundary.RevisionOrderNumber, 91 } 92 } 93 94 pipeline := []bson.M{ 95 {"$match": matchFilter}, 96 {"$sort": bson.D{{task.RevisionOrderNumberKey, 1}}}, 97 { 98 "$group": bson.M{ 99 "_id": "$" + task.RevisionKey, 100 "order": bson.M{"$first": "$" + task.RevisionOrderNumberKey}, 101 "tasks": bson.M{ 102 "$push": bson.M{ 103 "_id": "$" + task.IdKey, 104 "status": "$" + task.StatusKey, 105 "task_end_details": "$" + task.DetailsKey, 106 "activated": "$" + task.ActivatedKey, 107 "time_taken": "$" + task.TimeTakenKey, 108 "display_name": "$" + task.DisplayNameKey, 109 }, 110 }, 111 }, 112 }, 113 {"$sort": bson.M{task.RevisionOrderNumberKey: -1, task.DisplayNameKey: 1}}, 114 } 115 116 var output []bson.M 117 if err = db.Aggregate(task.Collection, pipeline, &output); err != nil { 118 return nil, nil, err 119 } 120 121 return output, versions, nil 122 }