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:
parent
cd909d410a
commit
d1e5d9c2e7
108
pkg/maven/settings.go
Normal file
108
pkg/maven/settings.go
Normal 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
202
pkg/maven/settings_test.go
Normal 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
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user