1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00

Settings file handling (prepares mtaBuild step) (#1176)

download settings file via http or copy from the local file system into either $M2_HOME/conf/settings.xml or into ~/.m2/settings.xml

Co-authored-by: Stephan Aßmus <stephan.assmus@sap.com>
This commit is contained in:
Marcus Holl 2020-02-25 14:17:00 +01:00 committed by GitHub
parent cd909d410a
commit d1e5d9c2e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 353 additions and 4 deletions

108
pkg/maven/settings.go Normal file
View File

@ -0,0 +1,108 @@
package maven
import (
"errors"
"fmt"
piperhttp "github.com/SAP/jenkins-library/pkg/http"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/piperutils"
"os"
"path/filepath"
"strings"
)
var getenv = os.Getenv
// SettingsFileType ...
type SettingsFileType int
const (
// GlobalSettingsFile ...
GlobalSettingsFile SettingsFileType = iota
// ProjectSettingsFile ...
ProjectSettingsFile
)
// GetSettingsFile ...
func GetSettingsFile(settingsFileType SettingsFileType, src string, fileUtils piperutils.FileUtils, httpClient piperhttp.Downloader) error {
var dest string
var err error
switch settingsFileType {
case GlobalSettingsFile:
dest, err = getGlobalSettingsFileDest()
case ProjectSettingsFile:
dest, err = getProjectSettingsFileDest()
default:
return errors.New("Invalid SettingsFileType")
}
if err != nil {
return err
}
if len(src) == 0 {
return fmt.Errorf("Settings file source location not provided")
}
log.Entry().Debugf("Copying file \"%s\" to \"%s\"", src, dest)
if strings.HasPrefix(src, "http:") || strings.HasPrefix(src, "https:") {
if err := httpClient.DownloadFile(src, dest, nil, nil); err != nil {
return err
}
} else {
// for sake os symetry it would be better to use a file protocol prefix here (file:)
parent := filepath.Dir(dest)
parentFolderExists, err := fileUtils.FileExists(parent)
if err != nil {
return err
}
if !parentFolderExists {
if err = fileUtils.MkdirAll(parent, 0775); err != nil {
return err
}
}
if _, err := fileUtils.Copy(src, dest); err != nil {
return err
}
}
return nil
}
func getGlobalSettingsFileDest() (string, error) {
m2Home, err := getEnvironmentVariable("M2_HOME")
if err != nil {
return "", err
}
return m2Home + "/conf/settings.xml", nil
}
func getProjectSettingsFileDest() (string, error) {
home, err := getEnvironmentVariable("HOME")
if err != nil {
return "", err
}
return home + "/.m2/settings.xml", nil
}
func getEnvironmentVariable(name string) (string, error) {
envVar := getenv(name)
if len(envVar) == 0 {
return "", fmt.Errorf("Environment variable \"%s\" not set or empty", name)
}
return envVar, nil
}

202
pkg/maven/settings_test.go Normal file
View File

@ -0,0 +1,202 @@
package maven
import (
"fmt"
piperhttp "github.com/SAP/jenkins-library/pkg/http"
"github.com/stretchr/testify/assert"
"net/http"
"os"
"testing"
)
func TestSettings(t *testing.T) {
defer func() {
getenv = os.Getenv
}()
getenv = func(name string) string {
if name == "M2_HOME" {
return "/usr/share/maven"
} else if name == "HOME" {
return "/home/me"
}
return ""
}
t.Run("Invalid settings file type", func(t *testing.T) {
httpClient := httpMock{}
fileUtils := fileUtilsMock{}
err := GetSettingsFile(-1, "/dev/null", &fileUtils, &httpClient)
if assert.Error(t, err) {
assert.Equal(t, "Invalid SettingsFileType", err.Error())
}
})
t.Run("Settings file source location not provided", func(t *testing.T) {
httpClient := httpMock{}
fileUtils := fileUtilsMock{}
err := GetSettingsFile(1, "", &fileUtils, &httpClient)
if assert.Error(t, err) {
assert.Equal(t, "Settings file source location not provided", err.Error())
}
})
t.Run("Retrieve global settings file", func(t *testing.T) {
httpClient := httpMock{}
fileUtils := fileUtilsMock{existingFiles: map[string]string{"/opt/sap/maven/global-settings.xml": ""}}
err := GetSettingsFile(GlobalSettingsFile, "/opt/sap/maven/global-settings.xml", &fileUtils, &httpClient)
if assert.NoError(t, err) {
assert.Equal(t, "/usr/share/maven/conf/settings.xml", fileUtils.copiedFiles["/opt/sap/maven/global-settings.xml"])
}
assert.Empty(t, httpClient.downloadedFiles)
})
t.Run("Retrieve project settings file", func(t *testing.T) {
httpClient := httpMock{}
fileUtils := fileUtilsMock{existingFiles: map[string]string{"/opt/sap/maven/project-settings.xml": ""}}
err := GetSettingsFile(ProjectSettingsFile, "/opt/sap/maven/project-settings.xml", &fileUtils, &httpClient)
if assert.NoError(t, err) {
assert.Equal(t, "/home/me/.m2/settings.xml", fileUtils.copiedFiles["/opt/sap/maven/project-settings.xml"])
}
assert.Empty(t, httpClient.downloadedFiles)
})
t.Run("Retrieve global settings file via http", func(t *testing.T) {
httpClient := httpMock{}
fileUtils := fileUtilsMock{}
err := GetSettingsFile(GlobalSettingsFile, "https://example.org/maven/global-settings.xml", &fileUtils, &httpClient)
if assert.NoError(t, err) {
assert.Equal(t, "/usr/share/maven/conf/settings.xml", httpClient.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{}
err := GetSettingsFile(GlobalSettingsFile, "https://example.org/maven/global-settings.xml", &fileUtils, &httpClient)
if assert.Error(t, err) {
assert.Equal(t, "Download failed", err.Error())
}
})
t.Run("Retrieve project settings file via http", func(t *testing.T) {
httpClient := httpMock{}
fileUtils := fileUtilsMock{}
err := GetSettingsFile(ProjectSettingsFile, "https://example.org/maven/project-settings.xml", &fileUtils, &httpClient)
if assert.NoError(t, err) {
assert.Equal(t, "/home/me/.m2/settings.xml", httpClient.downloadedFiles["https://example.org/maven/project-settings.xml"])
}
})
t.Run("Retrieve project settings file - file not found", func(t *testing.T) {
httpClient := httpMock{}
fileUtils := fileUtilsMock{}
err := GetSettingsFile(ProjectSettingsFile, "/opt/sap/maven/project-settings.xml", &fileUtils, &httpClient)
if assert.Error(t, err) {
assert.Contains(t, err.Error(), "Source file '/opt/sap/maven/project-settings.xml' does not exist")
}
})
}
type httpMock struct {
expectedError error
downloadedFiles map[string]string // src, dest
}
func (c *httpMock) SetOptions(options piperhttp.ClientOptions) {
}
func (c *httpMock) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error {
if c.expectedError != nil {
return c.expectedError
}
if c.downloadedFiles == nil {
c.downloadedFiles = make(map[string]string)
}
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
}

View File

@ -3,11 +3,25 @@ package piperutils
import (
"errors"
"io"
"io/ioutil"
"os"
)
// FileUtils ...
type FileUtils interface {
FileExists(filename string) (bool, error)
Copy(src, dest string) (int64, error)
FileRead(path string) ([]byte, error)
FileWrite(path string, content []byte, perm os.FileMode) error
MkdirAll(path string, perm os.FileMode) error
}
// Files ...
type Files struct {
}
// FileExists ...
func FileExists(filename string) (bool, error) {
func (f Files) FileExists(filename string) (bool, error) {
info, err := os.Stat(filename)
if os.IsNotExist(err) {
@ -20,10 +34,15 @@ func FileExists(filename string) (bool, error) {
return !info.IsDir(), nil
}
// Copy ...
func Copy(src, dst string) (int64, error) {
// FileExists ...
func FileExists(filename string) (bool, error) {
return Files{}.FileExists(filename)
}
exists, err := FileExists(src)
// Copy ...
func (f Files) Copy(src, dst string) (int64, error) {
exists, err := f.FileExists(src)
if err != nil {
return 0, err
@ -47,3 +66,23 @@ func Copy(src, dst string) (int64, error) {
nBytes, err := io.Copy(destination, source)
return nBytes, err
}
// Copy ...
func Copy(src, dst string) (int64, error) {
return Files{}.Copy(src, dst)
}
//FileRead ...
func (f Files) FileRead(path string) ([]byte, error) {
return ioutil.ReadFile(path)
}
// FileWrite ...
func (f Files) FileWrite(path string, content []byte, perm os.FileMode) error {
return ioutil.WriteFile(path, content, perm)
}
// MkdirAll ...
func (f Files) MkdirAll(path string, perm os.FileMode) error {
return os.MkdirAll(path, perm)
}