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  }