github.com/jfrog/jfrog-cli-core/v2@v2.51.0/artifactory/commands/utils/yarnutils.go (about) 1 package utils 2 3 import ( 4 "encoding/json" 5 ioutils "github.com/jfrog/gofrog/io" 6 "io" 7 "strconv" 8 "strings" 9 10 "github.com/jfrog/build-info-go/entities" 11 "github.com/jfrog/jfrog-cli-core/v2/common/build" 12 "github.com/jfrog/jfrog-cli-core/v2/common/format" 13 "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" 14 "github.com/jfrog/jfrog-client-go/artifactory" 15 "github.com/jfrog/jfrog-client-go/artifactory/services" 16 servicesUtils "github.com/jfrog/jfrog-client-go/artifactory/services/utils" 17 "github.com/jfrog/jfrog-client-go/utils/errorutils" 18 "github.com/jfrog/jfrog-client-go/utils/log" 19 ) 20 21 type aqlResult struct { 22 Results []*servicesUtils.ResultItem `json:"results,omitempty"` 23 } 24 25 func GetDependenciesFromLatestBuild(servicesManager artifactory.ArtifactoryServicesManager, buildName string) (map[string]*entities.Dependency, error) { 26 buildDependencies := make(map[string]*entities.Dependency) 27 previousBuild, found, err := servicesManager.GetBuildInfo(services.BuildInfoParams{BuildName: buildName, BuildNumber: servicesUtils.LatestBuildNumberKey}) 28 if err != nil || !found { 29 return buildDependencies, err 30 } 31 for _, module := range previousBuild.BuildInfo.Modules { 32 for _, dependency := range module.Dependencies { 33 buildDependencies[dependency.Id] = &entities.Dependency{Id: dependency.Id, Type: dependency.Type, 34 Checksum: entities.Checksum{Md5: dependency.Md5, Sha1: dependency.Sha1}} 35 } 36 } 37 return buildDependencies, nil 38 } 39 40 // Get dependency's checksum and type. 41 func getDependencyInfo(name, ver string, previousBuildDependencies map[string]*entities.Dependency, 42 servicesManager artifactory.ArtifactoryServicesManager) (checksum entities.Checksum, fileType string, err error) { 43 id := name + ":" + ver 44 if dep, ok := previousBuildDependencies[id]; ok { 45 // Get checksum from previous build. 46 checksum = dep.Checksum 47 fileType = dep.Type 48 return 49 } 50 51 // Get info from Artifactory. 52 log.Debug("Fetching checksums for", id) 53 var stream io.ReadCloser 54 stream, err = servicesManager.Aql(servicesUtils.CreateAqlQueryForYarn(name, ver)) 55 if err != nil { 56 return 57 } 58 defer ioutils.Close(stream, &err) 59 var result []byte 60 result, err = io.ReadAll(stream) 61 if err != nil { 62 return 63 } 64 parsedResult := new(aqlResult) 65 if err = json.Unmarshal(result, parsedResult); err != nil { 66 return entities.Checksum{}, "", errorutils.CheckError(err) 67 } 68 if len(parsedResult.Results) == 0 { 69 log.Debug(id, "could not be found in Artifactory.") 70 return 71 } 72 if i := strings.LastIndex(parsedResult.Results[0].Name, "."); i != -1 { 73 fileType = parsedResult.Results[0].Name[i+1:] 74 } 75 log.Debug(id, "was found in Artifactory. Name:", parsedResult.Results[0].Name, 76 "SHA-1:", parsedResult.Results[0].Actual_Sha1, 77 "MD5:", parsedResult.Results[0].Actual_Md5) 78 79 checksum = entities.Checksum{Sha1: parsedResult.Results[0].Actual_Sha1, Md5: parsedResult.Results[0].Actual_Md5, Sha256: parsedResult.Results[0].Sha256} 80 return 81 } 82 83 func ExtractYarnOptionsFromArgs(args []string) (threads int, detailedSummary, xrayScan bool, scanOutputFormat format.OutputFormat, cleanArgs []string, buildConfig *build.BuildConfiguration, err error) { 84 threads = 3 85 // Extract threads information from the args. 86 flagIndex, valueIndex, numOfThreads, err := coreutils.FindFlag("--threads", args) 87 if err != nil { 88 return 89 } 90 coreutils.RemoveFlagFromCommand(&args, flagIndex, valueIndex) 91 if numOfThreads != "" { 92 threads, err = strconv.Atoi(numOfThreads) 93 if err != nil { 94 err = errorutils.CheckError(err) 95 return 96 } 97 } 98 detailedSummary, xrayScan, scanOutputFormat, cleanArgs, buildConfig, err = ExtractNpmOptionsFromArgs(args) 99 return 100 } 101 102 func PrintMissingDependencies(missingDependencies []string) { 103 if len(missingDependencies) == 0 { 104 return 105 } 106 107 log.Warn(strings.Join(missingDependencies, "\n"), "\nThe npm dependencies above could not be found in Artifactory and therefore are not included in the build-info.\n"+ 108 "Deleting the local cache will force populating Artifactory with these dependencies.") 109 } 110 111 func CreateCollectChecksumsFunc(previousBuildDependencies map[string]*entities.Dependency, servicesManager artifactory.ArtifactoryServicesManager, missingDepsChan chan string) func(dependency *entities.Dependency) (bool, error) { 112 return func(dependency *entities.Dependency) (bool, error) { 113 splitDepId := strings.SplitN(dependency.Id, ":", 2) 114 name := splitDepId[0] 115 ver := splitDepId[1] 116 117 // Get dependency info. 118 checksum, fileType, err := getDependencyInfo(name, ver, previousBuildDependencies, servicesManager) 119 if err != nil || checksum.IsEmpty() { 120 missingDepsChan <- dependency.Id 121 return false, err 122 } 123 124 // Update dependency. 125 dependency.Type = fileType 126 dependency.Checksum = checksum 127 return true, nil 128 } 129 }