Skip to content

Commit 3332e8d

Browse files
committed
improve cleanup implementation, add more tests
Signed-off-by: Santiago M. Mola <[email protected]>
1 parent 507681b commit 3332e8d

File tree

2 files changed

+109
-55
lines changed

2 files changed

+109
-55
lines changed

Diff for: repository.go

+61-49
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ var (
5151
ErrIsBareRepository = errors.New("worktree not available in a bare repository")
5252
ErrUnableToResolveCommit = errors.New("unable to resolve commit")
5353
ErrPackedObjectsNotSupported = errors.New("Packed objects not supported")
54-
ErrDirNotEmpty = errors.New("directory is not empty")
5554
)
5655

5756
// Repository represents a git repository
@@ -344,65 +343,19 @@ func PlainClone(path string, isBare bool, o *CloneOptions) (*Repository, error)
344343
//
345344
// TODO(mcuadros): move isBare to CloneOptions in v5
346345
func PlainCloneContext(ctx context.Context, path string, isBare bool, o *CloneOptions) (*Repository, error) {
347-
dirEmpty := false
348-
dirExist := false
349-
350-
file, err := os.Stat(path)
346+
dirExists, err := checkExistsAndIsEmptyDir(path)
351347
if err != nil {
352348
return nil, err
353349
}
354350

355-
if !os.IsNotExist(err) {
356-
dirExist = file.IsDir()
357-
}
358-
359-
if dirExist {
360-
fh, err := os.Open(path)
361-
if err != nil {
362-
return nil, err
363-
}
364-
defer fh.Close()
365-
366-
names, err := fh.Readdirnames(1)
367-
if err != io.EOF && err != nil {
368-
return nil, err
369-
}
370-
if len(names) == 0 {
371-
dirEmpty = true
372-
} else {
373-
return nil, ErrDirNotEmpty
374-
}
375-
}
376-
377351
r, err := PlainInit(path, isBare)
378352
if err != nil {
379353
return nil, err
380354
}
381355

382356
err = r.clone(ctx, o)
383357
if err != nil && err != ErrRepositoryAlreadyExists {
384-
if dirEmpty {
385-
fh, err := os.Open(path)
386-
if err != nil {
387-
return nil, err
388-
}
389-
defer fh.Close()
390-
391-
names, err := fh.Readdirnames(-1)
392-
if err != nil && err != io.EOF {
393-
return nil, err
394-
}
395-
396-
for _, name := range names {
397-
err = os.RemoveAll(filepath.Join(path, name))
398-
if err != nil {
399-
return nil, err
400-
}
401-
}
402-
} else if !dirExist {
403-
os.RemoveAll(path)
404-
return nil, err
405-
}
358+
cleanUpDir(path, !dirExists)
406359
}
407360

408361
return r, err
@@ -416,6 +369,65 @@ func newRepository(s storage.Storer, worktree billy.Filesystem) *Repository {
416369
}
417370
}
418371

