github.com/jfrog/jfrog-cli-core/v2@v2.51.0/artifactory/commands/mvn/mvn.go (about) 1 package mvn 2 3 import ( 4 "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/generic" 5 commandsutils "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/utils" 6 "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" 7 "github.com/jfrog/jfrog-cli-core/v2/common/build" 8 "github.com/jfrog/jfrog-cli-core/v2/common/format" 9 "github.com/jfrog/jfrog-cli-core/v2/common/project" 10 "github.com/jfrog/jfrog-cli-core/v2/utils/config" 11 "github.com/jfrog/jfrog-cli-core/v2/utils/ioutils" 12 mvnutils "github.com/jfrog/jfrog-cli-core/v2/utils/mvn" 13 "github.com/jfrog/jfrog-client-go/utils/errorutils" 14 "github.com/jfrog/jfrog-client-go/utils/io/fileutils" 15 "github.com/spf13/viper" 16 ) 17 18 type MvnCommand struct { 19 goals []string 20 configPath string 21 insecureTls bool 22 configuration *build.BuildConfiguration 23 serverDetails *config.ServerDetails 24 threads int 25 detailedSummary bool 26 xrayScan bool 27 scanOutputFormat format.OutputFormat 28 result *commandsutils.Result 29 deploymentDisabled bool 30 // File path for Maven extractor in which all build's artifacts details will be listed at the end of the build. 31 buildArtifactsDetailsFile string 32 } 33 34 func NewMvnCommand() *MvnCommand { 35 return &MvnCommand{} 36 } 37 38 func (mc *MvnCommand) SetServerDetails(serverDetails *config.ServerDetails) *MvnCommand { 39 mc.serverDetails = serverDetails 40 return mc 41 } 42 43 func (mc *MvnCommand) SetConfiguration(configuration *build.BuildConfiguration) *MvnCommand { 44 mc.configuration = configuration 45 return mc 46 } 47 48 func (mc *MvnCommand) SetConfigPath(configPath string) *MvnCommand { 49 mc.configPath = configPath 50 return mc 51 } 52 53 func (mc *MvnCommand) SetGoals(goals []string) *MvnCommand { 54 mc.goals = goals 55 return mc 56 } 57 58 func (mc *MvnCommand) SetThreads(threads int) *MvnCommand { 59 mc.threads = threads 60 return mc 61 } 62 63 func (mc *MvnCommand) SetInsecureTls(insecureTls bool) *MvnCommand { 64 mc.insecureTls = insecureTls 65 return mc 66 } 67 68 func (mc *MvnCommand) SetDetailedSummary(detailedSummary bool) *MvnCommand { 69 mc.detailedSummary = detailedSummary 70 return mc 71 } 72 73 func (mc *MvnCommand) IsDetailedSummary() bool { 74 return mc.detailedSummary 75 } 76 77 func (mc *MvnCommand) SetXrayScan(xrayScan bool) *MvnCommand { 78 mc.xrayScan = xrayScan 79 return mc 80 } 81 82 func (mc *MvnCommand) IsXrayScan() bool { 83 return mc.xrayScan 84 } 85 86 func (mc *MvnCommand) SetScanOutputFormat(format format.OutputFormat) *MvnCommand { 87 mc.scanOutputFormat = format 88 return mc 89 } 90 91 func (mc *MvnCommand) Result() *commandsutils.Result { 92 return mc.result 93 } 94 95 func (mc *MvnCommand) setResult(result *commandsutils.Result) *MvnCommand { 96 mc.result = result 97 return mc 98 } 99 100 func (mc *MvnCommand) init() (vConfig *viper.Viper, err error) { 101 // Read config 102 vConfig, err = build.ReadMavenConfig(mc.configPath, nil) 103 if err != nil { 104 return 105 } 106 if mc.IsXrayScan() && !vConfig.IsSet("deployer") { 107 err = errorutils.CheckErrorf("Conditional upload can only be performed if deployer is set in the config") 108 return 109 } 110 // Maven's extractor deploys build artifacts. This should be disabled since there is no intent to deploy anything or deploy upon Xray scan results. 111 mc.deploymentDisabled = mc.IsXrayScan() || !vConfig.IsSet("deployer") 112 if mc.shouldCreateBuildArtifactsFile() { 113 // Created a file that will contain all the details about the build's artifacts 114 tempFile, err := fileutils.CreateTempFile() 115 if err != nil { 116 return nil, err 117 } 118 // If this is a Windows machine there is a need to modify the path for the build info file to match Java syntax with double \\ 119 mc.buildArtifactsDetailsFile = ioutils.DoubleWinPathSeparator(tempFile.Name()) 120 if err = tempFile.Close(); errorutils.CheckError(err) != nil { 121 return nil, err 122 } 123 } 124 return 125 } 126 127 // Maven extractor generates the details of the build's artifacts. 128 // This is required for Xray scan and for the detailed summary. 129 // We can either scan or print the generated artifacts. 130 func (mc *MvnCommand) shouldCreateBuildArtifactsFile() bool { 131 return (mc.IsDetailedSummary() && !mc.deploymentDisabled) || mc.IsXrayScan() 132 } 133 134 func (mc *MvnCommand) Run() error { 135 vConfig, err := mc.init() 136 if err != nil { 137 return err 138 } 139 140 mvnParams := mvnutils.NewMvnUtils(). 141 SetConfig(vConfig). 142 SetBuildArtifactsDetailsFile(mc.buildArtifactsDetailsFile). 143 SetBuildConf(mc.configuration). 144 SetGoals(mc.goals). 145 SetInsecureTls(mc.insecureTls). 146 SetDisableDeploy(mc.deploymentDisabled). 147 SetThreads(mc.threads) 148 if err = mvnutils.RunMvn(mvnParams); err != nil { 149 return err 150 } 151 152 if mc.buildArtifactsDetailsFile == "" { 153 return nil 154 } 155 156 if err = mc.unmarshalDeployableArtifacts(mc.buildArtifactsDetailsFile); err != nil { 157 return err 158 } 159 if mc.IsXrayScan() { 160 return mc.conditionalUpload() 161 } 162 return nil 163 } 164 165 // Returns the ServerDetails. The information returns from the config file provided. 166 func (mc *MvnCommand) ServerDetails() (*config.ServerDetails, error) { 167 // Get the serverDetails from the config file. 168 if mc.serverDetails == nil { 169 vConfig, err := project.ReadConfigFile(mc.configPath, project.YAML) 170 if err != nil { 171 return nil, err 172 } 173 mc.serverDetails, err = build.GetServerDetails(vConfig) 174 if err != nil { 175 return nil, err 176 } 177 } 178 return mc.serverDetails, nil 179 } 180 181 func (mc *MvnCommand) unmarshalDeployableArtifacts(filesPath string) error { 182 result, err := commandsutils.UnmarshalDeployableArtifacts(filesPath, mc.configPath, mc.IsXrayScan()) 183 if err != nil { 184 return err 185 } 186 mc.setResult(result) 187 return nil 188 } 189 190 func (mc *MvnCommand) CommandName() string { 191 return "rt_maven" 192 } 193 194 // ConditionalUpload will scan the artifact using Xray and will upload them only if the scan passes with no 195 // violation. 196 func (mc *MvnCommand) conditionalUpload() error { 197 // Initialize the server details (from config) if it hasn't been initialized yet. 198 _, err := mc.ServerDetails() 199 if err != nil { 200 return err 201 } 202 binariesSpecFile, pomSpecFile, err := commandsutils.ScanDeployableArtifacts(mc.result, mc.serverDetails, mc.threads, mc.scanOutputFormat) 203 // If the detailed summary wasn't requested, the reader should be closed here. 204 // (otherwise it will be closed by the detailed summary print method) 205 if !mc.IsDetailedSummary() { 206 e := mc.result.Reader().Close() 207 if e != nil { 208 return e 209 } 210 } else { 211 mc.result.Reader().Reset() 212 } 213 if err != nil { 214 return err 215 } 216 // The case scan failed 217 if binariesSpecFile == nil { 218 return nil 219 } 220 // First upload binaries 221 if len(binariesSpecFile.Files) > 0 { 222 uploadCmd := generic.NewUploadCommand() 223 uploadConfiguration := new(utils.UploadConfiguration) 224 uploadConfiguration.Threads = mc.threads 225 uploadCmd.SetUploadConfiguration(uploadConfiguration).SetBuildConfiguration(mc.configuration).SetSpec(binariesSpecFile).SetServerDetails(mc.serverDetails) 226 err = uploadCmd.Run() 227 if err != nil { 228 return err 229 } 230 } 231 if len(pomSpecFile.Files) > 0 { 232 // Then Upload pom.xml's 233 uploadCmd := generic.NewUploadCommand() 234 uploadConfiguration := new(utils.UploadConfiguration) 235 uploadConfiguration.Threads = mc.threads 236 uploadCmd.SetUploadConfiguration(uploadConfiguration).SetBuildConfiguration(mc.configuration).SetSpec(pomSpecFile).SetServerDetails(mc.serverDetails) 237 err = uploadCmd.Run() 238 } 239 return err 240 }