github.com/kubeshop/testkube@v1.17.23/cmd/tcl/testworkflow-toolkit/commands/clone.go (about)

     1  // Copyright 2024 Testkube.
     2  //
     3  // Licensed as a Testkube Pro file under the Testkube Community
     4  // License (the "License"); you may not use this file except in compliance with
     5  // the License. You may obtain a copy of the License at
     6  //
     7  //	https://github.com/kubeshop/testkube/blob/main/licenses/TCL.txt
     8  
     9  package commands
    10  
    11  import (
    12  	"fmt"
    13  	"net/url"
    14  	"os"
    15  	"path/filepath"
    16  
    17  	"github.com/spf13/cobra"
    18  
    19  	"github.com/kubeshop/testkube/pkg/ui"
    20  )
    21  
    22  func NewCloneCmd() *cobra.Command {
    23  	var (
    24  		paths    []string
    25  		username string
    26  		token    string
    27  		authType string
    28  		revision string
    29  	)
    30  
    31  	cmd := &cobra.Command{
    32  		Use:   "clone <uri> <outputPath>",
    33  		Short: "Clone the Git repository",
    34  		Args:  cobra.ExactArgs(2),
    35  
    36  		Run: func(cmd *cobra.Command, args []string) {
    37  			uri, err := url.Parse(args[0])
    38  			ui.ExitOnError("repository uri", err)
    39  			outputPath, err := filepath.Abs(args[1])
    40  			ui.ExitOnError("output path", err)
    41  
    42  			// Disable interactivity
    43  			os.Setenv("GIT_TERMINAL_PROMPT", "0")
    44  
    45  			authArgs := make([]string, 0)
    46  
    47  			if authType == "header" {
    48  				ui.Debug("auth type: header")
    49  				if token != "" {
    50  					authArgs = append(authArgs, "-c", fmt.Sprintf("http.extraHeader='%s'", "Authorization: Bearer "+token))
    51  				}
    52  				if username != "" {
    53  					uri.User = url.User(username)
    54  				}
    55  			} else {
    56  				ui.Debug("auth type: token")
    57  				if username != "" && token != "" {
    58  					uri.User = url.UserPassword(username, token)
    59  				} else if username != "" {
    60  					uri.User = url.User(username)
    61  				} else if token != "" {
    62  					uri.User = url.User(token)
    63  				}
    64  			}
    65  
    66  			// Mark directory as safe
    67  			configArgs := []string{"-c", fmt.Sprintf("safe.directory=%s", outputPath), "-c", "advice.detachedHead=false"}
    68  
    69  			// Clone repository
    70  			if len(paths) == 0 {
    71  				ui.Debug("full checkout")
    72  				err = Run("git", "clone", configArgs, authArgs, "--depth", 1, "--verbose", uri.String(), outputPath)
    73  				ui.ExitOnError("cloning repository", err)
    74  			} else {
    75  				ui.Debug("sparse checkout")
    76  				err = Run("git", "clone", configArgs, authArgs, "--filter=blob:none", "--no-checkout", "--sparse", "--depth", 1, "--verbose", uri.String(), outputPath)
    77  				ui.ExitOnError("cloning repository", err)
    78  				err = Run("git", "-C", outputPath, configArgs, "sparse-checkout", "set", "--no-cone", paths)
    79  				ui.ExitOnError("sparse checkout repository", err)
    80  				if revision != "" {
    81  					err = Run("git", "-C", outputPath, configArgs, "fetch", authArgs, "--depth", 1, "origin", revision)
    82  					ui.ExitOnError("fetching revision", err)
    83  					err = Run("git", "-C", outputPath, configArgs, "checkout", "FETCH_HEAD")
    84  					ui.ExitOnError("checking out head", err)
    85  					// TODO: Don't do it for commits
    86  					err = Run("git", "-C", outputPath, configArgs, "checkout", "-B", revision)
    87  					ui.ExitOnError("checking out the branch", err)
    88  				} else {
    89  					err = Run("git", "-C", outputPath, configArgs, "checkout")
    90  					ui.ExitOnError("fetching head", err)
    91  				}
    92  			}
    93  		},
    94  	}
    95  
    96  	cmd.Flags().StringSliceVarP(&paths, "paths", "p", nil, "paths for sparse checkout")
    97  	cmd.Flags().StringVarP(&username, "username", "u", "", "")
    98  	cmd.Flags().StringVarP(&token, "token", "t", "", "")
    99  	cmd.Flags().StringVarP(&authType, "authType", "a", "basic", "allowed: basic, header")
   100  	cmd.Flags().StringVarP(&revision, "revision", "r", "", "commit hash, branch name or tag")
   101  
   102  	return cmd
   103  }