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

     1  package git
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"runtime"
     7  
     8  	"k8s.io/klog/v2"
     9  
    10  	"github.com/openshift/source-to-image/pkg/api"
    11  	"github.com/openshift/source-to-image/pkg/api/constants"
    12  	"github.com/openshift/source-to-image/pkg/scm/git"
    13  	"github.com/openshift/source-to-image/pkg/util/fs"
    14  )
    15  
    16  // Clone knows how to clone a Git repository.
    17  type Clone struct {
    18  	git.Git
    19  	fs.FileSystem
    20  }
    21  
    22  // Download downloads the application source code from the Git repository
    23  // and checkout the Ref specified in the config.
    24  func (c *Clone) Download(config *api.Config) (*git.SourceInfo, error) {
    25  	targetSourceDir := filepath.Join(config.WorkingDir, constants.Source)
    26  	config.WorkingSourceDir = targetSourceDir
    27  
    28  	ref := config.Source.URL.Fragment
    29  	if ref == "" {
    30  		ref = "HEAD"
    31  	}
    32  
    33  	if len(config.ContextDir) > 0 {
    34  		targetSourceDir = filepath.Join(config.WorkingDir, constants.ContextTmp)
    35  		klog.V(1).Infof("Downloading %q (%q) ...", config.Source, config.ContextDir)
    36  	} else {
    37  		klog.V(1).Infof("Downloading %q ...", config.Source)
    38  	}
    39  
    40  	if !config.IgnoreSubmodules {
    41  		klog.V(2).Infof("Cloning sources into %q", targetSourceDir)
    42  	} else {
    43  		klog.V(2).Infof("Cloning sources (ignoring submodules) into %q", targetSourceDir)
    44  	}
    45  
    46  	cloneConfig := git.CloneConfig{Quiet: true}
    47  	err := c.Clone(config.Source, targetSourceDir, cloneConfig)
    48  	if err != nil {
    49  		klog.V(0).Infof("error: git clone failed: %v", err)
    50  		return nil, err
    51  	}
    52  
    53  	err = c.Checkout(targetSourceDir, ref)
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  	klog.V(1).Infof("Checked out %q", ref)
    58  	if !config.IgnoreSubmodules {
    59  		err = c.SubmoduleUpdate(targetSourceDir, true, true)
    60  		if err != nil {
    61  			return nil, err
    62  		}
    63  		klog.V(1).Infof("Updated submodules for %q", ref)
    64  	}
    65  
    66  	// Record Git's knowledge about file permissions
    67  	if runtime.GOOS == "windows" {
    68  		filemodes, err := c.LsTree(filepath.Join(targetSourceDir, config.ContextDir), ref, true)
    69  		if err != nil {
    70  			return nil, err
    71  		}
    72  		for _, filemode := range filemodes {
    73  			c.Chmod(filepath.Join(targetSourceDir, config.ContextDir, filemode.Name()), os.FileMode(filemode.Mode())&os.ModePerm)
    74  		}
    75  	}
    76  
    77  	info := c.GetInfo(targetSourceDir)
    78  	if len(config.ContextDir) > 0 {
    79  		originalTargetDir := filepath.Join(config.WorkingDir, constants.Source)
    80  		c.RemoveDirectory(originalTargetDir)
    81  		path := filepath.Join(targetSourceDir, config.ContextDir)
    82  		err := c.CopyContents(path, originalTargetDir, nil)
    83  		if err != nil {
    84  			return nil, err
    85  		}
    86  		c.RemoveDirectory(targetSourceDir)
    87  	}
    88  
    89  	if len(config.ContextDir) > 0 {
    90  		info.ContextDir = config.ContextDir
    91  	}
    92  
    93  	return info, nil
    94  }