go.fuchsia.dev/infra@v0.0.0-20240507153436-9b593402251b/cmd/recipe_wrapper/checkout/checkout.go (about)

     1  // Copyright 2019 The Fuchsia Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style license that can be
     3  // found in the LICENSE file.
     4  
     5  package checkout
     6  
     7  import (
     8  	"fmt"
     9  	"net/url"
    10  	"strings"
    11  	"time"
    12  
    13  	"go.fuchsia.dev/infra/checkout"
    14  
    15  	buildbucketpb "go.chromium.org/luci/buildbucket/proto"
    16  )
    17  
    18  const (
    19  	DefaultCheckoutTimeout = 10 * time.Minute
    20  )
    21  
    22  // ResolveRepo returns the host and project associated with the build's input.
    23  //
    24  // If the build input has a GitilesCommit, return its host and project.
    25  // If the build input only has a GerritChange, return its host and project.
    26  // If the build input has neither, return the host and project based on the
    27  // provided fallback remote.
    28  func ResolveRepo(buildInput *buildbucketpb.Build_Input, fallbackRemote string) (string, string, error) {
    29  	var host, project string
    30  	if buildInput.GitilesCommit != nil {
    31  		return buildInput.GitilesCommit.Host, buildInput.GitilesCommit.Project, nil
    32  	}
    33  	if len(buildInput.GerritChanges) > 0 {
    34  		host = checkout.RemoveCodeReviewSuffix(buildInput.GerritChanges[0].Host)
    35  		project = buildInput.GerritChanges[0].Project
    36  	} else {
    37  		remoteURL, err := url.Parse(fallbackRemote)
    38  		if err != nil {
    39  			return "", "", fmt.Errorf("could not parse remote %s as URL: %w", fallbackRemote, err)
    40  		}
    41  		host = remoteURL.Host
    42  		project = strings.TrimLeft(remoteURL.Path, "/")
    43  	}
    44  	return host, project, nil
    45  }
    46  
    47  // Resolve a build input's integration URL.
    48  func ResolveIntegrationURL(buildInput *buildbucketpb.Build_Input, hostOverride, projectOverride string) (*url.URL, error) {
    49  	var host string
    50  	if hostOverride != "" {
    51  		host = hostOverride
    52  	} else if changes := buildInput.GetGerritChanges(); changes != nil {
    53  		host = checkout.RemoveCodeReviewSuffix(changes[0].GetHost())
    54  	} else if gitilesCommit := buildInput.GetGitilesCommit(); gitilesCommit != nil {
    55  		host = gitilesCommit.GetHost()
    56  	} else {
    57  		return nil, fmt.Errorf("could not resolve host")
    58  	}
    59  
    60  	var project string
    61  	if projectOverride != "" {
    62  		project = projectOverride
    63  	} else {
    64  		project = "integration"
    65  	}
    66  
    67  	return &url.URL{
    68  		Scheme: "https",
    69  		Host:   host,
    70  		Path:   project,
    71  	}, nil
    72  }
    73  
    74  // Check whether a build input has a GerritChange from `remote`.
    75  func HasRepoChange(buildInput *buildbucketpb.Build_Input, remote string) (bool, error) {
    76  	if len(buildInput.GerritChanges) == 0 {
    77  		return false, nil
    78  	}
    79  	remoteURL, err := url.Parse(remote)
    80  	if err != nil {
    81  		return false, fmt.Errorf("could not parse URL %s", remote)
    82  	}
    83  	change := buildInput.GerritChanges[0]
    84  	if change.Project == strings.TrimLeft(remoteURL.Path, "/") && checkout.RemoveCodeReviewSuffix(change.GetHost()) == remoteURL.Host {
    85  		return true, nil
    86  	}
    87  	return false, nil
    88  }