github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/plugin/builtin/taskdata/version.go (about) 1 package taskdata 2 3 import ( 4 "net/http" 5 "time" 6 7 "github.com/evergreen-ci/evergreen/db" 8 "github.com/evergreen-ci/evergreen/model/version" 9 "github.com/evergreen-ci/evergreen/plugin" 10 "github.com/evergreen-ci/evergreen/util" 11 "github.com/gorilla/mux" 12 "gopkg.in/mgo.v2" 13 "gopkg.in/mgo.v2/bson" 14 ) 15 16 // CommitInfo represents the information about the commit 17 // associated with the version of a given project. This is displayed 18 // at the top of each header for each project. 19 type CommitInfo struct { 20 Author string `json:"author"` 21 Message string `json:"message"` 22 CreateTime time.Time `json:"create_time"` 23 Revision string `json:"revision"` 24 VersionId string `json:"version_id"` 25 } 26 27 // TaskForVersionId contains the id information about the group of tasks 28 // including the version id and the revision order number. 29 type TaskForVersionId struct { 30 VersionId string `bson:"vid"` 31 RevisionOrderNumber int `bson:"r"` 32 } 33 34 // TaskInfo contains the relevant TaskJSON information the tasks associated with a version. 35 type TaskInfo struct { 36 TaskId string `bson:"t_id" json:"task_id"` 37 TaskName string `bson:"tn" json:"task_name"` 38 Variant string `bson:"var" json:"variant"` 39 Data interface{} `bson:"d" json:"data"` 40 } 41 42 // TasksForVersion is a list of tasks that are associated with a given version id. 43 type TasksForVersion struct { 44 Id TaskForVersionId `bson:"_id" json:"id"` 45 Tasks []TaskInfo `bson:"t" json:"tasks"` 46 } 47 48 // VersionData includes the TaskInfo, and Commit information for a given version. 49 type VersionData struct { 50 JSONTasks []TaskInfo `json:"json_tasks"` 51 Commit CommitInfo `json:"commit_info"` 52 LastRevision bool `json:"last_revision"` 53 } 54 55 // getVersion returns a StatusOK if the route is hit 56 func getVersion(w http.ResponseWriter, r *http.Request) { 57 plugin.WriteJSON(w, http.StatusOK, "1") 58 } 59 60 // GetTasksForVersion sends back the list of TaskJSON documents associated with a version id. 61 func GetTasksForVersion(versionId, name string) ([]TaskJSON, error) { 62 var jsonForTasks []TaskJSON 63 err := db.FindAllQ(collection, db.Query(bson.M{VersionIdKey: versionId, 64 NameKey: name}).WithFields(DataKey, TaskIdKey, TaskNameKey), &jsonForTasks) 65 if err != nil { 66 if err != mgo.ErrNotFound { 67 return nil, err 68 } 69 return nil, err 70 } 71 72 return jsonForTasks, err 73 } 74 75 func uiGetTasksForVersion(w http.ResponseWriter, r *http.Request) { 76 jsonForTasks, err := GetTasksForVersion(mux.Vars(r)["version_id"], mux.Vars(r)["name"]) 77 if jsonForTasks == nil { 78 http.Error(w, "{}", http.StatusNotFound) 79 return 80 } 81 if err != nil { 82 http.Error(w, err.Error(), http.StatusInternalServerError) 83 return 84 } 85 plugin.WriteJSON(w, http.StatusOK, jsonForTasks) 86 return 87 } 88 89 func uiGetTasksForLatestVersion(w http.ResponseWriter, r *http.Request) { 90 project := mux.Vars(r)["project_id"] 91 name := mux.Vars(r)["name"] 92 skip, err := util.GetIntValue(r, "skip", 0) 93 if err != nil { 94 http.Error(w, err.Error(), http.StatusBadRequest) 95 return 96 } 97 if skip < 0 { 98 http.Error(w, "negative skip", http.StatusBadRequest) 99 return 100 } 101 102 data, err := GetTasksForLatestVersion(project, name, skip) 103 if err != nil { 104 if err == mgo.ErrNotFound { 105 http.Error(w, "{}", http.StatusNotFound) 106 return 107 } 108 http.Error(w, err.Error(), http.StatusInternalServerError) 109 return 110 } 111 112 plugin.WriteJSON(w, http.StatusOK, data) 113 } 114 115 // GetTasksForLatestVersion sends back the TaskJSON data associated with the latest version. 116 func GetTasksForLatestVersion(project, name string, skip int) (*VersionData, error) { 117 pipeline := []bson.M{ 118 // match on name and project 119 {"$match": bson.M{ 120 NameKey: name, 121 ProjectIdKey: project, 122 }}, 123 124 // sort on the revision number 125 {"$sort": bson.M{ 126 RevisionOrderNumberKey: -1, 127 }}, 128 129 // group by version id 130 {"$group": bson.M{ 131 "_id": bson.M{ 132 "r": "$" + RevisionOrderNumberKey, 133 "vid": "$" + VersionIdKey, 134 }, 135 "t": bson.M{ 136 "$push": bson.M{ 137 "d": "$" + DataKey, 138 "t_id": "$" + TaskIdKey, 139 "tn": "$" + TaskNameKey, 140 "var": "$" + VariantKey, 141 }, 142 }, 143 }}, 144 145 // sort on the _id 146 {"$sort": bson.M{ 147 "_id.r": -1, 148 }}, 149 150 {"$skip": skip}, 151 {"$limit": 2}, 152 } 153 154 tasksForVersions := []TasksForVersion{} 155 err := db.Aggregate(collection, pipeline, &tasksForVersions) 156 if err != nil { 157 return nil, err 158 } 159 if len(tasksForVersions) == 0 { 160 return nil, mgo.ErrNotFound 161 } 162 163 // we default have another revision 164 lastRevision := false 165 currentVersion := tasksForVersions[0] 166 167 // if there is only one version, then we are at the last revision. 168 if len(tasksForVersions) < 2 { 169 lastRevision = true 170 } 171 172 // get the version commit info 173 v, err := version.FindOne(version.ById(currentVersion.Id.VersionId)) 174 if err != nil { 175 return nil, err 176 } 177 178 commitInfo := CommitInfo{ 179 Author: v.Author, 180 Message: v.Message, 181 CreateTime: v.CreateTime, 182 Revision: v.Revision, 183 VersionId: v.Id, 184 } 185 data := &VersionData{currentVersion.Tasks, commitInfo, lastRevision} 186 return data, nil 187 188 }