mirror of
https://github.com/grdl/git-get.git
synced 2026-02-06 13:57:56 +00:00
Remove gogit and major refactoring (#2)
* Fix typo in readme * Reimplement all git methods without go-git * Rename repo pkg to git, add gitconfig methods * Improve tests for configuration reading * Rename package file to io and move RepoFinder there * Refactor printers - Remove smart printer - Decouple printers from git repos with interfaces - Update printer functions - Remove unnecessary flags - Add better remote URL detection * Update readme and go.mod * Add author to git commit in tests Otherwise tests will fail in CI. * Install git before running tests and don't use cgo * Add better error message, revert installing git * Ensure commit message is in quotes * Set up git config before running tests
This commit is contained in:
committed by
GitHub
parent
2ef739ea49
commit
8c132cdafa
245
pkg/git/repo_helpers_test.go
Normal file
245
pkg/git/repo_helpers_test.go
Normal file
@@ -0,0 +1,245 @@
|
||||
package git
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git-get/pkg/io"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// testRepo embeds testing.T into a Repo instance to simplify creation of test repos.
|
||||
// Any error thrown while creating a test repo will cause a t.Fatal call.
|
||||
type testRepo struct {
|
||||
*Repo
|
||||
*testing.T
|
||||
}
|
||||
|
||||
// TODO: this should be a method of a tempDir, not a repo
|
||||
// Automatically remove test repo when the test is over
|
||||
func (r *testRepo) cleanup() {
|
||||
err := os.RemoveAll(r.path)
|
||||
if err != nil {
|
||||
r.T.Errorf("failed removing test repo directory %s", r.path)
|
||||
}
|
||||
}
|
||||
|
||||
func testRepoEmpty(t *testing.T) *testRepo {
|
||||
dir, err := io.TempDir()
|
||||
checkFatal(t, err)
|
||||
|
||||
r, err := Open(dir)
|
||||
checkFatal(t, err)
|
||||
|
||||
tr := &testRepo{
|
||||
Repo: r,
|
||||
T: t,
|
||||
}
|
||||
|
||||
t.Cleanup(tr.cleanup)
|
||||
|
||||
tr.init()
|
||||
return tr
|
||||
}
|
||||
|
||||
func testRepoWithUntracked(t *testing.T) *testRepo {
|
||||
r := testRepoEmpty(t)
|
||||
r.writeFile("README.md", "I'm a readme file")
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func testRepoWithStaged(t *testing.T) *testRepo {
|
||||
r := testRepoEmpty(t)
|
||||
r.writeFile("README.md", "I'm a readme file")
|
||||
r.stageFile("README.md")
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func testRepoWithCommit(t *testing.T) *testRepo {
|
||||
r := testRepoEmpty(t)
|
||||
r.writeFile("README.md", "I'm a readme file")
|
||||
r.stageFile("README.md")
|
||||
r.commit("Initial commit")
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func testRepoWithUncommittedAndUntracked(t *testing.T) *testRepo {
|
||||
r := testRepoEmpty(t)
|
||||
r.writeFile("README.md", "I'm a readme file")
|
||||
r.stageFile("README.md")
|
||||
r.commit("Initial commit")
|
||||
r.writeFile("README.md", "These changes won't be committed")
|
||||
r.writeFile("untracked.txt", "I'm untracked")
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func testRepoWithBranch(t *testing.T) *testRepo {
|
||||
r := testRepoWithCommit(t)
|
||||
r.branch("feature/branch")
|
||||
r.checkout("feature/branch")
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func testRepoWithTag(t *testing.T) *testRepo {
|
||||
r := testRepoWithCommit(t)
|
||||
r.tag("v0.0.1")
|
||||
r.checkout("v0.0.1")
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func testRepoWithBranchWithUpstream(t *testing.T) *testRepo {
|
||||
origin := testRepoWithCommit(t)
|
||||
origin.branch("feature/branch")
|
||||
|
||||
r := origin.clone()
|
||||
r.checkout("feature/branch")
|
||||
return r
|
||||
}
|
||||
|
||||
func testRepoWithBranchWithoutUpstream(t *testing.T) *testRepo {
|
||||
origin := testRepoWithCommit(t)
|
||||
|
||||
r := origin.clone()
|
||||
r.branch("feature/branch")
|
||||
r.checkout("feature/branch")
|
||||
return r
|
||||
}
|
||||
|
||||
func testRepoWithBranchAhead(t *testing.T) *testRepo {
|
||||
origin := testRepoWithCommit(t)
|
||||
origin.branch("feature/branch")
|
||||
|
||||
r := origin.clone()
|
||||
r.checkout("feature/branch")
|
||||
|
||||
r.writeFile("local.new", "local.new")
|
||||
r.stageFile("local.new")
|
||||
r.commit("local.new")
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func testRepoWithBranchBehind(t *testing.T) *testRepo {
|
||||
origin := testRepoWithCommit(t)
|
||||
origin.branch("feature/branch")
|
||||
origin.checkout("feature/branch")
|
||||
|
||||
r := origin.clone()
|
||||
r.checkout("feature/branch")
|
||||
|
||||
origin.writeFile("origin.new", "origin.new")
|
||||
origin.stageFile("origin.new")
|
||||
origin.commit("origin.new")
|
||||
|
||||
err := r.Fetch()
|
||||
checkFatal(r.T, err)
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// returns a repo with 2 commits ahead and 1 behind
|
||||
func testRepoWithBranchAheadAndBehind(t *testing.T) *testRepo {
|
||||
origin := testRepoWithCommit(t)
|
||||
origin.branch("feature/branch")
|
||||
origin.checkout("feature/branch")
|
||||
|
||||
r := origin.clone()
|
||||
r.checkout("feature/branch")
|
||||
|
||||
origin.writeFile("origin.new", "origin.new")
|
||||
origin.stageFile("origin.new")
|
||||
origin.commit("origin.new")
|
||||
|
||||
r.writeFile("local.new", "local.new")
|
||||
r.stageFile("local.new")
|
||||
r.commit("local.new")
|
||||
|
||||
r.writeFile("local.new2", "local.new2")
|
||||
r.stageFile("local.new2")
|
||||
r.commit("local.new2")
|
||||
|
||||
err := r.Fetch()
|
||||
checkFatal(r.T, err)
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *testRepo) writeFile(filename string, content string) {
|
||||
path := path.Join(r.path, filename)
|
||||
err := io.Write(path, content)
|
||||
checkFatal(r.T, err)
|
||||
}
|
||||
|
||||
func (r *testRepo) init() {
|
||||
cmd := exec.Command("git", "init", "--quiet", r.path)
|
||||
runGitCmd(r.T, cmd)
|
||||
}
|
||||
|
||||
func (r *testRepo) stageFile(path string) {
|
||||
cmd := gitCmd(r.path, "add", path)
|
||||
runGitCmd(r.T, cmd)
|
||||
}
|
||||
|
||||
func (r *testRepo) commit(msg string) {
|
||||
cmd := gitCmd(r.path, "commit", "-m", fmt.Sprintf("%q", msg), "--author=\"user <user@example.com>\"")
|
||||
runGitCmd(r.T, cmd)
|
||||
}
|
||||
|
||||
func (r *testRepo) branch(name string) {
|
||||
cmd := gitCmd(r.path, "branch", name)
|
||||
runGitCmd(r.T, cmd)
|
||||
}
|
||||
|
||||
func (r *testRepo) tag(name string) {
|
||||
cmd := gitCmd(r.path, "tag", "-a", name, "-m", name)
|
||||
runGitCmd(r.T, cmd)
|
||||
}
|
||||
|
||||
func (r *testRepo) checkout(name string) {
|
||||
cmd := gitCmd(r.path, "checkout", name)
|
||||
runGitCmd(r.T, cmd)
|
||||
}
|
||||
|
||||
func (r *testRepo) clone() *testRepo {
|
||||
dir, err := io.TempDir()
|
||||
checkFatal(r.T, err)
|
||||
|
||||
url, err := url.Parse(fmt.Sprintf("file://%s/.git", r.path))
|
||||
checkFatal(r.T, err)
|
||||
|
||||
opts := &CloneOpts{
|
||||
URL: url,
|
||||
Quiet: true,
|
||||
Path: dir,
|
||||
}
|
||||
|
||||
repo, err := Clone(opts)
|
||||
checkFatal(r.T, err)
|
||||
|
||||
tr := &testRepo{
|
||||
Repo: repo,
|
||||
T: r.T,
|
||||
}
|
||||
|
||||
tr.T.Cleanup(tr.cleanup)
|
||||
return tr
|
||||
}
|
||||
|
||||
func runGitCmd(t *testing.T, cmd *exec.Cmd) {
|
||||
err := cmd.Run()
|
||||
checkFatal(t, cmdError(cmd, err))
|
||||
}
|
||||
|
||||
func checkFatal(t *testing.T, err error) {
|
||||
if err != nil {
|
||||
t.Fatalf("%+v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user