Skip to content

Commit 02df10f

Browse files
authored
feat(lib/main): separate _npmInstall method into _getNpmInstallCommand and _packageInstall (#580)
Separate `_npmInstall` method into two parts. * Get the command string (`_getNpmInstallCommand`) * Execute the command (`_packageInstall`) (Prepare for "Support for yarn #579".)
1 parent 3478b87 commit 02df10f

File tree

2 files changed

+113
-28
lines changed

2 files changed

+113
-28
lines changed

lib/main.js

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -385,31 +385,41 @@ Emulate only the body of the API Gateway event.
385385
return fs.existsSync(path.join(codeDirectory, 'package-lock.json'))
386386
}
387387

388-
_npmInstall (program, codeDirectory) {
389-
// Run on windows:
390-
// https://nodejs.org/api/child_process.html#child_process_spawning_bat_and_cmd_files_on_windows
391-
392-
const installCommand = this._shouldUseNpmCi(codeDirectory)
393-
? 'ci'
394-
: 'install'
395-
const npmInstallBaseOptions = [
388+
_getNpmInstallCommand (program, codeDirectory) {
389+
const installOptions = [
396390
'-s',
397-
installCommand,
391+
this._shouldUseNpmCi(codeDirectory) ? 'ci' : 'install',
398392
'--production',
399393
'--no-audit'
400394
]
401395

402396
if (program.optionalDependencies === false) {
403-
npmInstallBaseOptions.push('--no-optional')
397+
installOptions.push('--no-optional')
404398
}
405399

400+
if (!program.dockerImage) {
401+
installOptions.push('--prefix', codeDirectory)
402+
}
403+
404+
return {
405+
packageManager: 'npm',
406+
installOptions
407+
}
408+
}
409+
410+
_packageInstall (program, codeDirectory) {
411+
// Run on windows:
412+
// https://nodejs.org/api/child_process.html#child_process_spawning_bat_and_cmd_files_on_windows
413+
414+
const { packageManager, installOptions } = this._getNpmInstallCommand(program, codeDirectory)
415+
406416
const paramsOnContainer = (() => {
407417
// with docker
408418
let dockerVolumesOptions = []
409419
program.dockerVolumes && program.dockerVolumes.split(' ').forEach((volume) => {
410420
dockerVolumesOptions = dockerVolumesOptions.concat(['-v', volume])
411421
})
412-
const dockerCommand = [program.dockerImage, 'npm'].concat(npmInstallBaseOptions)
422+
const dockerCommand = [program.dockerImage, packageManager].concat(installOptions)
413423
const dockerBaseOptions = [
414424
'run', '--rm',
415425
'-v', `${fs.realpathSync(codeDirectory)}:/var/task`,
@@ -429,17 +439,16 @@ Emulate only the body of the API Gateway event.
429439
})()
430440

431441
const paramsOnHost = (() => {
432-
// simple npm install
433-
const options = npmInstallBaseOptions.concat(['--prefix', codeDirectory])
442+
// simple install
434443
if (process.platform === 'win32') {
435444
return {
436445
command: 'cmd.exe',
437-
options: ['/c', 'npm'].concat(options)
446+
options: ['/c', packageManager].concat(installOptions)
438447
}
439448
}
440449
return {
441-
command: 'npm',
442-
options
450+
command: packageManager,
451+
options: installOptions
443452
}
444453
})()
445454

@@ -518,7 +527,7 @@ Emulate only the body of the API Gateway event.
518527

519528
_codeDirectory () {
520529
// Why realpathSync?:
521-
// If tmpdir is symbolic link and npm>=7, `this._npmInstall()` may not work properly.
530+
// If tmpdir is symbolic link and npm>=7, `this._packageInstall()` may not work properly.
522531
return path.join(fs.realpathSync(os.tmpdir()), `${path.basename(path.resolve('.'))}-lambda`)
523532
}
524533

@@ -691,8 +700,8 @@ they may not work as expected in the Lambda environment.
691700
console.log('=> Moving files to temporary directory')
692701
await this._fileCopy(program, lambdaSrcDirectory, codeDirectory, true)
693702
if (!program.keepNodeModules) {
694-
console.log(`=> Running npm ${this._shouldUseNpmCi(codeDirectory) ? 'ci' : 'install'} --production`)
695-
await this._npmInstall(program, codeDirectory)
703+
console.log('=> Running package install')
704+
await this._packageInstall(program, codeDirectory)
696705
}
697706
await this._postInstallScript(program, codeDirectory)
698707
console.log('=> Zipping deployment package')

test/main.js

Lines changed: 85 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,83 @@ describe('lib/main', function () {
590590
})
591591
})
592592

593-
describe('_npmInstall', function () {
593+
describe('_getNpmInstallCommand', () => {
594+
describe('when package-lock.json exists', () => {
595+
const codeDirectory = '.'
596+
597+
it('npm ci', () => {
598+
const { packageManager, installOptions } = lambda._getNpmInstallCommand(program, codeDirectory)
599+
assert.equal(packageManager, 'npm')
600+
assert.deepEqual(installOptions, ['-s', 'ci', '--production', '--no-audit', '--prefix', codeDirectory])
601+
})
602+
603+
it('npm ci with "--no-optional"', () => {
604+
const { packageManager, installOptions } = lambda._getNpmInstallCommand(
605+
{
606+
...program,
607+
optionalDependencies: false
608+
},
609+
codeDirectory
610+
)
611+
assert.equal(packageManager, 'npm')
612+
assert.deepEqual(
613+
installOptions,
614+
['-s', 'ci', '--production', '--no-audit', '--no-optional', '--prefix', codeDirectory]
615+
)
616+
})
617+
618+
it('npm ci on docker', () => {
619+
const { packageManager, installOptions } = lambda._getNpmInstallCommand(
620+
{
621+
...program,
622+
dockerImage: 'test'
623+
},
624+
codeDirectory
625+
)
626+
assert.equal(packageManager, 'npm')
627+
assert.deepEqual(installOptions, ['-s', 'ci', '--production', '--no-audit'])
628+
})
629+
})
630+
631+
describe('when package-lock.json does not exist', () => {
632+
const codeDirectory = './test'
633+
634+
it('npm install', () => {
635+
const { packageManager, installOptions } = lambda._getNpmInstallCommand(program, './test')
636+
assert.equal(packageManager, 'npm')
637+
assert.deepEqual(installOptions, ['-s', 'install', '--production', '--no-audit', '--prefix', './test'])
638+
})
639+
640+
it('npm install with "--no-optional"', () => {
641+
const { packageManager, installOptions } = lambda._getNpmInstallCommand(
642+
{
643+
...program,
644+
optionalDependencies: false
645+
},
646+
codeDirectory
647+
)
648+
assert.equal(packageManager, 'npm')
649+
assert.deepEqual(
650+
installOptions,
651+
['-s', 'install', '--production', '--no-audit', '--no-optional', '--prefix', codeDirectory]
652+
)
653+
})
654+
655+
it('npm install on docker', () => {
656+
const { packageManager, installOptions } = lambda._getNpmInstallCommand(
657+
{
658+
...program,
659+
dockerImage: 'test'
660+
},
661+
codeDirectory
662+
)
663+
assert.equal(packageManager, 'npm')
664+
assert.deepEqual(installOptions, ['-s', 'install', '--production', '--no-audit'])
665+
})
666+
})
667+
})
668+
669+
describe('_packageInstall using "npm"', function () {
594670
_timeout({ this: this, sec: 60 }) // ci should be faster than install
595671

596672
// npm treats files as packages when installing, and so removes them.
@@ -605,7 +681,7 @@ describe('lib/main', function () {
605681
describe('when package-lock.json does exist', () => {
606682
it('should use "npm ci"', () => {
607683
const beforeAwsSdkStat = fs.statSync(path.join(codeDirectory, 'node_modules', 'aws-sdk'))
608-
return lambda._npmInstall(program, codeDirectory).then(() => {
684+
return lambda._packageInstall(program, codeDirectory).then(() => {
609685
const contents = fs.readdirSync(path.join(codeDirectory, 'node_modules'))
610686
assert.include(contents, 'dotenv')
611687

@@ -627,7 +703,7 @@ describe('lib/main', function () {
627703

628704
it('should use "npm install"', () => {
629705
const beforeAwsSdkStat = fs.statSync(path.join(codeDirectory, 'node_modules', 'aws-sdk'))
630-
return lambda._npmInstall(program, codeDirectory).then(() => {
706+
return lambda._packageInstall(program, codeDirectory).then(() => {
631707
const contents = fs.readdirSync(path.join(codeDirectory, 'node_modules'))
632708
assert.include(contents, 'dotenv')
633709

@@ -652,7 +728,7 @@ describe('lib/main', function () {
652728

653729
describe('No `--no-optionalDependencies`', () => {
654730
it('optionalDependencies is installed', () => {
655-
return lambda._npmInstall(program, codeDirectory).then(() => {
731+
return lambda._packageInstall(program, codeDirectory).then(() => {
656732
const contents = fs.readdirSync(path.join(codeDirectory, 'node_modules'))
657733
assert.include(contents, 'npm')
658734
})
@@ -665,7 +741,7 @@ describe('lib/main', function () {
665741
...program,
666742
optionalDependencies: false
667743
}
668-
return lambda._npmInstall(params, codeDirectory).then(() => {
744+
return lambda._packageInstall(params, codeDirectory).then(() => {
669745
const contents = fs.readdirSync(path.join(codeDirectory, 'node_modules'))
670746
assert.notInclude(contents, 'npm')
671747
})
@@ -674,7 +750,7 @@ describe('lib/main', function () {
674750
})
675751
})
676752

677-
describe('_npmInstall (When codeDirectory contains characters to be escaped)', () => {
753+
describe('_packageInstall using "npm" (When codeDirectory contains characters to be escaped)', () => {
678754
beforeEach(() => {
679755
// Since '\' can not be included in the file or directory name in Windows
680756
const directoryName = process.platform === 'win32'
@@ -694,7 +770,7 @@ describe('lib/main', function () {
694770
it('_npm adds node_modules', function () {
695771
_timeout({ this: this, sec: 30 }) // give it time to build the node modules
696772

697-
return lambda._npmInstall(program, codeDirectory).then(() => {
773+
return lambda._packageInstall(program, codeDirectory).then(() => {
698774
const contents = fs.readdirSync(codeDirectory)
699775
assert.include(contents, 'node_modules')
700776
})
@@ -768,15 +844,15 @@ describe('lib/main', function () {
768844
})
769845
})
770846

771-
describe('_zip', () => {
847+
describe('_zip using "npm"', () => {
772848
beforeEach(function () {
773849
_timeout({ this: this, sec: 30 }) // give it time to build the node modules
774850
return Promise.resolve().then(() => {
775851
return lambda._cleanDirectory(codeDirectory)
776852
}).then(() => {
777853
return lambda._fileCopy(program, '.', codeDirectory, true)
778854
}).then(() => {
779-
return lambda._npmInstall(program, codeDirectory)
855+
return lambda._packageInstall(program, codeDirectory)
780856
}).then(() => {
781857
if (process.platform !== 'win32') {
782858
fs.symlinkSync(

0 commit comments

Comments
 (0)