github.com/jfrog/frogbot@v1.1.1-0.20231221090046-821a26f50338/packagehandlers/yarnpackagehandler.go (about) 1 package packagehandlers 2 3 import ( 4 "errors" 5 "fmt" 6 biUtils "github.com/jfrog/build-info-go/build/utils" 7 "github.com/jfrog/frogbot/utils" 8 "github.com/jfrog/gofrog/version" 9 "github.com/jfrog/jfrog-client-go/utils/io/fileutils" 10 "github.com/jfrog/jfrog-client-go/utils/log" 11 ) 12 13 const ( 14 yarnV2Version = "2.0.0" 15 yarnV1PackageUpdateCmd = "upgrade" 16 yarnV2PackageUpdateCmd = "up" 17 modulesFolderFlag = "--modules-folder=" 18 ) 19 20 type YarnPackageHandler struct { 21 CommonPackageHandler 22 } 23 24 func (yarn *YarnPackageHandler) UpdateDependency(vulnDetails *utils.VulnerabilityDetails) error { 25 if vulnDetails.IsDirectDependency { 26 return yarn.updateDirectDependency(vulnDetails) 27 } else { 28 return &utils.ErrUnsupportedFix{ 29 PackageName: vulnDetails.ImpactedDependencyName, 30 FixedVersion: vulnDetails.SuggestedFixedVersion, 31 ErrorType: utils.IndirectDependencyFixNotSupported, 32 } 33 } 34 } 35 36 func (yarn *YarnPackageHandler) updateDirectDependency(vulnDetails *utils.VulnerabilityDetails) (err error) { 37 isYarn1, executableYarnVersion, err := isYarnV1Project() 38 if err != nil { 39 return 40 } 41 42 var installationCommand string 43 var extraArgs []string 44 45 if isYarn1 { 46 installationCommand = yarnV1PackageUpdateCmd 47 // This dir is created to store node_modules that are created during updating packages in Yarn V1. This dir is to be deleted and not pushed into the PR 48 var tmpNodeModulesDir string 49 tmpNodeModulesDir, err = fileutils.CreateTempDir() 50 defer func() { 51 err = errors.Join(err, fileutils.RemoveTempDir(tmpNodeModulesDir)) 52 }() 53 54 if err != nil { 55 return 56 } 57 extraArgs = append(extraArgs, modulesFolderFlag+tmpNodeModulesDir) 58 } else { 59 installationCommand = yarnV2PackageUpdateCmd 60 } 61 err = yarn.CommonPackageHandler.UpdateDependency(vulnDetails, installationCommand, extraArgs...) 62 if err != nil { 63 err = fmt.Errorf("running 'yarn %s for '%s' failed:\n%s\nHint: The Yarn version that was used is: %s. If your project was built with a different major version of Yarn, please configure your CI runner to include it", 64 installationCommand, 65 vulnDetails.ImpactedDependencyName, 66 err.Error(), 67 executableYarnVersion) 68 } 69 return 70 } 71 72 // isYarnV1Project gets the current executed yarn version and returns whether the current yarn version is V1 or not 73 func isYarnV1Project() (isYarn1 bool, executableYarnVersion string, err error) { 74 // NOTICE: in case your global yarn version is 1.x this function will always return true even if the project is originally in higher yarn version 75 executableYarnVersion, err = biUtils.GetVersion("yarn", "") 76 if err != nil { 77 return 78 } 79 log.Info("Using Yarn version: ", executableYarnVersion) 80 isYarn1 = version.NewVersion(executableYarnVersion).Compare(yarnV2Version) > 0 81 return 82 }