You've already forked sap-jenkins-library
							
							
				mirror of
				https://github.com/SAP/jenkins-library.git
				synced 2025-10-30 23:57:50 +02:00 
			
		
		
		
	Refactor maven utils and add tests for install artifacts (#2318)
Co-authored-by: Stephan Aßmus <stephan.assmus@sap.com>
This commit is contained in:
		| @@ -3,6 +3,10 @@ package cmd | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	piperhttp "github.com/SAP/jenkins-library/pkg/http" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
| 	"io" | ||||
| 	netHttp "net/http" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 	"text/template" | ||||
| @@ -42,11 +46,38 @@ func getGitWorktree(repository gitRepository) (gitWorktree, error) { | ||||
| 	return repository.Worktree() | ||||
| } | ||||
|  | ||||
| type artifactPrepareVersionUtils interface { | ||||
| 	Stdout(out io.Writer) | ||||
| 	Stderr(err io.Writer) | ||||
| 	RunExecutable(e string, p ...string) error | ||||
|  | ||||
| 	DownloadFile(url, filename string, header netHttp.Header, cookies []*netHttp.Cookie) error | ||||
|  | ||||
| 	Glob(pattern string) (matches []string, err error) | ||||
| 	FileExists(filename string) (bool, error) | ||||
| 	Copy(src, dest string) (int64, error) | ||||
| 	MkdirAll(path string, perm os.FileMode) error | ||||
| } | ||||
|  | ||||
| type artifactPrepareVersionUtilsBundle struct { | ||||
| 	*command.Command | ||||
| 	*piperutils.Files | ||||
| 	*piperhttp.Client | ||||
| } | ||||
|  | ||||
| func newArtifactPrepareVersionUtilsBundle() artifactPrepareVersionUtils { | ||||
| 	utils := artifactPrepareVersionUtilsBundle{ | ||||
| 		Command: &command.Command{}, | ||||
| 		Files:   &piperutils.Files{}, | ||||
| 		Client:  &piperhttp.Client{}, | ||||
| 	} | ||||
| 	utils.Stdout(log.Writer()) | ||||
| 	utils.Stderr(log.Writer()) | ||||
| 	return &utils | ||||
| } | ||||
|  | ||||
| func artifactPrepareVersion(config artifactPrepareVersionOptions, telemetryData *telemetry.CustomData, commonPipelineEnvironment *artifactPrepareVersionCommonPipelineEnvironment) { | ||||
| 	c := command.Command{} | ||||
| 	// reroute command output to logging framework | ||||
| 	c.Stdout(log.Writer()) | ||||
| 	c.Stderr(log.Writer()) | ||||
| 	utils := newArtifactPrepareVersionUtilsBundle() | ||||
|  | ||||
| 	// open local .git repository | ||||
| 	repository, err := openGit() | ||||
| @@ -54,7 +85,7 @@ func artifactPrepareVersion(config artifactPrepareVersionOptions, telemetryData | ||||
| 		log.Entry().WithError(err).Fatal("git repository required - none available") | ||||
| 	} | ||||
|  | ||||
| 	err = runArtifactPrepareVersion(&config, telemetryData, commonPipelineEnvironment, nil, &c, repository, getGitWorktree) | ||||
| 	err = runArtifactPrepareVersion(&config, telemetryData, commonPipelineEnvironment, nil, utils, repository, getGitWorktree) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("artifactPrepareVersion failed") | ||||
| 	} | ||||
| @@ -62,7 +93,7 @@ func artifactPrepareVersion(config artifactPrepareVersionOptions, telemetryData | ||||
|  | ||||
| var sshAgentAuth = ssh.NewSSHAgentAuth | ||||
|  | ||||
| func runArtifactPrepareVersion(config *artifactPrepareVersionOptions, telemetryData *telemetry.CustomData, commonPipelineEnvironment *artifactPrepareVersionCommonPipelineEnvironment, artifact versioning.Artifact, runner command.ExecRunner, repository gitRepository, getWorktree func(gitRepository) (gitWorktree, error)) error { | ||||
| func runArtifactPrepareVersion(config *artifactPrepareVersionOptions, telemetryData *telemetry.CustomData, commonPipelineEnvironment *artifactPrepareVersionCommonPipelineEnvironment, artifact versioning.Artifact, utils artifactPrepareVersionUtils, repository gitRepository, getWorktree func(gitRepository) (gitWorktree, error)) error { | ||||
|  | ||||
| 	telemetryData.Custom1Label = "buildTool" | ||||
| 	telemetryData.Custom1 = config.BuildTool | ||||
| @@ -82,7 +113,7 @@ func runArtifactPrepareVersion(config *artifactPrepareVersionOptions, telemetryD | ||||
|  | ||||
| 	var err error | ||||
| 	if artifact == nil { | ||||
| 		artifact, err = versioning.GetArtifact(config.BuildTool, config.FilePath, &artifactOpts, runner) | ||||
| 		artifact, err = versioning.GetArtifact(config.BuildTool, config.FilePath, &artifactOpts, utils) | ||||
| 		if err != nil { | ||||
| 			log.SetErrorCategory(log.ErrorConfiguration) | ||||
| 			return errors.Wrap(err, "failed to retrieve artifact") | ||||
|   | ||||
| @@ -95,11 +95,11 @@ func runDetect(config detectExecuteScanOptions, utils detectUtils) error { | ||||
| 	} | ||||
|  | ||||
| 	if config.InstallArtifacts { | ||||
| 		err := maven.InstallMavenArtifacts(utils, &maven.EvaluateOptions{ | ||||
| 		err := maven.InstallMavenArtifacts(&maven.EvaluateOptions{ | ||||
| 			M2Path:              config.M2Path, | ||||
| 			ProjectSettingsFile: config.ProjectSettingsFile, | ||||
| 			GlobalSettingsFile:  config.GlobalSettingsFile, | ||||
| 		}) | ||||
| 		}, utils) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -163,7 +163,7 @@ func addDetectArgs(args []string, config detectExecuteScanOptions, utils detectU | ||||
| 		args = append(args, fmt.Sprintf("--detect.source.path=%v", config.ScanPaths[0])) | ||||
| 	} | ||||
|  | ||||
| 	mavenArgs, err := maven.DownloadAndGetMavenParameters(config.GlobalSettingsFile, config.ProjectSettingsFile, utils, utils) | ||||
| 	mavenArgs, err := maven.DownloadAndGetMavenParameters(config.GlobalSettingsFile, config.ProjectSettingsFile, utils) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -5,7 +5,7 @@ import ( | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	piperhttp "github.com/SAP/jenkins-library/pkg/http" | ||||
| 	"io/ioutil" | ||||
| 	"math" | ||||
| 	"os" | ||||
| @@ -37,11 +37,35 @@ type pullRequestService interface { | ||||
| 	ListPullRequestsWithCommit(ctx context.Context, owner, repo, sha string, opts *github.PullRequestListOptions) ([]*github.PullRequest, *github.Response, error) | ||||
| } | ||||
|  | ||||
| type fortifyExecRunner interface { | ||||
| 	Stdout(out io.Writer) | ||||
| 	Stderr(err io.Writer) | ||||
| type fortifyUtils interface { | ||||
| 	maven.Utils | ||||
|  | ||||
| 	SetDir(d string) | ||||
| 	RunExecutable(e string, p ...string) error | ||||
|  | ||||
| 	GetArtifact(buildTool, buildDescriptorFile string, | ||||
| 		options *versioning.Options) (versioning.Artifact, error) | ||||
| } | ||||
|  | ||||
| type fortifyUtilsBundle struct { | ||||
| 	*command.Command | ||||
| 	*piperutils.Files | ||||
| 	*piperhttp.Client | ||||
| } | ||||
|  | ||||
| func (bundle *fortifyUtilsBundle) GetArtifact(buildTool, buildDescriptorFile string, | ||||
| 	options *versioning.Options) (versioning.Artifact, error) { | ||||
| 	return versioning.GetArtifact(buildTool, buildDescriptorFile, options, bundle) | ||||
| } | ||||
|  | ||||
| func newFortifyUtilsBundleBundle() fortifyUtils { | ||||
| 	utils := fortifyUtilsBundle{ | ||||
| 		Command: &command.Command{}, | ||||
| 		Files:   &piperutils.Files{}, | ||||
| 		Client:  &piperhttp.Client{}, | ||||
| 	} | ||||
| 	utils.Stdout(log.Writer()) | ||||
| 	utils.Stderr(log.Writer()) | ||||
| 	return &utils | ||||
| } | ||||
|  | ||||
| const checkString = "<---CHECK FORTIFY---" | ||||
| @@ -50,40 +74,37 @@ const classpathFileName = "fortify-execute-scan-cp.txt" | ||||
| func fortifyExecuteScan(config fortifyExecuteScanOptions, telemetryData *telemetry.CustomData, influx *fortifyExecuteScanInflux) { | ||||
| 	auditStatus := map[string]string{} | ||||
| 	sys := fortify.NewSystemInstance(config.ServerURL, config.APIEndpoint, config.AuthToken, time.Minute*15) | ||||
| 	c := &command.Command{} | ||||
| 	// reroute command output to logging framework | ||||
| 	c.Stdout(log.Entry().Writer()) | ||||
| 	c.Stderr(log.Entry().Writer()) | ||||
| 	utils := newFortifyUtilsBundleBundle() | ||||
|  | ||||
| 	artifact, err := determineArtifact(config, c) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Fatal() | ||||
| 	} | ||||
|  | ||||
| 	reports, err := runFortifyScan(config, sys, c, artifact, telemetryData, influx, auditStatus) | ||||
| 	reports, err := runFortifyScan(config, sys, utils, telemetryData, influx, auditStatus) | ||||
| 	piperutils.PersistReportsAndLinks("fortifyExecuteScan", config.ModulePath, reports, nil) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("Fortify scan and check failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func determineArtifact(config fortifyExecuteScanOptions, c *command.Command) (versioning.Artifact, error) { | ||||
| func determineArtifact(config fortifyExecuteScanOptions, utils fortifyUtils) (versioning.Artifact, error) { | ||||
| 	versioningOptions := versioning.Options{ | ||||
| 		M2Path:              config.M2Path, | ||||
| 		GlobalSettingsFile:  config.GlobalSettingsFile, | ||||
| 		ProjectSettingsFile: config.ProjectSettingsFile, | ||||
| 	} | ||||
|  | ||||
| 	artifact, err := versioning.GetArtifact(config.BuildTool, config.BuildDescriptorFile, &versioningOptions, c) | ||||
| 	artifact, err := utils.GetArtifact(config.BuildTool, config.BuildDescriptorFile, &versioningOptions) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("Unable to get artifact from descriptor %v: %w", config.BuildDescriptorFile, err) | ||||
| 	} | ||||
| 	return artifact, nil | ||||
| } | ||||
|  | ||||
| func runFortifyScan(config fortifyExecuteScanOptions, sys fortify.System, command fortifyExecRunner, artifact versioning.Artifact, telemetryData *telemetry.CustomData, influx *fortifyExecuteScanInflux, auditStatus map[string]string) ([]piperutils.Path, error) { | ||||
| func runFortifyScan(config fortifyExecuteScanOptions, sys fortify.System, utils fortifyUtils, telemetryData *telemetry.CustomData, influx *fortifyExecuteScanInflux, auditStatus map[string]string) ([]piperutils.Path, error) { | ||||
| 	var reports []piperutils.Path | ||||
| 	log.Entry().Debugf("Running Fortify scan against SSC at %v", config.ServerURL) | ||||
|  | ||||
| 	artifact, err := determineArtifact(config, utils) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Fatal() | ||||
| 	} | ||||
| 	coordinates, err := artifact.GetCoordinates() | ||||
| 	if err != nil { | ||||
| 		return reports, fmt.Errorf("unable to get project coordinates from descriptor %v: %w", config.BuildDescriptorFile, err) | ||||
| @@ -133,21 +154,21 @@ func runFortifyScan(config fortifyExecuteScanOptions, sys fortify.System, comman | ||||
|  | ||||
| 	// Create sourceanalyzer command based on configuration | ||||
| 	buildID := uuid.New().String() | ||||
| 	command.SetDir(config.ModulePath) | ||||
| 	utils.SetDir(config.ModulePath) | ||||
| 	os.MkdirAll(fmt.Sprintf("%v/%v", config.ModulePath, "target"), os.ModePerm) | ||||
|  | ||||
| 	if config.UpdateRulePack { | ||||
| 		err := command.RunExecutable("fortifyupdate", "-acceptKey", "-acceptSSLCertificate", "-url", config.ServerURL) | ||||
| 		err := utils.RunExecutable("fortifyupdate", "-acceptKey", "-acceptSSLCertificate", "-url", config.ServerURL) | ||||
| 		if err != nil { | ||||
| 			log.Entry().WithError(err).WithField("serverUrl", config.ServerURL).Fatal("Failed to update rule pack") | ||||
| 		} | ||||
| 		err = command.RunExecutable("fortifyupdate", "-acceptKey", "-acceptSSLCertificate", "-showInstalledRules") | ||||
| 		err = utils.RunExecutable("fortifyupdate", "-acceptKey", "-acceptSSLCertificate", "-showInstalledRules") | ||||
| 		if err != nil { | ||||
| 			log.Entry().WithError(err).WithField("serverUrl", config.ServerURL).Fatal("Failed to fetch details of installed rule pack") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	triggerFortifyScan(config, command, buildID, buildLabel, fortifyProjectName) | ||||
| 	triggerFortifyScan(config, utils, buildID, buildLabel, fortifyProjectName) | ||||
|  | ||||
| 	reports = append(reports, piperutils.Path{Target: fmt.Sprintf("%vtarget/fortify-scan.*", config.ModulePath)}) | ||||
| 	reports = append(reports, piperutils.Path{Target: fmt.Sprintf("%vtarget/*.fpr", config.ModulePath)}) | ||||
| @@ -161,7 +182,7 @@ func runFortifyScan(config fortifyExecuteScanOptions, sys fortify.System, comman | ||||
| 	} else { | ||||
| 		log.Entry().Debug("Generating XML report") | ||||
| 		xmlReportName := "fortify_result.xml" | ||||
| 		err = command.RunExecutable("ReportGenerator", "-format", "xml", "-f", xmlReportName, "-source", fmt.Sprintf("%vtarget/result.fpr", config.ModulePath)) | ||||
| 		err = utils.RunExecutable("ReportGenerator", "-format", "xml", "-f", xmlReportName, "-source", fmt.Sprintf("%vtarget/result.fpr", config.ModulePath)) | ||||
| 		message = fmt.Sprintf("Failed to generate XML report %v", xmlReportName) | ||||
| 		if err != nil { | ||||
| 			reports = append(reports, piperutils.Path{Target: fmt.Sprintf("%vfortify_result.xml", config.ModulePath)}) | ||||
| @@ -493,7 +514,7 @@ func calculateTimeDifferenceToLastUpload(uploadDate models.Iso8601MilliDateTime, | ||||
| 	return absoluteSeconds | ||||
| } | ||||
|  | ||||
| func executeTemplatedCommand(command fortifyExecRunner, cmdTemplate []string, context map[string]string) { | ||||
| func executeTemplatedCommand(utils fortifyUtils, cmdTemplate []string, context map[string]string) { | ||||
| 	for index, cmdTemplatePart := range cmdTemplate { | ||||
| 		result, err := piperutils.ExecuteTemplate(cmdTemplatePart, context) | ||||
| 		if err != nil { | ||||
| @@ -501,29 +522,29 @@ func executeTemplatedCommand(command fortifyExecRunner, cmdTemplate []string, co | ||||
| 		} | ||||
| 		cmdTemplate[index] = result | ||||
| 	} | ||||
| 	err := command.RunExecutable(cmdTemplate[0], cmdTemplate[1:]...) | ||||
| 	err := utils.RunExecutable(cmdTemplate[0], cmdTemplate[1:]...) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).WithField("command", cmdTemplate).Fatal("Failed to execute command") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func autoresolvePipClasspath(executable string, parameters []string, file string, command fortifyExecRunner) string { | ||||
| func autoresolvePipClasspath(executable string, parameters []string, file string, utils fortifyUtils) string { | ||||
| 	// redirect stdout and create cp file from command output | ||||
| 	outfile, err := os.Create(file) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("Failed to create classpath file") | ||||
| 	} | ||||
| 	defer outfile.Close() | ||||
| 	command.Stdout(outfile) | ||||
| 	err = command.RunExecutable(executable, parameters...) | ||||
| 	utils.Stdout(outfile) | ||||
| 	err = utils.RunExecutable(executable, parameters...) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).WithField("command", fmt.Sprintf("%v with parameters %v", executable, parameters)).Fatal("Failed to run classpath autodetection command") | ||||
| 	} | ||||
| 	command.Stdout(log.Entry().Writer()) | ||||
| 	utils.Stdout(log.Entry().Writer()) | ||||
| 	return readClasspathFile(file) | ||||
| } | ||||
|  | ||||
| func autoresolveMavenClasspath(config fortifyExecuteScanOptions, file string, command fortifyExecRunner) string { | ||||
| func autoresolveMavenClasspath(config fortifyExecuteScanOptions, file string, utils fortifyUtils) string { | ||||
| 	if filepath.IsAbs(file) { | ||||
| 		log.Entry().Warnf("Passing an absolute path for -Dmdep.outputFile results in the classpath only for the last module in multi-module maven projects.") | ||||
| 	} | ||||
| @@ -536,7 +557,7 @@ func autoresolveMavenClasspath(config fortifyExecuteScanOptions, file string, co | ||||
| 		Defines:             []string{fmt.Sprintf("-Dmdep.outputFile=%v", file), "-DincludeScope=compile"}, | ||||
| 		ReturnStdout:        false, | ||||
| 	} | ||||
| 	_, err := maven.Execute(&executeOptions, command) | ||||
| 	_, err := maven.Execute(&executeOptions, utils) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Warn("failed to determine classpath using Maven") | ||||
| 	} | ||||
| @@ -598,7 +619,7 @@ func removeDuplicates(contents, separator string) string { | ||||
| 	return contents | ||||
| } | ||||
|  | ||||
| func triggerFortifyScan(config fortifyExecuteScanOptions, command fortifyExecRunner, buildID, buildLabel, buildProject string) { | ||||
| func triggerFortifyScan(config fortifyExecuteScanOptions, utils fortifyUtils, buildID, buildLabel, buildProject string) { | ||||
| 	var err error = nil | ||||
| 	// Do special Python related prep | ||||
| 	pipVersion := "pip3" | ||||
| @@ -609,7 +630,7 @@ func triggerFortifyScan(config fortifyExecuteScanOptions, command fortifyExecRun | ||||
| 	classpath := "" | ||||
| 	if config.BuildTool == "maven" { | ||||
| 		if config.AutodetectClasspath { | ||||
| 			classpath = autoresolveMavenClasspath(config, classpathFileName, command) | ||||
| 			classpath = autoresolveMavenClasspath(config, classpathFileName, utils) | ||||
| 		} | ||||
| 		config.Translate, err = populateMavenTranslate(&config, classpath) | ||||
| 		if err != nil { | ||||
| @@ -620,17 +641,17 @@ func triggerFortifyScan(config fortifyExecuteScanOptions, command fortifyExecRun | ||||
| 		if config.AutodetectClasspath { | ||||
| 			separator := getSeparator() | ||||
| 			script := fmt.Sprintf("import sys;p=sys.path;p.remove('');print('%v'.join(p))", separator) | ||||
| 			classpath = autoresolvePipClasspath(config.PythonVersion, []string{"-c", script}, classpathFileName, command) | ||||
| 			classpath = autoresolvePipClasspath(config.PythonVersion, []string{"-c", script}, classpathFileName, utils) | ||||
| 		} | ||||
| 		// install the dev dependencies | ||||
| 		if len(config.PythonRequirementsFile) > 0 { | ||||
| 			context := map[string]string{} | ||||
| 			cmdTemplate := []string{pipVersion, "install", "--user", "-r", config.PythonRequirementsFile} | ||||
| 			cmdTemplate = append(cmdTemplate, tokenize(config.PythonRequirementsInstallSuffix)...) | ||||
| 			executeTemplatedCommand(command, cmdTemplate, context) | ||||
| 			executeTemplatedCommand(utils, cmdTemplate, context) | ||||
| 		} | ||||
|  | ||||
| 		executeTemplatedCommand(command, tokenize(config.PythonInstallCommand), map[string]string{"Pip": pipVersion}) | ||||
| 		executeTemplatedCommand(utils, tokenize(config.PythonInstallCommand), map[string]string{"Pip": pipVersion}) | ||||
|  | ||||
| 		config.Translate, err = populatePipTranslate(&config, classpath) | ||||
| 		if err != nil { | ||||
| @@ -639,9 +660,9 @@ func triggerFortifyScan(config fortifyExecuteScanOptions, command fortifyExecRun | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	translateProject(&config, command, buildID, classpath) | ||||
| 	translateProject(&config, utils, buildID, classpath) | ||||
|  | ||||
| 	scanProject(&config, command, buildID, buildLabel, buildProject) | ||||
| 	scanProject(&config, utils, buildID, buildLabel, buildProject) | ||||
| } | ||||
|  | ||||
| func populatePipTranslate(config *fortifyExecuteScanOptions, classpath string) (string, error) { | ||||
| @@ -685,7 +706,7 @@ func populateMavenTranslate(config *fortifyExecuteScanOptions, classpath string) | ||||
| 	return string(translateJSON), err | ||||
| } | ||||
|  | ||||
| func translateProject(config *fortifyExecuteScanOptions, command fortifyExecRunner, buildID, classpath string) { | ||||
| func translateProject(config *fortifyExecuteScanOptions, utils fortifyUtils, buildID, classpath string) { | ||||
| 	var translateList []map[string]string | ||||
| 	json.Unmarshal([]byte(config.Translate), &translateList) | ||||
| 	log.Entry().Debugf("Translating with options: %v", translateList) | ||||
| @@ -693,11 +714,11 @@ func translateProject(config *fortifyExecuteScanOptions, command fortifyExecRunn | ||||
| 		if len(classpath) > 0 { | ||||
| 			translate["autoClasspath"] = classpath | ||||
| 		} | ||||
| 		handleSingleTranslate(config, command, buildID, translate) | ||||
| 		handleSingleTranslate(config, utils, buildID, translate) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func handleSingleTranslate(config *fortifyExecuteScanOptions, command fortifyExecRunner, buildID string, t map[string]string) { | ||||
| func handleSingleTranslate(config *fortifyExecuteScanOptions, command fortifyUtils, buildID string, t map[string]string) { | ||||
| 	if t != nil { | ||||
| 		log.Entry().Debugf("Handling translate config %v", t) | ||||
| 		translateOptions := []string{ | ||||
| @@ -718,7 +739,7 @@ func handleSingleTranslate(config *fortifyExecuteScanOptions, command fortifyExe | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func scanProject(config *fortifyExecuteScanOptions, command fortifyExecRunner, buildID, buildLabel, buildProject string) { | ||||
| func scanProject(config *fortifyExecuteScanOptions, command fortifyUtils, buildID, buildLabel, buildProject string) { | ||||
| 	var scanOptions = []string{ | ||||
| 		"-verbose", | ||||
| 		"-64", | ||||
|   | ||||
| @@ -5,15 +5,16 @@ import ( | ||||
| 	"context" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"github.com/SAP/jenkins-library/pkg/mock" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/command" | ||||
| 	"github.com/SAP/jenkins-library/pkg/fortify" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/versioning" | ||||
| @@ -24,6 +25,31 @@ import ( | ||||
| 	"github.com/piper-validation/fortify-client-go/models" | ||||
| ) | ||||
|  | ||||
| type fortifyTestUtilsBundle struct { | ||||
| 	*execRunnerMock | ||||
| 	*mock.FilesMock | ||||
| 	getArtifactShouldFail bool | ||||
| } | ||||
|  | ||||
| func (f fortifyTestUtilsBundle) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error { | ||||
| 	panic("not expected to be called in tests") | ||||
| } | ||||
|  | ||||
| func (f fortifyTestUtilsBundle) GetArtifact(buildTool, buildDescriptorFile string, options *versioning.Options) (versioning.Artifact, error) { | ||||
| 	if f.getArtifactShouldFail { | ||||
| 		return nil, fmt.Errorf("build tool '%v' not supported", buildTool) | ||||
| 	} | ||||
| 	return artifactMock{Coordinates: newCoordinatesMock()}, nil | ||||
| } | ||||
|  | ||||
| func newFortifyTestUtilsBundle() fortifyTestUtilsBundle { | ||||
| 	utilsBundle := fortifyTestUtilsBundle{ | ||||
| 		execRunnerMock: &execRunnerMock{}, | ||||
| 		FilesMock:      &mock.FilesMock{}, | ||||
| 	} | ||||
| 	return utilsBundle | ||||
| } | ||||
|  | ||||
| type artifactMock struct { | ||||
| 	Coordinates coordinatesMock | ||||
| } | ||||
| @@ -325,27 +351,14 @@ func (er *execRunnerMock) RunExecutable(e string, p ...string) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func TestParametersAreValidated(t *testing.T) { | ||||
| 	type parameterTestData struct { | ||||
| 		nameOfRun     string | ||||
| 		config        fortifyExecuteScanOptions | ||||
| 		expectedError string | ||||
| 	} | ||||
| func TestDetermineArtifact(t *testing.T) { | ||||
| 	t.Run("Cannot get artifact without build tool", func(t *testing.T) { | ||||
| 		utilsMock := newFortifyTestUtilsBundle() | ||||
| 		utilsMock.getArtifactShouldFail = true | ||||
|  | ||||
| 	testData := []parameterTestData{ | ||||
| 		{ | ||||
| 			nameOfRun:     "all parameters empty", | ||||
| 			config:        fortifyExecuteScanOptions{}, | ||||
| 			expectedError: "Unable to get artifact from descriptor : build tool '' not supported", | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for _, data := range testData { | ||||
| 		t.Run(data.nameOfRun, func(t *testing.T) { | ||||
| 			_, err := determineArtifact(data.config, &command.Command{}) | ||||
| 			assert.EqualError(t, err, data.expectedError) | ||||
| 		}) | ||||
| 	} | ||||
| 		_, err := determineArtifact(fortifyExecuteScanOptions{}, utilsMock) | ||||
| 		assert.EqualError(t, err, "Unable to get artifact from descriptor : build tool '' not supported") | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func TestExecutions(t *testing.T) { | ||||
| @@ -374,11 +387,10 @@ func TestExecutions(t *testing.T) { | ||||
| 	for _, data := range testData { | ||||
| 		t.Run(data.nameOfRun, func(t *testing.T) { | ||||
| 			ff := fortifyMock{} | ||||
| 			runner := &execRunnerMock{} | ||||
| 			artMock := artifactMock{Coordinates: newCoordinatesMock()} | ||||
| 			utils := newFortifyTestUtilsBundle() | ||||
| 			influx := fortifyExecuteScanInflux{} | ||||
| 			auditStatus := map[string]string{} | ||||
| 			reports, _ := runFortifyScan(data.config, &ff, runner, artMock, nil, &influx, auditStatus) | ||||
| 			reports, _ := runFortifyScan(data.config, &ff, utils, nil, &influx, auditStatus) | ||||
| 			if len(data.expectedReports) != data.expectedReportsLength { | ||||
| 				assert.Fail(t, fmt.Sprintf("Wrong number of reports detected, expected %v, actual %v", data.expectedReportsLength, len(data.expectedReports))) | ||||
| 			} | ||||
| @@ -500,25 +512,25 @@ func TestTriggerFortifyScan(t *testing.T) { | ||||
| 			_ = os.RemoveAll(dir) | ||||
| 		}() | ||||
|  | ||||
| 		runner := execRunnerMock{} | ||||
| 		utils := newFortifyTestUtilsBundle() | ||||
| 		config := fortifyExecuteScanOptions{ | ||||
| 			BuildTool:           "maven", | ||||
| 			AutodetectClasspath: true, | ||||
| 			BuildDescriptorFile: "./pom.xml", | ||||
| 			Memory:              "-Xmx4G -Xms2G", | ||||
| 			Src:                 []string{"**/*.xml", "**/*.html", "**/*.jsp", "**/*.js", "src/main/resources/**/*", "src/main/java/**/*"}} | ||||
| 		triggerFortifyScan(config, &runner, "test", "testLabel", "my.group-myartifact") | ||||
| 		triggerFortifyScan(config, &utils, "test", "testLabel", "my.group-myartifact") | ||||
|  | ||||
| 		assert.Equal(t, 3, runner.numExecutions) | ||||
| 		assert.Equal(t, 3, utils.numExecutions) | ||||
|  | ||||
| 		assert.Equal(t, "mvn", runner.executions[0].executable) | ||||
| 		assert.Equal(t, []string{"--file", "./pom.xml", "-Dmdep.outputFile=fortify-execute-scan-cp.txt", "-DincludeScope=compile", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "dependency:build-classpath"}, runner.executions[0].parameters) | ||||
| 		assert.Equal(t, "mvn", utils.executions[0].executable) | ||||
| 		assert.Equal(t, []string{"--file", "./pom.xml", "-Dmdep.outputFile=fortify-execute-scan-cp.txt", "-DincludeScope=compile", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "dependency:build-classpath"}, utils.executions[0].parameters) | ||||
|  | ||||
| 		assert.Equal(t, "sourceanalyzer", runner.executions[1].executable) | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "test", "-Xmx4G", "-Xms2G", "-cp", "some.jar;someother.jar", "**/*.xml", "**/*.html", "**/*.jsp", "**/*.js", "src/main/resources/**/*", "src/main/java/**/*"}, runner.executions[1].parameters) | ||||
| 		assert.Equal(t, "sourceanalyzer", utils.executions[1].executable) | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "test", "-Xmx4G", "-Xms2G", "-cp", "some.jar;someother.jar", "**/*.xml", "**/*.html", "**/*.jsp", "**/*.js", "src/main/resources/**/*", "src/main/java/**/*"}, utils.executions[1].parameters) | ||||
|  | ||||
| 		assert.Equal(t, "sourceanalyzer", runner.executions[2].executable) | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "test", "-scan", "-Xmx4G", "-Xms2G", "-build-label", "testLabel", "-build-project", "my.group-myartifact", "-logfile", "target/fortify-scan.log", "-f", "target/result.fpr"}, runner.executions[2].parameters) | ||||
| 		assert.Equal(t, "sourceanalyzer", utils.executions[2].executable) | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "test", "-scan", "-Xmx4G", "-Xms2G", "-build-label", "testLabel", "-build-project", "my.group-myartifact", "-logfile", "target/fortify-scan.log", "-f", "target/result.fpr"}, utils.executions[2].parameters) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("pip", func(t *testing.T) { | ||||
| @@ -534,28 +546,28 @@ func TestTriggerFortifyScan(t *testing.T) { | ||||
| 			_ = os.RemoveAll(dir) | ||||
| 		}() | ||||
|  | ||||
| 		runner := execRunnerMock{} | ||||
| 		utils := newFortifyTestUtilsBundle() | ||||
| 		config := fortifyExecuteScanOptions{BuildTool: "pip", PythonVersion: "python2", AutodetectClasspath: true, BuildDescriptorFile: "./setup.py", PythonRequirementsFile: "./requirements.txt", PythonInstallCommand: "pip2 install --user", Memory: "-Xmx4G -Xms2G"} | ||||
| 		triggerFortifyScan(config, &runner, "test", "testLabel", "") | ||||
| 		triggerFortifyScan(config, &utils, "test", "testLabel", "") | ||||
|  | ||||
| 		assert.Equal(t, 5, runner.numExecutions) | ||||
| 		assert.Equal(t, 5, utils.numExecutions) | ||||
|  | ||||
| 		assert.Equal(t, "python2", runner.executions[0].executable) | ||||
| 		assert.Equal(t, "python2", utils.executions[0].executable) | ||||
| 		separator := getSeparator() | ||||
| 		template := fmt.Sprintf("import sys;p=sys.path;p.remove('');print('%v'.join(p))", separator) | ||||
| 		assert.Equal(t, []string{"-c", template}, runner.executions[0].parameters) | ||||
| 		assert.Equal(t, []string{"-c", template}, utils.executions[0].parameters) | ||||
|  | ||||
| 		assert.Equal(t, "pip2", runner.executions[1].executable) | ||||
| 		assert.Equal(t, []string{"install", "--user", "-r", "./requirements.txt", ""}, runner.executions[1].parameters) | ||||
| 		assert.Equal(t, "pip2", utils.executions[1].executable) | ||||
| 		assert.Equal(t, []string{"install", "--user", "-r", "./requirements.txt", ""}, utils.executions[1].parameters) | ||||
|  | ||||
| 		assert.Equal(t, "pip2", runner.executions[2].executable) | ||||
| 		assert.Equal(t, []string{"install", "--user"}, runner.executions[2].parameters) | ||||
| 		assert.Equal(t, "pip2", utils.executions[2].executable) | ||||
| 		assert.Equal(t, []string{"install", "--user"}, utils.executions[2].parameters) | ||||
|  | ||||
| 		assert.Equal(t, "sourceanalyzer", runner.executions[3].executable) | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "test", "-Xmx4G", "-Xms2G", "-python-path", "/usr/lib/python35.zip;/usr/lib/python3.5;/usr/lib/python3.5/plat-x86_64-linux-gnu;/usr/lib/python3.5/lib-dynload;/home/piper/.local/lib/python3.5/site-packages;/usr/local/lib/python3.5/dist-packages;/usr/lib/python3/dist-packages;./lib", "-exclude", fmt.Sprintf("./**/tests/**/*%s./**/setup.py", separator), "./**/*"}, runner.executions[3].parameters) | ||||
| 		assert.Equal(t, "sourceanalyzer", utils.executions[3].executable) | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "test", "-Xmx4G", "-Xms2G", "-python-path", "/usr/lib/python35.zip;/usr/lib/python3.5;/usr/lib/python3.5/plat-x86_64-linux-gnu;/usr/lib/python3.5/lib-dynload;/home/piper/.local/lib/python3.5/site-packages;/usr/local/lib/python3.5/dist-packages;/usr/lib/python3/dist-packages;./lib", "-exclude", fmt.Sprintf("./**/tests/**/*%s./**/setup.py", separator), "./**/*"}, utils.executions[3].parameters) | ||||
|  | ||||
| 		assert.Equal(t, "sourceanalyzer", runner.executions[4].executable) | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "test", "-scan", "-Xmx4G", "-Xms2G", "-build-label", "testLabel", "-logfile", "target/fortify-scan.log", "-f", "target/result.fpr"}, runner.executions[4].parameters) | ||||
| 		assert.Equal(t, "sourceanalyzer", utils.executions[4].executable) | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "test", "-scan", "-Xmx4G", "-Xms2G", "-build-label", "testLabel", "-logfile", "target/fortify-scan.log", "-f", "target/result.fpr"}, utils.executions[4].parameters) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -669,13 +681,13 @@ func TestCalculateTimeDifferenceToLastUpload(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestExecuteTemplatedCommand(t *testing.T) { | ||||
| 	runner := execRunnerMock{} | ||||
| 	utils := newFortifyTestUtilsBundle() | ||||
| 	template := []string{"{{.Executable}}", "-c", "{{.Param}}"} | ||||
| 	context := map[string]string{"Executable": "test.cmd", "Param": "abcd"} | ||||
| 	executeTemplatedCommand(&runner, template, context) | ||||
| 	executeTemplatedCommand(&utils, template, context) | ||||
|  | ||||
| 	assert.Equal(t, "test.cmd", runner.executions[0].executable) | ||||
| 	assert.Equal(t, []string{"-c", "abcd"}, runner.executions[0].parameters) | ||||
| 	assert.Equal(t, "test.cmd", utils.executions[0].executable) | ||||
| 	assert.Equal(t, []string{"-c", "abcd"}, utils.executions[0].parameters) | ||||
| } | ||||
|  | ||||
| func TestDeterminePullRequestMerge(t *testing.T) { | ||||
| @@ -717,35 +729,35 @@ func TestDeterminePullRequestMergeGithub(t *testing.T) { | ||||
|  | ||||
| func TestTranslateProject(t *testing.T) { | ||||
| 	t.Run("python", func(t *testing.T) { | ||||
| 		execRunner := execRunnerMock{} | ||||
| 		utils := newFortifyTestUtilsBundle() | ||||
| 		config := fortifyExecuteScanOptions{BuildTool: "pip", Memory: "-Xmx4G", Translate: `[{"pythonPath":"./some/path","src":"./**/*","exclude":"./tests/**/*"}]`} | ||||
| 		translateProject(&config, &execRunner, "/commit/7267658798797", "") | ||||
| 		assert.Equal(t, "sourceanalyzer", execRunner.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "/commit/7267658798797", "-Xmx4G", "-python-path", "./some/path", "-exclude", "./tests/**/*", "./**/*"}, execRunner.executions[0].parameters, "Expected different parameters") | ||||
| 		translateProject(&config, &utils, "/commit/7267658798797", "") | ||||
| 		assert.Equal(t, "sourceanalyzer", utils.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "/commit/7267658798797", "-Xmx4G", "-python-path", "./some/path", "-exclude", "./tests/**/*", "./**/*"}, utils.executions[0].parameters, "Expected different parameters") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("asp", func(t *testing.T) { | ||||
| 		execRunner := execRunnerMock{} | ||||
| 		utils := newFortifyTestUtilsBundle() | ||||
| 		config := fortifyExecuteScanOptions{BuildTool: "windows", Memory: "-Xmx6G", Translate: `[{"aspnetcore":"true","dotNetCoreVersion":"3.5","exclude":"./tests/**/*","libDirs":"tmp/","src":"./**/*"}]`} | ||||
| 		translateProject(&config, &execRunner, "/commit/7267658798797", "") | ||||
| 		assert.Equal(t, "sourceanalyzer", execRunner.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "/commit/7267658798797", "-Xmx6G", "-aspnetcore", "-dotnet-core-version", "3.5", "-libdirs", "tmp/", "-exclude", "./tests/**/*", "./**/*"}, execRunner.executions[0].parameters, "Expected different parameters") | ||||
| 		translateProject(&config, &utils, "/commit/7267658798797", "") | ||||
| 		assert.Equal(t, "sourceanalyzer", utils.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "/commit/7267658798797", "-Xmx6G", "-aspnetcore", "-dotnet-core-version", "3.5", "-libdirs", "tmp/", "-exclude", "./tests/**/*", "./**/*"}, utils.executions[0].parameters, "Expected different parameters") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("java", func(t *testing.T) { | ||||
| 		execRunner := execRunnerMock{} | ||||
| 		utils := newFortifyTestUtilsBundle() | ||||
| 		config := fortifyExecuteScanOptions{BuildTool: "maven", Memory: "-Xmx2G", Translate: `[{"classpath":"./classes/*.jar","extdirs":"tmp/","jdk":"1.8.0-21","source":"1.8","sourcepath":"src/ext/","src":"./**/*"}]`} | ||||
| 		translateProject(&config, &execRunner, "/commit/7267658798797", "") | ||||
| 		assert.Equal(t, "sourceanalyzer", execRunner.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "/commit/7267658798797", "-Xmx2G", "-cp", "./classes/*.jar", "-extdirs", "tmp/", "-source", "1.8", "-jdk", "1.8.0-21", "-sourcepath", "src/ext/", "./**/*"}, execRunner.executions[0].parameters, "Expected different parameters") | ||||
| 		translateProject(&config, &utils, "/commit/7267658798797", "") | ||||
| 		assert.Equal(t, "sourceanalyzer", utils.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "/commit/7267658798797", "-Xmx2G", "-cp", "./classes/*.jar", "-extdirs", "tmp/", "-source", "1.8", "-jdk", "1.8.0-21", "-sourcepath", "src/ext/", "./**/*"}, utils.executions[0].parameters, "Expected different parameters") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("auto classpath", func(t *testing.T) { | ||||
| 		execRunner := execRunnerMock{} | ||||
| 		utils := newFortifyTestUtilsBundle() | ||||
| 		config := fortifyExecuteScanOptions{BuildTool: "maven", Memory: "-Xmx2G", Translate: `[{"classpath":"./classes/*.jar", "extdirs":"tmp/","jdk":"1.8.0-21","source":"1.8","sourcepath":"src/ext/","src":"./**/*"}]`} | ||||
| 		translateProject(&config, &execRunner, "/commit/7267658798797", "./WEB-INF/lib/*.jar") | ||||
| 		assert.Equal(t, "sourceanalyzer", execRunner.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "/commit/7267658798797", "-Xmx2G", "-cp", "./WEB-INF/lib/*.jar", "-extdirs", "tmp/", "-source", "1.8", "-jdk", "1.8.0-21", "-sourcepath", "src/ext/", "./**/*"}, execRunner.executions[0].parameters, "Expected different parameters") | ||||
| 		translateProject(&config, &utils, "/commit/7267658798797", "./WEB-INF/lib/*.jar") | ||||
| 		assert.Equal(t, "sourceanalyzer", utils.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "/commit/7267658798797", "-Xmx2G", "-cp", "./WEB-INF/lib/*.jar", "-extdirs", "tmp/", "-source", "1.8", "-jdk", "1.8.0-21", "-sourcepath", "src/ext/", "./**/*"}, utils.executions[0].parameters, "Expected different parameters") | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -753,45 +765,45 @@ func TestScanProject(t *testing.T) { | ||||
| 	config := fortifyExecuteScanOptions{Memory: "-Xmx4G"} | ||||
|  | ||||
| 	t.Run("normal", func(t *testing.T) { | ||||
| 		execRunner := execRunnerMock{} | ||||
| 		scanProject(&config, &execRunner, "/commit/7267658798797", "label", "my.group-myartifact") | ||||
| 		assert.Equal(t, "sourceanalyzer", execRunner.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "/commit/7267658798797", "-scan", "-Xmx4G", "-build-label", "label", "-build-project", "my.group-myartifact", "-logfile", "target/fortify-scan.log", "-f", "target/result.fpr"}, execRunner.executions[0].parameters, "Expected different parameters") | ||||
| 		utils := newFortifyTestUtilsBundle() | ||||
| 		scanProject(&config, &utils, "/commit/7267658798797", "label", "my.group-myartifact") | ||||
| 		assert.Equal(t, "sourceanalyzer", utils.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "/commit/7267658798797", "-scan", "-Xmx4G", "-build-label", "label", "-build-project", "my.group-myartifact", "-logfile", "target/fortify-scan.log", "-f", "target/result.fpr"}, utils.executions[0].parameters, "Expected different parameters") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("quick", func(t *testing.T) { | ||||
| 		execRunner := execRunnerMock{} | ||||
| 		utils := newFortifyTestUtilsBundle() | ||||
| 		config.QuickScan = true | ||||
| 		scanProject(&config, &execRunner, "/commit/7267658798797", "", "") | ||||
| 		assert.Equal(t, "sourceanalyzer", execRunner.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "/commit/7267658798797", "-scan", "-Xmx4G", "-quick", "-logfile", "target/fortify-scan.log", "-f", "target/result.fpr"}, execRunner.executions[0].parameters, "Expected different parameters") | ||||
| 		scanProject(&config, &utils, "/commit/7267658798797", "", "") | ||||
| 		assert.Equal(t, "sourceanalyzer", utils.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"-verbose", "-64", "-b", "/commit/7267658798797", "-scan", "-Xmx4G", "-quick", "-logfile", "target/fortify-scan.log", "-f", "target/result.fpr"}, utils.executions[0].parameters, "Expected different parameters") | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func TestAutoresolveClasspath(t *testing.T) { | ||||
| 	t.Run("success pip", func(t *testing.T) { | ||||
| 		execRunner := execRunnerMock{} | ||||
| 		utils := newFortifyTestUtilsBundle() | ||||
| 		dir, err := ioutil.TempDir("", "classpath") | ||||
| 		assert.NoError(t, err, "Unexpected error detected") | ||||
| 		defer os.RemoveAll(dir) | ||||
| 		file := filepath.Join(dir, "cp.txt") | ||||
|  | ||||
| 		result := autoresolvePipClasspath("python2", []string{"-c", "import sys;p=sys.path;p.remove('');print(';'.join(p))"}, file, &execRunner) | ||||
| 		assert.Equal(t, "python2", execRunner.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"-c", "import sys;p=sys.path;p.remove('');print(';'.join(p))"}, execRunner.executions[0].parameters, "Expected different parameters") | ||||
| 		result := autoresolvePipClasspath("python2", []string{"-c", "import sys;p=sys.path;p.remove('');print(';'.join(p))"}, file, &utils) | ||||
| 		assert.Equal(t, "python2", utils.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"-c", "import sys;p=sys.path;p.remove('');print(';'.join(p))"}, utils.executions[0].parameters, "Expected different parameters") | ||||
| 		assert.Equal(t, "/usr/lib/python35.zip;/usr/lib/python3.5;/usr/lib/python3.5/plat-x86_64-linux-gnu;/usr/lib/python3.5/lib-dynload;/home/piper/.local/lib/python3.5/site-packages;/usr/local/lib/python3.5/dist-packages;/usr/lib/python3/dist-packages;./lib", result, "Expected different result") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("success maven", func(t *testing.T) { | ||||
| 		execRunner := execRunnerMock{} | ||||
| 		utils := newFortifyTestUtilsBundle() | ||||
| 		dir, err := ioutil.TempDir("", "classpath") | ||||
| 		assert.NoError(t, err, "Unexpected error detected") | ||||
| 		defer os.RemoveAll(dir) | ||||
| 		file := filepath.Join(dir, "cp.txt") | ||||
|  | ||||
| 		result := autoresolveMavenClasspath(fortifyExecuteScanOptions{BuildDescriptorFile: "pom.xml"}, file, &execRunner) | ||||
| 		assert.Equal(t, "mvn", execRunner.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"--file", "pom.xml", fmt.Sprintf("-Dmdep.outputFile=%v", file), "-DincludeScope=compile", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "dependency:build-classpath"}, execRunner.executions[0].parameters, "Expected different parameters") | ||||
| 		result := autoresolveMavenClasspath(fortifyExecuteScanOptions{BuildDescriptorFile: "pom.xml"}, file, &utils) | ||||
| 		assert.Equal(t, "mvn", utils.executions[0].executable, "Expected different executable") | ||||
| 		assert.Equal(t, []string{"--file", "pom.xml", fmt.Sprintf("-Dmdep.outputFile=%v", file), "-DincludeScope=compile", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "dependency:build-classpath"}, utils.executions[0].parameters, "Expected different parameters") | ||||
| 		assert.Equal(t, "some.jar;someother.jar", result, "Expected different result") | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -1,28 +1,21 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"github.com/SAP/jenkins-library/pkg/command" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/maven" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| ) | ||||
|  | ||||
| func mavenBuild(config mavenBuildOptions, telemetryData *telemetry.CustomData) { | ||||
| 	c := command.Command{} | ||||
| 	utils := maven.NewUtilsBundle() | ||||
|  | ||||
| 	c.Stdout(log.Writer()) | ||||
| 	c.Stderr(log.Writer()) | ||||
|  | ||||
| 	utils := piperutils.Files{} | ||||
|  | ||||
| 	err := runMavenBuild(&config, telemetryData, &c, &utils) | ||||
| 	err := runMavenBuild(&config, telemetryData, utils) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("step execution failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runMavenBuild(config *mavenBuildOptions, telemetryData *telemetry.CustomData, command command.ExecRunner, utils piperutils.FileUtils) error { | ||||
| func runMavenBuild(config *mavenBuildOptions, telemetryData *telemetry.CustomData, utils maven.Utils) error { | ||||
| 	var flags = []string{"-update-snapshots", "--batch-mode"} | ||||
|  | ||||
| 	exists, _ := utils.FileExists("integration-tests/pom.xml") | ||||
| @@ -57,6 +50,6 @@ func runMavenBuild(config *mavenBuildOptions, telemetryData *telemetry.CustomDat | ||||
| 		LogSuccessfulMavenTransfers: config.LogSuccessfulMavenTransfers, | ||||
| 	} | ||||
|  | ||||
| 	_, err := maven.Execute(&mavenOptions, command) | ||||
| 	_, err := maven.Execute(&mavenOptions, utils) | ||||
| 	return err | ||||
| } | ||||
|   | ||||
| @@ -1,68 +1,59 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"github.com/SAP/jenkins-library/pkg/mock" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| func TestMavenBuild(t *testing.T) { | ||||
| 	t.Run("mavenBuild should install the artifact", func(t *testing.T) { | ||||
| 		execMockRunner := mock.ExecMockRunner{} | ||||
|  | ||||
| 		mockedUtils := mock.FilesMock{} | ||||
| 		mockedUtils := newMavenMockUtils() | ||||
|  | ||||
| 		config := mavenBuildOptions{} | ||||
|  | ||||
| 		err := runMavenBuild(&config, nil, &execMockRunner, &mockedUtils) | ||||
| 		err := runMavenBuild(&config, nil, &mockedUtils) | ||||
|  | ||||
| 		assert.Nil(t, err) | ||||
| 		assert.Equal(t, execMockRunner.Calls[0].Exec, "mvn") | ||||
| 		assert.Contains(t, execMockRunner.Calls[0].Params, "install") | ||||
| 		assert.Equal(t, mockedUtils.Calls[0].Exec, "mvn") | ||||
| 		assert.Contains(t, mockedUtils.Calls[0].Params, "install") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("mavenBuild should skip integration tests", func(t *testing.T) { | ||||
| 		execMockRunner := mock.ExecMockRunner{} | ||||
|  | ||||
| 		mockedUtils := mock.FilesMock{} | ||||
| 		mockedUtils := newMavenMockUtils() | ||||
| 		mockedUtils.AddFile("integration-tests/pom.xml", []byte{}) | ||||
|  | ||||
| 		config := mavenBuildOptions{} | ||||
|  | ||||
| 		err := runMavenBuild(&config, nil, &execMockRunner, &mockedUtils) | ||||
| 		err := runMavenBuild(&config, nil, &mockedUtils) | ||||
|  | ||||
| 		assert.Nil(t, err) | ||||
| 		assert.Equal(t, execMockRunner.Calls[0].Exec, "mvn") | ||||
| 		assert.Contains(t, execMockRunner.Calls[0].Params, "-pl", "!integration-tests") | ||||
| 		assert.Equal(t, mockedUtils.Calls[0].Exec, "mvn") | ||||
| 		assert.Contains(t, mockedUtils.Calls[0].Params, "-pl", "!integration-tests") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("mavenBuild should flatten", func(t *testing.T) { | ||||
| 		execMockRunner := mock.ExecMockRunner{} | ||||
|  | ||||
| 		mockedUtils := mock.FilesMock{} | ||||
| 		mockedUtils := newMavenMockUtils() | ||||
|  | ||||
| 		config := mavenBuildOptions{Flatten: true} | ||||
|  | ||||
| 		err := runMavenBuild(&config, nil, &execMockRunner, &mockedUtils) | ||||
| 		err := runMavenBuild(&config, nil, &mockedUtils) | ||||
|  | ||||
| 		assert.Nil(t, err) | ||||
| 		assert.Contains(t, execMockRunner.Calls[0].Params, "flatten:flatten") | ||||
| 		assert.Contains(t, execMockRunner.Calls[0].Params, "-Dflatten.mode=resolveCiFriendliesOnly") | ||||
| 		assert.Contains(t, execMockRunner.Calls[0].Params, "-DupdatePomFile=true") | ||||
| 		assert.Contains(t, mockedUtils.Calls[0].Params, "flatten:flatten") | ||||
| 		assert.Contains(t, mockedUtils.Calls[0].Params, "-Dflatten.mode=resolveCiFriendliesOnly") | ||||
| 		assert.Contains(t, mockedUtils.Calls[0].Params, "-DupdatePomFile=true") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("mavenBuild should run only verify", func(t *testing.T) { | ||||
| 		execMockRunner := mock.ExecMockRunner{} | ||||
|  | ||||
| 		mockedUtils := mock.FilesMock{} | ||||
| 		mockedUtils := newMavenMockUtils() | ||||
|  | ||||
| 		config := mavenBuildOptions{Verify: true} | ||||
|  | ||||
| 		err := runMavenBuild(&config, nil, &execMockRunner, &mockedUtils) | ||||
| 		err := runMavenBuild(&config, nil, &mockedUtils) | ||||
|  | ||||
| 		assert.Nil(t, err) | ||||
| 		assert.Contains(t, execMockRunner.Calls[0].Params, "verify") | ||||
| 		assert.NotContains(t, execMockRunner.Calls[0].Params, "install") | ||||
| 		assert.Contains(t, mockedUtils.Calls[0].Params, "verify") | ||||
| 		assert.NotContains(t, mockedUtils.Calls[0].Params, "install") | ||||
| 	}) | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -2,24 +2,45 @@ package cmd | ||||
|  | ||||
| import ( | ||||
| 	"github.com/SAP/jenkins-library/pkg/command" | ||||
| 	piperhttp "github.com/SAP/jenkins-library/pkg/http" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/maven" | ||||
| 	"io/ioutil" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| ) | ||||
|  | ||||
| var writeFile = ioutil.WriteFile | ||||
| type mavenExecuteUtils interface { | ||||
| 	maven.Utils | ||||
| 	FileWrite(path string, content []byte, perm os.FileMode) error | ||||
| } | ||||
|  | ||||
| type mavenExecuteUtilsBundle struct { | ||||
| 	*command.Command | ||||
| 	*piperutils.Files | ||||
| 	*piperhttp.Client | ||||
| } | ||||
|  | ||||
| func newMavenExecuteUtilsBundle() mavenExecuteUtils { | ||||
| 	utils := mavenExecuteUtilsBundle{ | ||||
| 		Command: &command.Command{}, | ||||
| 		Files:   &piperutils.Files{}, | ||||
| 		Client:  &piperhttp.Client{}, | ||||
| 	} | ||||
| 	utils.Stdout(log.Writer()) | ||||
| 	utils.Stderr(log.Writer()) | ||||
| 	return &utils | ||||
| } | ||||
|  | ||||
| func mavenExecute(config mavenExecuteOptions, _ *telemetry.CustomData) { | ||||
| 	runner := command.Command{} | ||||
| 	err := runMavenExecute(config, &runner) | ||||
| 	err := runMavenExecute(config, newMavenExecuteUtilsBundle()) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("step execution failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runMavenExecute(config mavenExecuteOptions, runner command.ExecRunner) error { | ||||
| func runMavenExecute(config mavenExecuteOptions, utils mavenExecuteUtils) error { | ||||
| 	options := maven.ExecuteOptions{ | ||||
| 		PomPath:                     config.PomPath, | ||||
| 		ProjectSettingsFile:         config.ProjectSettingsFile, | ||||
| @@ -32,9 +53,9 @@ func runMavenExecute(config mavenExecuteOptions, runner command.ExecRunner) erro | ||||
| 		ReturnStdout:                config.ReturnStdout, | ||||
| 	} | ||||
|  | ||||
| 	output, err := maven.Execute(&options, runner) | ||||
| 	output, err := maven.Execute(&options, utils) | ||||
| 	if err == nil && config.ReturnStdout { | ||||
| 		err = writeFile(".pipeline/maven_output.txt", []byte(output), 0644) | ||||
| 		err = utils.FileWrite(".pipeline/maven_output.txt", []byte(output), 0644) | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|   | ||||
| @@ -2,50 +2,23 @@ package cmd | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/SAP/jenkins-library/pkg/command" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/maven" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| 	"io" | ||||
| 	"path/filepath" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"unicode" | ||||
| ) | ||||
|  | ||||
| type mavenExecuteIntegrationUtils interface { | ||||
| 	Stdout(out io.Writer) | ||||
| 	Stderr(err io.Writer) | ||||
| 	RunExecutable(e string, p ...string) error | ||||
|  | ||||
| 	FileExists(filename string) (bool, error) | ||||
| } | ||||
|  | ||||
| type mavenExecuteIntegrationUtilsBundle struct { | ||||
| 	*command.Command | ||||
| 	*piperutils.Files | ||||
| } | ||||
|  | ||||
| func newMavenExecuteIntegrationUtils() mavenExecuteIntegrationUtils { | ||||
| 	utils := mavenExecuteIntegrationUtilsBundle{ | ||||
| 		Command: &command.Command{}, | ||||
| 		Files:   &piperutils.Files{}, | ||||
| 	} | ||||
| 	utils.Stdout(log.Writer()) | ||||
| 	utils.Stderr(log.Writer()) | ||||
| 	return &utils | ||||
| } | ||||
|  | ||||
| func mavenExecuteIntegration(config mavenExecuteIntegrationOptions, _ *telemetry.CustomData) { | ||||
| 	utils := newMavenExecuteIntegrationUtils() | ||||
| 	err := runMavenExecuteIntegration(&config, utils) | ||||
| 	err := runMavenExecuteIntegration(&config, maven.NewUtilsBundle()) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("step execution failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runMavenExecuteIntegration(config *mavenExecuteIntegrationOptions, utils mavenExecuteIntegrationUtils) error { | ||||
| func runMavenExecuteIntegration(config *mavenExecuteIntegrationOptions, utils maven.Utils) error { | ||||
| 	pomPath := filepath.Join("integration-tests", "pom.xml") | ||||
| 	hasIntegrationTestsModule, _ := utils.FileExists(pomPath) | ||||
| 	if !hasIntegrationTestsModule { | ||||
| @@ -53,11 +26,11 @@ func runMavenExecuteIntegration(config *mavenExecuteIntegrationOptions, utils ma | ||||
| 	} | ||||
|  | ||||
| 	if config.InstallArtifacts { | ||||
| 		err := maven.InstallMavenArtifacts(utils, &maven.EvaluateOptions{ | ||||
| 		err := maven.InstallMavenArtifacts(&maven.EvaluateOptions{ | ||||
| 			M2Path:              config.M2Path, | ||||
| 			ProjectSettingsFile: config.ProjectSettingsFile, | ||||
| 			GlobalSettingsFile:  config.GlobalSettingsFile, | ||||
| 		}) | ||||
| 		}, utils) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|   | ||||
| @@ -1,8 +1,10 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"github.com/SAP/jenkins-library/pkg/mock" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"net/http" | ||||
| 	"path/filepath" | ||||
| 	"testing" | ||||
| ) | ||||
| @@ -12,6 +14,10 @@ type mavenExecuteIntegrationTestUtilsBundle struct { | ||||
| 	*mock.FilesMock | ||||
| } | ||||
|  | ||||
| func (m mavenExecuteIntegrationTestUtilsBundle) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error { | ||||
| 	return errors.New("Test should not download files.") | ||||
| } | ||||
|  | ||||
| func TestIntegrationTestModuleDoesNotExist(t *testing.T) { | ||||
| 	t.Parallel() | ||||
| 	utils := newMavenIntegrationTestsUtilsBundle() | ||||
| @@ -130,10 +136,10 @@ func TestValidateForkCount(t *testing.T) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func newMavenIntegrationTestsUtilsBundle() mavenExecuteIntegrationTestUtilsBundle { | ||||
| func newMavenIntegrationTestsUtilsBundle() *mavenExecuteIntegrationTestUtilsBundle { | ||||
| 	utilsBundle := mavenExecuteIntegrationTestUtilsBundle{ | ||||
| 		ExecMockRunner: &mock.ExecMockRunner{}, | ||||
| 		FilesMock:      &mock.FilesMock{}, | ||||
| 	} | ||||
| 	return utilsBundle | ||||
| 	return &utilsBundle | ||||
| } | ||||
|   | ||||
| @@ -1,47 +1,20 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"github.com/SAP/jenkins-library/pkg/command" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/maven" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| 	"io" | ||||
| 	"strconv" | ||||
| ) | ||||
|  | ||||
| type mavenStaticCodeChecksUtils interface { | ||||
| 	Stdout(out io.Writer) | ||||
| 	Stderr(err io.Writer) | ||||
| 	RunExecutable(e string, p ...string) error | ||||
|  | ||||
| 	FileExists(filename string) (bool, error) | ||||
| } | ||||
|  | ||||
| type mavenStaticCodeChecksUtilsBundle struct { | ||||
| 	*command.Command | ||||
| 	*piperutils.Files | ||||
| } | ||||
|  | ||||
| func newStaticCodeChecksUtils() mavenStaticCodeChecksUtils { | ||||
| 	utils := mavenStaticCodeChecksUtilsBundle{ | ||||
| 		Command: &command.Command{}, | ||||
| 		Files:   &piperutils.Files{}, | ||||
| 	} | ||||
| 	utils.Stdout(log.Writer()) | ||||
| 	utils.Stderr(log.Writer()) | ||||
| 	return &utils | ||||
| } | ||||
|  | ||||
| func mavenExecuteStaticCodeChecks(config mavenExecuteStaticCodeChecksOptions, telemetryData *telemetry.CustomData) { | ||||
| 	utils := newStaticCodeChecksUtils() | ||||
| 	err := runMavenStaticCodeChecks(&config, telemetryData, utils) | ||||
| 	err := runMavenStaticCodeChecks(&config, telemetryData, maven.NewUtilsBundle()) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("step execution failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runMavenStaticCodeChecks(config *mavenExecuteStaticCodeChecksOptions, telemetryData *telemetry.CustomData, utils mavenStaticCodeChecksUtils) error { | ||||
| func runMavenStaticCodeChecks(config *mavenExecuteStaticCodeChecksOptions, telemetryData *telemetry.CustomData, utils maven.Utils) error { | ||||
| 	var defines []string | ||||
| 	var goals []string | ||||
|  | ||||
| @@ -51,17 +24,17 @@ func runMavenStaticCodeChecks(config *mavenExecuteStaticCodeChecksOptions, telem | ||||
| 	} | ||||
|  | ||||
| 	if config.InstallArtifacts { | ||||
| 		err := maven.InstallMavenArtifacts(utils, &maven.EvaluateOptions{ | ||||
| 		err := maven.InstallMavenArtifacts(&maven.EvaluateOptions{ | ||||
| 			M2Path:              config.M2Path, | ||||
| 			ProjectSettingsFile: config.ProjectSettingsFile, | ||||
| 			GlobalSettingsFile:  config.GlobalSettingsFile, | ||||
| 		}) | ||||
| 		}, utils) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if testModulesExcludes := maven.GetTestModulesExcludes(); testModulesExcludes != nil { | ||||
| 	if testModulesExcludes := maven.GetTestModulesExcludes(utils); testModulesExcludes != nil { | ||||
| 		defines = append(defines, testModulesExcludes...) | ||||
| 	} | ||||
| 	if config.MavenModulesExcludes != nil { | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"testing" | ||||
|  | ||||
| @@ -13,6 +15,9 @@ import ( | ||||
| func TestRunMavenStaticCodeChecks(t *testing.T) { | ||||
| 	t.Run("should run spotBugs and pmd with all configured options", func(t *testing.T) { | ||||
| 		utils := newMavenStaticCodeChecksTestUtilsBundle() | ||||
| 		utils.FilesMock.AddFile("unit-tests/pom.xml", []byte(`<project> </project>`)) | ||||
| 		utils.FilesMock.AddFile("integration-tests/pom.xml", []byte(`<project> </project>`)) | ||||
|  | ||||
| 		config := mavenExecuteStaticCodeChecksOptions{ | ||||
| 			SpotBugs:                  true, | ||||
| 			Pmd:                       true, | ||||
| @@ -126,6 +131,10 @@ type mavenStaticCodeChecksTestUtilsBundle struct { | ||||
| 	*mock.FilesMock | ||||
| } | ||||
|  | ||||
| func (m mavenStaticCodeChecksTestUtilsBundle) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error { | ||||
| 	return errors.New("Test should not download files.") | ||||
| } | ||||
|  | ||||
| func newMavenStaticCodeChecksTestUtilsBundle() mavenStaticCodeChecksTestUtilsBundle { | ||||
| 	utilsBundle := mavenStaticCodeChecksTestUtilsBundle{ | ||||
| 		ExecMockRunner: &mock.ExecMockRunner{}, | ||||
|   | ||||
| @@ -1,12 +1,34 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"github.com/SAP/jenkins-library/pkg/mock" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"os" | ||||
| 	"net/http" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| type mavenMockUtils struct { | ||||
| 	shouldFail     bool | ||||
| 	requestedUrls  []string | ||||
| 	requestedFiles []string | ||||
| 	*mock.FilesMock | ||||
| 	*mock.ExecMockRunner | ||||
| } | ||||
|  | ||||
| func (m *mavenMockUtils) DownloadFile(_, _ string, _ http.Header, _ []*http.Cookie) error { | ||||
| 	return errors.New("Test should not download files.") | ||||
| } | ||||
|  | ||||
| func newMavenMockUtils() mavenMockUtils { | ||||
| 	utils := mavenMockUtils{ | ||||
| 		shouldFail:     false, | ||||
| 		FilesMock:      &mock.FilesMock{}, | ||||
| 		ExecMockRunner: &mock.ExecMockRunner{}, | ||||
| 	} | ||||
| 	return utils | ||||
| } | ||||
|  | ||||
| func TestMavenExecute(t *testing.T) { | ||||
| 	t.Run("mavenExecute should write output file", func(t *testing.T) { | ||||
| 		// init | ||||
| @@ -16,23 +38,12 @@ func TestMavenExecute(t *testing.T) { | ||||
| 			ReturnStdout:                true, | ||||
| 		} | ||||
|  | ||||
| 		mockRunner := mock.ExecMockRunner{} | ||||
| 		mockRunner.StdoutReturn = map[string]string{} | ||||
| 		mockRunner.StdoutReturn[""] = "test output" | ||||
|  | ||||
| 		var outputFile string | ||||
| 		var output []byte | ||||
|  | ||||
| 		oldWriteFile := writeFile | ||||
| 		writeFile = func(filename string, data []byte, perm os.FileMode) error { | ||||
| 			outputFile = filename | ||||
| 			output = data | ||||
| 			return nil | ||||
| 		} | ||||
| 		defer func() { writeFile = oldWriteFile }() | ||||
| 		mockUtils := newMavenMockUtils() | ||||
| 		mockUtils.StdoutReturn = map[string]string{} | ||||
| 		mockUtils.StdoutReturn[""] = "test output" | ||||
|  | ||||
| 		// test | ||||
| 		err := runMavenExecute(config, &mockRunner) | ||||
| 		err := runMavenExecute(config, &mockUtils) | ||||
|  | ||||
| 		// assert | ||||
| 		expectedParams := []string{ | ||||
| @@ -40,12 +51,17 @@ func TestMavenExecute(t *testing.T) { | ||||
| 		} | ||||
|  | ||||
| 		assert.NoError(t, err) | ||||
| 		if assert.Equal(t, 1, len(mockRunner.Calls)) { | ||||
| 			assert.Equal(t, "mvn", mockRunner.Calls[0].Exec) | ||||
| 			assert.Equal(t, expectedParams, mockRunner.Calls[0].Params) | ||||
| 		if assert.Equal(t, 1, len(mockUtils.Calls)) { | ||||
| 			assert.Equal(t, "mvn", mockUtils.Calls[0].Exec) | ||||
| 			assert.Equal(t, expectedParams, mockUtils.Calls[0].Params) | ||||
| 		} | ||||
|  | ||||
| 		outputFileExists, _ := mockUtils.FileExists(".pipeline/maven_output.txt") | ||||
| 		assert.True(t, outputFileExists) | ||||
|  | ||||
| 		output, _ := mockUtils.FileRead(".pipeline/maven_output.txt") | ||||
|  | ||||
| 		assert.Equal(t, "test output", string(output)) | ||||
| 		assert.Equal(t, ".pipeline/maven_output.txt", outputFile) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("mavenExecute should NOT write output file", func(t *testing.T) { | ||||
| @@ -55,23 +71,10 @@ func TestMavenExecute(t *testing.T) { | ||||
| 			LogSuccessfulMavenTransfers: true, | ||||
| 		} | ||||
|  | ||||
| 		mockRunner := mock.ExecMockRunner{} | ||||
| 		mockRunner.StdoutReturn = map[string]string{} | ||||
| 		mockRunner.StdoutReturn[""] = "test output" | ||||
|  | ||||
| 		var outputFile string | ||||
| 		var output []byte | ||||
|  | ||||
| 		oldWriteFile := writeFile | ||||
| 		writeFile = func(filename string, data []byte, perm os.FileMode) error { | ||||
| 			outputFile = filename | ||||
| 			output = data | ||||
| 			return nil | ||||
| 		} | ||||
| 		defer func() { writeFile = oldWriteFile }() | ||||
| 		mockUtils := newMavenMockUtils() | ||||
|  | ||||
| 		// test | ||||
| 		err := runMavenExecute(config, &mockRunner) | ||||
| 		err := runMavenExecute(config, &mockUtils) | ||||
|  | ||||
| 		// assert | ||||
| 		expectedParams := []string{ | ||||
| @@ -79,11 +82,12 @@ func TestMavenExecute(t *testing.T) { | ||||
| 		} | ||||
|  | ||||
| 		assert.NoError(t, err) | ||||
| 		if assert.Equal(t, 1, len(mockRunner.Calls)) { | ||||
| 			assert.Equal(t, "mvn", mockRunner.Calls[0].Exec) | ||||
| 			assert.Equal(t, expectedParams, mockRunner.Calls[0].Params) | ||||
| 		if assert.Equal(t, 1, len(mockUtils.Calls)) { | ||||
| 			assert.Equal(t, "mvn", mockUtils.Calls[0].Exec) | ||||
| 			assert.Equal(t, expectedParams, mockUtils.Calls[0].Params) | ||||
| 		} | ||||
| 		assert.Equal(t, "", string(output)) | ||||
| 		assert.Equal(t, "", outputFile) | ||||
|  | ||||
| 		outputFileExists, _ := mockUtils.FileExists(".pipeline/maven_output.txt") | ||||
| 		assert.False(t, outputFileExists) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
							
								
								
									
										135
									
								
								cmd/mtaBuild.go
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								cmd/mtaBuild.go
									
									
									
									
									
								
							| @@ -4,6 +4,7 @@ import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"path" | ||||
| 	"strings" | ||||
| @@ -39,9 +40,6 @@ modules: | ||||
|       builder: grunt | ||||
|       build-result: dist` | ||||
|  | ||||
| // for mocking | ||||
| var downloadAndCopySettingsFiles = maven.DownloadAndCopySettingsFiles | ||||
|  | ||||
| // MTABuildTarget ... | ||||
| type MTABuildTarget int | ||||
|  | ||||
| @@ -77,18 +75,64 @@ func (m MTABuildTarget) String() string { | ||||
| 	}[m] | ||||
| } | ||||
|  | ||||
| type mtaBuildUtils interface { | ||||
| 	maven.Utils | ||||
|  | ||||
| 	SetEnv(env []string) | ||||
| 	AppendEnv(env []string) | ||||
|  | ||||
| 	Abs(path string) (string, error) | ||||
| 	FileRead(path string) ([]byte, error) | ||||
| 	FileWrite(path string, content []byte, perm os.FileMode) error | ||||
|  | ||||
| 	DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error | ||||
|  | ||||
| 	DownloadAndCopySettingsFiles(globalSettingsFile string, projectSettingsFile string) error | ||||
|  | ||||
| 	SetNpmRegistries(defaultNpmRegistry string) error | ||||
| 	InstallAllDependencies(defaultNpmRegistry string) error | ||||
| } | ||||
|  | ||||
| type mtaBuildUtilsBundle struct { | ||||
| 	*command.Command | ||||
| 	*piperutils.Files | ||||
| 	*piperhttp.Client | ||||
| } | ||||
|  | ||||
| func (bundle *mtaBuildUtilsBundle) SetNpmRegistries(defaultNpmRegistry string) error { | ||||
| 	npmExecutorOptions := npm.ExecutorOptions{DefaultNpmRegistry: defaultNpmRegistry, ExecRunner: bundle} | ||||
| 	npmExecutor := npm.NewExecutor(npmExecutorOptions) | ||||
| 	return npmExecutor.SetNpmRegistries() | ||||
| } | ||||
|  | ||||
| func (bundle *mtaBuildUtilsBundle) InstallAllDependencies(defaultNpmRegistry string) error { | ||||
| 	npmExecutorOptions := npm.ExecutorOptions{DefaultNpmRegistry: defaultNpmRegistry, ExecRunner: bundle} | ||||
| 	npmExecutor := npm.NewExecutor(npmExecutorOptions) | ||||
| 	return npmExecutor.InstallAllDependencies(npmExecutor.FindPackageJSONFiles()) | ||||
| } | ||||
|  | ||||
| func (bundle *mtaBuildUtilsBundle) DownloadAndCopySettingsFiles(globalSettingsFile string, projectSettingsFile string) error { | ||||
| 	return maven.DownloadAndCopySettingsFiles(globalSettingsFile, projectSettingsFile, bundle) | ||||
| } | ||||
|  | ||||
| func newMtaBuildUtilsBundle() mtaBuildUtils { | ||||
| 	utils := mtaBuildUtilsBundle{ | ||||
| 		Command: &command.Command{}, | ||||
| 		Files:   &piperutils.Files{}, | ||||
| 		Client:  &piperhttp.Client{}, | ||||
| 	} | ||||
| 	utils.Stdout(log.Writer()) | ||||
| 	utils.Stderr(log.Writer()) | ||||
| 	return &utils | ||||
| } | ||||
|  | ||||
| func mtaBuild(config mtaBuildOptions, | ||||
| 	telemetryData *telemetry.CustomData, | ||||
| 	commonPipelineEnvironment *mtaBuildCommonPipelineEnvironment) { | ||||
| 	log.Entry().Debugf("Launching mta build") | ||||
| 	files := piperutils.Files{} | ||||
| 	httpClient := piperhttp.Client{} | ||||
| 	e := command.Command{} | ||||
| 	utils := newMtaBuildUtilsBundle() | ||||
|  | ||||
| 	npmExecutorOptions := npm.ExecutorOptions{DefaultNpmRegistry: config.DefaultNpmRegistry, ExecRunner: &e} | ||||
| 	npmExecutor := npm.NewExecutor(npmExecutorOptions) | ||||
|  | ||||
| 	err := runMtaBuild(config, commonPipelineEnvironment, &e, &files, &httpClient, npmExecutor) | ||||
| 	err := runMtaBuild(config, commonPipelineEnvironment, utils) | ||||
| 	if err != nil { | ||||
| 		log.Entry(). | ||||
| 			WithError(err). | ||||
| @@ -98,25 +142,19 @@ func mtaBuild(config mtaBuildOptions, | ||||
|  | ||||
| func runMtaBuild(config mtaBuildOptions, | ||||
| 	commonPipelineEnvironment *mtaBuildCommonPipelineEnvironment, | ||||
| 	e command.ExecRunner, | ||||
| 	p piperutils.FileUtils, | ||||
| 	httpClient piperhttp.Downloader, | ||||
| 	npmExecutor npm.Executor) error { | ||||
|  | ||||
| 	e.Stdout(log.Writer()) // not sure if using the logging framework here is a suitable approach. We handover already log formatted | ||||
| 	e.Stderr(log.Writer()) // entries to a logging framework again. But this is considered to be some kind of project standard. | ||||
| 	utils mtaBuildUtils) error { | ||||
|  | ||||
| 	var err error | ||||
|  | ||||
| 	err = handleSettingsFiles(config, p, httpClient) | ||||
| 	err = handleSettingsFiles(config, utils) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	err = npmExecutor.SetNpmRegistries() | ||||
| 	err = utils.SetNpmRegistries(config.DefaultNpmRegistry) | ||||
|  | ||||
| 	mtaYamlFile := "mta.yaml" | ||||
| 	mtaYamlFileExists, err := p.FileExists(mtaYamlFile) | ||||
| 	mtaYamlFileExists, err := utils.FileExists(mtaYamlFile) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| @@ -124,7 +162,7 @@ func runMtaBuild(config mtaBuildOptions, | ||||
|  | ||||
| 	if !mtaYamlFileExists { | ||||
|  | ||||
| 		if err = createMtaYamlFile(mtaYamlFile, config.ApplicationName, p); err != nil { | ||||
| 		if err = createMtaYamlFile(mtaYamlFile, config.ApplicationName, utils); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| @@ -132,11 +170,11 @@ func runMtaBuild(config mtaBuildOptions, | ||||
| 		log.Entry().Infof("\"%s\" file found in project sources", mtaYamlFile) | ||||
| 	} | ||||
|  | ||||
| 	if err = setTimeStamp(mtaYamlFile, p); err != nil { | ||||
| 	if err = setTimeStamp(mtaYamlFile, utils); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	mtarName, err := getMtarName(config, mtaYamlFile, p) | ||||
| 	mtarName, err := getMtarName(config, mtaYamlFile, utils) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| @@ -182,21 +220,21 @@ func runMtaBuild(config mtaBuildOptions, | ||||
| 		return fmt.Errorf("Unknown mta build tool: \"%s\"", config.MtaBuildTool) | ||||
| 	} | ||||
|  | ||||
| 	if err = addNpmBinToPath(e); err != nil { | ||||
| 	if err = addNpmBinToPath(utils); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if len(config.M2Path) > 0 { | ||||
| 		absolutePath, err := p.Abs(config.M2Path) | ||||
| 		absolutePath, err := utils.Abs(config.M2Path) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		e.AppendEnv([]string{"MAVEN_OPTS=-Dmaven.repo.local=" + absolutePath}) | ||||
| 		utils.AppendEnv([]string{"MAVEN_OPTS=-Dmaven.repo.local=" + absolutePath}) | ||||
| 	} | ||||
|  | ||||
| 	log.Entry().Infof("Executing mta build call: \"%s\"", strings.Join(call, " ")) | ||||
|  | ||||
| 	if err := e.RunExecutable(call[0], call[1:]...); err != nil { | ||||
| 	if err := utils.RunExecutable(call[0], call[1:]...); err != nil { | ||||
| 		log.SetErrorCategory(log.ErrorBuild) | ||||
| 		return err | ||||
| 	} | ||||
| @@ -205,12 +243,12 @@ func runMtaBuild(config mtaBuildOptions, | ||||
|  | ||||
| 	if config.InstallArtifacts { | ||||
| 		// install maven artifacts in local maven repo because `mbt build` executes `mvn package -B` | ||||
| 		err = installMavenArtifacts(e, config) | ||||
| 		err = installMavenArtifacts(utils, config) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		// mta-builder executes 'npm install --production', therefore we need 'npm ci/install' to install the dev-dependencies | ||||
| 		err = npmExecutor.InstallAllDependencies(npmExecutor.FindPackageJSONFiles()) | ||||
| 		err = utils.InstallAllDependencies(config.DefaultNpmRegistry) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -218,13 +256,13 @@ func runMtaBuild(config mtaBuildOptions, | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func installMavenArtifacts(e command.ExecRunner, config mtaBuildOptions) error { | ||||
| 	pomXMLExists, err := piperutils.FileExists("pom.xml") | ||||
| func installMavenArtifacts(utils mtaBuildUtils, config mtaBuildOptions) error { | ||||
| 	pomXMLExists, err := utils.FileExists("pom.xml") | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if pomXMLExists { | ||||
| 		err = maven.InstallMavenArtifacts(e, &maven.EvaluateOptions{M2Path: config.M2Path}) | ||||
| 		err = maven.InstallMavenArtifacts(&maven.EvaluateOptions{M2Path: config.M2Path}, utils) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -243,25 +281,25 @@ func getMarJarName(config mtaBuildOptions) string { | ||||
| 	return mtaJar | ||||
| } | ||||
|  | ||||
| func addNpmBinToPath(e command.ExecRunner) error { | ||||
| func addNpmBinToPath(utils mtaBuildUtils) error { | ||||
| 	dir, _ := os.Getwd() | ||||
| 	newPath := path.Join(dir, "node_modules", ".bin") | ||||
| 	oldPath := os.Getenv("PATH") | ||||
| 	if len(oldPath) > 0 { | ||||
| 		newPath = newPath + ":" + oldPath | ||||
| 	} | ||||
| 	e.SetEnv([]string{"PATH=" + newPath}) | ||||
| 	utils.SetEnv([]string{"PATH=" + newPath}) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func getMtarName(config mtaBuildOptions, mtaYamlFile string, p piperutils.FileUtils) (string, error) { | ||||
| func getMtarName(config mtaBuildOptions, mtaYamlFile string, utils mtaBuildUtils) (string, error) { | ||||
|  | ||||
| 	mtarName := config.MtarName | ||||
| 	if len(mtarName) == 0 { | ||||
|  | ||||
| 		log.Entry().Debugf("mtar name not provided via config. Extracting from file \"%s\"", mtaYamlFile) | ||||
|  | ||||
| 		mtaID, err := getMtaID(mtaYamlFile, p) | ||||
| 		mtaID, err := getMtaID(mtaYamlFile, utils) | ||||
|  | ||||
| 		if err != nil { | ||||
| 			log.SetErrorCategory(log.ErrorConfiguration) | ||||
| @@ -282,9 +320,9 @@ func getMtarName(config mtaBuildOptions, mtaYamlFile string, p piperutils.FileUt | ||||
|  | ||||
| } | ||||
|  | ||||
| func setTimeStamp(mtaYamlFile string, p piperutils.FileUtils) error { | ||||
| func setTimeStamp(mtaYamlFile string, utils mtaBuildUtils) error { | ||||
|  | ||||
| 	mtaYaml, err := p.FileRead(mtaYamlFile) | ||||
| 	mtaYaml, err := utils.FileRead(mtaYamlFile) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @@ -294,7 +332,7 @@ func setTimeStamp(mtaYamlFile string, p piperutils.FileUtils) error { | ||||
| 	timestampVar := "${timestamp}" | ||||
| 	if strings.Contains(mtaYamlStr, timestampVar) { | ||||
|  | ||||
| 		if err := p.FileWrite(mtaYamlFile, []byte(strings.ReplaceAll(mtaYamlStr, timestampVar, getTimestamp())), 0644); err != nil { | ||||
| 		if err := utils.FileWrite(mtaYamlFile, []byte(strings.ReplaceAll(mtaYamlStr, timestampVar, getTimestamp())), 0644); err != nil { | ||||
| 			log.SetErrorCategory(log.ErrorConfiguration) | ||||
| 			return err | ||||
| 		} | ||||
| @@ -311,7 +349,7 @@ func getTimestamp() string { | ||||
| 	return fmt.Sprintf("%d%02d%02d%02d%02d%02d", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second()) | ||||
| } | ||||
|  | ||||
| func createMtaYamlFile(mtaYamlFile, applicationName string, p piperutils.FileUtils) error { | ||||
| func createMtaYamlFile(mtaYamlFile, applicationName string, utils mtaBuildUtils) error { | ||||
|  | ||||
| 	log.Entry().Debugf("mta yaml file not found in project sources.") | ||||
|  | ||||
| @@ -319,13 +357,13 @@ func createMtaYamlFile(mtaYamlFile, applicationName string, p piperutils.FileUti | ||||
| 		return fmt.Errorf("'%[1]s' not found in project sources and 'applicationName' not provided as parameter - cannot generate '%[1]s' file", mtaYamlFile) | ||||
| 	} | ||||
|  | ||||
| 	packageFileExists, err := p.FileExists("package.json") | ||||
| 	packageFileExists, err := utils.FileExists("package.json") | ||||
| 	if !packageFileExists { | ||||
| 		return fmt.Errorf("package.json file does not exist") | ||||
| 	} | ||||
|  | ||||
| 	var result map[string]interface{} | ||||
| 	pContent, err := p.FileRead("package.json") | ||||
| 	pContent, err := utils.FileRead("package.json") | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @@ -346,17 +384,14 @@ func createMtaYamlFile(mtaYamlFile, applicationName string, p piperutils.FileUti | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	p.FileWrite(mtaYamlFile, []byte(mtaConfig), 0644) | ||||
| 	utils.FileWrite(mtaYamlFile, []byte(mtaConfig), 0644) | ||||
| 	log.Entry().Infof("\"%s\" created.", mtaYamlFile) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func handleSettingsFiles(config mtaBuildOptions, | ||||
| 	p piperutils.FileUtils, | ||||
| 	httpClient piperhttp.Downloader) error { | ||||
|  | ||||
| 	return downloadAndCopySettingsFiles(config.GlobalSettingsFile, config.ProjectSettingsFile, p, httpClient) | ||||
| func handleSettingsFiles(config mtaBuildOptions, utils mtaBuildUtils) error { | ||||
| 	return utils.DownloadAndCopySettingsFiles(config.GlobalSettingsFile, config.ProjectSettingsFile) | ||||
| } | ||||
|  | ||||
| func generateMta(id, applicationName, version string) (string, error) { | ||||
| @@ -389,10 +424,10 @@ func generateMta(id, applicationName, version string) (string, error) { | ||||
| 	return script.String(), nil | ||||
| } | ||||
|  | ||||
| func getMtaID(mtaYamlFile string, fileUtils piperutils.FileUtils) (string, error) { | ||||
| func getMtaID(mtaYamlFile string, utils mtaBuildUtils) (string, error) { | ||||
|  | ||||
| 	var result map[string]interface{} | ||||
| 	p, err := fileUtils.FileRead(mtaYamlFile) | ||||
| 	p, err := utils.FileRead(mtaYamlFile) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|   | ||||
| @@ -1,32 +1,60 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"github.com/SAP/jenkins-library/pkg/npm" | ||||
| 	"os" | ||||
| 	"errors" | ||||
| 	"net/http" | ||||
| 	"testing" | ||||
|  | ||||
| 	"fmt" | ||||
| 	piperhttp "github.com/SAP/jenkins-library/pkg/http" | ||||
| 	"github.com/SAP/jenkins-library/pkg/maven" | ||||
| 	"github.com/SAP/jenkins-library/pkg/mock" | ||||
| 	"github.com/ghodss/yaml" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| type mtaBuildTestUtilsBundle struct { | ||||
| 	*mock.ExecMockRunner | ||||
| 	*mock.FilesMock | ||||
| 	projectSettingsFile            string | ||||
| 	globalSettingsFile             string | ||||
| 	registryUsedInSetNpmRegistries string | ||||
| } | ||||
|  | ||||
| func (m *mtaBuildTestUtilsBundle) SetNpmRegistries(defaultNpmRegistry string) error { | ||||
| 	m.registryUsedInSetNpmRegistries = defaultNpmRegistry | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (m *mtaBuildTestUtilsBundle) InstallAllDependencies(defaultNpmRegistry string) error { | ||||
| 	return errors.New("Test should not install dependencies.") //TODO implement test | ||||
| } | ||||
|  | ||||
| func (m *mtaBuildTestUtilsBundle) DownloadAndCopySettingsFiles(globalSettingsFile string, projectSettingsFile string) error { | ||||
| 	m.projectSettingsFile = projectSettingsFile | ||||
| 	m.globalSettingsFile = globalSettingsFile | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (m *mtaBuildTestUtilsBundle) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error { | ||||
| 	return errors.New("Test should not download files.") | ||||
| } | ||||
|  | ||||
| func newMtaBuildTestUtilsBundle() *mtaBuildTestUtilsBundle { | ||||
| 	utilsBundle := mtaBuildTestUtilsBundle{ | ||||
| 		ExecMockRunner: &mock.ExecMockRunner{}, | ||||
| 		FilesMock:      &mock.FilesMock{}, | ||||
| 	} | ||||
| 	return &utilsBundle | ||||
| } | ||||
|  | ||||
| func TestMarBuild(t *testing.T) { | ||||
|  | ||||
| 	cpe := mtaBuildCommonPipelineEnvironment{} | ||||
| 	httpClient := piperhttp.Client{} | ||||
|  | ||||
| 	t.Run("Application name not set", func(t *testing.T) { | ||||
|  | ||||
| 		e := mock.ExecMockRunner{} | ||||
|  | ||||
| 		utilsMock := newMtaBuildTestUtilsBundle() | ||||
| 		options := mtaBuildOptions{} | ||||
|  | ||||
| 		fileUtils := MtaTestFileUtilsMock{} | ||||
|  | ||||
| 		err := runMtaBuild(options, &cpe, &e, &fileUtils, &httpClient, newNpmExecutor(&e)) | ||||
| 		err := runMtaBuild(options, &cpe, utilsMock) | ||||
|  | ||||
| 		assert.NotNil(t, err) | ||||
| 		assert.Equal(t, "'mta.yaml' not found in project sources and 'applicationName' not provided as parameter - cannot generate 'mta.yaml' file", err.Error()) | ||||
| @@ -35,37 +63,25 @@ func TestMarBuild(t *testing.T) { | ||||
|  | ||||
| 	t.Run("Provide default npm registry", func(t *testing.T) { | ||||
|  | ||||
| 		e := mock.ExecMockRunner{} | ||||
| 		e.StdoutReturn = map[string]string{"npm config get registry": "undefined"} | ||||
|  | ||||
| 		utilsMock := newMtaBuildTestUtilsBundle() | ||||
| 		options := mtaBuildOptions{ApplicationName: "myApp", MtaBuildTool: "classic", BuildTarget: "CF", DefaultNpmRegistry: "https://example.org/npm", MtarName: "myName"} | ||||
|  | ||||
| 		existingFiles := make(map[string]string) | ||||
| 		existingFiles["package.json"] = "{\"name\": \"myName\", \"version\": \"1.2.3\"}" | ||||
| 		fileUtils := MtaTestFileUtilsMock{existingFiles: existingFiles} | ||||
| 		utilsMock.AddFile("package.json", []byte("{\"name\": \"myName\", \"version\": \"1.2.3\"}")) | ||||
|  | ||||
| 		npmExecutor := newNpmExecutor(&e) | ||||
| 		npmExecutor.Options = npm.ExecutorOptions{DefaultNpmRegistry: options.DefaultNpmRegistry} | ||||
|  | ||||
| 		err := runMtaBuild(options, &cpe, &e, &fileUtils, &httpClient, npmExecutor) | ||||
| 		err := runMtaBuild(options, &cpe, utilsMock) | ||||
|  | ||||
| 		assert.Nil(t, err) | ||||
|  | ||||
| 		if assert.Len(t, e.Calls, 3) { // the second (unchecked) entry is the mta call | ||||
| 			assert.Equal(t, "npm", e.Calls[1].Exec) | ||||
| 			assert.Equal(t, []string{"config", "set", "registry", "https://example.org/npm"}, e.Calls[1].Params) | ||||
| 		} | ||||
| 		assert.Equal(t, "https://example.org/npm", utilsMock.registryUsedInSetNpmRegistries) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Package json does not exist", func(t *testing.T) { | ||||
|  | ||||
| 		e := mock.ExecMockRunner{} | ||||
| 		utilsMock := newMtaBuildTestUtilsBundle() | ||||
|  | ||||
| 		options := mtaBuildOptions{ApplicationName: "myApp"} | ||||
|  | ||||
| 		fileUtils := MtaTestFileUtilsMock{} | ||||
|  | ||||
| 		err := runMtaBuild(options, &cpe, &e, &fileUtils, &httpClient, newNpmExecutor(&e)) | ||||
| 		err := runMtaBuild(options, &cpe, utilsMock) | ||||
|  | ||||
| 		assert.NotNil(t, err) | ||||
|  | ||||
| @@ -75,16 +91,13 @@ func TestMarBuild(t *testing.T) { | ||||
|  | ||||
| 	t.Run("Write yaml file", func(t *testing.T) { | ||||
|  | ||||
| 		e := mock.ExecMockRunner{} | ||||
| 		utilsMock := newMtaBuildTestUtilsBundle() | ||||
|  | ||||
| 		options := mtaBuildOptions{ApplicationName: "myApp", MtaBuildTool: "classic", BuildTarget: "CF", MtarName: "myName"} | ||||
|  | ||||
| 		existingFiles := make(map[string]string) | ||||
| 		existingFiles["package.json"] = "{\"name\": \"myName\", \"version\": \"1.2.3\"}" | ||||
| 		utilsMock.AddFile("package.json", []byte("{\"name\": \"myName\", \"version\": \"1.2.3\"}")) | ||||
|  | ||||
| 		fileUtils := MtaTestFileUtilsMock{existingFiles: existingFiles} | ||||
|  | ||||
| 		err := runMtaBuild(options, &cpe, &e, &fileUtils, &httpClient, newNpmExecutor(&e)) | ||||
| 		err := runMtaBuild(options, &cpe, utilsMock) | ||||
|  | ||||
| 		assert.Nil(t, err) | ||||
|  | ||||
| @@ -99,70 +112,65 @@ func TestMarBuild(t *testing.T) { | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		assert.NotEmpty(t, fileUtils.writtenFiles["mta.yaml"]) | ||||
| 		assert.True(t, utilsMock.HasWrittenFile("mta.yaml")) | ||||
|  | ||||
| 		var result MtaResult | ||||
| 		yaml.Unmarshal([]byte(fileUtils.writtenFiles["mta.yaml"]), &result) | ||||
| 		mtaContent, _ := utilsMock.FileRead("mta.yaml") | ||||
| 		yaml.Unmarshal(mtaContent, &result) | ||||
|  | ||||
| 		assert.Equal(t, "myName", result.ID) | ||||
| 		assert.Equal(t, "1.2.3", result.Version) | ||||
| 		assert.Equal(t, "myApp", result.Modules[0].Name) | ||||
| 		assert.Equal(t, result.Modules[0].Parameters["version"], "1.2.3-${timestamp}") | ||||
| 		assert.Regexp(t, "^1\\.2\\.3-[\\d]{14}$", result.Modules[0].Parameters["version"]) | ||||
| 		assert.Equal(t, "myApp", result.Modules[0].Parameters["name"]) | ||||
|  | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Dont write mta yaml file when already present no timestamp placeholder", func(t *testing.T) { | ||||
|  | ||||
| 		e := mock.ExecMockRunner{} | ||||
| 		utilsMock := newMtaBuildTestUtilsBundle() | ||||
|  | ||||
| 		options := mtaBuildOptions{ApplicationName: "myApp", MtaBuildTool: "classic", BuildTarget: "CF"} | ||||
|  | ||||
| 		existingFiles := make(map[string]string) | ||||
| 		existingFiles["package.json"] = "{\"name\": \"myName\", \"version\": \"1.2.3\"}" | ||||
| 		existingFiles["mta.yaml"] = "already there" | ||||
| 		fileUtils := MtaTestFileUtilsMock{existingFiles: existingFiles} | ||||
| 		utilsMock.AddFile("package.json", []byte("{\"name\": \"myName\", \"version\": \"1.2.3\"}")) | ||||
| 		utilsMock.AddFile("mta.yaml", []byte("already there")) | ||||
|  | ||||
| 		_ = runMtaBuild(options, &cpe, &e, &fileUtils, &httpClient, newNpmExecutor(&e)) | ||||
| 		_ = runMtaBuild(options, &cpe, utilsMock) | ||||
|  | ||||
| 		assert.Empty(t, fileUtils.writtenFiles) | ||||
| 		assert.False(t, utilsMock.HasWrittenFile("mta.yaml")) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Write mta yaml file when already present with timestamp placeholder", func(t *testing.T) { | ||||
|  | ||||
| 		e := mock.ExecMockRunner{} | ||||
| 		utilsMock := newMtaBuildTestUtilsBundle() | ||||
|  | ||||
| 		options := mtaBuildOptions{ApplicationName: "myApp", MtaBuildTool: "classic", BuildTarget: "CF"} | ||||
|  | ||||
| 		existingFiles := make(map[string]string) | ||||
| 		existingFiles["package.json"] = "{\"name\": \"myName\", \"version\": \"1.2.3\"}" | ||||
| 		existingFiles["mta.yaml"] = "already there with-${timestamp}" | ||||
| 		fileUtils := MtaTestFileUtilsMock{existingFiles: existingFiles} | ||||
| 		utilsMock.AddFile("package.json", []byte("{\"name\": \"myName\", \"version\": \"1.2.3\"}")) | ||||
| 		utilsMock.AddFile("mta.yaml", []byte("already there with-${timestamp}")) | ||||
|  | ||||
| 		_ = runMtaBuild(options, &cpe, &e, &fileUtils, &httpClient, newNpmExecutor(&e)) | ||||
| 		_ = runMtaBuild(options, &cpe, utilsMock) | ||||
|  | ||||
| 		assert.NotEmpty(t, fileUtils.writtenFiles["mta.yaml"]) | ||||
| 		assert.True(t, utilsMock.HasWrittenFile("mta.yaml")) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Test mta build classic toolset", func(t *testing.T) { | ||||
|  | ||||
| 		e := mock.ExecMockRunner{} | ||||
| 		utilsMock := newMtaBuildTestUtilsBundle() | ||||
|  | ||||
| 		options := mtaBuildOptions{ApplicationName: "myApp", MtaBuildTool: "classic", BuildTarget: "CF", MtarName: "myName.mtar"} | ||||
|  | ||||
| 		cpe.mtarFilePath = "" | ||||
|  | ||||
| 		existingFiles := make(map[string]string) | ||||
| 		existingFiles["package.json"] = "{\"name\": \"myName\", \"version\": \"1.2.3\"}" | ||||
| 		fileUtils := MtaTestFileUtilsMock{existingFiles: existingFiles} | ||||
| 		utilsMock.AddFile("package.json", []byte("{\"name\": \"myName\", \"version\": \"1.2.3\"}")) | ||||
|  | ||||
| 		err := runMtaBuild(options, &cpe, &e, &fileUtils, &httpClient, newNpmExecutor(&e)) | ||||
| 		err := runMtaBuild(options, &cpe, utilsMock) | ||||
|  | ||||
| 		assert.Nil(t, err) | ||||
|  | ||||
| 		if assert.Len(t, e.Calls, 2) { | ||||
| 			assert.Equal(t, "java", e.Calls[1].Exec) | ||||
| 			assert.Equal(t, []string{"-jar", "mta.jar", "--mtar", "myName.mtar", "--build-target=CF", "build"}, e.Calls[1].Params) | ||||
| 		if assert.Len(t, utilsMock.Calls, 1) { | ||||
| 			assert.Equal(t, "java", utilsMock.Calls[0].Exec) | ||||
| 			assert.Equal(t, []string{"-jar", "mta.jar", "--mtar", "myName.mtar", "--build-target=CF", "build"}, utilsMock.Calls[0].Params) | ||||
| 		} | ||||
|  | ||||
| 		assert.Equal(t, "myName.mtar", cpe.mtarFilePath) | ||||
| @@ -170,66 +178,60 @@ func TestMarBuild(t *testing.T) { | ||||
|  | ||||
| 	t.Run("Test mta build classic toolset, mtarName from already existing mta.yaml", func(t *testing.T) { | ||||
|  | ||||
| 		e := mock.ExecMockRunner{} | ||||
| 		utilsMock := newMtaBuildTestUtilsBundle() | ||||
|  | ||||
| 		options := mtaBuildOptions{ApplicationName: "myApp", MtaBuildTool: "classic", BuildTarget: "CF"} | ||||
|  | ||||
| 		cpe.mtarFilePath = "" | ||||
|  | ||||
| 		existingFiles := make(map[string]string) | ||||
| 		existingFiles["package.json"] = "{\"name\": \"myName\", \"version\": \"1.2.3\"}" | ||||
| 		existingFiles["mta.yaml"] = "ID: \"myNameFromMtar\"" | ||||
| 		fileUtils := MtaTestFileUtilsMock{existingFiles: existingFiles} | ||||
| 		utilsMock.AddFile("package.json", []byte("{\"name\": \"myName\", \"version\": \"1.2.3\"}")) | ||||
| 		utilsMock.AddFile("mta.yaml", []byte("ID: \"myNameFromMtar\"")) | ||||
|  | ||||
| 		err := runMtaBuild(options, &cpe, &e, &fileUtils, &httpClient, newNpmExecutor(&e)) | ||||
| 		err := runMtaBuild(options, &cpe, utilsMock) | ||||
|  | ||||
| 		assert.Nil(t, err) | ||||
|  | ||||
| 		if assert.Len(t, e.Calls, 2) { | ||||
| 			assert.Equal(t, "java", e.Calls[1].Exec) | ||||
| 			assert.Equal(t, []string{"-jar", "mta.jar", "--mtar", "myNameFromMtar.mtar", "--build-target=CF", "build"}, e.Calls[1].Params) | ||||
| 		if assert.Len(t, utilsMock.Calls, 1) { | ||||
| 			assert.Equal(t, "java", utilsMock.Calls[0].Exec) | ||||
| 			assert.Equal(t, []string{"-jar", "mta.jar", "--mtar", "myNameFromMtar.mtar", "--build-target=CF", "build"}, utilsMock.Calls[0].Params) | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Test mta build classic toolset with configured mta jar", func(t *testing.T) { | ||||
|  | ||||
| 		e := mock.ExecMockRunner{} | ||||
| 		utilsMock := newMtaBuildTestUtilsBundle() | ||||
|  | ||||
| 		options := mtaBuildOptions{ApplicationName: "myApp", MtaBuildTool: "classic", BuildTarget: "CF", MtaJarLocation: "/opt/sap/mta/lib/mta.jar", MtarName: "myName.mtar"} | ||||
|  | ||||
| 		existingFiles := make(map[string]string) | ||||
| 		existingFiles["package.json"] = "{\"name\": \"myName\", \"version\": \"1.2.3\"}" | ||||
| 		fileUtils := MtaTestFileUtilsMock{existingFiles: existingFiles} | ||||
| 		utilsMock.AddFile("package.json", []byte("{\"name\": \"myName\", \"version\": \"1.2.3\"}")) | ||||
|  | ||||
| 		err := runMtaBuild(options, &cpe, &e, &fileUtils, &httpClient, newNpmExecutor(&e)) | ||||
| 		err := runMtaBuild(options, &cpe, utilsMock) | ||||
|  | ||||
| 		assert.Nil(t, err) | ||||
|  | ||||
| 		if assert.Len(t, e.Calls, 2) { | ||||
| 			assert.Equal(t, "java", e.Calls[1].Exec) | ||||
| 			assert.Equal(t, []string{"-jar", "/opt/sap/mta/lib/mta.jar", "--mtar", "myName.mtar", "--build-target=CF", "build"}, e.Calls[1].Params) | ||||
| 		if assert.Len(t, utilsMock.Calls, 1) { | ||||
| 			assert.Equal(t, "java", utilsMock.Calls[0].Exec) | ||||
| 			assert.Equal(t, []string{"-jar", "/opt/sap/mta/lib/mta.jar", "--mtar", "myName.mtar", "--build-target=CF", "build"}, utilsMock.Calls[0].Params) | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Mta build mbt toolset", func(t *testing.T) { | ||||
|  | ||||
| 		e := mock.ExecMockRunner{} | ||||
| 		utilsMock := newMtaBuildTestUtilsBundle() | ||||
|  | ||||
| 		cpe.mtarFilePath = "" | ||||
|  | ||||
| 		options := mtaBuildOptions{ApplicationName: "myApp", MtaBuildTool: "cloudMbt", Platform: "CF", MtarName: "myName.mtar"} | ||||
|  | ||||
| 		existingFiles := make(map[string]string) | ||||
| 		existingFiles["package.json"] = "{\"name\": \"myName\", \"version\": \"1.2.3\"}" | ||||
| 		fileUtils := MtaTestFileUtilsMock{existingFiles: existingFiles} | ||||
| 		utilsMock.AddFile("package.json", []byte("{\"name\": \"myName\", \"version\": \"1.2.3\"}")) | ||||
|  | ||||
| 		err := runMtaBuild(options, &cpe, &e, &fileUtils, &httpClient, newNpmExecutor(&e)) | ||||
| 		err := runMtaBuild(options, &cpe, utilsMock) | ||||
|  | ||||
| 		assert.Nil(t, err) | ||||
|  | ||||
| 		if assert.Len(t, e.Calls, 2) { | ||||
| 			assert.Equal(t, "mbt", e.Calls[1].Exec) | ||||
| 			assert.Equal(t, []string{"build", "--mtar", "myName.mtar", "--platform", "CF", "--target", "./"}, e.Calls[1].Params) | ||||
| 		if assert.Len(t, utilsMock.Calls, 1) { | ||||
| 			assert.Equal(t, "mbt", utilsMock.Calls[0].Exec) | ||||
| 			assert.Equal(t, []string{"build", "--mtar", "myName.mtar", "--platform", "CF", "--target", "./"}, utilsMock.Calls[0].Params) | ||||
| 		} | ||||
| 		assert.Equal(t, "myName.mtar", cpe.mtarFilePath) | ||||
| 	}) | ||||
| @@ -237,145 +239,51 @@ func TestMarBuild(t *testing.T) { | ||||
| 	t.Run("M2Path related tests", func(t *testing.T) { | ||||
| 		t.Run("Mta build mbt toolset with m2Path", func(t *testing.T) { | ||||
|  | ||||
| 			e := mock.ExecMockRunner{} | ||||
|  | ||||
| 			utilsMock := newMtaBuildTestUtilsBundle() | ||||
| 			utilsMock.CurrentDir = "root_folder/workspace" | ||||
| 			cpe.mtarFilePath = "" | ||||
|  | ||||
| 			options := mtaBuildOptions{ApplicationName: "myApp", MtaBuildTool: "cloudMbt", Platform: "CF", MtarName: "myName.mtar", M2Path: ".pipeline/local_repo"} | ||||
|  | ||||
| 			existingFiles := make(map[string]string) | ||||
| 			existingFiles["mta.yaml"] = "ID: \"myNameFromMtar\"" | ||||
| 			fileUtils := MtaTestFileUtilsMock{existingFiles: existingFiles} | ||||
| 			utilsMock.AddFile("mta.yaml", []byte("ID: \"myNameFromMtar\"")) | ||||
|  | ||||
| 			err := runMtaBuild(options, &cpe, &e, &fileUtils, &httpClient, newNpmExecutor(&e)) | ||||
| 			err := runMtaBuild(options, &cpe, utilsMock) | ||||
|  | ||||
| 			assert.Nil(t, err) | ||||
| 			assert.Contains(t, e.Env, "MAVEN_OPTS=-Dmaven.repo.local=/root_folder/workspace/.pipeline/local_repo") | ||||
| 			assert.Contains(t, utilsMock.Env, "MAVEN_OPTS=-Dmaven.repo.local=/root_folder/workspace/.pipeline/local_repo") | ||||
| 		}) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Settings file releatd tests", func(t *testing.T) { | ||||
|  | ||||
| 		var projectSettingsFile string | ||||
| 		var globalSettingsFile string | ||||
|  | ||||
| 		defer func() { | ||||
| 			downloadAndCopySettingsFiles = maven.DownloadAndCopySettingsFiles | ||||
| 		}() | ||||
|  | ||||
| 		downloadAndCopySettingsFiles = func( | ||||
| 			globalSettings string, | ||||
| 			projectSettings string, | ||||
| 			fileUtils maven.FileUtils, | ||||
| 			httpClient maven.SettingsDownloadUtils) error { | ||||
| 			projectSettingsFile = projectSettings | ||||
| 			globalSettingsFile = globalSettings | ||||
| 			return nil | ||||
| 		} | ||||
|  | ||||
| 		fileUtils := MtaTestFileUtilsMock{} | ||||
| 		fileUtils.existingFiles = make(map[string]string) | ||||
| 		fileUtils.existingFiles["package.json"] = "{\"name\": \"myName\", \"version\": \"1.2.3\"}" | ||||
|  | ||||
| 		t.Run("Copy global settings file", func(t *testing.T) { | ||||
|  | ||||
| 			defer func() { | ||||
| 				projectSettingsFile = "" | ||||
| 				globalSettingsFile = "" | ||||
| 			}() | ||||
|  | ||||
| 			e := mock.ExecMockRunner{} | ||||
| 			utilsMock := newMtaBuildTestUtilsBundle() | ||||
| 			utilsMock.AddFile("mta.yaml", []byte("ID: \"myNameFromMtar\"")) | ||||
|  | ||||
| 			options := mtaBuildOptions{ApplicationName: "myApp", GlobalSettingsFile: "/opt/maven/settings.xml", MtaBuildTool: "cloudMbt", Platform: "CF", MtarName: "myName"} | ||||
|  | ||||
| 			err := runMtaBuild(options, &cpe, &e, &fileUtils, &httpClient, newNpmExecutor(&e)) | ||||
| 			err := runMtaBuild(options, &cpe, utilsMock) | ||||
|  | ||||
| 			assert.Nil(t, err) | ||||
|  | ||||
| 			assert.Equal(t, globalSettingsFile, "/opt/maven/settings.xml") | ||||
| 			assert.Equal(t, projectSettingsFile, "") | ||||
| 			assert.Equal(t, "/opt/maven/settings.xml", utilsMock.globalSettingsFile) | ||||
| 			assert.Equal(t, "", utilsMock.projectSettingsFile) | ||||
| 		}) | ||||
|  | ||||
| 		t.Run("Copy project settings file", func(t *testing.T) { | ||||
|  | ||||
| 			defer func() { | ||||
| 				projectSettingsFile = "" | ||||
| 				globalSettingsFile = "" | ||||
| 			}() | ||||
|  | ||||
| 			e := mock.ExecMockRunner{} | ||||
| 			utilsMock := newMtaBuildTestUtilsBundle() | ||||
| 			utilsMock.AddFile("mta.yaml", []byte("ID: \"myNameFromMtar\"")) | ||||
|  | ||||
| 			options := mtaBuildOptions{ApplicationName: "myApp", ProjectSettingsFile: "/my/project/settings.xml", MtaBuildTool: "cloudMbt", Platform: "CF", MtarName: "myName"} | ||||
|  | ||||
| 			err := runMtaBuild(options, &cpe, &e, &fileUtils, &httpClient, newNpmExecutor(&e)) | ||||
| 			err := runMtaBuild(options, &cpe, utilsMock) | ||||
|  | ||||
| 			assert.Nil(t, err) | ||||
|  | ||||
| 			assert.Equal(t, "/my/project/settings.xml", projectSettingsFile) | ||||
| 			assert.Equal(t, "", globalSettingsFile) | ||||
| 			assert.Equal(t, "/my/project/settings.xml", utilsMock.projectSettingsFile) | ||||
| 			assert.Equal(t, "", utilsMock.globalSettingsFile) | ||||
| 		}) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| type MtaTestFileUtilsMock struct { | ||||
| 	existingFiles map[string]string | ||||
| 	writtenFiles  map[string]string | ||||
| 	copiedFiles   map[string]string | ||||
| } | ||||
|  | ||||
| func (f *MtaTestFileUtilsMock) FileExists(path string) (bool, error) { | ||||
|  | ||||
| 	if _, ok := f.existingFiles[path]; ok { | ||||
| 		return true, nil | ||||
| 	} | ||||
| 	return false, nil | ||||
| } | ||||
|  | ||||
| func (f *MtaTestFileUtilsMock) Copy(src, dest string) (int64, error) { | ||||
|  | ||||
| 	if f.copiedFiles == nil { | ||||
| 		f.copiedFiles = make(map[string]string) | ||||
| 	} | ||||
| 	f.copiedFiles[src] = dest | ||||
|  | ||||
| 	return 0, nil | ||||
| } | ||||
|  | ||||
| func (f *MtaTestFileUtilsMock) FileRead(path string) ([]byte, error) { | ||||
| 	return []byte(f.existingFiles[path]), nil | ||||
| } | ||||
|  | ||||
| func (f *MtaTestFileUtilsMock) FileWrite(path string, content []byte, perm os.FileMode) error { | ||||
|  | ||||
| 	if f.writtenFiles == nil { | ||||
| 		f.writtenFiles = make(map[string]string) | ||||
| 	} | ||||
|  | ||||
| 	if _, ok := f.writtenFiles[path]; ok { | ||||
| 		delete(f.writtenFiles, path) | ||||
| 	} | ||||
| 	f.writtenFiles[path] = string(content) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (f *MtaTestFileUtilsMock) MkdirAll(path string, perm os.FileMode) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (f *MtaTestFileUtilsMock) Abs(path string) (string, error) { | ||||
| 	return "/root_folder/workspace/" + path, nil | ||||
| } | ||||
|  | ||||
| func (f *MtaTestFileUtilsMock) Glob(pattern string) (matches []string, err error) { | ||||
| 	return nil, fmt.Errorf("not implemented. func is only present in order to fullfil the interface contract. Needs to be ajusted in case it gets used.") | ||||
| } | ||||
|  | ||||
| func (f *MtaTestFileUtilsMock) Chmod(path string, mode os.FileMode) error { | ||||
| 	return fmt.Errorf("not implemented. func is only present in order to fullfil the interface contract. Needs to be ajusted in case it gets used.") | ||||
| } | ||||
|  | ||||
| func newNpmExecutor(execRunner *mock.ExecMockRunner) *npm.Execute { | ||||
| 	utils := newNpmMockUtilsBundle() | ||||
| 	utils.execRunner = execRunner | ||||
| 	return &npm.Execute{Utils: &utils} | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,10 @@ package cmd | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	piperhttp "github.com/SAP/jenkins-library/pkg/http" | ||||
| 	"github.com/pkg/errors" | ||||
| 	"io" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| @@ -22,33 +25,47 @@ import ( | ||||
| // nexusUploadUtils defines an interface for utility functionality used from external packages, | ||||
| // so it can be easily mocked for testing. | ||||
| type nexusUploadUtils interface { | ||||
| 	Stdout(out io.Writer) | ||||
| 	Stderr(err io.Writer) | ||||
| 	SetEnv(env []string) | ||||
| 	RunExecutable(e string, p ...string) error | ||||
|  | ||||
| 	FileExists(path string) (bool, error) | ||||
| 	FileRead(path string) ([]byte, error) | ||||
| 	FileWrite(path string, content []byte, perm os.FileMode) error | ||||
| 	FileRemove(path string) error | ||||
| 	DirExists(path string) (bool, error) | ||||
| 	Glob(pattern string) (matches []string, err error) | ||||
| 	Copy(src, dest string) (int64, error) | ||||
| 	MkdirAll(path string, perm os.FileMode) error | ||||
|  | ||||
| 	DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error | ||||
|  | ||||
| 	UsesMta() bool | ||||
| 	UsesMaven() bool | ||||
| 	UsesNpm() bool | ||||
|  | ||||
| 	getEnvParameter(path, name string) string | ||||
| 	getExecRunner() command.ExecRunner | ||||
| 	evaluate(options *maven.EvaluateOptions, expression string) (string, error) | ||||
| } | ||||
|  | ||||
| type utilsBundle struct { | ||||
| 	*piperutils.ProjectStructure | ||||
| 	*piperutils.Files | ||||
| 	execRunner *command.Command | ||||
| 	*command.Command | ||||
| 	*piperhttp.Client | ||||
| } | ||||
|  | ||||
| func newUtilsBundle() *utilsBundle { | ||||
| 	return &utilsBundle{ | ||||
| 	utils := utilsBundle{ | ||||
| 		ProjectStructure: &piperutils.ProjectStructure{}, | ||||
| 		Files:            &piperutils.Files{}, | ||||
| 		Command:          &command.Command{}, | ||||
| 		Client:           &piperhttp.Client{}, | ||||
| 	} | ||||
| 	utils.Stdout(log.Writer()) | ||||
| 	utils.Stderr(log.Writer()) | ||||
| 	return &utils | ||||
| } | ||||
|  | ||||
| func (u *utilsBundle) FileWrite(filePath string, content []byte, perm os.FileMode) error { | ||||
| @@ -66,17 +83,8 @@ func (u *utilsBundle) getEnvParameter(path, name string) string { | ||||
| 	return piperenv.GetParameter(path, name) | ||||
| } | ||||
|  | ||||
| func (u *utilsBundle) getExecRunner() command.ExecRunner { | ||||
| 	if u.execRunner == nil { | ||||
| 		u.execRunner = &command.Command{} | ||||
| 		u.execRunner.Stdout(log.Writer()) | ||||
| 		u.execRunner.Stderr(log.Writer()) | ||||
| 	} | ||||
| 	return u.execRunner | ||||
| } | ||||
|  | ||||
| func (u *utilsBundle) evaluate(options *maven.EvaluateOptions, expression string) (string, error) { | ||||
| 	return maven.Evaluate(options, expression, u.getExecRunner()) | ||||
| 	return maven.Evaluate(options, expression, u) | ||||
| } | ||||
|  | ||||
| func nexusUpload(options nexusUploadOptions, _ *telemetry.CustomData) { | ||||
| @@ -123,7 +131,6 @@ func runNexusUpload(utils nexusUploadUtils, uploader nexus.Uploader, options *ne | ||||
| } | ||||
|  | ||||
| func uploadNpmArtifacts(utils nexusUploadUtils, uploader nexus.Uploader, options *nexusUploadOptions) error { | ||||
| 	execRunner := utils.getExecRunner() | ||||
| 	environment := []string{"npm_config_registry=http://" + uploader.GetNpmRepoURL(), "npm_config_email=project-piper@no-reply.com"} | ||||
| 	if options.Username != "" && options.Password != "" { | ||||
| 		auth := b64.StdEncoding.EncodeToString([]byte(options.Username + ":" + options.Password)) | ||||
| @@ -131,8 +138,8 @@ func uploadNpmArtifacts(utils nexusUploadUtils, uploader nexus.Uploader, options | ||||
| 	} else { | ||||
| 		log.Entry().Info("No credentials provided for npm upload, trying to upload anonymously.") | ||||
| 	} | ||||
| 	execRunner.SetEnv(environment) | ||||
| 	err := execRunner.RunExecutable("npm", "publish") | ||||
| 	utils.SetEnv(environment) | ||||
| 	err := utils.RunExecutable("npm", "publish") | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| @@ -236,7 +243,7 @@ func setupNexusCredentialsSettingsFile(utils nexusUploadUtils, options *nexusUpl | ||||
| 	} | ||||
|  | ||||
| 	log.Entry().Debugf("Writing nexus credentials to environment") | ||||
| 	utils.getExecRunner().SetEnv([]string{"NEXUS_username=" + options.Username, "NEXUS_password=" + options.Password}) | ||||
| 	utils.SetEnv([]string{"NEXUS_username=" + options.Username, "NEXUS_password=" + options.Password}) | ||||
|  | ||||
| 	mavenOptions.ProjectSettingsFile = settingsPath | ||||
| 	mavenOptions.Defines = append(mavenOptions.Defines, "-DrepositoryId="+settingsServerID) | ||||
| @@ -299,7 +306,7 @@ func uploadArtifacts(utils nexusUploadUtils, uploader nexus.Uploader, options *n | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	err = uploadArtifactsBundle(d, generatePOM, mavenOptions, utils.getExecRunner()) | ||||
| 	err = uploadArtifactsBundle(d, generatePOM, mavenOptions, utils) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("uploading artifacts for ID '%s' failed: %w", uploader.GetArtifactsID(), err) | ||||
| 	} | ||||
| @@ -317,7 +324,7 @@ func appendItemToString(list, item string, first bool) string { | ||||
| } | ||||
|  | ||||
| func uploadArtifactsBundle(d artifactDefines, generatePOM bool, mavenOptions maven.ExecuteOptions, | ||||
| 	execRunner command.ExecRunner) error { | ||||
| 	utils nexusUploadUtils) error { | ||||
| 	if d.file == "" { | ||||
| 		return fmt.Errorf("no file specified") | ||||
| 	} | ||||
| @@ -337,7 +344,7 @@ func uploadArtifactsBundle(d artifactDefines, generatePOM bool, mavenOptions mav | ||||
| 	} | ||||
|  | ||||
| 	mavenOptions.Defines = append(mavenOptions.Defines, defines...) | ||||
| 	_, err := maven.Execute(&mavenOptions, execRunner) | ||||
| 	_, err := maven.Execute(&mavenOptions, utils) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,12 +1,13 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"github.com/SAP/jenkins-library/pkg/command" | ||||
| 	"github.com/SAP/jenkins-library/pkg/maven" | ||||
| 	"github.com/SAP/jenkins-library/pkg/mock" | ||||
| 	"github.com/SAP/jenkins-library/pkg/nexus" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| @@ -15,19 +16,29 @@ import ( | ||||
|  | ||||
| type mockUtilsBundle struct { | ||||
| 	*mock.FilesMock | ||||
| 	*mock.ExecMockRunner | ||||
| 	mta        bool | ||||
| 	maven      bool | ||||
| 	npm        bool | ||||
| 	properties map[string]map[string]string | ||||
| 	cpe        map[string]string | ||||
| 	execRunner mock.ExecMockRunner | ||||
| } | ||||
|  | ||||
| func newMockUtilsBundle(usesMta, usesMaven, usesNpm bool) mockUtilsBundle { | ||||
| 	utils := mockUtilsBundle{FilesMock: &mock.FilesMock{}, mta: usesMta, maven: usesMaven, npm: usesNpm} | ||||
| func (m *mockUtilsBundle) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error { | ||||
| 	return errors.New("Test should not download files.") | ||||
| } | ||||
|  | ||||
| func newMockUtilsBundle(usesMta, usesMaven, usesNpm bool) *mockUtilsBundle { | ||||
| 	utils := mockUtilsBundle{ | ||||
| 		FilesMock:      &mock.FilesMock{}, | ||||
| 		ExecMockRunner: &mock.ExecMockRunner{}, | ||||
| 		mta:            usesMta, | ||||
| 		maven:          usesMaven, | ||||
| 		npm:            usesNpm, | ||||
| 	} | ||||
| 	utils.properties = map[string]map[string]string{} | ||||
| 	utils.cpe = map[string]string{} | ||||
| 	return utils | ||||
| 	return &utils | ||||
| } | ||||
|  | ||||
| func (m *mockUtilsBundle) UsesMta() bool { | ||||
| @@ -47,10 +58,6 @@ func (m *mockUtilsBundle) getEnvParameter(path, name string) string { | ||||
| 	return m.cpe[path] | ||||
| } | ||||
|  | ||||
| func (m *mockUtilsBundle) getExecRunner() command.ExecRunner { | ||||
| 	return &m.execRunner | ||||
| } | ||||
|  | ||||
| func (m *mockUtilsBundle) setProperty(pomFile, expression, value string) { | ||||
| 	pomFile = strings.ReplaceAll(pomFile, "/", string(os.PathSeparator)) | ||||
| 	pomFile = strings.ReplaceAll(pomFile, "\\", string(os.PathSeparator)) | ||||
| @@ -148,7 +155,7 @@ func TestUploadMTAProjects(t *testing.T) { | ||||
| 		options := createOptions() | ||||
| 		options.GroupID = "" | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.EqualError(t, err, "the 'groupId' parameter needs to be provided for MTA projects") | ||||
| 		assert.Equal(t, 0, len(uploader.GetArtifacts())) | ||||
| 		assert.Equal(t, 0, len(uploader.uploadedArtifacts)) | ||||
| @@ -162,7 +169,7 @@ func TestUploadMTAProjects(t *testing.T) { | ||||
| 		options := createOptions() | ||||
| 		options.ArtifactID = "" | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		if assert.NoError(t, err) { | ||||
| 			assert.Equal(t, 2, len(uploader.uploadedArtifacts)) | ||||
| 			assert.Equal(t, "test", uploader.GetArtifactsID()) | ||||
| @@ -174,7 +181,7 @@ func TestUploadMTAProjects(t *testing.T) { | ||||
| 		uploader := mockUploader{} | ||||
| 		options := createOptions() | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.EqualError(t, err, "could not read from required project descriptor file 'mta.yml'") | ||||
| 		assert.Equal(t, 0, len(uploader.GetArtifacts())) | ||||
| 		assert.Equal(t, 0, len(uploader.uploadedArtifacts)) | ||||
| @@ -186,7 +193,7 @@ func TestUploadMTAProjects(t *testing.T) { | ||||
| 		uploader := mockUploader{} | ||||
| 		options := createOptions() | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.EqualError(t, err, | ||||
| 			"failed to parse contents of the project descriptor file 'mta.yaml'") | ||||
| 		assert.Equal(t, 0, len(uploader.GetArtifacts())) | ||||
| @@ -199,7 +206,7 @@ func TestUploadMTAProjects(t *testing.T) { | ||||
| 		uploader := mockUploader{} | ||||
| 		options := createOptions() | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.EqualError(t, err, | ||||
| 			"the project descriptor file 'mta.yaml' has an invalid version: version must not be empty") | ||||
| 		assert.Equal(t, 0, len(uploader.GetArtifacts())) | ||||
| @@ -212,7 +219,7 @@ func TestUploadMTAProjects(t *testing.T) { | ||||
| 		uploader := mockUploader{} | ||||
| 		options := createOptions() | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.EqualError(t, err, "artifact file not found 'test.mtar'") | ||||
|  | ||||
| 		assert.Equal(t, "0.3.0", uploader.GetArtifactsVersion()) | ||||
| @@ -234,7 +241,7 @@ func TestUploadMTAProjects(t *testing.T) { | ||||
| 		uploader := mockUploader{} | ||||
| 		options := createOptions() | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.NoError(t, err, "expected mta.yaml project upload to work") | ||||
|  | ||||
| 		assert.Equal(t, "0.3.0", uploader.GetArtifactsVersion()) | ||||
| @@ -257,7 +264,7 @@ func TestUploadMTAProjects(t *testing.T) { | ||||
| 		uploader := mockUploader{} | ||||
| 		options := createOptions() | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.NoError(t, err, "expected mta.yml project upload to work") | ||||
|  | ||||
| 		assert.Equal(t, "0.3.0", uploader.GetArtifactsVersion()) | ||||
| @@ -281,7 +288,7 @@ func TestUploadArtifacts(t *testing.T) { | ||||
| 		uploader := mockUploader{} | ||||
| 		options := createOptions() | ||||
|  | ||||
| 		err := uploadArtifacts(&utils, &uploader, &options, false) | ||||
| 		err := uploadArtifacts(utils, &uploader, &options, false) | ||||
| 		assert.EqualError(t, err, "no group ID was provided, or could be established from project files") | ||||
| 	}) | ||||
| 	t.Run("Uploading MTA project fails without any artifacts", func(t *testing.T) { | ||||
| @@ -291,15 +298,15 @@ func TestUploadArtifacts(t *testing.T) { | ||||
|  | ||||
| 		_ = uploader.SetInfo(options.GroupID, "some.id", "3.0") | ||||
|  | ||||
| 		err := uploadArtifacts(&utils, &uploader, &options, false) | ||||
| 		err := uploadArtifacts(utils, &uploader, &options, false) | ||||
| 		assert.EqualError(t, err, "no artifacts to upload") | ||||
| 	}) | ||||
| 	t.Run("Uploading MTA project fails for unknown reasons", func(t *testing.T) { | ||||
| 		utils := newMockUtilsBundle(false, true, false) | ||||
|  | ||||
| 		// Configure mocked execRunner to fail | ||||
| 		utils.execRunner.ShouldFailOnCommand = map[string]error{} | ||||
| 		utils.execRunner.ShouldFailOnCommand["mvn"] = fmt.Errorf("failed") | ||||
| 		utils.ShouldFailOnCommand = map[string]error{} | ||||
| 		utils.ShouldFailOnCommand["mvn"] = fmt.Errorf("failed") | ||||
|  | ||||
| 		uploader := mockUploader{} | ||||
| 		options := createOptions() | ||||
| @@ -313,7 +320,7 @@ func TestUploadArtifacts(t *testing.T) { | ||||
| 			Type: "yaml", | ||||
| 		}) | ||||
|  | ||||
| 		err := uploadArtifacts(&utils, &uploader, &options, false) | ||||
| 		err := uploadArtifacts(utils, &uploader, &options, false) | ||||
| 		assert.EqualError(t, err, "uploading artifacts for ID 'some.id' failed: failed to run executable, command: '[mvn -Durl=http:// -DgroupId=my.group.id -Dversion=3.0 -DartifactId=some.id -Dfile=mta.yaml -Dpackaging=yaml -DgeneratePom=false -Dfiles=artifact.mtar -Dclassifiers= -Dtypes=yaml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode "+deployGoal+"]', error: failed") | ||||
| 	}) | ||||
| 	t.Run("Uploading bundle generates correct maven parameters", func(t *testing.T) { | ||||
| @@ -332,9 +339,9 @@ func TestUploadArtifacts(t *testing.T) { | ||||
| 			Type: "pom", | ||||
| 		}) | ||||
|  | ||||
| 		err := uploadArtifacts(&utils, &uploader, &options, false) | ||||
| 		err := uploadArtifacts(utils, &uploader, &options, false) | ||||
| 		assert.NoError(t, err, "expected upload as two bundles to work") | ||||
| 		assert.Equal(t, 1, len(utils.execRunner.Calls)) | ||||
| 		assert.Equal(t, 1, len(utils.Calls)) | ||||
|  | ||||
| 		expectedParameters1 := []string{ | ||||
| 			"-Durl=http://localhost:8081/repository/maven-releases/", | ||||
| @@ -350,8 +357,8 @@ func TestUploadArtifacts(t *testing.T) { | ||||
| 			"-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", | ||||
| 			"--batch-mode", | ||||
| 			deployGoal} | ||||
| 		assert.Equal(t, len(expectedParameters1), len(utils.execRunner.Calls[0].Params)) | ||||
| 		assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: expectedParameters1}, utils.execRunner.Calls[0]) | ||||
| 		assert.Equal(t, len(expectedParameters1), len(utils.Calls[0].Params)) | ||||
| 		assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: expectedParameters1}, utils.Calls[0]) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -364,13 +371,13 @@ func TestUploadNpmProjects(t *testing.T) { | ||||
| 		options.Username = "admin" | ||||
| 		options.Password = "admin123" | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.NoError(t, err, "expected npm upload to work") | ||||
|  | ||||
| 		assert.Equal(t, "localhost:8081/repository/npm-repo/", uploader.GetNpmRepoURL()) | ||||
|  | ||||
| 		assert.Equal(t, mock.ExecCall{Exec: "npm", Params: []string{"publish"}}, utils.execRunner.Calls[0]) | ||||
| 		assert.Equal(t, []string{"npm_config_registry=http://localhost:8081/repository/npm-repo/", "npm_config_email=project-piper@no-reply.com", "npm_config__auth=YWRtaW46YWRtaW4xMjM="}, utils.execRunner.Env) | ||||
| 		assert.Equal(t, mock.ExecCall{Exec: "npm", Params: []string{"publish"}}, utils.Calls[0]) | ||||
| 		assert.Equal(t, []string{"npm_config_registry=http://localhost:8081/repository/npm-repo/", "npm_config_email=project-piper@no-reply.com", "npm_config__auth=YWRtaW46YWRtaW4xMjM="}, utils.Env) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -381,7 +388,7 @@ func TestUploadMavenProjects(t *testing.T) { | ||||
| 		uploader := mockUploader{} | ||||
| 		options := createOptions() | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.EqualError(t, err, "pom.xml not found") | ||||
| 		assert.Equal(t, 0, len(uploader.uploadedArtifacts)) | ||||
| 	}) | ||||
| @@ -396,7 +403,7 @@ func TestUploadMavenProjects(t *testing.T) { | ||||
| 		uploader := mockUploader{} | ||||
| 		options := createOptions() | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.NoError(t, err, "expected Maven upload to work") | ||||
| 		assert.Equal(t, "1.0", uploader.GetArtifactsVersion()) | ||||
| 		assert.Equal(t, "my-app", uploader.GetArtifactsID()) | ||||
| @@ -419,7 +426,7 @@ func TestUploadMavenProjects(t *testing.T) { | ||||
| 		uploader := mockUploader{} | ||||
| 		options := createOptions() | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.EqualError(t, err, "target artifact not found for packaging 'jar'") | ||||
| 		assert.Equal(t, 0, len(uploader.uploadedArtifacts)) | ||||
| 	}) | ||||
| @@ -435,7 +442,7 @@ func TestUploadMavenProjects(t *testing.T) { | ||||
| 		uploader := mockUploader{} | ||||
| 		options := createOptions() | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.NoError(t, err, "expected Maven upload to work") | ||||
|  | ||||
| 		assert.Equal(t, "1.0", uploader.GetArtifactsVersion()) | ||||
| @@ -462,7 +469,7 @@ func TestUploadMavenProjects(t *testing.T) { | ||||
| 		uploader := mockUploader{} | ||||
| 		options := createOptions() | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.NoError(t, err, "expected Maven upload to work") | ||||
| 		assert.Equal(t, "1.0", uploader.GetArtifactsVersion()) | ||||
| 		assert.Equal(t, "my-app", uploader.GetArtifactsID()) | ||||
| @@ -487,7 +494,7 @@ func TestUploadMavenProjects(t *testing.T) { | ||||
| 		options := createOptions() | ||||
| 		options.GroupID = "awesome.group" | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.NoError(t, err, "expected Maven upload to work") | ||||
|  | ||||
| 		assert.Equal(t, "localhost:8081/repository/maven-releases/", | ||||
| @@ -512,7 +519,7 @@ func TestUploadMavenProjects(t *testing.T) { | ||||
| 		uploader := mockUploader{} | ||||
| 		options := createOptions() | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.NoError(t, err, "expected Maven upload to work") | ||||
|  | ||||
| 		assert.Equal(t, "localhost:8081/repository/maven-releases/", | ||||
| @@ -566,7 +573,7 @@ func TestUploadMavenProjects(t *testing.T) { | ||||
| 		uploader := mockUploader{} | ||||
| 		options := createOptions() | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.NoError(t, err, "expected upload of maven project with application module to succeed") | ||||
| 		assert.Equal(t, "1.0", uploader.GetArtifactsVersion()) | ||||
| 		assert.Equal(t, "my-app", uploader.GetArtifactsID()) | ||||
| @@ -586,7 +593,7 @@ func TestUploadMavenProjects(t *testing.T) { | ||||
| 			assert.Equal(t, "pom", artifacts[3].Type) | ||||
|  | ||||
| 		} | ||||
| 		if assert.Equal(t, 2, len(utils.execRunner.Calls)) { | ||||
| 		if assert.Equal(t, 2, len(utils.Calls)) { | ||||
| 			expectedParameters1 := []string{ | ||||
| 				"-Durl=http://localhost:8081/repository/maven-releases/", | ||||
| 				"-DgroupId=com.mycompany.app", | ||||
| @@ -600,8 +607,8 @@ func TestUploadMavenProjects(t *testing.T) { | ||||
| 				"-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", | ||||
| 				"--batch-mode", | ||||
| 				deployGoal} | ||||
| 			assert.Equal(t, len(expectedParameters1), len(utils.execRunner.Calls[0].Params)) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: expectedParameters1}, utils.execRunner.Calls[0]) | ||||
| 			assert.Equal(t, len(expectedParameters1), len(utils.Calls[0].Params)) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: expectedParameters1}, utils.Calls[0]) | ||||
|  | ||||
| 			expectedParameters2 := []string{ | ||||
| 				"-Durl=http://localhost:8081/repository/maven-releases/", | ||||
| @@ -613,8 +620,8 @@ func TestUploadMavenProjects(t *testing.T) { | ||||
| 				"-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", | ||||
| 				"--batch-mode", | ||||
| 				deployGoal} | ||||
| 			assert.Equal(t, len(expectedParameters2), len(utils.execRunner.Calls[1].Params)) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: expectedParameters2}, utils.execRunner.Calls[1]) | ||||
| 			assert.Equal(t, len(expectedParameters2), len(utils.Calls[1].Params)) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: expectedParameters2}, utils.Calls[1]) | ||||
| 		} | ||||
| 	}) | ||||
| 	t.Run("Write credentials settings", func(t *testing.T) { | ||||
| @@ -630,10 +637,10 @@ func TestUploadMavenProjects(t *testing.T) { | ||||
| 		options.Username = "admin" | ||||
| 		options.Password = "admin123" | ||||
|  | ||||
| 		err := runNexusUpload(&utils, &uploader, &options) | ||||
| 		err := runNexusUpload(utils, &uploader, &options) | ||||
| 		assert.NoError(t, err, "expected Maven upload to work") | ||||
|  | ||||
| 		assert.Equal(t, 1, len(utils.execRunner.Calls)) | ||||
| 		assert.Equal(t, 1, len(utils.Calls)) | ||||
| 		expectedParameters1 := []string{ | ||||
| 			"--settings", | ||||
| 			settingsPath, | ||||
| @@ -647,12 +654,12 @@ func TestUploadMavenProjects(t *testing.T) { | ||||
| 			"-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", | ||||
| 			"--batch-mode", | ||||
| 			deployGoal} | ||||
| 		assert.Equal(t, len(expectedParameters1), len(utils.execRunner.Calls[0].Params)) | ||||
| 		assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: expectedParameters1}, utils.execRunner.Calls[0]) | ||||
| 		assert.Equal(t, len(expectedParameters1), len(utils.Calls[0].Params)) | ||||
| 		assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: expectedParameters1}, utils.Calls[0]) | ||||
|  | ||||
| 		expectedEnv := []string{"NEXUS_username=admin", "NEXUS_password=admin123"} | ||||
| 		assert.Equal(t, 2, len(utils.execRunner.Env)) | ||||
| 		assert.Equal(t, expectedEnv, utils.execRunner.Env) | ||||
| 		assert.Equal(t, 2, len(utils.Env)) | ||||
| 		assert.Equal(t, expectedEnv, utils.Env) | ||||
|  | ||||
| 		assert.False(t, utils.HasFile(settingsPath)) | ||||
| 		assert.True(t, utils.HasRemovedFile(settingsPath)) | ||||
| @@ -663,13 +670,13 @@ func TestSetupNexusCredentialsSettingsFile(t *testing.T) { | ||||
| 	utils := newMockUtilsBundle(false, true, false) | ||||
| 	options := nexusUploadOptions{Username: "admin", Password: "admin123"} | ||||
| 	mavenOptions := maven.ExecuteOptions{} | ||||
| 	settingsPath, err := setupNexusCredentialsSettingsFile(&utils, &options, &mavenOptions) | ||||
| 	settingsPath, err := setupNexusCredentialsSettingsFile(utils, &options, &mavenOptions) | ||||
|  | ||||
| 	assert.NoError(t, err, "expected setting up credentials settings.xml to work") | ||||
| 	assert.Equal(t, 0, len(utils.execRunner.Calls)) | ||||
| 	assert.Equal(t, 0, len(utils.Calls)) | ||||
| 	expectedEnv := []string{"NEXUS_username=admin", "NEXUS_password=admin123"} | ||||
| 	assert.Equal(t, 2, len(utils.execRunner.Env)) | ||||
| 	assert.Equal(t, expectedEnv, utils.execRunner.Env) | ||||
| 	assert.Equal(t, 2, len(utils.Env)) | ||||
| 	assert.Equal(t, expectedEnv, utils.Env) | ||||
|  | ||||
| 	assert.True(t, settingsPath != "") | ||||
| 	assert.True(t, utils.HasFile(settingsPath)) | ||||
|   | ||||
| @@ -3,14 +3,16 @@ package maven | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"github.com/SAP/jenkins-library/pkg/command" | ||||
| 	piperhttp "github.com/SAP/jenkins-library/pkg/http" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
| 	"io" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
|  | ||||
| 	piperhttp "github.com/SAP/jenkins-library/pkg/http" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
| ) | ||||
|  | ||||
| // ExecuteOptions are used by Execute() to construct the Maven command line. | ||||
| @@ -36,44 +38,50 @@ type EvaluateOptions struct { | ||||
| 	Defines             []string `json:"defines,omitempty"` | ||||
| } | ||||
|  | ||||
| type mavenExecRunner interface { | ||||
| type Utils interface { | ||||
| 	Stdout(out io.Writer) | ||||
| 	Stderr(err io.Writer) | ||||
| 	RunExecutable(e string, p ...string) error | ||||
| } | ||||
|  | ||||
| type mavenUtils interface { | ||||
| 	FileUtils | ||||
| 	DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error | ||||
| 	Glob(pattern string) (matches []string, err error) | ||||
| 	FileExists(filename string) (bool, error) | ||||
| 	Copy(src, dest string) (int64, error) | ||||
| 	MkdirAll(path string, perm os.FileMode) error | ||||
| } | ||||
|  | ||||
| type utilsBundle struct { | ||||
| 	*piperhttp.Client | ||||
| 	*command.Command | ||||
| 	*piperutils.Files | ||||
| 	*piperhttp.Client | ||||
| } | ||||
|  | ||||
| func newUtils() *utilsBundle { | ||||
| 	return &utilsBundle{ | ||||
| 		Client: &piperhttp.Client{}, | ||||
| 		Files:  &piperutils.Files{}, | ||||
| func NewUtilsBundle() Utils { | ||||
| 	utils := utilsBundle{ | ||||
| 		Command: &command.Command{}, | ||||
| 		Files:   &piperutils.Files{}, | ||||
| 		Client:  &piperhttp.Client{}, | ||||
| 	} | ||||
| 	utils.Stdout(log.Writer()) | ||||
| 	utils.Stderr(log.Writer()) | ||||
| 	return &utils | ||||
| } | ||||
|  | ||||
| const mavenExecutable = "mvn" | ||||
|  | ||||
| // Execute constructs a mvn command line from the given options, and uses the provided | ||||
| // mavenExecRunner to execute it. | ||||
| func Execute(options *ExecuteOptions, command mavenExecRunner) (string, error) { | ||||
| func Execute(options *ExecuteOptions, utils Utils) (string, error) { | ||||
| 	stdOutBuf, stdOut := evaluateStdOut(options) | ||||
| 	command.Stdout(stdOut) | ||||
| 	command.Stderr(log.Writer()) | ||||
| 	utils.Stdout(stdOut) | ||||
| 	utils.Stderr(log.Writer()) | ||||
|  | ||||
| 	parameters, err := getParametersFromOptions(options, newUtils()) | ||||
| 	parameters, err := getParametersFromOptions(options, utils) | ||||
| 	if err != nil { | ||||
| 		return "", fmt.Errorf("failed to construct parameters from options: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	err = command.RunExecutable(mavenExecutable, parameters...) | ||||
| 	err = utils.RunExecutable(mavenExecutable, parameters...) | ||||
| 	if err != nil { | ||||
| 		log.SetErrorCategory(log.ErrorBuild) | ||||
| 		commandLine := append([]string{mavenExecutable}, parameters...) | ||||
| @@ -89,7 +97,7 @@ func Execute(options *ExecuteOptions, command mavenExecRunner) (string, error) { | ||||
| // Evaluate constructs ExecuteOptions for using the maven-help-plugin's 'evaluate' goal to | ||||
| // evaluate a given expression from a pom file. This allows to retrieve the value of - for | ||||
| // example - 'project.version' from a pom file exactly as Maven itself evaluates it. | ||||
| func Evaluate(options *EvaluateOptions, expression string, command mavenExecRunner) (string, error) { | ||||
| func Evaluate(options *EvaluateOptions, expression string, utils Utils) (string, error) { | ||||
| 	defines := []string{"-Dexpression=" + expression, "-DforceStdout", "-q"} | ||||
| 	defines = append(defines, options.Defines...) | ||||
| 	executeOptions := ExecuteOptions{ | ||||
| @@ -101,7 +109,7 @@ func Evaluate(options *EvaluateOptions, expression string, command mavenExecRunn | ||||
| 		Defines:             defines, | ||||
| 		ReturnStdout:        true, | ||||
| 	} | ||||
| 	value, err := Execute(&executeOptions, command) | ||||
| 	value, err := Execute(&executeOptions, utils) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| @@ -113,7 +121,7 @@ func Evaluate(options *EvaluateOptions, expression string, command mavenExecRunn | ||||
|  | ||||
| // InstallFile installs a maven artifact and its pom into the local maven repository. | ||||
| // If "file" is empty, only the pom is installed. "pomFile" must not be empty. | ||||
| func InstallFile(file, pomFile string, options *EvaluateOptions, command mavenExecRunner) error { | ||||
| func InstallFile(file, pomFile string, options *EvaluateOptions, utils Utils) error { | ||||
| 	if len(pomFile) == 0 { | ||||
| 		return fmt.Errorf("pomFile can't be empty") | ||||
| 	} | ||||
| @@ -139,7 +147,7 @@ func InstallFile(file, pomFile string, options *EvaluateOptions, command mavenEx | ||||
| 		ProjectSettingsFile: options.ProjectSettingsFile, | ||||
| 		GlobalSettingsFile:  options.GlobalSettingsFile, | ||||
| 	} | ||||
| 	_, err := Execute(&mavenOptionsInstall, command) | ||||
| 	_, err := Execute(&mavenOptionsInstall, utils) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("failed to install maven artifacts: %w", err) | ||||
| 	} | ||||
| @@ -147,12 +155,12 @@ func InstallFile(file, pomFile string, options *EvaluateOptions, command mavenEx | ||||
| } | ||||
|  | ||||
| // InstallMavenArtifacts finds maven modules (identified by pom.xml files) and installs the artifacts into the local maven repository. | ||||
| func InstallMavenArtifacts(command mavenExecRunner, options *EvaluateOptions) error { | ||||
| 	return doInstallMavenArtifacts(command, options, newUtils()) | ||||
| func InstallMavenArtifacts(options *EvaluateOptions, utils Utils) error { | ||||
| 	return doInstallMavenArtifacts(options, utils) | ||||
| } | ||||
|  | ||||
| func doInstallMavenArtifacts(command mavenExecRunner, options *EvaluateOptions, utils mavenUtils) error { | ||||
| 	err := flattenPom(command, options) | ||||
| func doInstallMavenArtifacts(options *EvaluateOptions, utils Utils) error { | ||||
| 	err := flattenPom(options, utils) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @@ -178,7 +186,7 @@ func doInstallMavenArtifacts(command mavenExecRunner, options *EvaluateOptions, | ||||
| 		// otherwise we would evaluate the root pom in all iterations. | ||||
| 		evaluateProjectPackagingOptions := *options | ||||
| 		evaluateProjectPackagingOptions.PomPath = pomFile | ||||
| 		packaging, err := Evaluate(&evaluateProjectPackagingOptions, "project.packaging", command) | ||||
| 		packaging, err := Evaluate(&evaluateProjectPackagingOptions, "project.packaging", utils) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -193,13 +201,13 @@ func doInstallMavenArtifacts(command mavenExecRunner, options *EvaluateOptions, | ||||
| 		} | ||||
|  | ||||
| 		if packaging == "pom" { | ||||
| 			err = InstallFile("", pathToPomFile, options, command) | ||||
| 			err = InstallFile("", pathToPomFile, options, utils) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} else { | ||||
|  | ||||
| 			err = installJarWarArtifacts(pathToPomFile, currentModuleDir, command, utils, options) | ||||
| 			err = installJarWarArtifacts(pathToPomFile, currentModuleDir, options, utils) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| @@ -208,15 +216,15 @@ func doInstallMavenArtifacts(command mavenExecRunner, options *EvaluateOptions, | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func installJarWarArtifacts(pomFile, dir string, command mavenExecRunner, utils mavenUtils, options *EvaluateOptions) error { | ||||
| func installJarWarArtifacts(pomFile, dir string, options *EvaluateOptions, utils Utils) error { | ||||
| 	options.PomPath = filepath.Join(dir, "pom.xml") | ||||
| 	finalName, err := Evaluate(options, "project.build.finalName", command) | ||||
| 	finalName, err := Evaluate(options, "project.build.finalName", utils) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if finalName == "" { | ||||
| 		log.Entry().Warn("project.build.finalName is empty, skipping install of artifact. Installing only the pom file.") | ||||
| 		err = InstallFile("", pomFile, options, command) | ||||
| 		err = InstallFile("", pomFile, options, utils) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -235,26 +243,26 @@ func installJarWarArtifacts(pomFile, dir string, command mavenExecRunner, utils | ||||
|  | ||||
| 	// Due to spring's jar repackaging we need to check for an "original" jar file because the repackaged one is no suitable source for dependent maven modules | ||||
| 	if originalJarExists { | ||||
| 		err = InstallFile(originalJarFile(dir, finalName), pomFile, options, command) | ||||
| 		err = InstallFile(originalJarFile(dir, finalName), pomFile, options, utils) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} else if jarExists { | ||||
| 		err = InstallFile(jarFile(dir, finalName), pomFile, options, command) | ||||
| 		err = InstallFile(jarFile(dir, finalName), pomFile, options, utils) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if warExists { | ||||
| 		err = InstallFile(warFile(dir, finalName), pomFile, options, command) | ||||
| 		err = InstallFile(warFile(dir, finalName), pomFile, options, utils) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if classesJarExists { | ||||
| 		err = InstallFile(classesJarFile(dir, finalName), pomFile, options, command) | ||||
| 		err = InstallFile(classesJarFile(dir, finalName), pomFile, options, utils) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -278,16 +286,16 @@ func warFile(dir, finalName string) string { | ||||
| 	return filepath.Join(dir, "target", finalName+".war") | ||||
| } | ||||
|  | ||||
| func flattenPom(command mavenExecRunner, o *EvaluateOptions) error { | ||||
| func flattenPom(options *EvaluateOptions, utils Utils) error { | ||||
| 	mavenOptionsFlatten := ExecuteOptions{ | ||||
| 		Goals:               []string{"flatten:flatten"}, | ||||
| 		Defines:             []string{"-Dflatten.mode=resolveCiFriendliesOnly"}, | ||||
| 		PomPath:             "pom.xml", | ||||
| 		M2Path:              o.M2Path, | ||||
| 		ProjectSettingsFile: o.ProjectSettingsFile, | ||||
| 		GlobalSettingsFile:  o.GlobalSettingsFile, | ||||
| 		M2Path:              options.M2Path, | ||||
| 		ProjectSettingsFile: options.ProjectSettingsFile, | ||||
| 		GlobalSettingsFile:  options.GlobalSettingsFile, | ||||
| 	} | ||||
| 	_, err := Execute(&mavenOptionsFlatten, command) | ||||
| 	_, err := Execute(&mavenOptionsFlatten, utils) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| @@ -301,10 +309,10 @@ func evaluateStdOut(options *ExecuteOptions) (*bytes.Buffer, io.Writer) { | ||||
| 	return stdOutBuf, stdOut | ||||
| } | ||||
|  | ||||
| func getParametersFromOptions(options *ExecuteOptions, utils mavenUtils) ([]string, error) { | ||||
| func getParametersFromOptions(options *ExecuteOptions, utils Utils) ([]string, error) { | ||||
| 	var parameters []string | ||||
|  | ||||
| 	parameters, err := DownloadAndGetMavenParameters(options.GlobalSettingsFile, options.ProjectSettingsFile, utils, utils) | ||||
| 	parameters, err := DownloadAndGetMavenParameters(options.GlobalSettingsFile, options.ProjectSettingsFile, utils) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @@ -336,11 +344,8 @@ func getParametersFromOptions(options *ExecuteOptions, utils mavenUtils) ([]stri | ||||
| 	return parameters, nil | ||||
| } | ||||
|  | ||||
| func GetTestModulesExcludes() []string { | ||||
| 	return getTestModulesExcludes(newUtils()) | ||||
| } | ||||
|  | ||||
| func getTestModulesExcludes(utils mavenUtils) []string { | ||||
| // GetTestModulesExcludes return testing modules that you be excluded from reactor | ||||
| func GetTestModulesExcludes(utils Utils) []string { | ||||
| 	var excludes []string | ||||
| 	exists, _ := utils.FileExists("unit-tests/pom.xml") | ||||
| 	if exists { | ||||
|   | ||||
| @@ -11,14 +11,15 @@ import ( | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| type mockUtils struct { | ||||
| type MockUtils struct { | ||||
| 	shouldFail     bool | ||||
| 	requestedUrls  []string | ||||
| 	requestedFiles []string | ||||
| 	*mock.FilesMock | ||||
| 	*mock.ExecMockRunner | ||||
| } | ||||
|  | ||||
| func (m *mockUtils) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error { | ||||
| func (m *MockUtils) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error { | ||||
| 	m.requestedUrls = append(m.requestedUrls, url) | ||||
| 	m.requestedFiles = append(m.requestedFiles, filename) | ||||
| 	if m.shouldFail { | ||||
| @@ -27,43 +28,48 @@ func (m *mockUtils) DownloadFile(url, filename string, header http.Header, cooki | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func newMockUtils(downloadShouldFail bool) mockUtils { | ||||
| 	utils := mockUtils{shouldFail: downloadShouldFail, FilesMock: &mock.FilesMock{}} | ||||
| func NewMockUtils(downloadShouldFail bool) MockUtils { | ||||
| 	utils := MockUtils{ | ||||
| 		shouldFail:     downloadShouldFail, | ||||
| 		FilesMock:      &mock.FilesMock{}, | ||||
| 		ExecMockRunner: &mock.ExecMockRunner{}, | ||||
| 	} | ||||
| 	return utils | ||||
| } | ||||
|  | ||||
| func TestExecute(t *testing.T) { | ||||
| 	t.Run("should return stdOut", func(t *testing.T) { | ||||
| 		expectedOutput := "mocked output" | ||||
| 		execMockRunner := mock.ExecMockRunner{} | ||||
| 		execMockRunner.StdoutReturn = map[string]string{"mvn --file pom.xml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode": "mocked output"} | ||||
| 		utils := NewMockUtils(false) | ||||
| 		utils.StdoutReturn = map[string]string{"mvn --file pom.xml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode": "mocked output"} | ||||
| 		opts := ExecuteOptions{PomPath: "pom.xml", ReturnStdout: true} | ||||
|  | ||||
| 		mavenOutput, _ := Execute(&opts, &execMockRunner) | ||||
| 		mavenOutput, _ := Execute(&opts, &utils) | ||||
|  | ||||
| 		assert.Equal(t, expectedOutput, mavenOutput) | ||||
| 	}) | ||||
| 	t.Run("should not return stdOut", func(t *testing.T) { | ||||
| 		expectedOutput := "" | ||||
| 		execMockRunner := mock.ExecMockRunner{} | ||||
| 		execMockRunner.StdoutReturn = map[string]string{"mvn --file pom.xml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode": "mocked output"} | ||||
| 		utils := NewMockUtils(false) | ||||
| 		utils.StdoutReturn = map[string]string{"mvn --file pom.xml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode": "mocked output"} | ||||
| 		opts := ExecuteOptions{PomPath: "pom.xml", ReturnStdout: false} | ||||
|  | ||||
| 		mavenOutput, _ := Execute(&opts, &execMockRunner) | ||||
| 		mavenOutput, _ := Execute(&opts, &utils) | ||||
|  | ||||
| 		assert.Equal(t, expectedOutput, mavenOutput) | ||||
| 	}) | ||||
| 	t.Run("should log that command failed if executing maven failed", func(t *testing.T) { | ||||
| 		execMockRunner := mock.ExecMockRunner{ShouldFailOnCommand: map[string]error{"mvn --file pom.xml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode": errors.New("error case")}} | ||||
| 		utils := NewMockUtils(false) | ||||
| 		utils.ShouldFailOnCommand = map[string]error{"mvn --file pom.xml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode": errors.New("error case")} | ||||
| 		opts := ExecuteOptions{PomPath: "pom.xml", ReturnStdout: false} | ||||
|  | ||||
| 		output, err := Execute(&opts, &execMockRunner) | ||||
| 		output, err := Execute(&opts, &utils) | ||||
|  | ||||
| 		assert.EqualError(t, err, "failed to run executable, command: '[mvn --file pom.xml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode]', error: error case") | ||||
| 		assert.Equal(t, "", output) | ||||
| 	}) | ||||
| 	t.Run("should have all configured parameters in the exec call", func(t *testing.T) { | ||||
| 		execMockRunner := mock.ExecMockRunner{} | ||||
| 		utils := NewMockUtils(false) | ||||
| 		opts := ExecuteOptions{PomPath: "pom.xml", ProjectSettingsFile: "settings.xml", | ||||
| 			GlobalSettingsFile: "anotherSettings.xml", M2Path: ".m2/", | ||||
| 			Goals: []string{"flatten", "install"}, Defines: []string{"-Da=b"}, | ||||
| @@ -73,29 +79,29 @@ func TestExecute(t *testing.T) { | ||||
| 			"-Dmaven.repo.local=.m2/", "--file", "pom.xml", "-q", "-Da=b", "--batch-mode", | ||||
| 			"flatten", "install"} | ||||
|  | ||||
| 		mavenOutput, _ := Execute(&opts, &execMockRunner) | ||||
| 		mavenOutput, _ := Execute(&opts, &utils) | ||||
|  | ||||
| 		assert.Equal(t, len(expectedParameters), len(execMockRunner.Calls[0].Params)) | ||||
| 		assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: expectedParameters}, execMockRunner.Calls[0]) | ||||
| 		assert.Equal(t, len(expectedParameters), len(utils.Calls[0].Params)) | ||||
| 		assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: expectedParameters}, utils.Calls[0]) | ||||
| 		assert.Equal(t, "", mavenOutput) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func TestEvaluate(t *testing.T) { | ||||
| 	t.Run("should evaluate expression", func(t *testing.T) { | ||||
| 		execMockRunner := mock.ExecMockRunner{} | ||||
| 		execMockRunner.StdoutReturn = map[string]string{"mvn --file pom.xml -Dexpression=project.groupId -DforceStdout -q -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate": "com.awesome"} | ||||
| 		utils := NewMockUtils(false) | ||||
| 		utils.StdoutReturn = map[string]string{"mvn --file pom.xml -Dexpression=project.groupId -DforceStdout -q -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate": "com.awesome"} | ||||
|  | ||||
| 		result, err := Evaluate(&EvaluateOptions{PomPath: "pom.xml"}, "project.groupId", &execMockRunner) | ||||
| 		result, err := Evaluate(&EvaluateOptions{PomPath: "pom.xml"}, "project.groupId", &utils) | ||||
| 		if assert.NoError(t, err) { | ||||
| 			assert.Equal(t, "com.awesome", result) | ||||
| 		} | ||||
| 	}) | ||||
| 	t.Run("should not evaluate expression", func(t *testing.T) { | ||||
| 		execMockRunner := mock.ExecMockRunner{} | ||||
| 		execMockRunner.StdoutReturn = map[string]string{"mvn --file pom.xml -Dexpression=project.groupId -DforceStdout -q -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate": "null object or invalid expression"} | ||||
| 		utils := NewMockUtils(false) | ||||
| 		utils.StdoutReturn = map[string]string{"mvn --file pom.xml -Dexpression=project.groupId -DforceStdout -q -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate": "null object or invalid expression"} | ||||
|  | ||||
| 		result, err := Evaluate(&EvaluateOptions{PomPath: "pom.xml"}, "project.groupId", &execMockRunner) | ||||
| 		result, err := Evaluate(&EvaluateOptions{PomPath: "pom.xml"}, "project.groupId", &utils) | ||||
| 		if assert.EqualError(t, err, "expression 'project.groupId' in file 'pom.xml' could not be resolved") { | ||||
| 			assert.Equal(t, "", result) | ||||
| 		} | ||||
| @@ -104,7 +110,7 @@ func TestEvaluate(t *testing.T) { | ||||
|  | ||||
| func TestGetParameters(t *testing.T) { | ||||
| 	t.Run("should resolve configured parameters and download the settings files", func(t *testing.T) { | ||||
| 		utils := newMockUtils(false) | ||||
| 		utils := NewMockUtils(false) | ||||
| 		opts := ExecuteOptions{PomPath: "pom.xml", GlobalSettingsFile: "https://mysettings.com", ProjectSettingsFile: "http://myprojectsettings.com", ReturnStdout: false} | ||||
| 		expectedParameters := []string{ | ||||
| 			"--global-settings", ".pipeline/mavenGlobalSettings.xml", | ||||
| @@ -126,7 +132,7 @@ func TestGetParameters(t *testing.T) { | ||||
| 		} | ||||
| 	}) | ||||
| 	t.Run("should resolve configured parameters and not download existing settings files", func(t *testing.T) { | ||||
| 		utils := newMockUtils(false) | ||||
| 		utils := NewMockUtils(false) | ||||
| 		utils.AddFile(".pipeline/mavenGlobalSettings.xml", []byte("dummyContent")) | ||||
| 		utils.AddFile(".pipeline/mavenProjectSettings.xml", []byte("dummyContent")) | ||||
| 		opts := ExecuteOptions{PomPath: "pom.xml", GlobalSettingsFile: "https://mysettings.com", ProjectSettingsFile: "http://myprojectsettings.com", ReturnStdout: false} | ||||
| @@ -148,20 +154,20 @@ func TestGetParameters(t *testing.T) { | ||||
|  | ||||
| func TestGetTestModulesExcludes(t *testing.T) { | ||||
| 	t.Run("Should return excludes for unit- and integration-tests", func(t *testing.T) { | ||||
| 		utils := newMockUtils(false) | ||||
| 		utils := NewMockUtils(false) | ||||
| 		utils.AddFile("unit-tests/pom.xml", []byte("dummyContent")) | ||||
| 		utils.AddFile("integration-tests/pom.xml", []byte("dummyContent")) | ||||
| 		expected := []string{"-pl", "!unit-tests", "-pl", "!integration-tests"} | ||||
|  | ||||
| 		modulesExcludes := getTestModulesExcludes(&utils) | ||||
| 		modulesExcludes := GetTestModulesExcludes(&utils) | ||||
| 		assert.Equal(t, expected, modulesExcludes) | ||||
| 	}) | ||||
| 	t.Run("Should not return excludes for unit- and integration-tests", func(t *testing.T) { | ||||
| 		utils := newMockUtils(false) | ||||
| 		utils := NewMockUtils(false) | ||||
|  | ||||
| 		var expected []string | ||||
|  | ||||
| 		modulesExcludes := getTestModulesExcludes(&utils) | ||||
| 		modulesExcludes := GetTestModulesExcludes(&utils) | ||||
| 		assert.Equal(t, expected, modulesExcludes) | ||||
| 	}) | ||||
| } | ||||
| @@ -179,58 +185,54 @@ func TestMavenInstall(t *testing.T) { | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Install a file", func(t *testing.T) { | ||||
| 		execMockRunner := mock.ExecMockRunner{} | ||||
| 		utils := NewMockUtils(false) | ||||
| 		expectedParameters := []string{"-Dfile=app.jar", "-Dpackaging=jar", "-DpomFile=pom.xml", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "install:install-file"} | ||||
|  | ||||
| 		err := InstallFile("app.jar", "pom.xml", &EvaluateOptions{}, &execMockRunner) | ||||
| 		err := InstallFile("app.jar", "pom.xml", &EvaluateOptions{}, &utils) | ||||
|  | ||||
| 		assert.NoError(t, err) | ||||
| 		if assert.Equal(t, len(expectedParameters), len(execMockRunner.Calls[0].Params)) { | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: expectedParameters}, execMockRunner.Calls[0]) | ||||
| 		if assert.Equal(t, len(expectedParameters), len(utils.Calls[0].Params)) { | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: expectedParameters}, utils.Calls[0]) | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Install files in a project", func(t *testing.T) { | ||||
| 		utils := newMockUtils(false) | ||||
| 		utils := NewMockUtils(false) | ||||
| 		utils.AddFile("target/foo.jar", []byte("dummyContent")) | ||||
| 		utils.AddFile("target/foo.war", []byte("dummyContent")) | ||||
| 		utils.AddFile("pom.xml", []byte("<project></project>")) | ||||
|  | ||||
| 		options := EvaluateOptions{} | ||||
|  | ||||
| 		options.ProjectSettingsFile = "settings.xml" | ||||
|  | ||||
| 		execMockRunner := mock.ExecMockRunner{} | ||||
| 		execMockRunner.StdoutReturn = map[string]string{"mvn --settings settings.xml --file pom.xml -Dexpression=project.build.finalName -DforceStdout -q -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate": "foo"} | ||||
| 		err := doInstallMavenArtifacts(&execMockRunner, &options, &utils) | ||||
| 		utils.StdoutReturn = map[string]string{"mvn --settings settings.xml --file pom.xml -Dexpression=project.build.finalName -DforceStdout -q -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate": "foo"} | ||||
| 		err := doInstallMavenArtifacts(&options, &utils) | ||||
|  | ||||
| 		assert.NoError(t, err) | ||||
| 		if assert.Equal(t, 5, len(execMockRunner.Calls)) { | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--settings", "settings.xml", "--file", "pom.xml", "-Dflatten.mode=resolveCiFriendliesOnly", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "flatten:flatten"}}, execMockRunner.Calls[0]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--settings", "settings.xml", "--file", "pom.xml", "-Dexpression=project.packaging", "-DforceStdout", "-q", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate"}}, execMockRunner.Calls[1]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--settings", "settings.xml", "--file", "pom.xml", "-Dexpression=project.build.finalName", "-DforceStdout", "-q", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate"}}, execMockRunner.Calls[2]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--settings", "settings.xml", "-Dfile=" + filepath.Join(".", "target", "foo.jar"), "-Dpackaging=jar", "-DpomFile=pom.xml", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "install:install-file"}}, execMockRunner.Calls[3]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--settings", "settings.xml", "-Dfile=" + filepath.Join(".", "target", "foo.war"), "-DpomFile=pom.xml", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "install:install-file"}}, execMockRunner.Calls[4]) | ||||
| 		if assert.Equal(t, 5, len(utils.Calls)) { | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--settings", "settings.xml", "--file", "pom.xml", "-Dflatten.mode=resolveCiFriendliesOnly", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "flatten:flatten"}}, utils.Calls[0]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--settings", "settings.xml", "--file", "pom.xml", "-Dexpression=project.packaging", "-DforceStdout", "-q", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate"}}, utils.Calls[1]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--settings", "settings.xml", "--file", "pom.xml", "-Dexpression=project.build.finalName", "-DforceStdout", "-q", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate"}}, utils.Calls[2]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--settings", "settings.xml", "-Dfile=" + filepath.Join(".", "target", "foo.jar"), "-Dpackaging=jar", "-DpomFile=pom.xml", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "install:install-file"}}, utils.Calls[3]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--settings", "settings.xml", "-Dfile=" + filepath.Join(".", "target", "foo.war"), "-DpomFile=pom.xml", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "install:install-file"}}, utils.Calls[4]) | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Install files in a spring-boot project", func(t *testing.T) { | ||||
| 		utils := newMockUtils(false) | ||||
| 		utils := NewMockUtils(false) | ||||
| 		utils.AddFile("target/foo.jar", []byte("dummyContent")) | ||||
| 		utils.AddFile("target/foo.jar.original", []byte("dummyContent")) | ||||
| 		utils.AddFile("pom.xml", []byte("<project></project>")) | ||||
|  | ||||
| 		options := EvaluateOptions{} | ||||
| 		execMockRunner := mock.ExecMockRunner{} | ||||
| 		execMockRunner.StdoutReturn = map[string]string{"mvn --file pom.xml -Dexpression=project.build.finalName -DforceStdout -q -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate": "foo"} | ||||
| 		err := doInstallMavenArtifacts(&execMockRunner, &options, &utils) | ||||
| 		utils.StdoutReturn = map[string]string{"mvn --file pom.xml -Dexpression=project.build.finalName -DforceStdout -q -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate": "foo"} | ||||
| 		err := doInstallMavenArtifacts(&options, &utils) | ||||
|  | ||||
| 		assert.NoError(t, err) | ||||
| 		if assert.Equal(t, 4, len(execMockRunner.Calls)) { | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--file", "pom.xml", "-Dflatten.mode=resolveCiFriendliesOnly", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "flatten:flatten"}}, execMockRunner.Calls[0]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--file", "pom.xml", "-Dexpression=project.packaging", "-DforceStdout", "-q", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate"}}, execMockRunner.Calls[1]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--file", "pom.xml", "-Dexpression=project.build.finalName", "-DforceStdout", "-q", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate"}}, execMockRunner.Calls[2]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"-Dfile=" + filepath.Join(".", "target", "foo.jar.original"), "-Dpackaging=jar", "-DpomFile=pom.xml", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "install:install-file"}}, execMockRunner.Calls[3]) | ||||
| 		if assert.Equal(t, 4, len(utils.Calls)) { | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--file", "pom.xml", "-Dflatten.mode=resolveCiFriendliesOnly", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "flatten:flatten"}}, utils.Calls[0]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--file", "pom.xml", "-Dexpression=project.packaging", "-DforceStdout", "-q", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate"}}, utils.Calls[1]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"--file", "pom.xml", "-Dexpression=project.build.finalName", "-DforceStdout", "-q", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate"}}, utils.Calls[2]) | ||||
| 			assert.Equal(t, mock.ExecCall{Exec: "mvn", Params: []string{"-Dfile=" + filepath.Join(".", "target", "foo.jar.original"), "-Dpackaging=jar", "-DpomFile=pom.xml", "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "install:install-file"}}, utils.Calls[3]) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -11,25 +11,20 @@ import ( | ||||
|  | ||||
| var getenv = os.Getenv | ||||
|  | ||||
| // SettingsDownloadUtils defines an interface for downloading files. | ||||
| // SettingsDownloadUtils defines an interface for downloading and storing maven settings files. | ||||
| type SettingsDownloadUtils interface { | ||||
| 	DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error | ||||
| } | ||||
|  | ||||
| // FileUtils defines the external file-related functionality needed by this package. | ||||
| type FileUtils interface { | ||||
| 	FileExists(filename string) (bool, error) | ||||
| 	Copy(src, dest string) (int64, error) | ||||
| 	MkdirAll(path string, perm os.FileMode) error | ||||
| 	Glob(pattern string) (matches []string, err error) | ||||
| } | ||||
|  | ||||
| // DownloadAndGetMavenParameters downloads the global or project settings file if the strings contain URLs. | ||||
| // It then constructs the arguments that need to be passed to maven in order to point to use these settings files. | ||||
| func DownloadAndGetMavenParameters(globalSettingsFile string, projectSettingsFile string, fileUtils FileUtils, httpClient SettingsDownloadUtils) ([]string, error) { | ||||
| func DownloadAndGetMavenParameters(globalSettingsFile string, projectSettingsFile string, utils SettingsDownloadUtils) ([]string, error) { | ||||
| 	mavenArgs := []string{} | ||||
| 	if len(globalSettingsFile) > 0 { | ||||
| 		globalSettingsFileName, err := downloadSettingsIfURL(globalSettingsFile, ".pipeline/mavenGlobalSettings.xml", fileUtils, httpClient, false) | ||||
| 		globalSettingsFileName, err := downloadSettingsIfURL(globalSettingsFile, ".pipeline/mavenGlobalSettings.xml", utils, false) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| @@ -40,7 +35,7 @@ func DownloadAndGetMavenParameters(globalSettingsFile string, projectSettingsFil | ||||
| 	} | ||||
|  | ||||
| 	if len(projectSettingsFile) > 0 { | ||||
| 		projectSettingsFileName, err := downloadSettingsIfURL(projectSettingsFile, ".pipeline/mavenProjectSettings.xml", fileUtils, httpClient, false) | ||||
| 		projectSettingsFileName, err := downloadSettingsIfURL(projectSettingsFile, ".pipeline/mavenProjectSettings.xml", utils, false) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| @@ -55,14 +50,14 @@ func DownloadAndGetMavenParameters(globalSettingsFile string, projectSettingsFil | ||||
| // DownloadAndCopySettingsFiles downloads the global or project settings file if the strings contain URLs. | ||||
| // It copies the given files to either the locations specified in the environment variables M2_HOME and HOME | ||||
| // or the default locations where maven expects them. | ||||
| func DownloadAndCopySettingsFiles(globalSettingsFile string, projectSettingsFile string, fileUtils FileUtils, httpClient SettingsDownloadUtils) error { | ||||
| func DownloadAndCopySettingsFiles(globalSettingsFile string, projectSettingsFile string, utils SettingsDownloadUtils) error { | ||||
| 	if len(projectSettingsFile) > 0 { | ||||
| 		destination, err := getProjectSettingsFileDest() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		if err := downloadAndCopySettingsFile(projectSettingsFile, destination, fileUtils, httpClient); err != nil { | ||||
| 		if err := downloadAndCopySettingsFile(projectSettingsFile, destination, utils); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} else { | ||||
| @@ -75,7 +70,7 @@ func DownloadAndCopySettingsFiles(globalSettingsFile string, projectSettingsFile | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if err := downloadAndCopySettingsFile(globalSettingsFile, destination, fileUtils, httpClient); err != nil { | ||||
| 		if err := downloadAndCopySettingsFile(globalSettingsFile, destination, utils); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} else { | ||||
| @@ -86,7 +81,7 @@ func DownloadAndCopySettingsFiles(globalSettingsFile string, projectSettingsFile | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func downloadAndCopySettingsFile(src string, dest string, fileUtils FileUtils, httpClient SettingsDownloadUtils) error { | ||||
| func downloadAndCopySettingsFile(src string, dest string, utils SettingsDownloadUtils) error { | ||||
| 	if len(src) == 0 { | ||||
| 		return fmt.Errorf("Settings file source location not provided") | ||||
| 	} | ||||
| @@ -98,7 +93,7 @@ func downloadAndCopySettingsFile(src string, dest string, fileUtils FileUtils, h | ||||
| 	log.Entry().Debugf("Copying file \"%s\" to \"%s\"", src, dest) | ||||
|  | ||||
| 	if strings.HasPrefix(src, "http:") || strings.HasPrefix(src, "https:") { | ||||
| 		err := downloadSettingsFromURL(src, dest, fileUtils, httpClient, true) | ||||
| 		err := downloadSettingsFromURL(src, dest, utils, true) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -108,19 +103,19 @@ func downloadAndCopySettingsFile(src string, dest string, fileUtils FileUtils, h | ||||
|  | ||||
| 		parent := filepath.Dir(dest) | ||||
|  | ||||
| 		parentFolderExists, err := fileUtils.FileExists(parent) | ||||
| 		parentFolderExists, err := utils.FileExists(parent) | ||||
|  | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		if !parentFolderExists { | ||||
| 			if err = fileUtils.MkdirAll(parent, 0775); err != nil { | ||||
| 			if err = utils.MkdirAll(parent, 0775); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if _, err := fileUtils.Copy(src, dest); err != nil { | ||||
| 		if _, err := utils.Copy(src, dest); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| @@ -128,10 +123,10 @@ func downloadAndCopySettingsFile(src string, dest string, fileUtils FileUtils, h | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func downloadSettingsIfURL(settingsFileOption, settingsFile string, fileUtils FileUtils, httpClient SettingsDownloadUtils, overwrite bool) (string, error) { | ||||
| func downloadSettingsIfURL(settingsFileOption, settingsFile string, utils SettingsDownloadUtils, overwrite bool) (string, error) { | ||||
| 	result := settingsFileOption | ||||
| 	if strings.HasPrefix(settingsFileOption, "http:") || strings.HasPrefix(settingsFileOption, "https:") { | ||||
| 		err := downloadSettingsFromURL(settingsFileOption, settingsFile, fileUtils, httpClient, overwrite) | ||||
| 		err := downloadSettingsFromURL(settingsFileOption, settingsFile, utils, overwrite) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
| @@ -140,13 +135,13 @@ func downloadSettingsIfURL(settingsFileOption, settingsFile string, fileUtils Fi | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func downloadSettingsFromURL(url, filename string, fileUtils FileUtils, httpClient SettingsDownloadUtils, overwrite bool) error { | ||||
| 	exists, _ := fileUtils.FileExists(filename) | ||||
| func downloadSettingsFromURL(url, filename string, utils SettingsDownloadUtils, overwrite bool) error { | ||||
| 	exists, _ := utils.FileExists(filename) | ||||
| 	if exists && !overwrite { | ||||
| 		log.Entry().Infof("Not downloading maven settings file, because it already exists at '%s'", filename) | ||||
| 		return nil | ||||
| 	} | ||||
| 	err := httpClient.DownloadFile(url, filename, nil, nil) | ||||
| 	err := utils.DownloadFile(url, filename, nil, nil) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("failed to download maven settings from URL '%s' to file '%s': %w", | ||||
| 			url, filename, err) | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package maven | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	piperhttp "github.com/SAP/jenkins-library/pkg/http" | ||||
| 	"github.com/SAP/jenkins-library/pkg/mock" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| @@ -26,60 +27,56 @@ func TestSettings(t *testing.T) { | ||||
|  | ||||
| 	t.Run("Settings file source location not provided", func(t *testing.T) { | ||||
|  | ||||
| 		httpClient := httpMock{} | ||||
| 		fileUtils := fileUtilsMock{} | ||||
| 		utilsMock := newSettingsDownloadTestUtilsBundle() | ||||
|  | ||||
| 		err := downloadAndCopySettingsFile("", "foo", &fileUtils, &httpClient) | ||||
| 		err := downloadAndCopySettingsFile("", "foo", utilsMock) | ||||
|  | ||||
| 		assert.EqualError(t, err, "Settings file source location not provided") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Settings file destination location not provided", func(t *testing.T) { | ||||
|  | ||||
| 		httpClient := httpMock{} | ||||
| 		fileUtils := fileUtilsMock{} | ||||
| 		utilsMock := newSettingsDownloadTestUtilsBundle() | ||||
|  | ||||
| 		err := downloadAndCopySettingsFile("/opt/sap/maven/global-settings.xml", "", &fileUtils, &httpClient) | ||||
| 		err := downloadAndCopySettingsFile("/opt/sap/maven/global-settings.xml", "", utilsMock) | ||||
|  | ||||
| 		assert.EqualError(t, err, "Settings file destination location not provided") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Retrieve settings files", func(t *testing.T) { | ||||
|  | ||||
| 		httpClient := httpMock{} | ||||
| 		fileUtils := fileUtilsMock{existingFiles: map[string]string{ | ||||
| 			"/opt/sap/maven/global-settings.xml":  "", | ||||
| 			"/opt/sap/maven/project-settings.xml": "", | ||||
| 		}} | ||||
| 		utilsMock := newSettingsDownloadTestUtilsBundle() | ||||
|  | ||||
| 		err := DownloadAndCopySettingsFiles("/opt/sap/maven/global-settings.xml", "/opt/sap/maven/project-settings.xml", &fileUtils, &httpClient) | ||||
| 		utilsMock.AddFile("/opt/sap/maven/global-settings.xml", []byte("")) | ||||
| 		utilsMock.AddFile("/opt/sap/maven/project-settings.xml", []byte("")) | ||||
|  | ||||
| 		err := DownloadAndCopySettingsFiles("/opt/sap/maven/global-settings.xml", "/opt/sap/maven/project-settings.xml", utilsMock) | ||||
|  | ||||
| 		if assert.NoError(t, err) { | ||||
| 			assert.Equal(t, "/usr/share/maven/conf/settings.xml", fileUtils.copiedFiles["/opt/sap/maven/global-settings.xml"]) | ||||
| 			assert.Equal(t, "/home/me/.m2/settings.xml", fileUtils.copiedFiles["/opt/sap/maven/project-settings.xml"]) | ||||
| 			assert.True(t, utilsMock.HasCopiedFile("/opt/sap/maven/global-settings.xml", "/usr/share/maven/conf/settings.xml")) | ||||
| 			assert.True(t, utilsMock.HasCopiedFile("/opt/sap/maven/project-settings.xml", "/home/me/.m2/settings.xml")) | ||||
| 		} | ||||
|  | ||||
| 		assert.Empty(t, httpClient.downloadedFiles) | ||||
| 		assert.Empty(t, utilsMock.downloadedFiles) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Retrieve settings file via http", func(t *testing.T) { | ||||
|  | ||||
| 		httpClient := httpMock{} | ||||
| 		fileUtils := fileUtilsMock{} | ||||
| 		utilsMock := newSettingsDownloadTestUtilsBundle() | ||||
|  | ||||
| 		err := downloadAndCopySettingsFile("https://example.org/maven/global-settings.xml", "/usr/share/maven/conf/settings.xml", &fileUtils, &httpClient) | ||||
| 		err := downloadAndCopySettingsFile("https://example.org/maven/global-settings.xml", "/usr/share/maven/conf/settings.xml", utilsMock) | ||||
|  | ||||
| 		if assert.NoError(t, err) { | ||||
| 			assert.Equal(t, "/usr/share/maven/conf/settings.xml", httpClient.downloadedFiles["https://example.org/maven/global-settings.xml"]) | ||||
| 			assert.Equal(t, "/usr/share/maven/conf/settings.xml", utilsMock.downloadedFiles["https://example.org/maven/global-settings.xml"]) | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("Retrieve settings file via http - received error from downloader", func(t *testing.T) { | ||||
|  | ||||
| 		httpClient := httpMock{expectedError: fmt.Errorf("Download failed")} | ||||
| 		fileUtils := fileUtilsMock{} | ||||
| 		utilsMock := newSettingsDownloadTestUtilsBundle() | ||||
| 		utilsMock.expectedError = fmt.Errorf("Download failed") | ||||
|  | ||||
| 		err := downloadAndCopySettingsFile("https://example.org/maven/global-settings.xml", "/usr/share/maven/conf/settings.xml", &fileUtils, &httpClient) | ||||
| 		err := downloadAndCopySettingsFile("https://example.org/maven/global-settings.xml", "/usr/share/maven/conf/settings.xml", utilsMock) | ||||
|  | ||||
| 		if assert.Error(t, err) { | ||||
| 			assert.Contains(t, err.Error(), "failed to download maven settings from URL") | ||||
| @@ -88,26 +85,33 @@ func TestSettings(t *testing.T) { | ||||
|  | ||||
| 	t.Run("Retrieve project settings file - file not found", func(t *testing.T) { | ||||
|  | ||||
| 		httpClient := httpMock{} | ||||
| 		fileUtils := fileUtilsMock{} | ||||
| 		utilsMock := newSettingsDownloadTestUtilsBundle() | ||||
|  | ||||
| 		err := downloadAndCopySettingsFile("/opt/sap/maven/project-settings.xml", "/home/me/.m2/settings.xml", &fileUtils, &httpClient) | ||||
| 		err := downloadAndCopySettingsFile("/opt/sap/maven/project-settings.xml", "/home/me/.m2/settings.xml", utilsMock) | ||||
|  | ||||
| 		if assert.Error(t, err) { | ||||
| 			assert.Contains(t, err.Error(), "Source file '/opt/sap/maven/project-settings.xml' does not exist") | ||||
| 			assert.Contains(t, err.Error(), "cannot copy '/opt/sap/maven/project-settings.xml': file does not exist") | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| type httpMock struct { | ||||
| func newSettingsDownloadTestUtilsBundle() *settingsDownloadTestUtils { | ||||
| 	utilsBundle := settingsDownloadTestUtils{ | ||||
| 		FilesMock: &mock.FilesMock{}, | ||||
| 	} | ||||
| 	return &utilsBundle | ||||
| } | ||||
|  | ||||
| type settingsDownloadTestUtils struct { | ||||
| 	*mock.FilesMock | ||||
| 	expectedError   error | ||||
| 	downloadedFiles map[string]string // src, dest | ||||
| } | ||||
|  | ||||
| func (c *httpMock) SetOptions(options piperhttp.ClientOptions) { | ||||
| func (c *settingsDownloadTestUtils) SetOptions(options piperhttp.ClientOptions) { | ||||
| } | ||||
|  | ||||
| func (c *httpMock) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error { | ||||
| func (c *settingsDownloadTestUtils) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error { | ||||
|  | ||||
| 	if c.expectedError != nil { | ||||
| 		return c.expectedError | ||||
| @@ -119,70 +123,3 @@ func (c *httpMock) DownloadFile(url, filename string, header http.Header, cookie | ||||
| 	c.downloadedFiles[url] = filename | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type fileUtilsMock struct { | ||||
| 	existingFiles map[string]string | ||||
| 	writtenFiles  map[string]string | ||||
| 	copiedFiles   map[string]string | ||||
| } | ||||
|  | ||||
| func (f *fileUtilsMock) FileExists(path string) (bool, error) { | ||||
|  | ||||
| 	if _, ok := f.existingFiles[path]; ok { | ||||
| 		return true, nil | ||||
| 	} | ||||
| 	return false, nil | ||||
| } | ||||
|  | ||||
| func (f *fileUtilsMock) Copy(src, dest string) (int64, error) { | ||||
|  | ||||
| 	exists, err := f.FileExists(src) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
|  | ||||
| 	if !exists { | ||||
| 		return 0, fmt.Errorf("Source file '"+src+"' does not exist", src) | ||||
| 	} | ||||
|  | ||||
| 	if f.copiedFiles == nil { | ||||
| 		f.copiedFiles = make(map[string]string) | ||||
| 	} | ||||
| 	f.copiedFiles[src] = dest | ||||
|  | ||||
| 	return 0, nil | ||||
| } | ||||
|  | ||||
| func (f *fileUtilsMock) FileRead(path string) ([]byte, error) { | ||||
| 	return []byte(f.existingFiles[path]), nil | ||||
| } | ||||
|  | ||||
| func (f *fileUtilsMock) FileWrite(path string, content []byte, perm os.FileMode) error { | ||||
|  | ||||
| 	if f.writtenFiles == nil { | ||||
| 		f.writtenFiles = make(map[string]string) | ||||
| 	} | ||||
|  | ||||
| 	if _, ok := f.writtenFiles[path]; ok { | ||||
| 		delete(f.writtenFiles, path) | ||||
| 	} | ||||
| 	f.writtenFiles[path] = string(content) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (f *fileUtilsMock) MkdirAll(path string, perm os.FileMode) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (f *fileUtilsMock) Chmod(path string, mode os.FileMode) error { | ||||
| 	return fmt.Errorf("not implemented. func is only present in order to fullfil the interface contract. Needs to be ajusted in case it gets used.") | ||||
| } | ||||
|  | ||||
| func (f *fileUtilsMock) Abs(path string) (string, error) { | ||||
| 	return "", fmt.Errorf("not implemented. func is only present in order to fullfil the interface contract. Needs to be ajusted in case it gets used.") | ||||
| } | ||||
|  | ||||
| func (f *fileUtilsMock) Glob(pattern string) (matches []string, err error) { | ||||
| 	return nil, fmt.Errorf("not implemented. func is only present in order to fullfil the interface contract. Needs to be ajusted in case it gets used.") | ||||
| } | ||||
|   | ||||
| @@ -49,6 +49,7 @@ func (p *fileProperties) isDir() bool { | ||||
| type FilesMock struct { | ||||
| 	files        map[string]*fileProperties | ||||
| 	writtenFiles []string | ||||
| 	copiedFiles  map[string]string | ||||
| 	removedFiles []string | ||||
| 	CurrentDir   string | ||||
| 	Separator    string | ||||
| @@ -61,6 +62,9 @@ func (f *FilesMock) init() { | ||||
| 	if f.Separator == "" { | ||||
| 		f.Separator = string(os.PathSeparator) | ||||
| 	} | ||||
| 	if f.copiedFiles == nil { | ||||
| 		f.copiedFiles = map[string]string{} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // toAbsPath checks if the given path is relative, and if so converts it to an absolute path considering the | ||||
| @@ -134,6 +138,12 @@ func (f *FilesMock) HasWrittenFile(path string) bool { | ||||
| 	return piperutils.ContainsString(f.writtenFiles, f.toAbsPath(path)) | ||||
| } | ||||
|  | ||||
| // HasCopiedFile returns true if the virtual file system at one point contained an entry for the given source and destination, | ||||
| // and it was written via CopyFile(). | ||||
| func (f *FilesMock) HasCopiedFile(src string, dest string) bool { | ||||
| 	return f.copiedFiles[f.toAbsPath(src)] == f.toAbsPath(dest) | ||||
| } | ||||
|  | ||||
| // FileExists returns true if file content has been associated with the given path, false otherwise. | ||||
| // Only relative paths are supported. | ||||
| func (f *FilesMock) FileExists(path string) (bool, error) { | ||||
| @@ -187,6 +197,7 @@ func (f *FilesMock) Copy(src, dst string) (int64, error) { | ||||
| 		return 0, fmt.Errorf("cannot copy '%s': %w", src, os.ErrNotExist) | ||||
| 	} | ||||
| 	f.AddFileWithMode(dst, *props.content, props.mode) | ||||
| 	f.copiedFiles[f.toAbsPath(src)] = f.toAbsPath(dst) | ||||
| 	return int64(len(*props.content)), nil | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ import ( | ||||
| type Docker struct { | ||||
| 	artifact         Artifact | ||||
| 	content          []byte | ||||
| 	execRunner       mavenExecRunner | ||||
| 	utils            Utils | ||||
| 	options          *Options | ||||
| 	path             string | ||||
| 	versionSource    string | ||||
| @@ -75,7 +75,7 @@ func (d *Docker) GetVersion() (string, error) { | ||||
| 		if d.options == nil { | ||||
| 			d.options = &Options{} | ||||
| 		} | ||||
| 		d.artifact, err = GetArtifact(d.versionSource, d.path, d.options, d.execRunner) | ||||
| 		d.artifact, err = GetArtifact(d.versionSource, d.path, d.options, d.utils) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
|   | ||||
| @@ -4,7 +4,6 @@ import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/command" | ||||
| 	"github.com/SAP/jenkins-library/pkg/maven" | ||||
|  | ||||
| 	"github.com/pkg/errors" | ||||
| @@ -17,8 +16,8 @@ type mavenExecRunner interface { | ||||
| } | ||||
|  | ||||
| type mavenRunner interface { | ||||
| 	Execute(*maven.ExecuteOptions, mavenExecRunner) (string, error) | ||||
| 	Evaluate(*maven.EvaluateOptions, string, mavenExecRunner) (string, error) | ||||
| 	Execute(*maven.ExecuteOptions, maven.Utils) (string, error) | ||||
| 	Evaluate(*maven.EvaluateOptions, string, maven.Utils) (string, error) | ||||
| } | ||||
|  | ||||
| // MavenDescriptor holds the unique identifier combination for Maven built Java artifacts | ||||
| @@ -31,9 +30,9 @@ type MavenDescriptor struct { | ||||
|  | ||||
| // Maven defines a maven artifact used for versioning | ||||
| type Maven struct { | ||||
| 	options    maven.EvaluateOptions | ||||
| 	runner     mavenRunner | ||||
| 	execRunner mavenExecRunner | ||||
| 	options maven.EvaluateOptions | ||||
| 	runner  mavenRunner | ||||
| 	utils   maven.Utils | ||||
| } | ||||
|  | ||||
| func (m *Maven) init() { | ||||
| @@ -41,8 +40,8 @@ func (m *Maven) init() { | ||||
| 		m.options.PomPath = "pom.xml" | ||||
| 	} | ||||
|  | ||||
| 	if m.execRunner == nil { | ||||
| 		m.execRunner = &command.Command{} | ||||
| 	if m.utils == nil { | ||||
| 		m.utils = maven.NewUtilsBundle() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -78,7 +77,7 @@ func (m *Maven) GetCoordinates() (Coordinates, error) { | ||||
| func (m *Maven) GetPackaging() (string, error) { | ||||
| 	m.init() | ||||
|  | ||||
| 	packaging, err := m.runner.Evaluate(&m.options, "project.packaging", m.execRunner) | ||||
| 	packaging, err := m.runner.Evaluate(&m.options, "project.packaging", m.utils) | ||||
| 	if err != nil { | ||||
| 		return "", errors.Wrap(err, "Maven - getting packaging failed") | ||||
| 	} | ||||
| @@ -89,7 +88,7 @@ func (m *Maven) GetPackaging() (string, error) { | ||||
| func (m *Maven) GetGroupID() (string, error) { | ||||
| 	m.init() | ||||
|  | ||||
| 	groupID, err := m.runner.Evaluate(&m.options, "project.groupId", m.execRunner) | ||||
| 	groupID, err := m.runner.Evaluate(&m.options, "project.groupId", m.utils) | ||||
| 	if err != nil { | ||||
| 		return "", errors.Wrap(err, "Maven - getting groupId failed") | ||||
| 	} | ||||
| @@ -100,7 +99,7 @@ func (m *Maven) GetGroupID() (string, error) { | ||||
| func (m *Maven) GetArtifactID() (string, error) { | ||||
| 	m.init() | ||||
|  | ||||
| 	artifactID, err := m.runner.Evaluate(&m.options, "project.artifactId", m.execRunner) | ||||
| 	artifactID, err := m.runner.Evaluate(&m.options, "project.artifactId", m.utils) | ||||
| 	if err != nil { | ||||
| 		return "", errors.Wrap(err, "Maven - getting artifactId failed") | ||||
| 	} | ||||
| @@ -111,7 +110,7 @@ func (m *Maven) GetArtifactID() (string, error) { | ||||
| func (m *Maven) GetVersion() (string, error) { | ||||
| 	m.init() | ||||
|  | ||||
| 	version, err := m.runner.Evaluate(&m.options, "project.version", m.execRunner) | ||||
| 	version, err := m.runner.Evaluate(&m.options, "project.version", m.utils) | ||||
| 	if err != nil { | ||||
| 		return "", errors.Wrap(err, "Maven - getting version failed") | ||||
| 	} | ||||
| @@ -123,7 +122,7 @@ func (m *Maven) GetVersion() (string, error) { | ||||
| func (m *Maven) SetVersion(version string) error { | ||||
| 	m.init() | ||||
|  | ||||
| 	groupID, err := m.runner.Evaluate(&m.options, "project.groupId", m.execRunner) | ||||
| 	groupID, err := m.runner.Evaluate(&m.options, "project.groupId", m.utils) | ||||
| 	if err != nil { | ||||
| 		return errors.Wrap(err, "Maven - getting groupId failed") | ||||
| 	} | ||||
| @@ -141,7 +140,7 @@ func (m *Maven) SetVersion(version string) error { | ||||
| 			"-DgenerateBackupPoms=false", | ||||
| 		}, | ||||
| 	} | ||||
| 	_, err = m.runner.Execute(&opts, m.execRunner) | ||||
| 	_, err = m.runner.Execute(&opts, m.utils) | ||||
| 	if err != nil { | ||||
| 		return errors.Wrapf(err, "Maven - setting version %v failed", version) | ||||
| 	} | ||||
|   | ||||
| @@ -17,7 +17,7 @@ type mavenMockRunner struct { | ||||
| 	expression          string | ||||
| } | ||||
|  | ||||
| func (m *mavenMockRunner) Evaluate(opts *maven.EvaluateOptions, expression string, runner mavenExecRunner) (string, error) { | ||||
| func (m *mavenMockRunner) Evaluate(opts *maven.EvaluateOptions, expression string, utils maven.Utils) (string, error) { | ||||
| 	m.opts = opts | ||||
| 	m.expression = expression | ||||
| 	if len(m.evaluateErrorString) > 0 { | ||||
| @@ -26,7 +26,7 @@ func (m *mavenMockRunner) Evaluate(opts *maven.EvaluateOptions, expression strin | ||||
| 	return m.stdout, nil | ||||
| } | ||||
|  | ||||
| func (m *mavenMockRunner) Execute(opts *maven.ExecuteOptions, runner mavenExecRunner) (string, error) { | ||||
| func (m *mavenMockRunner) Execute(opts *maven.ExecuteOptions, utils maven.Utils) (string, error) { | ||||
| 	m.execOpts = opts | ||||
| 	if len(m.executeErrorString) > 0 { | ||||
| 		return "", fmt.Errorf(m.executeErrorString) | ||||
|   | ||||
| @@ -31,19 +31,24 @@ type Options struct { | ||||
| 	VersioningScheme    string | ||||
| } | ||||
|  | ||||
| // Utils defines the versioning operations for various build tools | ||||
| type Utils interface { | ||||
| 	maven.Utils | ||||
| } | ||||
|  | ||||
| type mvnRunner struct{} | ||||
|  | ||||
| func (m *mvnRunner) Execute(options *maven.ExecuteOptions, execRunner mavenExecRunner) (string, error) { | ||||
| 	return maven.Execute(options, execRunner) | ||||
| func (m *mvnRunner) Execute(options *maven.ExecuteOptions, utils maven.Utils) (string, error) { | ||||
| 	return maven.Execute(options, utils) | ||||
| } | ||||
| func (m *mvnRunner) Evaluate(options *maven.EvaluateOptions, expression string, execRunner mavenExecRunner) (string, error) { | ||||
| 	return maven.Evaluate(options, expression, execRunner) | ||||
| func (m *mvnRunner) Evaluate(options *maven.EvaluateOptions, expression string, utils maven.Utils) (string, error) { | ||||
| 	return maven.Evaluate(options, expression, utils) | ||||
| } | ||||
|  | ||||
| var fileExists func(string) (bool, error) | ||||
|  | ||||
| // GetArtifact returns the build tool specific implementation for retrieving version, etc. of an artifact | ||||
| func GetArtifact(buildTool, buildDescriptorFilePath string, opts *Options, execRunner mavenExecRunner) (Artifact, error) { | ||||
| func GetArtifact(buildTool, buildDescriptorFilePath string, opts *Options, utils Utils) (Artifact, error) { | ||||
| 	var artifact Artifact | ||||
| 	if fileExists == nil { | ||||
| 		fileExists = piperutils.FileExists | ||||
| @@ -57,7 +62,7 @@ func GetArtifact(buildTool, buildDescriptorFilePath string, opts *Options, execR | ||||
| 		} | ||||
| 	case "docker": | ||||
| 		artifact = &Docker{ | ||||
| 			execRunner:       execRunner, | ||||
| 			utils:            utils, | ||||
| 			options:          opts, | ||||
| 			path:             buildDescriptorFilePath, | ||||
| 			versionSource:    opts.VersionSource, | ||||
| @@ -100,8 +105,8 @@ func GetArtifact(buildTool, buildDescriptorFilePath string, opts *Options, execR | ||||
| 			buildDescriptorFilePath = "pom.xml" | ||||
| 		} | ||||
| 		artifact = &Maven{ | ||||
| 			runner:     &mvnRunner{}, | ||||
| 			execRunner: execRunner, | ||||
| 			runner: &mvnRunner{}, | ||||
| 			utils:  utils, | ||||
| 			options: maven.EvaluateOptions{ | ||||
| 				PomPath:             buildDescriptorFilePath, | ||||
| 				ProjectSettingsFile: opts.ProjectSettingsFile, | ||||
|   | ||||
| @@ -29,12 +29,12 @@ func (s *Scan) ExecuteMavenScanForPomFile(config *ScanOptions, utils Utils, pomP | ||||
| 	} | ||||
|  | ||||
| 	if config.InstallArtifacts { | ||||
| 		err := maven.InstallMavenArtifacts(utils, &maven.EvaluateOptions{ | ||||
| 		err := maven.InstallMavenArtifacts(&maven.EvaluateOptions{ | ||||
| 			M2Path:              config.M2Path, | ||||
| 			ProjectSettingsFile: config.ProjectSettingsFile, | ||||
| 			GlobalSettingsFile:  config.GlobalSettingsFile, | ||||
| 			PomPath:             pomPath, | ||||
| 		}) | ||||
| 		}, utils) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| package whitesource | ||||
|  | ||||
| import ( | ||||
| 	"github.com/SAP/jenkins-library/pkg/maven" | ||||
| 	"io" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| ) | ||||
|  | ||||
| @@ -15,16 +15,10 @@ type File interface { | ||||
|  | ||||
| // Utils captures all external functionality that needs to be exchangeable in tests. | ||||
| type Utils interface { | ||||
| 	Stdout(out io.Writer) | ||||
| 	Stderr(err io.Writer) | ||||
| 	RunExecutable(executable string, params ...string) error | ||||
|  | ||||
| 	DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error | ||||
| 	maven.Utils | ||||
|  | ||||
| 	Chdir(path string) error | ||||
| 	Getwd() (string, error) | ||||
| 	MkdirAll(path string, perm os.FileMode) error | ||||
| 	FileExists(path string) (bool, error) | ||||
| 	FileRead(path string) ([]byte, error) | ||||
| 	FileWrite(path string, content []byte, perm os.FileMode) error | ||||
| 	FileRemove(path string) error | ||||
|   | ||||
		Reference in New Issue
	
	Block a user