372+
func checkExistsAndIsEmptyDir(path string) (exists bool, err error) {
373+
fi, err := os.Stat(path)
374+
if err != nil {
375+
if os.IsNotExist(err) {
376+
return false, nil
377+
}
378+
379+
return false, err
380+
}
381+
382+
if !fi.IsDir() {
383+
return false, fmt.Errorf("path is not a directory: %s", path)
384+
}
385+
386+
f, err := os.Open(path)
387+
if err != nil {
388+
return false, err
389+
}
390+
391+
defer ioutil.CheckClose(f, &err)
392+
393+
_, err = f.Readdirnames(1)
394+
if err == io.EOF {
395+
return true, nil
396+
}
397+
398+
if err != nil {
399+
return true, err
400+
}
401+
402+
return true, fmt.Errorf("directory is not empty: %s", path)
403+
}
404+
405+
func cleanUpDir(path string, all bool) error {
406+
if all {
407+
return os.RemoveAll(path)
408+
}
409+
410+
f, err := os.Open(path)
411+
if err != nil {
412+
return err
413+
}
414+
415+
defer ioutil.CheckClose(f, &err)
416+
417+
names, err := f.Readdirnames(-1)
418+
if err != nil {
419+
return err
420+
}
421+
422+
for _, name := range names {
423+
if err := os.RemoveAll(filepath.Join(path, name)); err != nil {
424+
return err
425+
}
426+
}
427+
428+
return nil
429+
}
430+
419431
// Config return the repository config
420432
func (r *Repository) Config() (*config.Config, error) {
421433
return r.Storer.Config()

Diff for: repository_test.go

+48-6
Original file line numberDiff line numberDiff line change
@@ -593,24 +593,66 @@ func (s *RepositorySuite) TestPlainCloneContextWithProperParameters(c *C) {
593593
c.Assert(err, NotNil)
594594
}
595595

596-
func (s *RepositorySuite) TestPlainCloneContextWithIncorrectRepo(c *C) {
596+
func (s *RepositorySuite) TestPlainCloneContextNonExistentWithExistentDir(c *C) {
597+
ctx, cancel := context.WithCancel(context.Background())
598+
cancel()
599+
600+
tmpDir := c.MkDir()
601+
repoDir := tmpDir
602+
603+
r, err := PlainCloneContext(ctx, repoDir, false, &CloneOptions{
604+
URL: "incorrectOnPurpose",
605+
})
606+
c.Assert(r, NotNil)
607+
c.Assert(err, NotNil)
608+
609+
_, err = os.Stat(repoDir)
610+
c.Assert(os.IsNotExist(err), Equals, false)
611+
612+
names, err := ioutil.ReadDir(repoDir)
613+
c.Assert(err, IsNil)
614+
c.Assert(names, HasLen, 0)
615+
}
616+
617+
func (s *RepositorySuite) TestPlainCloneContextNonExistentWithNonExistentDir(c *C) {
597618
ctx, cancel := context.WithCancel(context.Background())
598619
cancel()
599620

600621
tmpDir := c.MkDir()
601622
repoDir := filepath.Join(tmpDir, "repoDir")
623+
602624
r, err := PlainCloneContext(ctx, repoDir, false, &CloneOptions{
603625
URL: "incorrectOnPurpose",
604626
})
605-
c.Assert(r, IsNil)
627+
c.Assert(r, NotNil)
606628
c.Assert(err, NotNil)
607629

608630
_, err = os.Stat(repoDir)
609-
dirNotExist := os.IsNotExist(err)
610-
c.Assert(dirNotExist, Equals, true)
631+
c.Assert(os.IsNotExist(err), Equals, true)
632+
}
633+
634+
func (s *RepositorySuite) TestPlainCloneContextNonExistentWithNotDir(c *C) {
635+
ctx, cancel := context.WithCancel(context.Background())
636+
cancel()
637+
638+
tmpDir := c.MkDir()
639+
repoDir := filepath.Join(tmpDir, "repoDir")
640+
f, err := os.Create(repoDir)
641+
c.Assert(err, IsNil)
642+
c.Assert(f.Close(), IsNil)
643+
644+
r, err := PlainCloneContext(ctx, repoDir, false, &CloneOptions{
645+
URL: "incorrectOnPurpose",
646+
})
647+
c.Assert(r, IsNil)
648+
c.Assert(err, NotNil)
649+
650+
fi, err := os.Stat(repoDir)
651+
c.Assert(err, IsNil)
652+
c.Assert(fi.IsDir(), Equals, false)
611653
}
612654

613-
func (s *RepositorySuite) TestPlainCloneContextWithNotEmptyDir(c *C) {
655+
func (s *RepositorySuite) TestPlainCloneContextNonExistentWithNotEmptyDir(c *C) {
614656
ctx, cancel := context.WithCancel(context.Background())
615657
cancel()
616658

@@ -627,7 +669,7 @@ func (s *RepositorySuite) TestPlainCloneContextWithNotEmptyDir(c *C) {
627669
URL: "incorrectOnPurpose",
628670
})
629671
c.Assert(r, IsNil)
630-
c.Assert(err, Equals, ErrDirNotEmpty)
672+
c.Assert(err, NotNil)
631673
}
632674

633675
func (s *RepositorySuite) TestPlainCloneWithRecurseSubmodules(c *C) {

0 commit comments

Comments
 (0)