mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 19:51:50 +00:00
Closes [#1110](https://github.com/sourcegraph/devx-support/issues/1110) Closes DINF-96 We don't print the stdErr when a command fails … in particular when git fails. Therefore we see very little in the panic of what went wrong. Explanation: > There's a weird behavior that occurs where an error isn't accessible in the err variable // from a *Cmd executing a git command after calling CombinedOutput(). // This occurs due to how Git handles errors and how the exec package in Go interprets the command's output. // Git often writes error messages to stderr, but it might still exit with a status code of 0 (indicating success). // In this case, CombinedOutput() won't return an error, but the error message will be in the out variable. ## Test plan Manual testing ```go func main() { ctx := context.Background() cmd := exec.CommandContext(ctx, "git", "rev-parse", "--is-inside-work-tree") out, err := handleGitCommandExec(cmd) if err != nil { // er := errors.Wrap(err, fmt.Sprintf("idsdsd: %s", string(out))) panic(err) } fmt.Println("hello", string(out)) } ``` ## Changelog <!-- OPTIONAL; info at https://www.notion.so/sourcegraph/Writing-a-changelog-entry-dd997f411d524caabf0d8d38a24a878c -->
99 lines
2.8 KiB
Go
99 lines
2.8 KiB
Go
package gitops
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"github.com/sourcegraph/sourcegraph/internal/execute"
|
|
"github.com/sourcegraph/sourcegraph/internal/oobmigration"
|
|
"github.com/sourcegraph/sourcegraph/lib/errors"
|
|
)
|
|
|
|
var ErrNoTags = errors.New("no tags found")
|
|
|
|
func determineDiffArgs(baseBranch, commit string) (string, error) {
|
|
// We have a different base branch (possibily) and on aspect agents we are in a detached state with only 100 commit depth
|
|
// so we might not know about this base branch ... so we first fetch the base and then diff
|
|
//
|
|
// Determine the base branch
|
|
if baseBranch == "" {
|
|
// When the base branch is not set, then this is probably a build where a commit got merged
|
|
// onto the current branch. So we just diff with the current commit
|
|
return "@^", nil
|
|
}
|
|
|
|
// fetch the branch to make sure it exists
|
|
refspec := fmt.Sprintf("+refs/heads/%s:refs/remotes/origin/%s", baseBranch, baseBranch)
|
|
if _, err := exec.Command("git", "fetch", "origin", refspec).Output(); err != nil {
|
|
return "", errors.Newf("failed to fetch %s: %s", baseBranch, err)
|
|
} else {
|
|
return fmt.Sprintf("origin/%s...%s", baseBranch, commit), nil
|
|
}
|
|
}
|
|
|
|
func GetHEADChangedFiles() ([]string, error) {
|
|
output, err := execute.Git(context.Background(), "diff", "--name-only", "@^")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
changedFiles := strings.Split(strings.TrimSpace(string(output)), "\n")
|
|
return changedFiles, nil
|
|
}
|
|
|
|
func GetBranchChangedFiles(baseBranch, commit string) ([]string, error) {
|
|
diffArgs, err := determineDiffArgs(baseBranch, commit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
output, err := execute.Git(context.Background(), "diff", "--name-only", diffArgs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
changedFiles := strings.Split(strings.TrimSpace(string(output)), "\n")
|
|
return changedFiles, nil
|
|
}
|
|
|
|
func GetLatestTag() (string, error) {
|
|
output, err := execute.Git(context.Background(), "tag", "--list", "v*")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
tagMap := map[string]struct{}{}
|
|
for _, tag := range strings.Split(string(output), "\n") {
|
|
if version, ok := oobmigration.NewVersionFromString(tag); ok {
|
|
tagMap[version.String()] = struct{}{}
|
|
}
|
|
}
|
|
if len(tagMap) == 0 {
|
|
return "", ErrNoTags
|
|
}
|
|
|
|
versions := make([]oobmigration.Version, 0, len(tagMap))
|
|
for tag := range tagMap {
|
|
version, _ := oobmigration.NewVersionFromString(tag)
|
|
versions = append(versions, version)
|
|
}
|
|
oobmigration.SortVersions(versions)
|
|
|
|
return versions[len(versions)-1].String(), nil
|
|
}
|
|
|
|
func HasIncludedCommit(commits ...string) (bool, error) {
|
|
found := false
|
|
var errs error
|
|
for _, mustIncludeCommit := range commits {
|
|
output, err := execute.Git(context.Background(), "merge-base", "--is-ancestor", mustIncludeCommit, "HEAD")
|
|
if err == nil {
|
|
found = true
|
|
break
|
|
}
|
|
errs = errors.Append(errs, errors.Errorf("%v | Output: %q", err, string(output)))
|
|
}
|
|
|
|
return found, errs
|
|
}
|