2020-03-07 00:10:10 +02:00
|
|
|
package nexus
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"github.com/SAP/jenkins-library/pkg/log"
|
2020-03-20 19:20:52 +02:00
|
|
|
"strings"
|
2020-03-07 00:10:10 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
// ArtifactDescription describes a single artifact that can be uploaded to a Nexus repository manager.
|
|
|
|
// The File string must point to an existing file. The Classifier can be empty.
|
|
|
|
type ArtifactDescription struct {
|
|
|
|
Classifier string `json:"classifier"`
|
|
|
|
Type string `json:"type"`
|
|
|
|
File string `json:"file"`
|
|
|
|
}
|
|
|
|
|
2020-03-20 19:20:52 +02:00
|
|
|
// Upload combines information about an artifact and its sub-artifacts which are supposed to be uploaded together.
|
|
|
|
// Call SetRepoURL(), SetArtifactsVersion(), SetArtifactID(), and add at least one artifact via AddArtifact().
|
2020-03-07 00:10:10 +02:00
|
|
|
type Upload struct {
|
2021-03-10 16:06:42 +02:00
|
|
|
protocol string
|
2020-04-11 12:56:44 +02:00
|
|
|
mavenRepoURL string
|
|
|
|
npmRepoURL string
|
|
|
|
groupID string
|
|
|
|
version string
|
|
|
|
artifactID string
|
|
|
|
artifacts []ArtifactDescription
|
2020-03-07 00:10:10 +02:00
|
|
|
}
|
|
|
|
|
2020-03-20 19:20:52 +02:00
|
|
|
// Uploader provides an interface for configuring the target Nexus Repository and adding artifacts.
|
2020-03-07 00:10:10 +02:00
|
|
|
type Uploader interface {
|
2020-04-11 12:56:44 +02:00
|
|
|
SetRepoURL(nexusURL, nexusVersion, mavenRepository, npmRepository string) error
|
2021-03-10 16:06:42 +02:00
|
|
|
GetNexusURLProtocol() string
|
2020-04-11 12:56:44 +02:00
|
|
|
GetMavenRepoURL() string
|
|
|
|
GetNpmRepoURL() string
|
2020-03-20 19:20:52 +02:00
|
|
|
SetInfo(groupID, artifactsID, version string) error
|
|
|
|
GetGroupID() string
|
|
|
|
GetArtifactsID() string
|
|
|
|
GetArtifactsVersion() string
|
2020-03-07 00:10:10 +02:00
|
|
|
AddArtifact(artifact ArtifactDescription) error
|
|
|
|
GetArtifacts() []ArtifactDescription
|
2020-03-20 19:20:52 +02:00
|
|
|
Clear()
|
2020-03-07 00:10:10 +02:00
|
|
|
}
|
|
|
|
|
2020-04-11 12:56:44 +02:00
|
|
|
// SetRepoURL constructs the base URL to the Nexus repository. mavenRepository or npmRepository may be empty.
|
|
|
|
func (nexusUpload *Upload) SetRepoURL(nexusURL, nexusVersion, mavenRepository, npmRepository string) error {
|
2021-03-10 16:06:42 +02:00
|
|
|
protocol, err := _GetNexusURLProtocol(nexusURL)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
nexusUpload.protocol = protocol
|
2020-04-11 12:56:44 +02:00
|
|
|
mavenRepoURL, err := getBaseURL(nexusURL, nexusVersion, mavenRepository)
|
2020-03-07 00:10:10 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-04-11 12:56:44 +02:00
|
|
|
nexusUpload.mavenRepoURL = mavenRepoURL
|
|
|
|
npmRepositoryURL, err := getBaseURL(nexusURL, nexusVersion, npmRepository)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
nexusUpload.npmRepoURL = npmRepositoryURL
|
2020-03-07 00:10:10 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-03-31 15:16:18 +02:00
|
|
|
func getBaseURL(nexusURL, nexusVersion, repository string) (string, error) {
|
|
|
|
if nexusURL == "" {
|
|
|
|
return "", errors.New("nexusURL must not be empty")
|
|
|
|
}
|
|
|
|
nexusURL = strings.ToLower(nexusURL)
|
|
|
|
var protocols = []string{"http://", "https://"}
|
|
|
|
for _, protocol := range protocols {
|
|
|
|
if strings.HasPrefix(nexusURL, protocol) {
|
|
|
|
nexusURL = strings.TrimPrefix(nexusURL, protocol)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2021-03-10 16:06:42 +02:00
|
|
|
|
2020-03-31 15:16:18 +02:00
|
|
|
baseURL := nexusURL
|
2021-03-10 16:06:42 +02:00
|
|
|
|
|
|
|
if repository != "" {
|
|
|
|
switch nexusVersion {
|
|
|
|
case "nexus2":
|
|
|
|
baseURL += "/content/repositories/"
|
|
|
|
case "nexus3":
|
|
|
|
baseURL += "/repository/"
|
|
|
|
default:
|
|
|
|
return "", fmt.Errorf("unsupported Nexus version '%s', must be 'nexus2' or 'nexus3'", nexusVersion)
|
|
|
|
}
|
|
|
|
baseURL += repository + "/"
|
|
|
|
// Replace any double slashes, as nexus does not like them
|
|
|
|
baseURL = strings.ReplaceAll(baseURL, "//", "/")
|
2020-03-31 15:16:18 +02:00
|
|
|
}
|
2021-03-10 16:06:42 +02:00
|
|
|
|
2020-03-31 15:16:18 +02:00
|
|
|
return baseURL, nil
|
|
|
|
}
|
|
|
|
|
2021-03-10 16:06:42 +02:00
|
|
|
// _GetNexusURLProtocol returns the protocol specified in the nexusUrl which was set thru setNexusUrl (internal method)
|
|
|
|
func _GetNexusURLProtocol(nexusURL string) (string, error) {
|
|
|
|
if nexusURL == "" {
|
|
|
|
return "", errors.New("nexusURL must not be empty")
|
|
|
|
}
|
|
|
|
nexusURL = strings.ToLower(nexusURL)
|
|
|
|
var protocols = []string{"http://", "https://"}
|
|
|
|
for _, protocol := range protocols {
|
|
|
|
if strings.HasPrefix(nexusURL, protocol) {
|
|
|
|
return strings.ReplaceAll(protocol, "://", ""), nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "http", nil
|
|
|
|
}
|
|
|
|
|
2020-04-11 12:56:44 +02:00
|
|
|
// GetMavenRepoURL returns the base URL for the nexus-maven repository.
|
|
|
|
func (nexusUpload *Upload) GetMavenRepoURL() string {
|
|
|
|
return nexusUpload.mavenRepoURL
|
|
|
|
}
|
|
|
|
|
2021-03-10 16:06:42 +02:00
|
|
|
// GetNexusURLProtocol returns the protocol specified in the nexusUrl which was set thru setNexusUrl
|
|
|
|
func (nexusUpload *Upload) GetNexusURLProtocol() string {
|
|
|
|
if nexusUpload.protocol == "" {
|
|
|
|
return "http"
|
|
|
|
}
|
|
|
|
return nexusUpload.protocol
|
|
|
|
}
|
|
|
|
|
2020-04-11 12:56:44 +02:00
|
|
|
// GetNpmRepoURL returns the base URL for the nexus-npm repository.
|
|
|
|
func (nexusUpload *Upload) GetNpmRepoURL() string {
|
|
|
|
return nexusUpload.npmRepoURL
|
2020-03-20 19:20:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// ErrEmptyGroupID is returned from SetInfo, if groupID is empty.
|
|
|
|
var ErrEmptyGroupID = errors.New("groupID must not be empty")
|
|
|
|
|
|
|
|
// ErrEmptyArtifactID is returned from SetInfo, if artifactID is empty.
|
|
|
|
var ErrEmptyArtifactID = errors.New("artifactID must not be empty")
|
|
|
|
|
|
|
|
// ErrInvalidArtifactID is returned from SetInfo, if artifactID contains slashes.
|
|
|
|
var ErrInvalidArtifactID = errors.New("artifactID may not include slashes")
|
|
|
|
|
|
|
|
// ErrEmptyVersion is returned from SetInfo, if version is empty.
|
|
|
|
var ErrEmptyVersion = errors.New("version must not be empty")
|
|
|
|
|
|
|
|
// SetInfo sets the common info for all uploaded artifacts. This info is external to
|
2020-03-07 00:10:10 +02:00
|
|
|
// the artifact descriptions so that it is consistent for all of them.
|
2020-03-20 19:20:52 +02:00
|
|
|
func (nexusUpload *Upload) SetInfo(groupID, artifactID, version string) error {
|
|
|
|
if groupID == "" {
|
|
|
|
return ErrEmptyGroupID
|
|
|
|
}
|
|
|
|
if artifactID == "" {
|
|
|
|
return ErrEmptyArtifactID
|
|
|
|
}
|
|
|
|
if strings.Contains(artifactID, "/") {
|
|
|
|
return ErrInvalidArtifactID
|
|
|
|
}
|
2020-03-07 00:10:10 +02:00
|
|
|
if version == "" {
|
2020-03-20 19:20:52 +02:00
|
|
|
return ErrEmptyVersion
|
2020-03-07 00:10:10 +02:00
|
|
|
}
|
2020-03-20 19:20:52 +02:00
|
|
|
nexusUpload.groupID = groupID
|
|
|
|
nexusUpload.artifactID = artifactID
|
2020-03-07 00:10:10 +02:00
|
|
|
nexusUpload.version = version
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-03-20 19:20:52 +02:00
|
|
|
// GetArtifactsVersion returns the common version for all artifacts.
|
|
|
|
func (nexusUpload *Upload) GetArtifactsVersion() string {
|
|
|
|
return nexusUpload.version
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetGroupID returns the common groupId for all artifacts.
|
|
|
|
func (nexusUpload *Upload) GetGroupID() string {
|
|
|
|
return nexusUpload.groupID
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetArtifactsID returns the common artifactId for all artifacts.
|
|
|
|
func (nexusUpload *Upload) GetArtifactsID() string {
|
|
|
|
return nexusUpload.artifactID
|
|
|
|
}
|
|
|
|
|
2020-03-07 00:10:10 +02:00
|
|
|
// AddArtifact adds a single artifact to be uploaded later via UploadArtifacts(). If an identical artifact
|
|
|
|
// description is already contained in the Upload, the function does nothing and returns no error.
|
|
|
|
func (nexusUpload *Upload) AddArtifact(artifact ArtifactDescription) error {
|
|
|
|
err := validateArtifact(artifact)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if nexusUpload.containsArtifact(artifact) {
|
|
|
|
log.Entry().Infof("Nexus Upload already contains artifact %v\n", artifact)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
nexusUpload.artifacts = append(nexusUpload.artifacts, artifact)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func validateArtifact(artifact ArtifactDescription) error {
|
2020-03-20 19:20:52 +02:00
|
|
|
if artifact.File == "" || artifact.Type == "" {
|
|
|
|
return fmt.Errorf("Artifact.File (%v) or Type (%v) is empty",
|
|
|
|
artifact.File, artifact.Type)
|
2020-03-07 00:10:10 +02:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (nexusUpload *Upload) containsArtifact(artifact ArtifactDescription) bool {
|
|
|
|
for _, n := range nexusUpload.artifacts {
|
|
|
|
if artifact == n {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetArtifacts returns a copy of the artifact descriptions array stored in the Upload.
|
|
|
|
func (nexusUpload *Upload) GetArtifacts() []ArtifactDescription {
|
|
|
|
artifacts := make([]ArtifactDescription, len(nexusUpload.artifacts))
|
|
|
|
copy(artifacts, nexusUpload.artifacts)
|
|
|
|
return artifacts
|
|
|
|
}
|
|
|
|
|
2020-03-20 19:20:52 +02:00
|
|
|
// Clear removes any contained artifact descriptions.
|
|
|
|
func (nexusUpload *Upload) Clear() {
|
|
|
|
nexusUpload.artifacts = []ArtifactDescription{}
|
2020-03-07 00:10:10 +02:00
|
|
|
}
|