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  }