fork of go-git with some jj specific features
at main 5.6 kB view raw
1package git 2 3import ( 4 "context" 5 "os" 6 "path/filepath" 7 "testing" 8 9 "github.com/go-git/go-billy/v5/memfs" 10 "github.com/go-git/go-git/v5/config" 11 "github.com/go-git/go-git/v5/plumbing" 12 "github.com/go-git/go-git/v5/storage/memory" 13 "github.com/stretchr/testify/suite" 14 15 fixtures "github.com/go-git/go-git-fixtures/v4" 16) 17 18type SubmoduleSuite struct { 19 suite.Suite 20 BaseSuite 21 Worktree *Worktree 22} 23 24func TestSubmoduleSuite(t *testing.T) { 25 suite.Run(t, new(SubmoduleSuite)) 26} 27 28func (s *SubmoduleSuite) SetupTest() { 29 path := fixtures.ByTag("submodule").One().Worktree().Root() 30 31 dir, err := os.MkdirTemp("", "") 32 s.NoError(err) 33 34 r, err := PlainClone(filepath.Join(dir, "worktree"), false, &CloneOptions{ 35 URL: path, 36 }) 37 38 s.NoError(err) 39 40 s.Repository = r 41 s.Worktree, err = r.Worktree() 42 s.NoError(err) 43} 44 45func (s *SubmoduleSuite) TestInit() { 46 sm, err := s.Worktree.Submodule("basic") 47 s.NoError(err) 48 49 s.False(sm.initialized) 50 err = sm.Init() 51 s.NoError(err) 52 53 s.True(sm.initialized) 54 55 cfg, err := s.Repository.Config() 56 s.NoError(err) 57 58 s.Len(cfg.Submodules, 1) 59 s.NotNil(cfg.Submodules["basic"]) 60 61 status, err := sm.Status() 62 s.NoError(err) 63 s.False(status.IsClean()) 64} 65 66func (s *SubmoduleSuite) TestUpdate() { 67 if testing.Short() { 68 s.T().Skip("skipping test in short mode.") 69 } 70 71 sm, err := s.Worktree.Submodule("basic") 72 s.NoError(err) 73 74 err = sm.Update(&SubmoduleUpdateOptions{ 75 Init: true, 76 }) 77 78 s.NoError(err) 79 80 r, err := sm.Repository() 81 s.NoError(err) 82 83 ref, err := r.Reference(plumbing.HEAD, true) 84 s.NoError(err) 85 s.Equal("6ecf0ef2c2dffb796033e5a02219af86ec6584e5", ref.Hash().String()) 86 87 status, err := sm.Status() 88 s.NoError(err) 89 s.True(status.IsClean()) 90} 91 92func (s *SubmoduleSuite) TestRepositoryWithoutInit() { 93 sm, err := s.Worktree.Submodule("basic") 94 s.NoError(err) 95 96 r, err := sm.Repository() 97 s.ErrorIs(err, ErrSubmoduleNotInitialized) 98 s.Nil(r) 99} 100 101func (s *SubmoduleSuite) TestUpdateWithoutInit() { 102 sm, err := s.Worktree.Submodule("basic") 103 s.NoError(err) 104 105 err = sm.Update(&SubmoduleUpdateOptions{}) 106 s.ErrorIs(err, ErrSubmoduleNotInitialized) 107} 108 109func (s *SubmoduleSuite) TestUpdateWithNotFetch() { 110 sm, err := s.Worktree.Submodule("basic") 111 s.NoError(err) 112 113 err = sm.Update(&SubmoduleUpdateOptions{ 114 Init: true, 115 NoFetch: true, 116 }) 117 118 // Since we are not fetching, the object is not there 119 s.ErrorIs(err, plumbing.ErrObjectNotFound) 120} 121 122func (s *SubmoduleSuite) TestUpdateWithRecursion() { 123 if testing.Short() { 124 s.T().Skip("skipping test in short mode.") 125 } 126 127 sm, err := s.Worktree.Submodule("itself") 128 s.NoError(err) 129 130 err = sm.Update(&SubmoduleUpdateOptions{ 131 Init: true, 132 RecurseSubmodules: 2, 133 }) 134 135 s.NoError(err) 136 137 fs := s.Worktree.Filesystem 138 _, err = fs.Stat(fs.Join("itself", "basic", "LICENSE")) 139 s.NoError(err) 140} 141 142func (s *SubmoduleSuite) TestUpdateWithInitAndUpdate() { 143 if testing.Short() { 144 s.T().Skip("skipping test in short mode.") 145 } 146 147 sm, err := s.Worktree.Submodule("basic") 148 s.NoError(err) 149 150 err = sm.Update(&SubmoduleUpdateOptions{ 151 Init: true, 152 }) 153 s.NoError(err) 154 155 idx, err := s.Repository.Storer.Index() 156 s.NoError(err) 157 158 for i, e := range idx.Entries { 159 if e.Name == "basic" { 160 e.Hash = plumbing.NewHash("b029517f6300c2da0f4b651b8642506cd6aaf45d") 161 } 162 163 idx.Entries[i] = e 164 } 165 166 err = s.Repository.Storer.SetIndex(idx) 167 s.NoError(err) 168 169 err = sm.Update(&SubmoduleUpdateOptions{}) 170 s.NoError(err) 171 172 r, err := sm.Repository() 173 s.NoError(err) 174 175 ref, err := r.Reference(plumbing.HEAD, true) 176 s.NoError(err) 177 s.Equal("b029517f6300c2da0f4b651b8642506cd6aaf45d", ref.Hash().String()) 178 179} 180 181func (s *SubmoduleSuite) TestSubmodulesInit() { 182 sm, err := s.Worktree.Submodules() 183 s.NoError(err) 184 185 err = sm.Init() 186 s.NoError(err) 187 188 sm, err = s.Worktree.Submodules() 189 s.NoError(err) 190 191 for _, m := range sm { 192 s.True(m.initialized) 193 } 194} 195 196func (s *SubmoduleSuite) TestGitSubmodulesSymlink() { 197 f, err := s.Worktree.Filesystem.Create("badfile") 198 s.NoError(err) 199 defer func() { _ = f.Close() }() 200 201 err = s.Worktree.Filesystem.Remove(gitmodulesFile) 202 s.NoError(err) 203 204 err = s.Worktree.Filesystem.Symlink("badfile", gitmodulesFile) 205 s.NoError(err) 206 207 _, err = s.Worktree.Submodules() 208 s.ErrorIs(err, ErrGitModulesSymlink) 209} 210 211func (s *SubmoduleSuite) TestSubmodulesStatus() { 212 sm, err := s.Worktree.Submodules() 213 s.NoError(err) 214 215 status, err := sm.Status() 216 s.NoError(err) 217 s.Len(status, 2) 218} 219 220func (s *SubmoduleSuite) TestSubmodulesUpdateContext() { 221 if testing.Short() { 222 s.T().Skip("skipping test in short mode.") 223 } 224 225 sm, err := s.Worktree.Submodules() 226 s.NoError(err) 227 228 ctx, cancel := context.WithCancel(context.Background()) 229 cancel() 230 231 err = sm.UpdateContext(ctx, &SubmoduleUpdateOptions{Init: true}) 232 s.NotNil(err) 233} 234 235func (s *SubmoduleSuite) TestSubmodulesFetchDepth() { 236 if testing.Short() { 237 s.T().Skip("skipping test in short mode.") 238 } 239 240 sm, err := s.Worktree.Submodule("basic") 241 s.NoError(err) 242 243 err = sm.Update(&SubmoduleUpdateOptions{ 244 Init: true, 245 Depth: 1, 246 }) 247 s.NoError(err) 248 249 r, err := sm.Repository() 250 s.NoError(err) 251 252 lr, err := r.Log(&LogOptions{}) 253 s.NoError(err) 254 255 commitCount := 0 256 for _, err := lr.Next(); err == nil; _, err = lr.Next() { 257 commitCount++ 258 } 259 s.NoError(err) 260 261 s.Equal(1, commitCount) 262} 263 264func (s *SubmoduleSuite) TestSubmoduleParseScp() { 265 repo := &Repository{ 266 Storer: memory.NewStorage(), 267 wt: memfs.New(), 268 } 269 worktree := &Worktree{ 270 Filesystem: memfs.New(), 271 r: repo, 272 } 273 submodule := &Submodule{ 274 initialized: true, 275 c: nil, 276 w: worktree, 277 } 278 279 submodule.c = &config.Submodule{ 280 URL: "git@github.com:username/submodule_repo", 281 } 282 283 _, err := submodule.Repository() 284 s.NoError(err) 285}