github.com/jfrog/jfrog-cli-core@v1.12.1/artifactory/utils/pip/setuppy.go (about) 1 package pip 2 3 import ( 4 "errors" 5 "os" 6 "os/exec" 7 "path/filepath" 8 "strings" 9 10 "github.com/jfrog/jfrog-client-go/utils" 11 "github.com/jfrog/jfrog-client-go/utils/errorutils" 12 "github.com/jfrog/jfrog-client-go/utils/io/fileutils" 13 ) 14 15 // Get the project-name by running 'egg_info' command on setup.py and extracting it from 'PKG-INFO' file. 16 func ExtractPackageNameFromSetupPy(setuppyFilePath, pythonExecutablePath string) (string, error) { 17 // Execute egg_info command and return PKG-INFO content. 18 content, err := getEgginfoPkginfoContent(setuppyFilePath, pythonExecutablePath) 19 if err != nil { 20 return "", err 21 } 22 23 // Extract project name from file content. 24 return getProjectNameFromFileContent(content) 25 } 26 27 // Get package-name from PKG-INFO file content. 28 // If pattern of package-name not found, return an error. 29 func getProjectNameFromFileContent(content []byte) (string, error) { 30 // Create package-name regexp. 31 packageNameRegexp, err := utils.GetRegExp(`(?m)^Name\:\s(\w[\w-\.]+)`) 32 if err != nil { 33 return "", err 34 } 35 36 // Find first match of packageNameRegexp. 37 match := packageNameRegexp.FindStringSubmatch(string(content)) 38 if len(match) < 2 { 39 return "", errorutils.CheckError(errors.New("Failed extracting package name from content.")) 40 } 41 42 return match[1], nil 43 } 44 45 // Run egg-info command on setup.py, the command generates metadata files. 46 // Return the content of the 'PKG-INFO' file. 47 func getEgginfoPkginfoContent(setuppyFilePath, pythonExecutablePath string) ([]byte, error) { 48 eggBase, err := fileutils.CreateTempDir() 49 if err != nil { 50 return nil, err 51 } 52 defer fileutils.RemoveTempDir(eggBase) 53 54 // Execute the egg_info command. 55 if err = exec.Command(pythonExecutablePath, setuppyFilePath, "egg_info", "--egg-base", eggBase).Run(); err != nil { 56 return nil, errorutils.CheckError(err) 57 } 58 59 // Read PKG_INFO under <eggBase>/*.egg-info/PKG-INFO. 60 return extractPackageNameFromEggBase(eggBase) 61 } 62 63 // Parse the output of 'python egg_info' command, in order to find the path of generated file 'PKG-INFO'. 64 func extractPackageNameFromEggBase(eggBase string) ([]byte, error) { 65 files, err := os.ReadDir(eggBase) 66 if errorutils.CheckError(err) != nil { 67 return nil, err 68 } 69 for _, file := range files { 70 if strings.HasSuffix(file.Name(), ".egg-info") { 71 pkginfoPath := filepath.Join(eggBase, file.Name(), "PKG-INFO") 72 // Read PKG-INFO file. 73 pkginfoFileExists, err := fileutils.IsFileExists(pkginfoPath, false) 74 if errorutils.CheckError(err) != nil { 75 return nil, err 76 } 77 if !pkginfoFileExists { 78 return nil, errorutils.CheckError(errors.New("File 'PKG-INFO' couldn't be found in its designated location: " + pkginfoPath)) 79 } 80 81 return os.ReadFile(pkginfoPath) 82 } 83 } 84 85 return nil, errorutils.CheckError(errors.New("couldn't find pkg info files")) 86 }