github.com/jfrog/jfrog-cli-core/v2@v2.51.0/utils/python/utils.go (about) 1 package utils 2 3 import ( 4 "fmt" 5 "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" 6 "net/url" 7 "os" 8 "path/filepath" 9 "strings" 10 11 "github.com/jfrog/build-info-go/utils/pythonutils" 12 "github.com/jfrog/gofrog/io" 13 gofrogcmd "github.com/jfrog/gofrog/io" 14 "github.com/jfrog/jfrog-cli-core/v2/utils/config" 15 "github.com/jfrog/jfrog-client-go/auth" 16 "github.com/jfrog/jfrog-client-go/utils/errorutils" 17 "github.com/jfrog/jfrog-client-go/utils/log" 18 "github.com/spf13/viper" 19 ) 20 21 const ( 22 pipenvRemoteRegistryFlag = "--pypi-mirror" 23 pipRemoteRegistryFlag = "-i" 24 poetryConfigAuthPrefix = "http-basic." 25 poetryConfigRepoPrefix = "repositories." 26 pyproject = "pyproject.toml" 27 ) 28 29 func GetPypiRepoUrlWithCredentials(serverDetails *config.ServerDetails, repository string, isCurationCmd bool) (*url.URL, string, string, error) { 30 rtUrl, err := url.Parse(serverDetails.GetArtifactoryUrl()) 31 if err != nil { 32 return nil, "", "", errorutils.CheckError(err) 33 } 34 35 username := serverDetails.GetUser() 36 password := serverDetails.GetPassword() 37 38 // Get credentials from access-token if exists. 39 if serverDetails.GetAccessToken() != "" { 40 if username == "" { 41 username = auth.ExtractUsernameFromAccessToken(serverDetails.GetAccessToken()) 42 } 43 password = serverDetails.GetAccessToken() 44 } 45 // In case of curation command, the download urls should be routed through a dedicated api. 46 if isCurationCmd { 47 rtUrl.Path += coreutils.CurationPassThroughApi 48 } 49 rtUrl.Path += "api/pypi/" + repository + "/simple" 50 return rtUrl, username, password, err 51 } 52 53 func GetPypiRemoteRegistryFlag(tool pythonutils.PythonTool) string { 54 if tool == pythonutils.Pip { 55 return pipRemoteRegistryFlag 56 } 57 return pipenvRemoteRegistryFlag 58 } 59 60 func GetPypiRepoUrl(serverDetails *config.ServerDetails, repository string, isCurationCmd bool) (string, error) { 61 rtUrl, username, password, err := GetPypiRepoUrlWithCredentials(serverDetails, repository, isCurationCmd) 62 if err != nil { 63 return "", err 64 } 65 if password != "" { 66 rtUrl.User = url.UserPassword(username, password) 67 } 68 return rtUrl.String(), err 69 } 70 71 func ConfigPoetryRepo(url, username, password, configRepoName string) error { 72 // Add the poetry repository config 73 err := runPoetryConfigCommand([]string{poetryConfigRepoPrefix + configRepoName, url}, false) 74 if err != nil { 75 return err 76 } 77 78 // Set the poetry repository credentials 79 err = runPoetryConfigCommand([]string{poetryConfigAuthPrefix + configRepoName, username, password}, true) 80 if err != nil { 81 return err 82 } 83 84 // Add the repository config to the pyproject.toml 85 currentDir, err := os.Getwd() 86 if err != nil { 87 return errorutils.CheckError(err) 88 } 89 if err = addRepoToPyprojectFile(filepath.Join(currentDir, pyproject), configRepoName, url); err != nil { 90 return err 91 } 92 return poetryUpdate() 93 } 94 95 func poetryUpdate() (err error) { 96 log.Info("Running Poetry update") 97 cmd := io.NewCommand("poetry", "update", []string{}) 98 err = gofrogcmd.RunCmd(cmd) 99 if err != nil { 100 return errorutils.CheckErrorf("Poetry config command failed with: %s", err.Error()) 101 } 102 return 103 } 104 105 func runPoetryConfigCommand(args []string, maskArgs bool) error { 106 logMessage := "config " 107 if maskArgs { 108 logMessage += "***" 109 } else { 110 logMessage += strings.Join(args, " ") 111 } 112 log.Info(fmt.Sprintf("Running Poetry %s", logMessage)) 113 cmd := io.NewCommand("poetry", "config", args) 114 err := gofrogcmd.RunCmd(cmd) 115 if err != nil { 116 return errorutils.CheckErrorf("Poetry config command failed with: %s", err.Error()) 117 } 118 return nil 119 } 120 121 func addRepoToPyprojectFile(filepath, poetryRepoName, repoUrl string) error { 122 viper.SetConfigType("toml") 123 viper.SetConfigFile(filepath) 124 err := viper.ReadInConfig() 125 if err != nil { 126 return errorutils.CheckErrorf("Failed to read pyproject.toml: %s", err.Error()) 127 } 128 viper.Set("tool.poetry.source", []map[string]string{{"name": poetryRepoName, "url": repoUrl}}) 129 err = viper.WriteConfig() 130 if err != nil { 131 return errorutils.CheckErrorf("Failed to add tool.poetry.source to pyproject.toml: %s", err.Error()) 132 } 133 log.Info(fmt.Sprintf("Added tool.poetry.source name:%q url:%q", poetryRepoName, repoUrl)) 134 return err 135 }