blob: 55f7532199aa567b5fe22b53b7bea9d340e52767 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package checkout
import (
"context"
"fmt"
"io"
"net/url"
"os"
"strings"
buildbucketpb "go.chromium.org/luci/buildbucket/proto"
"go.fuchsia.dev/infra/execution"
)
const gitFatalLogPrefix = "fatal: "
// Checkout checks out the git repo at repoURL according to the given build
// input.
//
// defaultRevision specifies the revision to check out if the build was
// triggered by a commit or change on a *different* repository, in which case we
// can't use the build input to determine which revision of `repoURL` to check
// out.
func Checkout(ctx context.Context, input *buildbucketpb.Build_Input, repoURL url.URL, defaultRevision, dir string) error {
strat, err := newStrategy(input, repoURL, defaultRevision)
if err != nil {
return err
}
var stderrBuf strings.Builder
stderrWriter := io.MultiWriter(os.Stderr, &stderrBuf)
// Write everything to stderr. luciexe expects the stdout of the
// recipe_bootstrap tool to be a proto.
executor := execution.NewExecutor(os.Stderr, stderrWriter, dir)
if err := strat.Checkout(ctx, executor); err != nil {
// When git fails it usually emits a "fatal" log in the last line of
// stderr. Make a best effort at parsing out that line and including it in
// the error message.
lines := strings.Split(strings.TrimSpace(stderrBuf.String()), "\n")
lastLine := lines[len(lines)-1]
if strings.HasPrefix(lastLine, gitFatalLogPrefix) {
return fmt.Errorf("%s. Original error: %w", strings.TrimPrefix(lastLine, gitFatalLogPrefix), err)
}
return err
}
return nil
}