fix: copy ignored tracked files (#1074)

* fix: copy ignored tracked files

* fix

* refactor: Extract callback to fileCollector

fix: temporary tar archive not deletable on windows
fix: `.*` in gitignore ignores all files

* Move nolint: gocyclo

* pass context as parameter

* goimport

* Add fs interface + one test

* fix lint, also test for ignored non tracked file

* fix filename

* Apply suggestions from code review

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
ChristopherHX
2022-04-04 17:27:00 +02:00
committed by GitHub
parent e0044ba913
commit c27e079407
3 changed files with 321 additions and 65 deletions

View File

@@ -576,7 +576,6 @@ func (cr *containerReference) exec(cmd []string, env map[string]string, user, wo
}
}
// nolint: gocyclo
func (cr *containerReference) copyDir(dstPath string, srcPath string, useGitIgnore bool) common.Executor {
return func(ctx context.Context) error {
logger := common.Logger(ctx)
@@ -585,8 +584,17 @@ func (cr *containerReference) copyDir(dstPath string, srcPath string, useGitIgno
return err
}
log.Debugf("Writing tarball %s from %s", tarFile.Name(), srcPath)
defer tarFile.Close()
defer os.Remove(tarFile.Name())
defer func(tarFile *os.File) {
name := tarFile.Name()
err := tarFile.Close()
if err != nil {
logger.Error(err)
}
err = os.Remove(name)
if err != nil {
logger.Error(err)
}
}(tarFile)
tw := tar.NewWriter(tarFile)
srcPrefix := filepath.Dir(srcPath)
@@ -605,69 +613,17 @@ func (cr *containerReference) copyDir(dstPath string, srcPath string, useGitIgno
ignorer = gitignore.NewMatcher(ps)
}
err = filepath.Walk(srcPath, func(file string, fi os.FileInfo, err error) error {
if err != nil {
return err
}
fc := &fileCollector{
Fs: &defaultFs{},
Ignorer: ignorer,
SrcPath: srcPath,
SrcPrefix: srcPrefix,
Handler: &tarCollector{
TarWriter: tw,
},
}
sansPrefix := strings.TrimPrefix(file, srcPrefix)
split := strings.Split(sansPrefix, string(filepath.Separator))
if ignorer != nil && ignorer.Match(split, fi.IsDir()) {
if fi.IsDir() {
return filepath.SkipDir
}
return nil
}
// return on non-regular files (thanks to [kumo](https://medium.com/@komuw/just-like-you-did-fbdd7df829d3) for this suggested update)
linkName := fi.Name()
if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
linkName, err = os.Readlink(file)
if err != nil {
return errors.WithMessagef(err, "unable to readlink %s", file)
}
} else if !fi.Mode().IsRegular() {
return nil
}
// create a new dir/file header
header, err := tar.FileInfoHeader(fi, linkName)
if err != nil {
return err
}
// update the name to correctly reflect the desired destination when untaring
header.Name = filepath.ToSlash(sansPrefix)
header.Mode = int64(fi.Mode())
header.ModTime = fi.ModTime()
// write the header
if err := tw.WriteHeader(header); err != nil {
return err
}
// symlinks don't need to be copied
if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
return nil
}
// open files for taring
f, err := os.Open(file)
if err != nil {
return err
}
// copy file data into tar writer
if _, err := io.Copy(tw, f); err != nil {
return err
}
// manually close here after each file operation; deferring would cause each file close
// to wait until all operations have completed.
f.Close()
return nil
})
err = filepath.Walk(srcPath, fc.collectFiles(ctx, []string{}))
if err != nil {
return err
}