diff --git a/util/gitutil/gitutil.go b/util/gitutil/gitutil.go index b933cb46..8ab76ab2 100644 --- a/util/gitutil/gitutil.go +++ b/util/gitutil/gitutil.go @@ -6,6 +6,7 @@ import ( "net/url" "os" "os/exec" + "path/filepath" "strings" "github.com/pkg/errors" @@ -68,6 +69,14 @@ func (c *Git) RootDir() (string, error) { return c.clean(c.run("rev-parse", "--show-toplevel")) } +func (c *Git) GitDir() (string, error) { + dir, err := c.RootDir() + if err != nil { + return "", err + } + return filepath.Join(dir, ".git"), nil +} + func (c *Git) RemoteURL() (string, error) { // Try to get the remote URL from the origin remote first if ru, err := c.clean(c.run("remote", "get-url", "origin")); err == nil && ru != "" { diff --git a/util/gitutil/testutil.go b/util/gitutil/testutil.go index 8cdabc15..ea9dd058 100644 --- a/util/gitutil/testutil.go +++ b/util/gitutil/testutil.go @@ -39,9 +39,10 @@ func GitCheckoutBranch(c *Git, tb testing.TB, name string) { require.Empty(tb, out) } -func GitAdd(c *Git, tb testing.TB, file string) { +func GitAdd(c *Git, tb testing.TB, files ...string) { tb.Helper() - _, err := fakeGit(c, "add", file) + args := append([]string{"add"}, files...) + _, err := fakeGit(c, args...) require.NoError(tb, err) } diff --git a/util/gitutil/testutilserve.go b/util/gitutil/testutilserve.go new file mode 100644 index 00000000..631ed693 --- /dev/null +++ b/util/gitutil/testutilserve.go @@ -0,0 +1,62 @@ +package gitutil + +import ( + "context" + "fmt" + "net" + "net/http" + "testing" + + "github.com/stretchr/testify/require" +) + +func GitServeHTTP(c *Git, t testing.TB) (url string) { + t.Helper() + gitUpdateServerInfo(c, t) + ctx, cancel := context.WithCancel(context.TODO()) + + ready := make(chan struct{}) + done := make(chan struct{}) + + name := "test.git" + dir, err := c.GitDir() + if err != nil { + cancel() + } + + var addr string + go func() { + mux := http.NewServeMux() + prefix := fmt.Sprintf("/%s/", name) + mux.Handle(prefix, http.StripPrefix(prefix, http.FileServer(http.Dir(dir)))) + l, err := net.Listen("tcp", "localhost:0") + if err != nil { + panic(err) + } + + addr = l.Addr().String() + + close(ready) + + s := http.Server{Handler: mux} //nolint:gosec // potential attacks are not relevant for tests + go s.Serve(l) + <-ctx.Done() + s.Shutdown(context.TODO()) + l.Close() + + close(done) + }() + <-ready + + t.Cleanup(func() { + cancel() + <-done + }) + return fmt.Sprintf("http://%s/%s", addr, name) +} + +func gitUpdateServerInfo(c *Git, tb testing.TB) { + tb.Helper() + _, err := fakeGit(c, "update-server-info") + require.NoError(tb, err) +}