Beispiel #1
0
func Clone(url, dir string, opt vcs.CloneOpt) (*Repository, error) {
	_, err := gitcmd.Clone(url, dir, opt)
	if err != nil {
		return nil, err
	}
	// Note: This will call Open ~3 times as it jumps between
	// gitcmd -> gogit -> gitcmd until we replace it with a native version or
	// refactor.
	return Open(dir)
}
Beispiel #2
0
func TestRepository_Clone_ssh(t *testing.T) {
	t.Parallel()

	gitCommands := []string{
		"GIT_COMMITTER_NAME=a [email protected] GIT_COMMITTER_DATE=2006-01-02T15:04:05Z git commit --allow-empty -m foo --author='a <*****@*****.**>' --date 2006-01-02T15:04:05Z",
		"git tag t0",
		"git checkout -b b0",
	}
	// TODO(sqs): test hg ssh support when it's implemented
	tests := map[string]struct {
		repoDir      string
		cloner       func(url, dir string, opt vcs.CloneOpt) (vcs.Repository, error)
		wantCommitID vcs.CommitID // commit ID that tag t0 refers to
	}{
		"git go-git": {
			repoDir:      initGitRepository(t, gitCommands...),
			cloner:       func(url, dir string, opt vcs.CloneOpt) (vcs.Repository, error) { return git.Clone(url, dir, opt) },
			wantCommitID: "ea167fe3d76b1e5fd3ed8ca44cbd2fe3897684f8",
		},
		"git cmd": {
			repoDir:      initGitRepository(t, gitCommands...),
			cloner:       func(url, dir string, opt vcs.CloneOpt) (vcs.Repository, error) { return gitcmd.Clone(url, dir, opt) },
			wantCommitID: "ea167fe3d76b1e5fd3ed8ca44cbd2fe3897684f8",
		},
	}

	for label, test := range tests {
		func() {
			s, remoteOpts := startGitShellSSHServer(t, label, filepath.Dir(test.repoDir))
			defer s.Close()

			opt := vcs.CloneOpt{
				Bare:       true,
				RemoteOpts: remoteOpts,
			}

			gitURL := s.GitURL + "/" + filepath.Base(test.repoDir)
			cloneDir := makeTmpDir(t, "ssh-clone")
			t.Logf("Cloning from %s to %s", gitURL, cloneDir)
			r, err := test.cloner(gitURL, cloneDir, opt)
			if err != nil {
				t.Fatalf("%s: test.cloner: %s", label, err)
			}

			tags, err := r.Tags()
			if err != nil {
				t.Errorf("%s: Tags: %s", label, err)
			}

			wantTags := []*vcs.Tag{{Name: "t0", CommitID: test.wantCommitID}}
			if !reflect.DeepEqual(tags, wantTags) {
				t.Errorf("%s: got tags %s, want %s", label, asJSON(tags), asJSON(wantTags))
			}

			branches, err := r.Branches(vcs.BranchesOptions{})
			if err != nil {
				t.Errorf("%s: Branches: %s", label, err)
			}
			wantBranches := []*vcs.Branch{
				{Name: "b0", Head: test.wantCommitID},
				{Name: "master", Head: test.wantCommitID},
			}
			if !reflect.DeepEqual(branches, wantBranches) {
				t.Errorf("%s: got branches %s, want %s", label, asJSON(branches), asJSON(wantBranches))
			}
		}()
	}
}
Beispiel #3
0
func TestRepository_UpdateEverything_ssh(t *testing.T) {
	t.Parallel()

	// TODO(sqs): this test has a lot of overlap with
	// TestRepository_UpdateEverything.

	gitCommands := []string{
		"GIT_COMMITTER_NAME=a [email protected] GIT_COMMITTER_DATE=2006-01-02T15:04:05Z git commit --allow-empty -m foo --author='a <*****@*****.**>' --date 2006-01-02T15:04:05Z",
	}
	// TODO(sqs): test hg ssh support when it's implemented
	tests := map[string]struct {
		vcs, baseDir, headDir string

		opener func(dir string) (vcs.Repository, error)
		cloner func(url, dir string, opt vcs.CloneOpt) (vcs.Repository, error)

		// newCmds should commit a file "newfile" in the repository
		// root and tag the commit with "second". This is used to test
		// that UpdateEverything picks up the new file from the
		// mirror's origin.
		newCmds []string

		wantUpdateResult *vcs.UpdateResult
	}{
		"git": { // git
			vcs: "git", baseDir: initGitRepository(t, gitCommands...), headDir: makeTmpDir(t, "git-update-ssh"),
			opener:  func(dir string) (vcs.Repository, error) { return git.Open(dir) },
			cloner:  func(url, dir string, opt vcs.CloneOpt) (vcs.Repository, error) { return git.Clone(url, dir, opt) },
			newCmds: []string{"git tag t0", "git checkout -b b0"},
			wantUpdateResult: &vcs.UpdateResult{
				Changes: []vcs.Change{
					{Op: vcs.NewOp, Branch: "b0"},
					{Op: vcs.NewOp, Branch: "t0"},
				},
			},
		},
		"git cmd": { // gitcmd
			vcs: "git", baseDir: initGitRepository(t, gitCommands...), headDir: makeTmpDir(t, "git-update-ssh"),
			opener:  func(dir string) (vcs.Repository, error) { return gitcmd.Open(dir) },
			cloner:  func(url, dir string, opt vcs.CloneOpt) (vcs.Repository, error) { return gitcmd.Clone(url, dir, opt) },
			newCmds: []string{"git tag t0", "git checkout -b b0"},
			wantUpdateResult: &vcs.UpdateResult{
				Changes: []vcs.Change{
					{Op: vcs.NewOp, Branch: "b0"},
					{Op: vcs.NewOp, Branch: "t0"},
				},
			},
		},
	}

	for label, test := range tests {
		func() {
			s, remoteOpts := startGitShellSSHServer(t, label, filepath.Dir(test.baseDir))
			defer s.Close()

			baseURL := s.GitURL + "/" + filepath.Base(test.baseDir)
			t.Logf("Cloning from %s to %s", baseURL, test.headDir)
			_, err := test.cloner(baseURL, test.headDir, vcs.CloneOpt{Bare: true, Mirror: true, RemoteOpts: remoteOpts})
			if err != nil {
				t.Errorf("Clone(%q, %q, %q): %s", label, baseURL, test.headDir, err)
				return
			}

			r, err := test.opener(test.headDir)
			if err != nil {
				t.Errorf("opener[->%s](%q): %s", reflect.TypeOf(test.opener).Out(0), test.headDir, err)
				return
			}

			// r should not have any tags yet.
			tags, err := r.Tags()
			if err != nil {
				t.Errorf("%s: Tags: %s", label, err)
				return
			}
			if len(tags) != 0 {
				t.Errorf("%s: got tags %v, want none", label, tags)
			}

			// run the newCmds to create the new file in the origin repository (NOT
			// the mirror repository; we want to test that UpdateEverything updates the
			// mirror repository).
			for _, cmd := range test.newCmds {
				c := exec.Command("bash", "-c", cmd)
				c.Dir = test.baseDir
				out, err := c.CombinedOutput()
				if err != nil {
					t.Fatalf("%s: exec `%s` failed: %s. Output was:\n\n%s", label, cmd, err, out)
				}
			}

			// update the mirror.
			result, err := r.(vcs.RemoteUpdater).UpdateEverything(remoteOpts)
			if err != nil {
				t.Errorf("%s: UpdateEverything: %s", label, err)
				return
			}
			if !reflect.DeepEqual(result, test.wantUpdateResult) {
				t.Errorf("%s: got UpdateResult == %v, want %v", label, asJSON(result), asJSON(test.wantUpdateResult))
			}

			// r should now have the tag t0 we added to the base repo,
			// since we just updated r.
			tags, err = r.Tags()
			if err != nil {
				t.Errorf("%s: Tags: %s", label, err)
				return
			}
			if got, want := tagNames(tags), []string{"t0"}; !reflect.DeepEqual(got, want) {
				t.Errorf("%s: got tags %v, want %v", label, got, want)
			}

			// r should now have the branch b0 we added to the base
			// repo, since we just updated r.
			branches, err := r.Branches(vcs.BranchesOptions{})
			if err != nil {
				t.Errorf("%s: Branches: %s", label, err)
				return
			}
			if got, want := branchNames(branches), []string{"b0", "master"}; !reflect.DeepEqual(got, want) {
				t.Errorf("%s: got branches %v, want %v", label, got, want)
			}
		}()
	}
}