github.com/osievert/jfrog-cli-core@v1.2.7/artifactory/utils/dependenciesutils.go (about)

     1  package utils
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"net/http"
     7  	"os"
     8  	"path"
     9  
    10  	bintrayutils "github.com/jfrog/jfrog-cli-core/bintray/utils"
    11  	"github.com/jfrog/jfrog-cli-core/utils/config"
    12  	"github.com/jfrog/jfrog-cli-core/utils/coreutils"
    13  	"github.com/jfrog/jfrog-client-go/bintray"
    14  	"github.com/jfrog/jfrog-client-go/bintray/auth"
    15  	"github.com/jfrog/jfrog-client-go/bintray/services"
    16  	"github.com/jfrog/jfrog-client-go/bintray/services/utils"
    17  	"github.com/jfrog/jfrog-client-go/http/httpclient"
    18  	"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
    19  	"github.com/jfrog/jfrog-client-go/utils/errorutils"
    20  	"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
    21  	"github.com/jfrog/jfrog-client-go/utils/log"
    22  )
    23  
    24  const (
    25  	// This env var should be used for downloading the extractor jars through an Artifactory remote
    26  	// repository, instead of downloading directly from jcenter. The remote repository should be
    27  	// configured to proxy jcenter.
    28  	// The env var should store a server ID configured by JFrog CLI.
    29  	JCenterRemoteServerEnv = "JFROG_CLI_JCENTER_REMOTE_SERVER"
    30  	// If the JCenterRemoteServerEnv env var is used, a maven remote repository named jcenter is assumed.
    31  	// This env var can be used to use a different remote repository name.
    32  	JCenterRemoteRepoEnv = "JFROG_CLI_JCENTER_REMOTE_REPO"
    33  )
    34  
    35  // Download the relevant build-info-extractor jar, if it does not already exist locally.
    36  // By default, the jar is downloaded directly from jcenter.
    37  // If the JCenterRemoteServerEnv environment variable is configured, the jar will be
    38  // downloaded from a remote Artifactory repository which proxies jcenter.
    39  //
    40  // downloadPath: The Bintray or Artifactory download path.
    41  // filename: The local file name.
    42  // targetPath: The local download path (without the file name).
    43  func DownloadExtractorIfNeeded(downloadPath, targetPath string) error {
    44  	// If the file exists locally, we're done.
    45  	exists, err := fileutils.IsFileExists(targetPath, false)
    46  	if exists || err != nil {
    47  		return err
    48  	}
    49  
    50  	artDetails, remotePath, err := GetJcenterRemoteDetails(downloadPath)
    51  	if err != nil {
    52  		return err
    53  	}
    54  
    55  	// Download through a remote repository in Artifactory, if configured to do so.
    56  	if artDetails != nil {
    57  		return downloadFileFromArtifactory(artDetails, remotePath, targetPath)
    58  	}
    59  
    60  	// If not configured to download through a remote repository in Artifactory,
    61  	// download from jcenter.
    62  	return downloadFileFromBintray(remotePath, targetPath)
    63  }
    64  
    65  func GetJcenterRemoteDetails(downloadPath string) (artDetails *config.ArtifactoryDetails, remotePath string, err error) {
    66  	// Download through a remote repository in Artifactory, if configured to do so.
    67  	serverId := os.Getenv(JCenterRemoteServerEnv)
    68  	if serverId != "" {
    69  		artDetails, err = config.GetArtifactorySpecificConfig(serverId, false, true)
    70  		if err != nil {
    71  			return
    72  		}
    73  
    74  		remotePath = path.Join(getJcenterRemoteRepoName(), downloadPath)
    75  		return
    76  	}
    77  
    78  	// If not configured to download through a remote repository in Artifactory,
    79  	// download from jcenter.
    80  	remotePath = path.Join("bintray/jcenter", downloadPath)
    81  	return
    82  }
    83  
    84  func getJcenterRemoteRepoName() string {
    85  	jcenterRemoteRepo := os.Getenv(JCenterRemoteRepoEnv)
    86  	if jcenterRemoteRepo == "" {
    87  		jcenterRemoteRepo = "jcenter"
    88  	}
    89  	return jcenterRemoteRepo
    90  }
    91  
    92  func downloadFileFromArtifactory(artDetails *config.ArtifactoryDetails, downloadPath, targetPath string) error {
    93  	downloadUrl := fmt.Sprintf("%s%s", artDetails.Url, downloadPath)
    94  	log.Info("Downloading build-info-extractor from", downloadUrl)
    95  	filename, localDir := fileutils.GetFileAndDirFromPath(targetPath)
    96  
    97  	downloadFileDetails := &httpclient.DownloadFileDetails{
    98  		FileName:      filename,
    99  		DownloadPath:  downloadUrl,
   100  		LocalPath:     localDir,
   101  		LocalFileName: filename,
   102  	}
   103  
   104  	auth, err := artDetails.CreateArtAuthConfig()
   105  	if err != nil {
   106  		return err
   107  	}
   108  	certsPath, err := coreutils.GetJfrogCertsDir()
   109  	if err != nil {
   110  		return err
   111  	}
   112  
   113  	client, err := jfroghttpclient.JfrogClientBuilder().
   114  		SetCertificatesPath(certsPath).
   115  		SetInsecureTls(artDetails.InsecureTls).
   116  		SetServiceDetails(&auth).
   117  		Build()
   118  	if err != nil {
   119  		return err
   120  	}
   121  
   122  	httpClientDetails := auth.CreateHttpClientDetails()
   123  	resp, err := client.DownloadFile(downloadFileDetails, "", &httpClientDetails, 3, false)
   124  	if err == nil && resp.StatusCode != http.StatusOK {
   125  		err = errorutils.CheckError(errors.New(resp.Status + " received when attempting to download " + downloadUrl))
   126  	}
   127  
   128  	return err
   129  }
   130  
   131  func downloadFileFromBintray(downloadPath, targetPath string) error {
   132  	bintrayConfig := auth.NewBintrayDetails()
   133  	config := bintray.NewConfigBuilder().SetBintrayDetails(bintrayConfig).Build()
   134  
   135  	pathDetails, err := utils.CreatePathDetails(downloadPath)
   136  	if err != nil {
   137  		return err
   138  	}
   139  
   140  	params := &services.DownloadFileParams{}
   141  	params.PathDetails = pathDetails
   142  	params.TargetPath = targetPath
   143  	params.Flat = true
   144  
   145  	_, _, err = bintrayutils.DownloadFileFromBintray(config, params)
   146  	return err
   147  }