diff --git a/go.mod b/go.mod index 2999160..fa67506 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.14 require ( github.com/go-git/go-billy/v5 v5.0.0 github.com/go-git/go-git/v5 v5.1.0 + github.com/libgit2/git2go/v30 v30.0.3 github.com/mitchellh/go-homedir v1.1.0 github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.0.0 diff --git a/new/helpers_test.go b/new/helpers_test.go index 07d1289..c6038f0 100644 --- a/new/helpers_test.go +++ b/new/helpers_test.go @@ -2,26 +2,63 @@ package new import ( "io/ioutil" + urlpkg "net/url" "os" "testing" "time" "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-billy/v5/memfs" "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/storage/memory" "github.com/pkg/errors" - //"github.com/go-git/go-git/v5" ) -func checkFatal(t *testing.T, err error) { - if err != nil { - t.Fatalf("%+v", err) +type TestRepo struct { + Repo *git.Repository + URL *urlpkg.URL + t *testing.T +} + +func NewRepoEmpty(t *testing.T) *TestRepo { + dir := NewTempDir(t) + + repo, err := git.PlainInit(dir, false) + checkFatal(t, err) + + url, err := urlpkg.Parse("file://" + dir) + checkFatal(t, err) + + return &TestRepo{ + Repo: repo, + URL: url, + t: t, } } -func newTempDir(t *testing.T) string { +func NewRepoWithUntracked(t *testing.T) *TestRepo { + repo := NewRepoEmpty(t) + repo.NewFile("README", "I'm a README file") + + return repo +} + +func NewRepoWithStaged(t *testing.T) *TestRepo { + repo := NewRepoEmpty(t) + repo.NewFile("README", "I'm a README file") + repo.AddFile("README") + + return repo +} +func NewRepoWithCommit(t *testing.T) *TestRepo { + repo := NewRepoEmpty(t) + repo.NewFile("README", "I'm a README file") + repo.AddFile("README") + repo.NewCommit("Initial commit") + + return repo +} + +func NewTempDir(t *testing.T) string { dir, err := ioutil.TempDir("", "git-get-repo-") checkFatal(t, errors.Wrap(err, "Failed creating test repo directory")) @@ -36,38 +73,28 @@ func newTempDir(t *testing.T) string { return dir } -func newTestRepo(t *testing.T) *git.Repository { - fs := memfs.New() - storage := memory.NewStorage() - - repo, err := git.Init(storage, fs) - checkFatal(t, errors.Wrap(err, "Failed initializing a temp repo")) - - return repo -} - -func createFile(t *testing.T, repo *git.Repository, name string) { - wt, err := repo.Worktree() - checkFatal(t, errors.Wrap(err, "Failed getting worktree")) +func (r *TestRepo) NewFile(name string, content string) { + wt, err := r.Repo.Worktree() + checkFatal(r.t, errors.Wrap(err, "Failed getting worktree")) file, err := wt.Filesystem.Create(name) - checkFatal(t, errors.Wrap(err, "Failed creating a file")) + checkFatal(r.t, errors.Wrap(err, "Failed creating a file")) - _, err = file.Write([]byte("I'm a file")) - checkFatal(t, errors.Wrap(err, "Failed writing a file")) + _, err = file.Write([]byte(content)) + checkFatal(r.t, errors.Wrap(err, "Failed writing a file")) } -func stageFile(t *testing.T, repo *git.Repository, name string) { - wt, err := repo.Worktree() - checkFatal(t, errors.Wrap(err, "Failed getting worktree")) +func (r *TestRepo) AddFile(name string) { + wt, err := r.Repo.Worktree() + checkFatal(r.t, errors.Wrap(err, "Failed getting worktree")) _, err = wt.Add(name) - checkFatal(t, errors.Wrap(err, "Failed adding file to index")) + checkFatal(r.t, errors.Wrap(err, "Failed adding file to index")) } -func createCommit(t *testing.T, repo *git.Repository, msg string) { - wt, err := repo.Worktree() - checkFatal(t, errors.Wrap(err, "Failed getting worktree")) +func (r *TestRepo) NewCommit(msg string) { + wt, err := r.Repo.Worktree() + checkFatal(r.t, errors.Wrap(err, "Failed getting worktree")) opts := &git.CommitOptions{ Author: &object.Signature{ @@ -78,7 +105,7 @@ func createCommit(t *testing.T, repo *git.Repository, msg string) { } _, err = wt.Commit(msg, opts) - checkFatal(t, errors.Wrap(err, "Failed creating commit")) + checkFatal(r.t, errors.Wrap(err, "Failed creating commit")) } // @@ -125,3 +152,9 @@ func createCommit(t *testing.T, repo *git.Repository, msg string) { // err = repo.CheckoutHead(options) // checkFatal(t, errors.Wrap(err, "Failed checking out tree")) //} + +func checkFatal(t *testing.T, err error) { + if err != nil { + t.Fatalf("%+v", err) + } +} diff --git a/new/repo.go b/new/repo.go index a56dd1f..06ba858 100644 --- a/new/repo.go +++ b/new/repo.go @@ -2,14 +2,11 @@ package new import ( "io" + "net/url" "os" - "github.com/go-git/go-git/v5/plumbing/cache" - "github.com/go-git/go-git/v5/storage/filesystem" "github.com/pkg/errors" - "github.com/go-git/go-billy/v5" - "github.com/go-git/go-git/v5" ) @@ -18,14 +15,14 @@ type Repo struct { Status *RepoStatus } -func CloneRepo(url string, path billy.Filesystem, quiet bool) (r *Repo, err error) { +func CloneRepo(url *url.URL, path string, quiet bool) (r *Repo, err error) { var output io.Writer if !quiet { output = os.Stdout } opts := &git.CloneOptions{ - URL: url, + URL: url.String(), Auth: nil, RemoteName: git.DefaultRemoteName, ReferenceName: "", @@ -37,11 +34,7 @@ func CloneRepo(url string, path billy.Filesystem, quiet bool) (r *Repo, err erro Tags: git.AllTags, } - dotgit, _ := path.Chroot(git.GitDirName) - s := filesystem.NewStorage(dotgit, cache.NewObjectLRUDefault()) - - repo, err := git.Clone(s, path, opts) - + repo, err := git.PlainClone(path, false, opts) if err != nil { return nil, errors.Wrap(err, "Failed cloning repo") } diff --git a/new/repo_test.go b/new/repo_test.go index 7b01833..2d3c8ad 100644 --- a/new/repo_test.go +++ b/new/repo_test.go @@ -2,31 +2,13 @@ package new import ( "testing" - - "github.com/go-git/go-billy/v5/osfs" - - "github.com/go-git/go-billy/v5/memfs" ) -func TestRepoCloneInMemory(t *testing.T) { - path := memfs.New() - repo, err := CloneRepo("https://github.com/grdl/dotfiles", path, true) - checkFatal(t, err) +func TestRepoClone(t *testing.T) { + origin := NewRepoWithCommit(t) + path := NewTempDir(t) - wt, err := repo.repo.Worktree() - checkFatal(t, err) - - files, err := wt.Filesystem.ReadDir("") - checkFatal(t, err) - - if len(files) == 0 { - t.Errorf("Cloned repo should contain files") - } -} - -func TestRepoCloneOnDisk(t *testing.T) { - path := osfs.New(newTempDir(t)) - repo, err := CloneRepo("https://github.com/grdl/dotfiles", path, true) + repo, err := CloneRepo(origin.URL, path, true) checkFatal(t, err) wt, err := repo.repo.Worktree() @@ -41,67 +23,66 @@ func TestRepoCloneOnDisk(t *testing.T) { } func TestRepoEmpty(t *testing.T) { - repo := newTestRepo(t) + repo := NewRepoEmpty(t) - wt, err := repo.Worktree() + wt, err := repo.Repo.Worktree() checkFatal(t, err) status, err := wt.Status() + checkFatal(t, err) if !status.IsClean() { t.Errorf("Empty repo should be clean") } } func TestRepoWithUntrackedFile(t *testing.T) { - repo := newTestRepo(t) - createFile(t, repo, "file") + repo := NewRepoWithUntracked(t) - wt, err := repo.Worktree() + wt, err := repo.Repo.Worktree() checkFatal(t, err) status, err := wt.Status() + checkFatal(t, err) if status.IsClean() { t.Errorf("Repo with untracked file should not be clean") } - if !status.IsUntracked("file") { + // TODO: remove magic strings + if !status.IsUntracked("README") { t.Errorf("New file should be untracked") } } func TestRepoWithStagedFile(t *testing.T) { - repo := newTestRepo(t) - createFile(t, repo, "file") - stageFile(t, repo, "file") + repo := NewRepoWithStaged(t) - wt, err := repo.Worktree() + wt, err := repo.Repo.Worktree() checkFatal(t, err) status, err := wt.Status() + checkFatal(t, err) if status.IsClean() { t.Errorf("Repo with staged file should not be clean") } - if status.IsUntracked("file") { + if status.IsUntracked("README") { t.Errorf("Staged file should not be untracked") } } func TestRepoWithSingleCommit(t *testing.T) { - repo := newTestRepo(t) - createFile(t, repo, "file") - stageFile(t, repo, "file") - createCommit(t, repo, "Initial commit") + repo := NewRepoWithCommit(t) - wt, err := repo.Worktree() + wt, err := repo.Repo.Worktree() checkFatal(t, err) status, err := wt.Status() + checkFatal(t, err) if !status.IsClean() { t.Errorf("Repo with committed file should be clean") } - if status.IsUntracked("file") { + if status.IsUntracked("README") { t.Errorf("Committed file should not be untracked") } }