github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/plugin/builtin/taskdata/tag.go (about) 1 package taskdata 2 3 import ( 4 "net/http" 5 6 "github.com/evergreen-ci/evergreen" 7 "github.com/evergreen-ci/evergreen/db" 8 "github.com/evergreen-ci/evergreen/model/task" 9 "github.com/evergreen-ci/evergreen/plugin" 10 "github.com/evergreen-ci/evergreen/util" 11 "github.com/gorilla/mux" 12 "github.com/pkg/errors" 13 "gopkg.in/mgo.v2" 14 "gopkg.in/mgo.v2/bson" 15 ) 16 17 type TagContainer struct { 18 Tag string `bson:"_id" json:"tag"` 19 } 20 21 func uiGetTags(w http.ResponseWriter, r *http.Request) { 22 taskId := mux.Vars(r)["task_id"] 23 tags, err := GetTags(taskId) 24 if err != nil { 25 http.Error(w, err.Error(), http.StatusInternalServerError) 26 return 27 } 28 plugin.WriteJSON(w, http.StatusOK, tags) 29 } 30 31 // GetTags finds TaskJSONs that have tags in the project associated with a 32 // given task. 33 func GetTags(taskId string) ([]TagContainer, error) { 34 t, err := task.FindOne(task.ById(taskId)) 35 if err != nil { 36 return nil, err 37 } 38 tags := []TagContainer{} 39 err = db.Aggregate(collection, []bson.M{ 40 {"$match": bson.M{ProjectIdKey: t.Project, TagKey: bson.M{"$exists": true, "$ne": ""}}}, 41 {"$project": bson.M{TagKey: 1}}, bson.M{"$group": bson.M{"_id": "$tag"}}, 42 }, &tags) 43 if err != nil { 44 return nil, err 45 } 46 return tags, nil 47 } 48 49 // handleTaskTags will update the TaskJSON's tags depending on the request. 50 func uiHandleTaskTag(w http.ResponseWriter, r *http.Request) { 51 taskId := mux.Vars(r)["task_id"] 52 name := mux.Vars(r)["name"] 53 54 var err error 55 switch r.Method { 56 case evergreen.MethodDelete: 57 err = DeleteTagFromTask(taskId, name) 58 case evergreen.MethodPost: 59 tc := TagContainer{} 60 err = util.ReadJSONInto(util.NewRequestReader(r), &tc) 61 if err != nil { 62 http.Error(w, err.Error(), http.StatusInternalServerError) 63 return 64 } 65 if tc.Tag == "" { 66 http.Error(w, "tag must not be blank", http.StatusBadRequest) 67 return 68 } 69 err = SetTagForTask(taskId, name, tc.Tag) 70 } 71 72 if err != nil { 73 if err == mgo.ErrNotFound { 74 http.Error(w, "{}", http.StatusNotFound) 75 return 76 } 77 http.Error(w, err.Error(), http.StatusInternalServerError) 78 return 79 } 80 81 plugin.WriteJSON(w, http.StatusOK, "") 82 } 83 84 func DeleteTagFromTask(taskId, name string) error { 85 t, err := task.FindOne(task.ById(taskId)) 86 if err != nil { 87 return errors.WithStack(err) 88 } 89 90 _, err = db.UpdateAll(collection, 91 bson.M{VersionIdKey: t.Version, NameKey: name}, 92 bson.M{"$unset": bson.M{TagKey: 1}}) 93 94 return errors.WithStack(err) 95 } 96 97 func SetTagForTask(taskId, name, tag string) error { 98 t, err := task.FindOne(task.ById(taskId)) 99 if err != nil { 100 return errors.WithStack(err) 101 } 102 _, err = db.UpdateAll(collection, 103 bson.M{VersionIdKey: t.Version, NameKey: name}, 104 bson.M{"$set": bson.M{TagKey: tag}}) 105 106 return errors.WithStack(err) 107 } 108 func apiGetTagsForTask(w http.ResponseWriter, r *http.Request) { 109 t := plugin.GetTask(r) 110 if t == nil { 111 http.Error(w, "task not found", http.StatusNotFound) 112 return 113 } 114 115 taskName := mux.Vars(r)["task_name"] 116 name := mux.Vars(r)["name"] 117 tagged, err := GetTagsForTask(t.Project, t.BuildVariant, taskName, name) 118 if err != nil { 119 http.Error(w, err.Error(), http.StatusInternalServerError) 120 return 121 } 122 plugin.WriteJSON(w, http.StatusOK, tagged) 123 } 124 125 // GetTagsForTask gets all of the tasks with tags for the given task name and 126 // build variant. 127 func GetTagsForTask(project, buildVariant, taskName, name string) ([]TaskJSON, error) { 128 tagged := []TaskJSON{} 129 jsonQuery := db.Query(bson.M{ 130 ProjectIdKey: project, 131 VariantKey: buildVariant, 132 TaskNameKey: taskName, 133 TagKey: bson.M{"$exists": true, "$ne": ""}, 134 NameKey: name}) 135 err := db.FindAllQ(collection, jsonQuery, &tagged) 136 if err != nil { 137 return nil, err 138 } 139 return tagged, nil 140 } 141 142 func uiGetTaskJSONByTag(w http.ResponseWriter, r *http.Request) { 143 projectId := mux.Vars(r)["project_id"] 144 tag := mux.Vars(r)["tag"] 145 variant := mux.Vars(r)["variant"] 146 taskName := mux.Vars(r)["task_name"] 147 name := mux.Vars(r)["name"] 148 149 jsonForTask, err := GetTaskJSONByTag(projectId, tag, variant, taskName, name) 150 151 if err != nil { 152 if err != mgo.ErrNotFound { 153 http.Error(w, err.Error(), http.StatusInternalServerError) 154 return 155 } 156 http.Error(w, "{}", http.StatusNotFound) 157 return 158 } 159 if len(r.FormValue("full")) != 0 { // if specified, include the json data's container as well 160 plugin.WriteJSON(w, http.StatusOK, jsonForTask) 161 return 162 } 163 plugin.WriteJSON(w, http.StatusOK, jsonForTask) 164 } 165 166 // GetTaskJSONByTag finds a TaskJSON by a tag 167 func GetTaskJSONByTag(projectId, tag, variant, taskName, name string) (*TaskJSON, error) { 168 jsonForTask := &TaskJSON{} 169 err := db.FindOneQ(collection, 170 db.Query(bson.M{"project_id": projectId, 171 TagKey: tag, 172 VariantKey: variant, 173 TaskNameKey: taskName, 174 NameKey: name, 175 }), jsonForTask) 176 if err != nil { 177 return nil, err 178 } 179 return jsonForTask, nil 180 }