You've already forked sap-jenkins-library
mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-07-17 01:42:43 +02:00
Refactor pkg/npm and npmExecuteScripts (#1684)
This change refactors the npm pkg and npmExecuteScripts implementations to be reusable for future steps, e.g., npmExecuteLint. In addition, it fixes few small bugs related to unit test execution on Windows and the fileUtils mocking implementation. Co-authored-by: Daniel Kurzynski <daniel.kurzynski@sap.com> Co-authored-by: Stephan Aßmus <stephan.assmus@sap.com>
This commit is contained in:
@ -1,185 +1,30 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/SAP/jenkins-library/pkg/command"
|
||||
"github.com/SAP/jenkins-library/pkg/log"
|
||||
"github.com/SAP/jenkins-library/pkg/npm"
|
||||
FileUtils "github.com/SAP/jenkins-library/pkg/piperutils"
|
||||
"github.com/SAP/jenkins-library/pkg/telemetry"
|
||||
"github.com/bmatcuk/doublestar"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type npmExecuteScriptsUtilsInterface interface {
|
||||
fileExists(path string) (bool, error)
|
||||
glob(pattern string) (matches []string, err error)
|
||||
getwd() (dir string, err error)
|
||||
chdir(dir string) error
|
||||
getExecRunner() execRunner
|
||||
}
|
||||
|
||||
type npmExecuteScriptsUtilsBundle struct {
|
||||
projectStructure FileUtils.ProjectStructure
|
||||
fileUtils FileUtils.Files
|
||||
execRunner *command.Command
|
||||
}
|
||||
|
||||
func (u *npmExecuteScriptsUtilsBundle) fileExists(path string) (bool, error) {
|
||||
return u.fileUtils.FileExists(path)
|
||||
}
|
||||
|
||||
func (u *npmExecuteScriptsUtilsBundle) glob(pattern string) (matches []string, err error) {
|
||||
return doublestar.Glob(pattern)
|
||||
}
|
||||
|
||||
func (u *npmExecuteScriptsUtilsBundle) getwd() (dir string, err error) {
|
||||
return os.Getwd()
|
||||
}
|
||||
|
||||
func (u *npmExecuteScriptsUtilsBundle) chdir(dir string) error {
|
||||
return os.Chdir(dir)
|
||||
}
|
||||
|
||||
func (u *npmExecuteScriptsUtilsBundle) getExecRunner() execRunner {
|
||||
if u.execRunner == nil {
|
||||
u.execRunner = &command.Command{}
|
||||
u.execRunner.Stdout(log.Writer())
|
||||
u.execRunner.Stderr(log.Writer())
|
||||
}
|
||||
return u.execRunner
|
||||
}
|
||||
|
||||
func npmExecuteScripts(config npmExecuteScriptsOptions, telemetryData *telemetry.CustomData) {
|
||||
utils := npmExecuteScriptsUtilsBundle{}
|
||||
npmExecutorOptions := npm.ExecutorOptions{DefaultNpmRegistry: config.DefaultNpmRegistry, SapNpmRegistry: config.SapNpmRegistry}
|
||||
npmExecutor := npm.NewExecutor(npmExecutorOptions)
|
||||
|
||||
err := runNpmExecuteScripts(&utils, &config)
|
||||
err := runNpmExecuteScripts(npmExecutor, &config)
|
||||
if err != nil {
|
||||
log.Entry().WithError(err).Fatal("step execution failed")
|
||||
}
|
||||
}
|
||||
func runNpmExecuteScripts(utils npmExecuteScriptsUtilsInterface, options *npmExecuteScriptsOptions) error {
|
||||
execRunner := utils.getExecRunner()
|
||||
packageJSONFiles, err := findPackageJSONFiles(utils)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
oldWorkingDirectory, err := utils.getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func runNpmExecuteScripts(npmExecutor npm.Executor, config *npmExecuteScriptsOptions) error {
|
||||
packageJSONFiles := npmExecutor.FindPackageJSONFiles()
|
||||
|
||||
if options.VirtualFrameBuffer {
|
||||
cmd, err := execRunner.RunExecutableInBackground("Xvfb", "-ac", ":99", "-screen", "0", "1280x1024x16")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to start virtual frame buffer%w", err)
|
||||
}
|
||||
defer cmd.Kill()
|
||||
execRunner.SetEnv([]string{"DISPLAY=:99"})
|
||||
}
|
||||
|
||||
for _, file := range packageJSONFiles {
|
||||
dir := path.Dir(file)
|
||||
err = utils.chdir(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// set in each directory to respect existing config in rc files
|
||||
err = npm.SetNpmRegistries(
|
||||
&npm.RegistryOptions{
|
||||
DefaultNpmRegistry: options.DefaultNpmRegistry,
|
||||
SapNpmRegistry: options.SapNpmRegistry,
|
||||
}, execRunner)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
packageLockExists, yarnLockExists, err := checkIfLockFilesExist(utils)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if options.Install {
|
||||
err = installDependencies(dir, packageLockExists, yarnLockExists, execRunner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range options.RunScripts {
|
||||
log.Entry().WithField("WorkingDirectory", dir).Info("run-script " + v)
|
||||
err = execRunner.RunExecutable("npm", "run-script", v, "--if-present")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
err = utils.chdir(oldWorkingDirectory)
|
||||
if config.Install {
|
||||
err := npmExecutor.InstallAllDependencies(packageJSONFiles)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func findPackageJSONFiles(utils npmExecuteScriptsUtilsInterface) ([]string, error) {
|
||||
unfilteredListOfPackageJSONFiles, err := utils.glob("**/package.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var packageJSONFiles []string
|
||||
|
||||
for _, file := range unfilteredListOfPackageJSONFiles {
|
||||
if strings.Contains(file, "node_modules") {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(file, "gen/") || strings.Contains(file, "/gen/") {
|
||||
continue
|
||||
}
|
||||
packageJSONFiles = append(packageJSONFiles, file)
|
||||
log.Entry().Info("Discovered package.json file " + file)
|
||||
}
|
||||
return packageJSONFiles, nil
|
||||
}
|
||||
func checkIfLockFilesExist(utils npmExecuteScriptsUtilsInterface) (bool, bool, error) {
|
||||
packageLockExists, err := utils.fileExists("package-lock.json")
|
||||
|
||||
if err != nil {
|
||||
return false, false, err
|
||||
}
|
||||
yarnLockExists, err := utils.fileExists("yarn.lock")
|
||||
if err != nil {
|
||||
return false, false, err
|
||||
}
|
||||
return packageLockExists, yarnLockExists, nil
|
||||
}
|
||||
|
||||
func installDependencies(dir string, packageLockExists bool, yarnLockExists bool, execRunner execRunner) (err error) {
|
||||
log.Entry().WithField("WorkingDirectory", dir).Info("Running install")
|
||||
if packageLockExists {
|
||||
err = execRunner.RunExecutable("npm", "ci")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if yarnLockExists {
|
||||
err = execRunner.RunExecutable("yarn", "install", "--frozen-lockfile")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
log.Entry().Warn("No package lock file found. " +
|
||||
"It is recommended to create a `package-lock.json` file by running `npm install` locally." +
|
||||
" Add this file to your version control. " +
|
||||
"By doing so, the builds of your application become more reliable.")
|
||||
err = execRunner.RunExecutable("npm", "install")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return npmExecutor.RunScriptsInAllPackages(config.RunScripts, nil, config.VirtualFrameBuffer)
|
||||
}
|
||||
|
Reference in New Issue
Block a user