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  }