mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-12 10:55:20 +02:00
chore(npmExecuteScripts): unit tests (#3597)
This commit is contained in:
parent
e38d5ef69f
commit
e49820f5e4
@ -339,11 +339,15 @@ func (f *FilesMock) FileRename(oldPath, newPath string) error {
|
||||
}
|
||||
|
||||
// TempDir create a temp-styled directory in the in-memory, so that this path is established to exist.
|
||||
func (f *FilesMock) TempDir(_, pattern string) (string, error) {
|
||||
tmpDir := "/tmp/test"
|
||||
func (f *FilesMock) TempDir(baseDir string, pattern string) (string, error) {
|
||||
if len(baseDir) == 0 {
|
||||
baseDir = "/tmp"
|
||||
}
|
||||
|
||||
tmpDir := baseDir
|
||||
|
||||
if pattern != "" {
|
||||
tmpDir = fmt.Sprintf("/tmp/%stest", pattern)
|
||||
tmpDir = fmt.Sprintf("%s/%stest", baseDir, pattern)
|
||||
}
|
||||
|
||||
err := f.MkdirAll(tmpDir, 0755)
|
||||
|
@ -628,8 +628,8 @@ func TestFilesMockTempDir(t *testing.T) {
|
||||
files := FilesMock{}
|
||||
dir, err := files.TempDir("", "")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "/tmp/test", dir)
|
||||
ok, err := files.DirExists("/tmp/test")
|
||||
assert.Equal(t, "/tmp", dir)
|
||||
ok, err := files.DirExists("/tmp")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, ok)
|
||||
})
|
||||
|
@ -20,6 +20,7 @@ type ExecMockRunner struct {
|
||||
stdin io.Reader
|
||||
stdout io.Writer
|
||||
stderr io.Writer
|
||||
Stub func(call string, stdoutReturn map[string]string, shouldFailOnCommand map[string]error, stdout io.Writer) error
|
||||
StdoutReturn map[string]string
|
||||
ShouldFailOnCommand map[string]error
|
||||
}
|
||||
@ -67,7 +68,7 @@ func (m *ExecMockRunner) RunExecutable(e string, p ...string) error {
|
||||
|
||||
c := strings.Join(append([]string{e}, p...), " ")
|
||||
|
||||
return handleCall(c, m.StdoutReturn, m.ShouldFailOnCommand, m.stdout)
|
||||
return m.handleCall(c, m.StdoutReturn, m.ShouldFailOnCommand, m.stdout)
|
||||
}
|
||||
|
||||
func (m *ExecMockRunner) GetExitCode() int {
|
||||
@ -82,7 +83,7 @@ func (m *ExecMockRunner) RunExecutableInBackground(e string, p ...string) (comma
|
||||
|
||||
c := strings.Join(append([]string{e}, p...), " ")
|
||||
|
||||
err := handleCall(c, m.StdoutReturn, m.ShouldFailOnCommand, m.stdout)
|
||||
err := m.handleCall(c, m.StdoutReturn, m.ShouldFailOnCommand, m.stdout)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -109,6 +110,14 @@ func (m *ExecMockRunner) GetStderr() io.Writer {
|
||||
return m.stderr
|
||||
}
|
||||
|
||||
func (m *ExecMockRunner) handleCall(call string, stdoutReturn map[string]string, shouldFailOnCommand map[string]error, stdout io.Writer) error {
|
||||
if m.Stub != nil {
|
||||
return m.Stub(call, stdoutReturn, shouldFailOnCommand, stdout)
|
||||
} else {
|
||||
return handleCall(call, stdoutReturn, shouldFailOnCommand, stdout)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *ShellMockRunner) SetDir(d string) {
|
||||
m.Dir = d
|
||||
}
|
||||
|
@ -10,17 +10,19 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
configFilename = ".piperNpmrc"
|
||||
defaultConfigFilename = ".piperNpmrc" // default by npm
|
||||
)
|
||||
|
||||
var (
|
||||
propertiesLoadFile = properties.LoadFile
|
||||
propertiesLoadFile = properties.LoadFile
|
||||
propertiesWriteFile = ioutil.WriteFile
|
||||
)
|
||||
|
||||
func NewNPMRC(path string) NPMRC {
|
||||
if !strings.HasSuffix(path, configFilename) {
|
||||
path = filepath.Join(path, configFilename)
|
||||
if !strings.HasSuffix(path, defaultConfigFilename) {
|
||||
path = filepath.Join(path, defaultConfigFilename)
|
||||
}
|
||||
|
||||
return NPMRC{filepath: path, values: properties.NewProperties()}
|
||||
}
|
||||
|
||||
@ -30,7 +32,7 @@ type NPMRC struct {
|
||||
}
|
||||
|
||||
func (rc *NPMRC) Write() error {
|
||||
if err := ioutil.WriteFile(rc.filepath, []byte(rc.values.String()), 0644); err != nil {
|
||||
if err := propertiesWriteFile(rc.filepath, []byte(rc.values.String()), 0644); err != nil {
|
||||
return errors.Wrapf(err, "failed to write %s", rc.filepath)
|
||||
}
|
||||
return nil
|
||||
|
@ -20,7 +20,7 @@ func TestNewNPMRC(t *testing.T) {
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{name: "current dir", args: args{""}, want: configFilename},
|
||||
{name: "current dir", args: args{""}, want: defaultConfigFilename},
|
||||
{name: "sub dir", args: args{mock.Anything}, want: filepath.Join(mock.Anything, ".piperNpmrc")},
|
||||
{name: "file path in current dir", args: args{".piperNpmrc"}, want: ".piperNpmrc"},
|
||||
{name: "file path in sub dir", args: args{filepath.Join(mock.Anything, ".piperNpmrc")}, want: filepath.Join(mock.Anything, ".piperNpmrc")},
|
||||
|
@ -14,6 +14,10 @@ const (
|
||||
ignoreFilename = ".npmignore"
|
||||
)
|
||||
|
||||
var (
|
||||
writeIgnoreFile = ioutil.WriteFile
|
||||
)
|
||||
|
||||
func NewNPMIgnore(path string) NPMIgnore {
|
||||
if !strings.HasSuffix(path, ignoreFilename) {
|
||||
path = filepath.Join(path, ignoreFilename)
|
||||
@ -29,7 +33,7 @@ type NPMIgnore struct {
|
||||
func (ignorefile *NPMIgnore) Write() error {
|
||||
content := strings.Join(ignorefile.values, "\n")
|
||||
|
||||
if err := ioutil.WriteFile(ignorefile.filepath, []byte(content+"\n"), 0644); err != nil {
|
||||
if err := writeIgnoreFile(ignorefile.filepath, []byte(content+"\n"), 0644); err != nil {
|
||||
return errors.Wrapf(err, "failed to write %s", ignorefile.filepath)
|
||||
}
|
||||
return nil
|
||||
|
@ -57,11 +57,7 @@ type ExecRunner interface {
|
||||
|
||||
// Utils interface for mocking
|
||||
type Utils interface {
|
||||
Chdir(path string) error
|
||||
FileExists(filename string) (bool, error)
|
||||
FileRead(path string) ([]byte, error)
|
||||
Getwd() (string, error)
|
||||
Glob(pattern string) (matches []string, err error)
|
||||
piperutils.FileUtils
|
||||
|
||||
GetExecRunner() ExecRunner
|
||||
}
|
||||
|
@ -2,15 +2,12 @@ package npm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/log"
|
||||
CredentialUtils "github.com/SAP/jenkins-library/pkg/piperutils"
|
||||
FileUtils "github.com/SAP/jenkins-library/pkg/piperutils"
|
||||
)
|
||||
|
||||
// PublishAllPackages executes npm publish for all package.json files defined in packageJSONFiles list
|
||||
@ -37,7 +34,7 @@ func (exec *Execute) publish(packageJSON, registry, username, password string, p
|
||||
execRunner := exec.Utils.GetExecRunner()
|
||||
|
||||
npmignore := NewNPMIgnore(filepath.Dir(packageJSON))
|
||||
if exists, err := FileUtils.FileExists(npmignore.filepath); exists {
|
||||
if exists, err := exec.Utils.FileExists(npmignore.filepath); exists {
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to check for existing %s file", npmignore.filepath)
|
||||
}
|
||||
@ -65,7 +62,7 @@ func (exec *Execute) publish(packageJSON, registry, username, password string, p
|
||||
// update .piperNpmrc
|
||||
if len(registry) > 0 {
|
||||
// check existing .npmrc file
|
||||
if exists, err := FileUtils.FileExists(npmrc.filepath); exists {
|
||||
if exists, err := exec.Utils.FileExists(npmrc.filepath); exists {
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to check for existing %s file", npmrc.filepath)
|
||||
}
|
||||
@ -94,36 +91,46 @@ func (exec *Execute) publish(packageJSON, registry, username, password string, p
|
||||
}
|
||||
|
||||
if packBeforePublish {
|
||||
tmpDirectory := getTempDirForNpmTarBall()
|
||||
defer os.RemoveAll(tmpDirectory)
|
||||
tmpDirectory, err := exec.Utils.TempDir(".", "temp-")
|
||||
|
||||
err := execRunner.RunExecutable("npm", "pack", "--pack-destination", tmpDirectory)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "creating temp directory failed")
|
||||
}
|
||||
|
||||
defer exec.Utils.RemoveAll(tmpDirectory)
|
||||
|
||||
err = execRunner.RunExecutable("npm", "pack", "--pack-destination", tmpDirectory)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = FileUtils.Copy(npmrc.filepath, filepath.Join(tmpDirectory, ".piperNpmrc"))
|
||||
_, err = exec.Utils.Copy(npmrc.filepath, filepath.Join(tmpDirectory, ".piperNpmrc"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error copying piperNpmrc file from %v to %v with error: %w",
|
||||
npmrc.filepath, filepath.Join(tmpDirectory, ".piperNpmrc"), err)
|
||||
}
|
||||
|
||||
tarballFileName := ""
|
||||
err = filepath.Walk(tmpDirectory, func(path string, info os.FileInfo, err error) error {
|
||||
if filepath.Ext(path) == ".tgz" {
|
||||
tarballFileName = "." + string(filepath.Separator) + path
|
||||
log.Entry().Debugf("found tarball file at %v", tarballFileName)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
tarballs, err := exec.Utils.Glob(filepath.Join(tmpDirectory, "*.tgz"))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// rename the .npmrc file since it interferes with publish
|
||||
err = os.Rename(filepath.Join(filepath.Dir(packageJSON), ".npmrc"), filepath.Join(filepath.Dir(packageJSON), ".tmpNpmrc"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when renaming current .npmrc file : %w", err)
|
||||
if len(tarballs) != 1 {
|
||||
return fmt.Errorf("found more tarballs than expected: %v", tarballs)
|
||||
}
|
||||
|
||||
tarballFileName := tarballs[0]
|
||||
|
||||
projectNpmrc := filepath.Join(filepath.Dir(packageJSON), ".npmrc")
|
||||
projectNpmrcExists, _ := exec.Utils.FileExists(projectNpmrc)
|
||||
|
||||
if projectNpmrcExists {
|
||||
// rename the .npmrc file since it interferes with publish
|
||||
err = exec.Utils.FileRename(projectNpmrc, projectNpmrc+".tmp")
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when renaming current .npmrc file : %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = execRunner.RunExecutable("npm", "publish", "--tarball", tarballFileName, "--userconfig", filepath.Join(tmpDirectory, ".piperNpmrc"), "--registry", registry)
|
||||
@ -131,10 +138,12 @@ func (exec *Execute) publish(packageJSON, registry, username, password string, p
|
||||
return err
|
||||
}
|
||||
|
||||
// undo the renaming ot the .npmrc to keep the workspace like before
|
||||
err = os.Rename(filepath.Join(filepath.Dir(packageJSON), ".tmpNpmrc"), filepath.Join(filepath.Dir(packageJSON), ".npmrc"))
|
||||
if err != nil {
|
||||
log.Entry().Warnf("unable to rename the .npmrc file : %v", err)
|
||||
if projectNpmrcExists {
|
||||
// undo the renaming ot the .npmrc to keep the workspace like before
|
||||
err = exec.Utils.FileRename(projectNpmrc+".tmp", projectNpmrc)
|
||||
if err != nil {
|
||||
log.Entry().Warnf("unable to rename the .npmrc file : %v", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err := execRunner.RunExecutable("npm", "publish", "--userconfig", npmrc.filepath, "--registry", registry)
|
||||
@ -145,11 +154,3 @@ func (exec *Execute) publish(packageJSON, registry, username, password string, p
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getTempDirForNpmTarBall() string {
|
||||
tmpFolder, err := ioutil.TempDir(".", "temp-")
|
||||
if err != nil {
|
||||
log.Entry().WithError(err).WithField("path", tmpFolder).Debug("Creating temp directory failed")
|
||||
}
|
||||
return tmpFolder
|
||||
}
|
||||
|
341
pkg/npm/publish_test.go
Normal file
341
pkg/npm/publish_test.go
Normal file
@ -0,0 +1,341 @@
|
||||
package npm
|
||||
|
||||
import (
|
||||
"io"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/piperutils"
|
||||
"github.com/magiconair/properties"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNpmPublish(t *testing.T) {
|
||||
tt := []struct {
|
||||
name string
|
||||
|
||||
files map[string]string
|
||||
|
||||
packageDescriptors []string
|
||||
registryURL string
|
||||
registryUser string
|
||||
registryPassword string
|
||||
packBeforePublish bool
|
||||
|
||||
expectedPublishConfigPath string
|
||||
expectedPublishConfig string
|
||||
expectedError string
|
||||
}{
|
||||
// project in root folder
|
||||
{
|
||||
name: "success - single project, publish normal, unpacked package - target registry in npmrc",
|
||||
|
||||
files: map[string]string{
|
||||
"package.json": `{"name": "piper-project", "version": "0.0.1"}`,
|
||||
".piperNpmrc": "_auth=VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nregistry=https://my.private.npm.registry/",
|
||||
},
|
||||
|
||||
packageDescriptors: []string{"package.json"},
|
||||
|
||||
expectedPublishConfigPath: `\.piperNpmrc`,
|
||||
expectedPublishConfig: "_auth=VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nregistry=https://my.private.npm.registry/",
|
||||
},
|
||||
{
|
||||
name: "success - single project, publish normal, unpacked package - target registry from pipeline",
|
||||
|
||||
files: map[string]string{
|
||||
"package.json": `{"name": "piper-project", "version": "0.0.1"}`,
|
||||
},
|
||||
|
||||
packageDescriptors: []string{"package.json"},
|
||||
|
||||
expectedPublishConfigPath: `\.piperNpmrc`,
|
||||
expectedPublishConfig: "registry = https://my.private.npm.registry/\n_auth = VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nalways-auth = true\n",
|
||||
|
||||
registryURL: "https://my.private.npm.registry/",
|
||||
registryUser: "ThisIsTheUser",
|
||||
registryPassword: "AndHereIsThePassword",
|
||||
},
|
||||
{
|
||||
name: "success - single project, publish normal, unpacked package - target registry from pipeline (precedence over npmrc)",
|
||||
|
||||
files: map[string]string{
|
||||
"package.json": `{"name": "piper-project", "version": "0.0.1"}`,
|
||||
".piperNpmrc": "_auth=VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nregistry=https://my.private.npm.registry/",
|
||||
},
|
||||
|
||||
packageDescriptors: []string{"package.json"},
|
||||
|
||||
expectedPublishConfigPath: `\.piperNpmrc`,
|
||||
expectedPublishConfig: "_auth = VGhpc0lzVGhlT3RoZXJVc2VyOkFuZEhlcmVJc1RoZU90aGVyUGFzc3dvcmQ=\nregistry = https://my.other.private.npm.registry/\nalways-auth = true\n",
|
||||
|
||||
registryURL: "https://my.other.private.npm.registry/",
|
||||
registryUser: "ThisIsTheOtherUser",
|
||||
registryPassword: "AndHereIsTheOtherPassword",
|
||||
},
|
||||
{
|
||||
name: "success - single project, publish normal, packed - target registry in npmrc",
|
||||
|
||||
files: map[string]string{
|
||||
"package.json": `{"name": "piper-project", "version": "0.0.1"}`,
|
||||
".piperNpmrc": "_auth=VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nregistry=https://my.private.npm.registry/",
|
||||
},
|
||||
|
||||
packageDescriptors: []string{"package.json"},
|
||||
|
||||
packBeforePublish: true,
|
||||
|
||||
expectedPublishConfigPath: `temp-(?:test|[0-9]+)/\.piperNpmrc`,
|
||||
expectedPublishConfig: "_auth=VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nregistry=https://my.private.npm.registry/",
|
||||
},
|
||||
{
|
||||
name: "success - single project, publish normal, packed - target registry from pipeline",
|
||||
|
||||
files: map[string]string{
|
||||
"package.json": `{"name": "piper-project", "version": "0.0.1"}`,
|
||||
},
|
||||
|
||||
packageDescriptors: []string{"package.json"},
|
||||
|
||||
packBeforePublish: true,
|
||||
|
||||
expectedPublishConfigPath: `temp-(?:test|[0-9]+)/\.piperNpmrc`,
|
||||
expectedPublishConfig: "registry = https://my.private.npm.registry/\n_auth = VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nalways-auth = true\n",
|
||||
|
||||
registryURL: "https://my.private.npm.registry/",
|
||||
registryUser: "ThisIsTheUser",
|
||||
registryPassword: "AndHereIsThePassword",
|
||||
},
|
||||
{
|
||||
name: "success - single project, publish normal, packed - target registry from pipeline",
|
||||
|
||||
files: map[string]string{
|
||||
"package.json": `{"name": "piper-project", "version": "0.0.1"}`,
|
||||
".piperNpmrc": "_auth=VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nregistry=https://my.private.npm.registry/",
|
||||
},
|
||||
|
||||
packageDescriptors: []string{"package.json"},
|
||||
|
||||
packBeforePublish: true,
|
||||
|
||||
expectedPublishConfigPath: `temp-(?:test|[0-9]+)/\.piperNpmrc`,
|
||||
expectedPublishConfig: "_auth = VGhpc0lzVGhlT3RoZXJVc2VyOkFuZEhlcmVJc1RoZU90aGVyUGFzc3dvcmQ=\nregistry = https://my.other.private.npm.registry/\nalways-auth = true\n",
|
||||
|
||||
registryURL: "https://my.other.private.npm.registry/",
|
||||
registryUser: "ThisIsTheOtherUser",
|
||||
registryPassword: "AndHereIsTheOtherPassword",
|
||||
},
|
||||
// project in a subfolder
|
||||
{
|
||||
name: "success - single project, publish normal, unpacked package - target registry in npmrc",
|
||||
|
||||
files: map[string]string{
|
||||
"sub/package.json": `{"name": "piper-project", "version": "0.0.1"}`,
|
||||
"sub/.piperNpmrc": "_auth=VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nregistry=https://my.private.npm.registry/",
|
||||
},
|
||||
|
||||
packageDescriptors: []string{"sub/package.json"},
|
||||
|
||||
expectedPublishConfigPath: `sub/\.piperNpmrc`,
|
||||
expectedPublishConfig: "_auth=VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nregistry=https://my.private.npm.registry/",
|
||||
},
|
||||
{
|
||||
name: "success - single project, publish normal, unpacked package - target registry from pipeline",
|
||||
|
||||
files: map[string]string{
|
||||
"sub/package.json": `{"name": "piper-project", "version": "0.0.1"}`,
|
||||
},
|
||||
|
||||
packageDescriptors: []string{"sub/package.json"},
|
||||
|
||||
expectedPublishConfigPath: `sub/\.piperNpmrc`,
|
||||
expectedPublishConfig: "registry = https://my.private.npm.registry/\n_auth = VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nalways-auth = true\n",
|
||||
|
||||
registryURL: "https://my.private.npm.registry/",
|
||||
registryUser: "ThisIsTheUser",
|
||||
registryPassword: "AndHereIsThePassword",
|
||||
},
|
||||
{
|
||||
name: "success - single project, publish normal, unpacked package - target registry from pipeline (precedence over npmrc)",
|
||||
|
||||
files: map[string]string{
|
||||
"sub/package.json": `{"name": "piper-project", "version": "0.0.1"}`,
|
||||
"sub/.piperNpmrc": "_auth=VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nregistry=https://my.private.npm.registry/",
|
||||
},
|
||||
|
||||
packageDescriptors: []string{"sub/package.json"},
|
||||
|
||||
expectedPublishConfigPath: `sub/\.piperNpmrc`,
|
||||
expectedPublishConfig: "_auth = VGhpc0lzVGhlT3RoZXJVc2VyOkFuZEhlcmVJc1RoZU90aGVyUGFzc3dvcmQ=\nregistry = https://my.other.private.npm.registry/\nalways-auth = true\n",
|
||||
|
||||
registryURL: "https://my.other.private.npm.registry/",
|
||||
registryUser: "ThisIsTheOtherUser",
|
||||
registryPassword: "AndHereIsTheOtherPassword",
|
||||
},
|
||||
{
|
||||
name: "success - single project, publish normal, packed - target registry in npmrc",
|
||||
|
||||
files: map[string]string{
|
||||
"sub/package.json": `{"name": "piper-project", "version": "0.0.1"}`,
|
||||
"sub/.piperNpmrc": "_auth=VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nregistry=https://my.private.npm.registry/",
|
||||
},
|
||||
|
||||
packageDescriptors: []string{"sub/package.json"},
|
||||
|
||||
packBeforePublish: true,
|
||||
|
||||
expectedPublishConfigPath: `temp-(?:test|[0-9]+)/\.piperNpmrc`,
|
||||
expectedPublishConfig: "_auth=VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nregistry=https://my.private.npm.registry/",
|
||||
},
|
||||
{
|
||||
name: "success - single project, publish normal, packed - target registry from pipeline",
|
||||
|
||||
files: map[string]string{
|
||||
"sub/package.json": `{"name": "piper-project", "version": "0.0.1"}`,
|
||||
},
|
||||
|
||||
packageDescriptors: []string{"sub/package.json"},
|
||||
|
||||
packBeforePublish: true,
|
||||
|
||||
expectedPublishConfigPath: `temp-(?:test|[0-9]+)/\.piperNpmrc`,
|
||||
expectedPublishConfig: "registry = https://my.private.npm.registry/\n_auth = VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nalways-auth = true\n",
|
||||
|
||||
registryURL: "https://my.private.npm.registry/",
|
||||
registryUser: "ThisIsTheUser",
|
||||
registryPassword: "AndHereIsThePassword",
|
||||
},
|
||||
{
|
||||
name: "success - single project, publish normal, packed - target registry from pipeline",
|
||||
|
||||
files: map[string]string{
|
||||
"sub/package.json": `{"name": "piper-project", "version": "0.0.1"}`,
|
||||
"sub/.piperNpmrc": "_auth=VGhpc0lzVGhlVXNlcjpBbmRIZXJlSXNUaGVQYXNzd29yZA==\nregistry=https://my.private.npm.registry/",
|
||||
},
|
||||
|
||||
packageDescriptors: []string{"sub/package.json"},
|
||||
|
||||
packBeforePublish: true,
|
||||
|
||||
expectedPublishConfigPath: `temp-(?:test|[0-9]+)/\.piperNpmrc`,
|
||||
expectedPublishConfig: "_auth = VGhpc0lzVGhlT3RoZXJVc2VyOkFuZEhlcmVJc1RoZU90aGVyUGFzc3dvcmQ=\nregistry = https://my.other.private.npm.registry/\nalways-auth = true\n",
|
||||
|
||||
registryURL: "https://my.other.private.npm.registry/",
|
||||
registryUser: "ThisIsTheOtherUser",
|
||||
registryPassword: "AndHereIsTheOtherPassword",
|
||||
},
|
||||
// TODO multiple projects
|
||||
// TODO scoped packages
|
||||
/*{
|
||||
name: "success - publish scoped, packed - target registry in npmrc",
|
||||
|
||||
files: map[string]string{
|
||||
"package.json": `{"name": "@piper/project", "version": "0.0.1"}`,
|
||||
".piperNpmrc": testNpmrc.String(),
|
||||
},
|
||||
|
||||
packageDescriptors: []string{"package.json"},
|
||||
|
||||
packBeforePublish: true,
|
||||
|
||||
expectedPublishConfigPath: `temp-(?:test|[0-9]+)/\.piperNpmrc`,
|
||||
expectedPublishConfig: testNpmrc,
|
||||
},
|
||||
{
|
||||
name: "success - publish scoped, packed - target registry from pipeline",
|
||||
|
||||
files: map[string]string{
|
||||
"package.json": `{"name": "@piper/project", "version": "0.0.1"}`,
|
||||
".piperNpmrc": testNpmrc.String(),
|
||||
},
|
||||
|
||||
packageDescriptors: []string{"package.json"},
|
||||
|
||||
packBeforePublish: true,
|
||||
|
||||
expectedPublishConfigPath: `temp-(?:test|[0-9]+)/\.piperNpmrc`,
|
||||
expectedPublishConfig: testNpmrc,
|
||||
|
||||
registryURL: "https://my.private.npm.registry/",
|
||||
registryUser: "ThisIsTheUser",
|
||||
registryPassword: "AndHereIsThePassword",
|
||||
},*/
|
||||
}
|
||||
|
||||
for _, test := range tt {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
utils := newNpmMockUtilsBundle()
|
||||
|
||||
for path, content := range test.files {
|
||||
utils.AddFile(path, []byte(content))
|
||||
}
|
||||
|
||||
options := ExecutorOptions{}
|
||||
|
||||
exec := &Execute{
|
||||
Utils: &utils,
|
||||
Options: options,
|
||||
}
|
||||
|
||||
propertiesLoadFile = func(filename string, enc properties.Encoding) (*properties.Properties, error) {
|
||||
p := properties.NewProperties()
|
||||
|
||||
b, err := utils.FileRead(filename)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = p.Load(b, properties.UTF8)
|
||||
return p, err
|
||||
}
|
||||
|
||||
propertiesWriteFile = utils.FileWrite
|
||||
writeIgnoreFile = utils.FileWrite
|
||||
|
||||
// This stub simulates the behavior of npm pack and puts a tgz into the requested
|
||||
utils.execRunner.Stub = func(call string, stdoutReturn map[string]string, shouldFailOnCommand map[string]error, stdout io.Writer) error {
|
||||
r := regexp.MustCompile(`npm\s+pack\s+.*--pack-destination\s+(?P<destination>[^\s]+).*`)
|
||||
|
||||
matches := r.FindStringSubmatch(call)
|
||||
|
||||
if len(matches) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
packDestination := matches[1]
|
||||
|
||||
utils.AddFile(filepath.Join(packDestination, "package.tgz"), []byte("this is a tgz file"))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
err := exec.PublishAllPackages(test.packageDescriptors, test.registryURL, test.registryUser, test.registryPassword, test.packBeforePublish)
|
||||
|
||||
if len(test.expectedError) == 0 && assert.NoError(t, err) {
|
||||
if assert.NotEmpty(t, utils.execRunner.Calls) {
|
||||
// last call is expected to be npm publish
|
||||
publishCmd := utils.execRunner.Calls[len(utils.execRunner.Calls)-1]
|
||||
|
||||
assert.Equal(t, "npm", publishCmd.Exec)
|
||||
assert.Equal(t, "publish", publishCmd.Params[0])
|
||||
|
||||
if assert.Contains(t, publishCmd.Params, "--userconfig") {
|
||||
effectivePublishConfigPath := publishCmd.Params[piperutils.FindString(publishCmd.Params, "--userconfig")+1]
|
||||
|
||||
assert.Regexp(t, test.expectedPublishConfigPath, effectivePublishConfigPath)
|
||||
|
||||
effectiveConfig, err := utils.FileRead(effectivePublishConfigPath)
|
||||
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equal(t, test.expectedPublishConfig, string(effectiveConfig))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert.EqualError(t, err, test.expectedError)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -16,12 +16,18 @@ func ContainsInt(s []int, e int) bool {
|
||||
|
||||
//ContainsString checks whether the element is part of the slice
|
||||
func ContainsString(s []string, e string) bool {
|
||||
for _, a := range s {
|
||||
return FindString(s, e) >= 0
|
||||
}
|
||||
|
||||
//FindString returns the position of element e in the given slice or -1 if it's not in
|
||||
func FindString(s []string, e string) int {
|
||||
for i, a := range s {
|
||||
if a == e {
|
||||
return true
|
||||
return i
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
//ContainsStringPart checks whether the element is contained as part of one of the elements of the slice
|
||||
|
@ -29,6 +29,18 @@ func TestContainsString(t *testing.T) {
|
||||
assert.False(t, ContainsString(stringList, "baz"))
|
||||
}
|
||||
|
||||
func TestFindString(t *testing.T) {
|
||||
var stringList []string
|
||||
assert.Equal(t, -1, FindString(stringList, "test"))
|
||||
assert.Equal(t, -1, FindString(stringList, ""))
|
||||
|
||||
stringList = append(stringList, "", "foo", "bar", "foo")
|
||||
assert.Equal(t, 0, FindString(stringList, ""))
|
||||
assert.Equal(t, 2, FindString(stringList, "bar"))
|
||||
assert.Equal(t, 1, FindString(stringList, "foo"))
|
||||
assert.Equal(t, -1, FindString(stringList, "baz"))
|
||||
}
|
||||
|
||||
func TestRemoveAll(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("empty array", func(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user