| package fakegit // import "github.com/docker/docker/testutil/fakegit" | |
| import ( | |
| "fmt" | |
| "net/http" | |
| "net/http/httptest" | |
| "os" | |
| "os/exec" | |
| "path/filepath" | |
| "testing" | |
| "github.com/docker/docker/testutil/fakecontext" | |
| "github.com/docker/docker/testutil/fakestorage" | |
| ) | |
| type gitServer interface { | |
| URL() string | |
| Close() error | |
| } | |
| type localGitServer struct { | |
| *httptest.Server | |
| } | |
| func (r *localGitServer) Close() error { | |
| r.Server.Close() | |
| return nil | |
| } | |
| func (r *localGitServer) URL() string { | |
| return r.Server.URL | |
| } | |
| // FakeGit is a fake git server | |
| type FakeGit struct { | |
| root string | |
| server gitServer | |
| RepoURL string | |
| } | |
| // Close closes the server, implements Closer interface | |
| func (g *FakeGit) Close() { | |
| g.server.Close() | |
| os.RemoveAll(g.root) | |
| } | |
| // New create a fake git server that can be used for git related tests | |
| func New(c testing.TB, name string, files map[string]string, enforceLocalServer bool) *FakeGit { | |
| c.Helper() | |
| ctx := fakecontext.New(c, "", fakecontext.WithFiles(files)) | |
| defer ctx.Close() | |
| curdir, err := os.Getwd() | |
| if err != nil { | |
| c.Fatal(err) | |
| } | |
| defer os.Chdir(curdir) | |
| if output, err := exec.Command("git", "init", ctx.Dir).CombinedOutput(); err != nil { | |
| c.Fatalf("error trying to init repo: %s (%s)", err, output) | |
| } | |
| err = os.Chdir(ctx.Dir) | |
| if err != nil { | |
| c.Fatal(err) | |
| } | |
| if output, err := exec.Command("git", "config", "user.name", "Fake User").CombinedOutput(); err != nil { | |
| c.Fatalf("error trying to set 'user.name': %s (%s)", err, output) | |
| } | |
| if output, err := exec.Command("git", "config", "user.email", "fake.user@example.com").CombinedOutput(); err != nil { | |
| c.Fatalf("error trying to set 'user.email': %s (%s)", err, output) | |
| } | |
| if output, err := exec.Command("git", "add", "*").CombinedOutput(); err != nil { | |
| c.Fatalf("error trying to add files to repo: %s (%s)", err, output) | |
| } | |
| if output, err := exec.Command("git", "commit", "-a", "-m", "Initial commit").CombinedOutput(); err != nil { | |
| c.Fatalf("error trying to commit to repo: %s (%s)", err, output) | |
| } | |
| root, err := os.MkdirTemp("", "docker-test-git-repo") | |
| if err != nil { | |
| c.Fatal(err) | |
| } | |
| repoPath := filepath.Join(root, name+".git") | |
| if output, err := exec.Command("git", "clone", "--bare", ctx.Dir, repoPath).CombinedOutput(); err != nil { | |
| os.RemoveAll(root) | |
| c.Fatalf("error trying to clone --bare: %s (%s)", err, output) | |
| } | |
| err = os.Chdir(repoPath) | |
| if err != nil { | |
| os.RemoveAll(root) | |
| c.Fatal(err) | |
| } | |
| if output, err := exec.Command("git", "update-server-info").CombinedOutput(); err != nil { | |
| os.RemoveAll(root) | |
| c.Fatalf("error trying to git update-server-info: %s (%s)", err, output) | |
| } | |
| err = os.Chdir(curdir) | |
| if err != nil { | |
| os.RemoveAll(root) | |
| c.Fatal(err) | |
| } | |
| var server gitServer | |
| if !enforceLocalServer { | |
| // use fakeStorage server, which might be local or remote (at test daemon) | |
| server = fakestorage.New(c, root) | |
| } else { | |
| // always start a local http server on CLI test machine | |
| httpServer := httptest.NewServer(http.FileServer(http.Dir(root))) | |
| server = &localGitServer{httpServer} | |
| } | |
| return &FakeGit{ | |
| root: root, | |
| server: server, | |
| RepoURL: fmt.Sprintf("%s/%s.git", server.URL(), name), | |
| } | |
| } |