github.com/openshift/source-to-image@v1.4.1-0.20240516041539-bf52fc02204e/pkg/scm/downloaders/file/download.go (about)

     1  package file
     2  
     3  import (
     4  	"fmt"
     5  	"path/filepath"
     6  	"regexp"
     7  
     8  	"github.com/openshift/source-to-image/pkg/api"
     9  	"github.com/openshift/source-to-image/pkg/api/constants"
    10  	"github.com/openshift/source-to-image/pkg/ignore"
    11  	"github.com/openshift/source-to-image/pkg/scm/git"
    12  	"github.com/openshift/source-to-image/pkg/util/fs"
    13  	utillog "github.com/openshift/source-to-image/pkg/util/log"
    14  )
    15  
    16  var log = utillog.StderrLog
    17  
    18  // RecursiveCopyError indicates a copy operation failed because the destination is within the copy's source tree.
    19  type RecursiveCopyError struct {
    20  	error
    21  }
    22  
    23  // File represents a simplest possible Downloader implementation where the
    24  // sources are just copied from local directory.
    25  type File struct {
    26  	fs.FileSystem
    27  }
    28  
    29  // Download copies sources from a local directory into the working directory.
    30  // Caller guarantees that config.Source.IsLocal() is true.
    31  func (f *File) Download(config *api.Config) (*git.SourceInfo, error) {
    32  	config.WorkingSourceDir = filepath.Join(config.WorkingDir, constants.Source)
    33  
    34  	copySrc := config.Source.LocalPath()
    35  	if len(config.ContextDir) > 0 {
    36  		copySrc = filepath.Join(copySrc, config.ContextDir)
    37  	}
    38  
    39  	log.V(1).Infof("Copying sources from %q to %q", copySrc, config.WorkingSourceDir)
    40  	absWorkingSourceDir, err := filepath.Abs(config.WorkingSourceDir)
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  	absCopySrc, err := filepath.Abs(copySrc)
    45  	if err != nil {
    46  		return nil, err
    47  	}
    48  	if filepath.HasPrefix(absWorkingSourceDir, absCopySrc) {
    49  		return nil, RecursiveCopyError{error: fmt.Errorf("recursive copy requested, source directory %q contains the target directory %q", copySrc, config.WorkingSourceDir)}
    50  	}
    51  
    52  	di := ignore.DockerIgnorer{}
    53  	filesToIgnore, lerr := di.GetListOfFilesToIgnore(copySrc)
    54  	if lerr != nil {
    55  		return nil, lerr
    56  	}
    57  
    58  	var isIgnored func(path string) bool
    59  
    60  	if config.ExcludeRegExp != "" {
    61  		exclude, err := regexp.Compile(config.ExcludeRegExp)
    62  		if err != nil {
    63  			return nil, err
    64  		}
    65  		isIgnored = func(path string) bool {
    66  			_, ok := filesToIgnore[path]
    67  			return ok || exclude.MatchString(path)
    68  		}
    69  	} else {
    70  		isIgnored = func(path string) bool {
    71  			_, ok := filesToIgnore[path]
    72  			return ok
    73  		}
    74  	}
    75  
    76  	if copySrc != config.WorkingSourceDir {
    77  		f.KeepSymlinks(config.KeepSymlinks)
    78  		err = f.CopyContents(copySrc, config.WorkingSourceDir, isIgnored)
    79  		if err != nil {
    80  			return nil, err
    81  		}
    82  	}
    83  
    84  	return &git.SourceInfo{
    85  		Location:   config.Source.LocalPath(),
    86  		ContextDir: config.ContextDir,
    87  	}, nil
    88  }