go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/buildbucket/appengine/common/common.go (about)

     1  // Copyright 2023 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package common
    16  
    17  import (
    18  	"context"
    19  
    20  	"go.chromium.org/luci/common/errors"
    21  	"go.chromium.org/luci/gae/service/datastore"
    22  
    23  	"go.chromium.org/luci/buildbucket/appengine/internal/perm"
    24  	"go.chromium.org/luci/buildbucket/appengine/model"
    25  )
    26  
    27  // GetBuild returns the build with the given ID or NotFound appstatus if it is
    28  // not found.
    29  // A shortcut for GetBuildEntities with only Build.
    30  func GetBuild(ctx context.Context, id int64) (*model.Build, error) {
    31  	entities, err := GetBuildEntities(ctx, id, model.BuildKind)
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  	return entities[0].(*model.Build), nil
    36  }
    37  
    38  func GetBuildEntities(ctx context.Context, id int64, kinds ...string) ([]any, error) {
    39  	if len(kinds) == 0 {
    40  		return nil, errors.Reason("no entities to get").Err()
    41  	}
    42  
    43  	var toGet []any
    44  	bk := datastore.KeyForObj(ctx, &model.Build{ID: id})
    45  	appendEntity := func(kind string) error {
    46  		switch kind {
    47  		case model.BuildKind:
    48  			toGet = append(toGet, &model.Build{ID: id})
    49  		case model.BuildStatusKind:
    50  			toGet = append(toGet, &model.BuildStatus{Build: bk})
    51  		case model.BuildStepsKind:
    52  			toGet = append(toGet, &model.BuildSteps{Build: bk})
    53  		case model.BuildInfraKind:
    54  			toGet = append(toGet, &model.BuildInfra{Build: bk})
    55  		case model.BuildInputPropertiesKind:
    56  			toGet = append(toGet, &model.BuildInputProperties{Build: bk})
    57  		case model.BuildOutputPropertiesKind:
    58  			toGet = append(toGet, &model.BuildOutputProperties{Build: bk})
    59  		default:
    60  			return errors.Reason("unknown entity kind %s", kind).Err()
    61  		}
    62  		return nil
    63  	}
    64  
    65  	for _, kind := range kinds {
    66  		if err := appendEntity(kind); err != nil {
    67  			return nil, err
    68  		}
    69  	}
    70  
    71  	switch err := datastore.Get(ctx, toGet...); {
    72  	case errors.Contains(err, datastore.ErrNoSuchEntity):
    73  		return nil, perm.NotFoundErr(ctx)
    74  	case err != nil:
    75  		return nil, errors.Annotate(err, "error fetching build entities with ID %d", id).Err()
    76  	default:
    77  		return toGet, nil
    78  	}
    79  }