1package git
2
3import (
4 "context"
5 "os"
6 "path/filepath"
7 "testing"
8
9 "github.com/go-git/go-git/v5/plumbing"
10
11 fixtures "github.com/go-git/go-git-fixtures/v4"
12 . "gopkg.in/check.v1"
13)
14
15type SubmoduleSuite struct {
16 BaseSuite
17 Worktree *Worktree
18 path string
19}
20
21var _ = Suite(&SubmoduleSuite{})
22
23func (s *SubmoduleSuite) SetUpTest(c *C) {
24 path := fixtures.ByTag("submodule").One().Worktree().Root()
25
26 dir, clean := s.TemporalDir()
27 defer clean()
28
29 r, err := PlainClone(filepath.Join(dir, "worktree"), false, &CloneOptions{
30 URL: path,
31 })
32
33 c.Assert(err, IsNil)
34
35 s.Repository = r
36 s.Worktree, err = r.Worktree()
37 c.Assert(err, IsNil)
38
39 s.path = dir
40}
41
42func (s *SubmoduleSuite) TearDownTest(c *C) {
43 err := os.RemoveAll(s.path)
44 c.Assert(err, IsNil)
45}
46
47func (s *SubmoduleSuite) TestInit(c *C) {
48 sm, err := s.Worktree.Submodule("basic")
49 c.Assert(err, IsNil)
50
51 c.Assert(sm.initialized, Equals, false)
52 err = sm.Init()
53 c.Assert(err, IsNil)
54
55 c.Assert(sm.initialized, Equals, true)
56
57 cfg, err := s.Repository.Config()
58 c.Assert(err, IsNil)
59
60 c.Assert(cfg.Submodules, HasLen, 1)
61 c.Assert(cfg.Submodules["basic"], NotNil)
62
63 status, err := sm.Status()
64 c.Assert(err, IsNil)
65 c.Assert(status.IsClean(), Equals, false)
66}
67
68func (s *SubmoduleSuite) TestUpdate(c *C) {
69 if testing.Short() {
70 c.Skip("skipping test in short mode.")
71 }
72
73 sm, err := s.Worktree.Submodule("basic")
74 c.Assert(err, IsNil)
75
76 err = sm.Update(&SubmoduleUpdateOptions{
77 Init: true,
78 })
79
80 c.Assert(err, IsNil)
81
82 r, err := sm.Repository()
83 c.Assert(err, IsNil)
84
85 ref, err := r.Reference(plumbing.HEAD, true)
86 c.Assert(err, IsNil)
87 c.Assert(ref.Hash().String(), Equals, "6ecf0ef2c2dffb796033e5a02219af86ec6584e5")
88
89 status, err := sm.Status()
90 c.Assert(err, IsNil)
91 c.Assert(status.IsClean(), Equals, true)
92}
93
94func (s *SubmoduleSuite) TestRepositoryWithoutInit(c *C) {
95 sm, err := s.Worktree.Submodule("basic")
96 c.Assert(err, IsNil)
97
98 r, err := sm.Repository()
99 c.Assert(err, Equals, ErrSubmoduleNotInitialized)
100 c.Assert(r, IsNil)
101}
102
103func (s *SubmoduleSuite) TestUpdateWithoutInit(c *C) {
104 sm, err := s.Worktree.Submodule("basic")
105 c.Assert(err, IsNil)
106
107 err = sm.Update(&SubmoduleUpdateOptions{})
108 c.Assert(err, Equals, ErrSubmoduleNotInitialized)
109}
110
111func (s *SubmoduleSuite) TestUpdateWithNotFetch(c *C) {
112 sm, err := s.Worktree.Submodule("basic")
113 c.Assert(err, IsNil)
114
115 err = sm.Update(&SubmoduleUpdateOptions{
116 Init: true,
117 NoFetch: true,
118 })
119
120 // Since we are not fetching, the object is not there
121 c.Assert(err, Equals, plumbing.ErrObjectNotFound)
122}
123
124func (s *SubmoduleSuite) TestUpdateWithRecursion(c *C) {
125 if testing.Short() {
126 c.Skip("skipping test in short mode.")
127 }
128
129 sm, err := s.Worktree.Submodule("itself")
130 c.Assert(err, IsNil)
131
132 err = sm.Update(&SubmoduleUpdateOptions{
133 Init: true,
134 RecurseSubmodules: 2,
135 })
136
137 c.Assert(err, IsNil)
138
139 fs := s.Worktree.Filesystem
140 _, err = fs.Stat(fs.Join("itself", "basic", "LICENSE"))
141 c.Assert(err, IsNil)
142}
143
144func (s *SubmoduleSuite) TestUpdateWithInitAndUpdate(c *C) {
145 if testing.Short() {
146 c.Skip("skipping test in short mode.")
147 }
148
149 sm, err := s.Worktree.Submodule("basic")
150 c.Assert(err, IsNil)
151
152 err = sm.Update(&SubmoduleUpdateOptions{
153 Init: true,
154 })
155 c.Assert(err, IsNil)
156
157 idx, err := s.Repository.Storer.Index()
158 c.Assert(err, IsNil)
159
160 for i, e := range idx.Entries {
161 if e.Name == "basic" {
162 e.Hash = plumbing.NewHash("b029517f6300c2da0f4b651b8642506cd6aaf45d")
163 }
164
165 idx.Entries[i] = e
166 }
167
168 err = s.Repository.Storer.SetIndex(idx)
169 c.Assert(err, IsNil)
170
171 err = sm.Update(&SubmoduleUpdateOptions{})
172 c.Assert(err, IsNil)
173
174 r, err := sm.Repository()
175 c.Assert(err, IsNil)
176
177 ref, err := r.Reference(plumbing.HEAD, true)
178 c.Assert(err, IsNil)
179 c.Assert(ref.Hash().String(), Equals, "b029517f6300c2da0f4b651b8642506cd6aaf45d")
180
181}
182
183func (s *SubmoduleSuite) TestSubmodulesInit(c *C) {
184 sm, err := s.Worktree.Submodules()
185 c.Assert(err, IsNil)
186
187 err = sm.Init()
188 c.Assert(err, IsNil)
189
190 sm, err = s.Worktree.Submodules()
191 c.Assert(err, IsNil)
192
193 for _, m := range sm {
194 c.Assert(m.initialized, Equals, true)
195 }
196}
197
198func (s *SubmoduleSuite) TestGitSubmodulesSymlink(c *C) {
199 f, err := s.Worktree.Filesystem.Create("badfile")
200 c.Assert(err, IsNil)
201 defer f.Close()
202
203 err = s.Worktree.Filesystem.Remove(gitmodulesFile)
204 c.Assert(err, IsNil)
205
206 err = s.Worktree.Filesystem.Symlink("badfile", gitmodulesFile)
207 c.Assert(err, IsNil)
208
209 _, err = s.Worktree.Submodules()
210 c.Assert(err, Equals, ErrGitModulesSymlink)
211}
212
213func (s *SubmoduleSuite) TestSubmodulesStatus(c *C) {
214 sm, err := s.Worktree.Submodules()
215 c.Assert(err, IsNil)
216
217 status, err := sm.Status()
218 c.Assert(err, IsNil)
219 c.Assert(status, HasLen, 2)
220}
221
222func (s *SubmoduleSuite) TestSubmodulesUpdateContext(c *C) {
223 if testing.Short() {
224 c.Skip("skipping test in short mode.")
225 }
226
227 sm, err := s.Worktree.Submodules()
228 c.Assert(err, IsNil)
229
230 ctx, cancel := context.WithCancel(context.Background())
231 cancel()
232
233 err = sm.UpdateContext(ctx, &SubmoduleUpdateOptions{Init: true})
234 c.Assert(err, NotNil)
235}