1package examples
2
3import (
4 "flag"
5 "go/build"
6 "io/ioutil"
7 "os"
8 "os/exec"
9 "path/filepath"
10 "testing"
11)
12
13var examplesTest = flag.Bool("examples", false, "run the examples tests")
14
15var defaultURL = "https://github.com/git-fixtures/basic.git"
16
17var args = map[string][]string{
18 "branch": {defaultURL, tempFolder()},
19 "checkout": {defaultURL, tempFolder(), "35e85108805c84807bc66a02d91535e1e24b38b9"},
20 "clone": {defaultURL, tempFolder()},
21 "context": {defaultURL, tempFolder()},
22 "commit": {cloneRepository(defaultURL, tempFolder())},
23 "custom_http": {defaultURL},
24 "open": {cloneRepository(defaultURL, tempFolder())},
25 "progress": {defaultURL, tempFolder()},
26 "push": {setEmptyRemote(cloneRepository(defaultURL, tempFolder()))},
27 "revision": {cloneRepository(defaultURL, tempFolder()), "master~2^"},
28 "showcase": {defaultURL, tempFolder()},
29 "tag": {cloneRepository(defaultURL, tempFolder())},
30 "pull": {createRepositoryWithRemote(tempFolder(), defaultURL)},
31 "ls": {cloneRepository(defaultURL, tempFolder()), "HEAD", "vendor"},
32 "merge_base": {cloneRepository(defaultURL, tempFolder()), "--is-ancestor", "HEAD~3", "HEAD^"},
33}
34
35var ignored = map[string]bool{}
36
37var tempFolders = []string{}
38
39func TestExamples(t *testing.T) {
40 flag.Parse()
41 if !*examplesTest && os.Getenv("CI") == "" {
42 t.Skip("skipping examples tests, pass --examples to execute it")
43 return
44 }
45
46 defer deleteTempFolders()
47
48 examples, err := filepath.Glob(examplesFolder())
49 if err != nil {
50 t.Errorf("error finding tests: %s", err)
51 }
52
53 for _, example := range examples {
54 dir := filepath.Dir(example)
55 _, name := filepath.Split(dir)
56
57 if ignored[name] {
58 continue
59 }
60
61 t.Run(name, func(t *testing.T) {
62 testExample(t, name, dir)
63 })
64 }
65}
66
67func tempFolder() string {
68 path, err := ioutil.TempDir("", "")
69 CheckIfError(err)
70
71 tempFolders = append(tempFolders, path)
72 return path
73}
74
75func packageFolder() string {
76 return filepath.Join(
77 build.Default.GOPATH,
78 "src", "github.com/go-git/go-git/v5",
79 )
80}
81
82func examplesFolder() string {
83 return filepath.Join(
84 packageFolder(),
85 "_examples", "*", "main.go",
86 )
87}
88
89func cloneRepository(url, folder string) string {
90 cmd := exec.Command("git", "clone", url, folder)
91 err := cmd.Run()
92 CheckIfError(err)
93
94 return folder
95}
96
97func createBareRepository(dir string) string {
98 return createRepository(dir, true)
99}
100
101func createRepository(dir string, isBare bool) string {
102 var cmd *exec.Cmd
103 if isBare {
104 cmd = exec.Command("git", "init", "--bare", dir)
105 } else {
106 cmd = exec.Command("git", "init", dir)
107 }
108 err := cmd.Run()
109 CheckIfError(err)
110
111 return dir
112}
113
114func createRepositoryWithRemote(local, remote string) string {
115 createRepository(local, false)
116 addRemote(local, remote)
117 return local
118}
119
120func setEmptyRemote(dir string) string {
121 remote := createBareRepository(tempFolder())
122 setRemote(dir, remote)
123 return dir
124}
125
126func setRemote(local, remote string) {
127 cmd := exec.Command("git", "remote", "set-url", "origin", remote)
128 cmd.Dir = local
129 err := cmd.Run()
130 CheckIfError(err)
131}
132
133func addRemote(local, remote string) {
134 cmd := exec.Command("git", "remote", "add", "origin", remote)
135 cmd.Dir = local
136 err := cmd.Run()
137 CheckIfError(err)
138}
139
140func testExample(t *testing.T, name, dir string) {
141 arguments := append([]string{"run", dir}, args[name]...)
142 cmd := exec.Command("go", arguments...)
143
144 cmd.Stdout = os.Stdout
145 cmd.Stderr = os.Stderr
146
147 if err := cmd.Run(); err != nil {
148 t.Errorf("error running cmd %q", err)
149 }
150}
151
152func deleteTempFolders() {
153 for _, folder := range tempFolders {
154 err := os.RemoveAll(folder)
155 CheckIfError(err)
156 }
157}