fork of go-git with some jj specific features
1package git
2
3import (
4 "os"
5 "testing"
6
7 "github.com/go-git/go-git/v5/plumbing"
8 "github.com/go-git/go-git/v5/plumbing/cache"
9 "github.com/go-git/go-git/v5/plumbing/format/packfile"
10 "github.com/go-git/go-git/v5/storage/filesystem"
11 "github.com/go-git/go-git/v5/storage/memory"
12
13 "github.com/go-git/go-billy/v5"
14 "github.com/go-git/go-billy/v5/memfs"
15 "github.com/go-git/go-billy/v5/osfs"
16 "github.com/go-git/go-billy/v5/util"
17 fixtures "github.com/go-git/go-git-fixtures/v4"
18 . "gopkg.in/check.v1"
19)
20
21func Test(t *testing.T) { TestingT(t) }
22
23type BaseSuite struct {
24 fixtures.Suite
25 Repository *Repository
26
27 cache map[string]*Repository
28}
29
30func (s *BaseSuite) SetUpSuite(c *C) {
31 s.buildBasicRepository(c)
32
33 s.cache = make(map[string]*Repository)
34}
35
36func (s *BaseSuite) TearDownSuite(c *C) {
37 s.Suite.TearDownSuite(c)
38}
39
40func (s *BaseSuite) buildBasicRepository(c *C) {
41 f := fixtures.Basic().One()
42 s.Repository = s.NewRepository(f)
43}
44
45// NewRepository returns a new repository using the .git folder, if the fixture
46// is tagged as worktree the filesystem from fixture is used, otherwise a new
47// memfs filesystem is used as worktree.
48func (s *BaseSuite) NewRepository(f *fixtures.Fixture) *Repository {
49 var worktree, dotgit billy.Filesystem
50 if f.Is("worktree") {
51 r, err := PlainOpen(f.Worktree().Root())
52 if err != nil {
53 panic(err)
54 }
55
56 return r
57 }
58
59 dotgit = f.DotGit()
60 worktree = memfs.New()
61
62 st := filesystem.NewStorage(dotgit, cache.NewObjectLRUDefault())
63
64 r, err := Open(st, worktree)
65 if err != nil {
66 panic(err)
67 }
68
69 return r
70}
71
72// NewRepositoryWithEmptyWorktree returns a new repository using the .git folder
73// from the fixture but without a empty memfs worktree, the index and the
74// modules are deleted from the .git folder.
75func (s *BaseSuite) NewRepositoryWithEmptyWorktree(f *fixtures.Fixture) *Repository {
76 dotgit := f.DotGit()
77 err := dotgit.Remove("index")
78 if err != nil {
79 panic(err)
80 }
81
82 err = util.RemoveAll(dotgit, "modules")
83 if err != nil {
84 panic(err)
85 }
86
87 worktree := memfs.New()
88
89 st := filesystem.NewStorage(dotgit, cache.NewObjectLRUDefault())
90
91 r, err := Open(st, worktree)
92 if err != nil {
93 panic(err)
94 }
95
96 return r
97
98}
99
100func (s *BaseSuite) NewRepositoryFromPackfile(f *fixtures.Fixture) *Repository {
101 h := f.PackfileHash
102 if r, ok := s.cache[h]; ok {
103 return r
104 }
105
106 storer := memory.NewStorage()
107 p := f.Packfile()
108 defer p.Close()
109
110 if err := packfile.UpdateObjectStorage(storer, p); err != nil {
111 panic(err)
112 }
113
114 storer.SetReference(plumbing.NewHashReference(plumbing.HEAD, plumbing.NewHash(f.Head)))
115
116 r, err := Open(storer, memfs.New())
117 if err != nil {
118 panic(err)
119 }
120
121 s.cache[h] = r
122 return r
123}
124
125func (s *BaseSuite) GetBasicLocalRepositoryURL() string {
126 fixture := fixtures.Basic().One()
127 return s.GetLocalRepositoryURL(fixture)
128}
129
130func (s *BaseSuite) GetLocalRepositoryURL(f *fixtures.Fixture) string {
131 return f.DotGit().Root()
132}
133
134func (s *BaseSuite) TemporalDir() (path string, clean func()) {
135 fs := osfs.New(os.TempDir())
136 path, err := util.TempDir(fs, "", "")
137 if err != nil {
138 panic(err)
139 }
140
141 return fs.Join(fs.Root(), path), func() {
142 util.RemoveAll(fs, path)
143 }
144}
145
146func (s *BaseSuite) TemporalFilesystem() (fs billy.Filesystem, clean func()) {
147 fs = osfs.New(os.TempDir())
148 path, err := util.TempDir(fs, "", "")
149 if err != nil {
150 panic(err)
151 }
152
153 fs, err = fs.Chroot(path)
154 if err != nil {
155 panic(err)
156 }
157
158 return fs, func() {
159 util.RemoveAll(fs, path)
160 }
161}
162
163type SuiteCommon struct{}
164
165var _ = Suite(&SuiteCommon{})
166
167var countLinesTests = [...]struct {
168 i string // the string we want to count lines from
169 e int // the expected number of lines in i
170}{
171 {"", 0},
172 {"a", 1},
173 {"a\n", 1},
174 {"a\nb", 2},
175 {"a\nb\n", 2},
176 {"a\nb\nc", 3},
177 {"a\nb\nc\n", 3},
178 {"a\n\n\nb\n", 4},
179 {"first line\n\tsecond line\nthird line\n", 3},
180}
181
182func (s *SuiteCommon) TestCountLines(c *C) {
183 for i, t := range countLinesTests {
184 o := countLines(t.i)
185 c.Assert(o, Equals, t.e, Commentf("subtest %d, input=%q", i, t.i))
186 }
187}
188
189func AssertReferences(c *C, r *Repository, expected map[string]string) {
190 for name, target := range expected {
191 expected := plumbing.NewReferenceFromStrings(name, target)
192
193 obtained, err := r.Reference(expected.Name(), true)
194 c.Assert(err, IsNil)
195
196 c.Assert(obtained, DeepEquals, expected)
197 }
198}
199
200func AssertReferencesMissing(c *C, r *Repository, expected []string) {
201 for _, name := range expected {
202 _, err := r.Reference(plumbing.ReferenceName(name), false)
203 c.Assert(err, NotNil)
204 c.Assert(err, Equals, plumbing.ErrReferenceNotFound)
205 }
206}