go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/cv/internal/userhtml/cl_submission.go (about)

     1  // Copyright 2021 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 userhtml
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  
    21  	"go.chromium.org/luci/cv/internal/common"
    22  	"go.chromium.org/luci/cv/internal/run"
    23  	"go.chromium.org/luci/cv/internal/run/eventpb"
    24  )
    25  
    26  // StringifySubmissionSuccesses composes a message indicating the urls of the
    27  // CLs that were just submitted, and the number of pending CLs.
    28  func StringifySubmissionSuccesses(allCls []*run.RunCL, v *run.LogEntry_CLSubmitted) string {
    29  	var sb strings.Builder
    30  	currentlySubmitted := common.MakeCLIDs(v.NewlySubmittedCls...)
    31  	clidToURL := makeURLMap(allCls)
    32  	switch len(currentlySubmitted) {
    33  	case 0:
    34  		sb.WriteString("No CLs were submitted successfully")
    35  	case 1:
    36  		_, _ = fmt.Fprintf(&sb, "CL %s was submitted successfully", clidToURL[currentlySubmitted[0]])
    37  	default:
    38  		_, _ = fmt.Fprintf(&sb, "%d CLs were submitted successfully:", len(currentlySubmitted))
    39  		for _, clid := range currentlySubmitted {
    40  			_, _ = fmt.Fprintf(&sb, "\n  * %s", clidToURL[clid])
    41  		}
    42  	}
    43  	if left := len(allCls) - int(v.TotalSubmitted); left > 0 {
    44  		_, _ = fmt.Fprintf(&sb, "\n%d out of %d CLs are still pending", left, len(allCls))
    45  	}
    46  	return sb.String()
    47  }
    48  
    49  // StringifySubmissionFailureReason makes a human-readable message detailing
    50  // the reason for the failure of this submission.
    51  func StringifySubmissionFailureReason(allCls []*run.RunCL, sc *eventpb.SubmissionCompleted) string {
    52  	var sb strings.Builder
    53  	if sc.GetFailureReason() != nil {
    54  		switch sc.GetFailureReason().(type) {
    55  		case *eventpb.SubmissionCompleted_Timeout:
    56  			return "Timeout"
    57  		case *eventpb.SubmissionCompleted_ClFailures:
    58  			clidToURL := makeURLMap(allCls)
    59  			msg, err := sFormatCLSubmissionFailures(clidToURL, sc.GetClFailures())
    60  			if err != nil {
    61  				panic(err)
    62  			}
    63  			sb.WriteString(msg)
    64  		}
    65  	}
    66  	return sb.String()
    67  }
    68  
    69  func listify(cls []string) string {
    70  	var sb strings.Builder
    71  	for i, v := range cls {
    72  		if i == len(cls)-1 && len(cls) > 1 {
    73  			sb.WriteString(" and ")
    74  		} else if i > 0 {
    75  			sb.WriteString(", ")
    76  		}
    77  		sb.WriteString(v)
    78  	}
    79  	sb.WriteString(" ")
    80  	return sb.String()
    81  }
    82  
    83  // sFormatCLSubmissionFailures returns a string with the messages for cl submission failures.
    84  func sFormatCLSubmissionFailures(clidToURL map[common.CLID]string, fs *eventpb.SubmissionCompleted_CLSubmissionFailures) (string, error) {
    85  	var sb strings.Builder
    86  	for i, f := range fs.GetFailures() {
    87  		if i > 0 {
    88  			sb.WriteRune('\n')
    89  		}
    90  		if _, err := fmt.Fprintf(&sb, "CL %s failed to be submitted due to '%s'", clidToURL[common.CLID(f.GetClid())], f.GetMessage()); err != nil {
    91  			return "", err
    92  		}
    93  	}
    94  	return sb.String(), nil
    95  }
    96  
    97  func makeURLMap(cls []*run.RunCL) map[common.CLID]string {
    98  	ret := make(map[common.CLID]string, len(cls))
    99  	for _, cl := range cls {
   100  		ret[cl.ID] = cl.ExternalID.MustURL()
   101  	}
   102  	return ret
   103  }