96 lines
3.5 KiB
Go
96 lines
3.5 KiB
Go
//go:build integration
|
|
|
|
package main
|
|
|
|
// The fetch step's merge on real git repositories (issue 1676); preview_test.go proves the commands with a fake runner.
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/buildstep"
|
|
"git.novox.be/novox/mesh-sdk/go/forgekey"
|
|
)
|
|
|
|
func git(t *testing.T, dir string, args ...string) string {
|
|
t.Helper()
|
|
cmd := exec.Command("git", append([]string{"-C", dir, "-c", "user.name=t", "-c", "user.email=t@example.invalid", "-c", "commit.gpgsign=false"}, args...)...)
|
|
out, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
t.Fatalf("git %v: %v\n%s", args, err, out)
|
|
}
|
|
return strings.TrimSpace(string(out))
|
|
}
|
|
|
|
func TestRealFetchMergesAConflictAndAPlainFetch(t *testing.T) {
|
|
root := t.TempDir()
|
|
bare, work := filepath.Join(root, "forge", "o", "r.git"), filepath.Join(root, "work")
|
|
os.MkdirAll(bare, 0o755)
|
|
os.MkdirAll(work, 0o755)
|
|
git(t, bare, "init", "-q", "--bare")
|
|
git(t, work, "init", "-q", "-b", "main")
|
|
files := typeScriptModule(`{"dependencies":{"@novox/mesh-sdk":"^0.1.6"}}`)
|
|
files["a.txt"] = "one\ntwo\nthree\n"
|
|
for n, c := range files {
|
|
write(t, filepath.Join(work, n), c, 0o644)
|
|
}
|
|
git(t, work, "add", ".")
|
|
git(t, work, "commit", "-q", "-m", "fork")
|
|
fork := git(t, work, "rev-parse", "HEAD")
|
|
change := func(from, ref string, f map[string]string) string {
|
|
git(t, work, "checkout", "-q", "-B", "tmp", from)
|
|
for n, c := range f {
|
|
write(t, filepath.Join(work, n), c, 0o644)
|
|
}
|
|
git(t, work, "add", ".")
|
|
git(t, work, "commit", "-q", "-m", "c")
|
|
git(t, work, "push", "-q", "-f", bare, "HEAD:"+ref)
|
|
return git(t, work, "rev-parse", "HEAD")
|
|
}
|
|
trunk := change(fork, "refs/heads/main", map[string]string{"a.txt": "one\ntwo\nTRUNK\n"})
|
|
clean := change(fork, "refs/pull/1/head", map[string]string{"modules/m/extra.ts": "export {}\n"})
|
|
clash := change(fork, "refs/pull/2/head", map[string]string{"a.txt": "one\ntwo\nHEAD\n"})
|
|
|
|
m, _, _ := newMachine(t)
|
|
m.Run = forgekey.ExecRunner
|
|
m.RemoteBase = "file://" + filepath.Join(root, "forge") + "/"
|
|
m.FetchOptions = []buildstep.Option{buildstep.AllowFileRemote()}
|
|
|
|
out, err := m.fetch(context.Background(), map[string]any{"repository": "o/r", "commit": clean, "ref": "refs/pull/1/head", "base": trunk})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
r := out.(FetchResult)
|
|
tree := filepath.Join(m.Work, r.Workspace, "tree")
|
|
if r.Merge == "" || strings.Join(r.Changed, ",") != "modules/m/extra.ts" || len(r.Conflicts) != 0 || len(r.Modules) != 1 {
|
|
t.Fatalf("clean: %+v", r)
|
|
}
|
|
if want := git(t, tree, "rev-parse", r.Merge+":modules/m"); r.Trees["modules/m"].Tree != want {
|
|
t.Errorf("tree = %s, want %s", r.Trees["modules/m"].Tree, want)
|
|
}
|
|
if got := git(t, tree, "rev-parse", "HEAD"); got != r.Merge {
|
|
t.Errorf("the workspace is at %s, want the merge %s", got, r.Merge)
|
|
}
|
|
|
|
out, err = m.fetch(context.Background(), map[string]any{"repository": "o/r", "commit": clash, "ref": "refs/pull/2/head", "base": trunk})
|
|
if err != nil {
|
|
t.Fatalf("a conflict failed the step: %v", err)
|
|
}
|
|
r = out.(FetchResult)
|
|
if r.Merge != "" || strings.Join(r.Conflicts, ",") != "a.txt" {
|
|
t.Fatalf("conflict: %+v", r)
|
|
}
|
|
if got := git(t, filepath.Join(m.Work, r.Workspace, "tree"), "rev-parse", "HEAD"); got != trunk {
|
|
t.Errorf("after a conflict the workspace is at %s, want the trunk %s", got, trunk)
|
|
}
|
|
|
|
out, err = m.fetch(context.Background(), map[string]any{"repository": "o/r", "commit": clean, "ref": "refs/pull/1/head"})
|
|
if err != nil || out.(FetchResult).Merge != "" || out.(FetchResult).Trees != nil {
|
|
t.Errorf("no base: %+v %v", out, err)
|
|
}
|
|
}
|