Skip to content

Commit a7df17e

Browse files
feat: various fixes and improvements (#17)
* feat: iris-1661 add option to install certain packages using their package.json scripts * feat: added option to always upload to S3 * fix: npm output going to stdout broke elivagar buildspec-set-env-vars.sh
1 parent c79596d commit a7df17e

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

cli.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
#!/usr/bin/env node
2+
'use strict'
3+
24
const program = require('commander')
35
const { local } = require('./index')
46

7+
function commaSeparatedList(value, dummyPrevious) {
8+
return value.split(',');
9+
}
10+
511
program
612
.command('local <bucket>')
713
.option('-s, --source <directory>', 'Source location', process.env.PWD)
8-
.option('-l, --layer', 'Source tree is a Lambda layer. Package the tree as-is. Do not install it as an npm package. A package.json is required but only for the name and version.')
9-
.action(async (bucket, { source, layer }) => {
10-
process.stdout.write(await local(bucket, source, layer))
14+
.option('-l, --layer', 'Source tree is a Lambda layer. Package the tree as-is. ' +
15+
'Do not install it as an npm package. A package.json is required but only for the name and version.')
16+
.option('--script-install <packages>', 'Run "npm install --only=prod" on the comma-delimited list of ' +
17+
'packages, which runs scripts in their package.json. All scripts in all other packages are ignored.', commaSeparatedList)
18+
.option('--always-upload', 'Always upload files even if they already exist on S3.')
19+
.action(async (bucket, { source, layer, scriptInstall, alwaysUpload }) => {
20+
process.stdout.write(await local(bucket, source, layer, scriptInstall, alwaysUpload))
1121
})
1222

1323
program.parse(process.argv)

index.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use strict'
2+
13
const { spawn } = require('child_process')
24
const { readFile: readFileAsync } = require('fs')
35
const { promisify } = require('util')
@@ -16,7 +18,9 @@ const run = (cmd, args, options) => new Promise((resolve, reject) => {
1618
let stderr = []
1719

1820
p.stdout.on('data', data => {
19-
process.stdout.write(chalk.magenta(data.toString()))
21+
// Re-route stdout to stderr, because the only thing the 'local' function should return to stdout
22+
// is the name of the zip file.
23+
process.stderr.write(chalk.magenta(data.toString()))
2024
stdout.push(data.toString())
2125
})
2226

@@ -59,28 +63,40 @@ const existsOnS3 = async (zipFileName, bucket) => {
5963
.catch(() => false)
6064
}
6165

62-
const local = async (bucket, sourcefolder, layer) => createTempDir()
66+
const local = async (bucket, sourcefolder, layer, scriptInstallPackages, alwaysUpload) => createTempDir()
6367
.then(async tempDir => {
6468
const pkg = path.join(sourcefolder, 'package.json')
6569
const { name, version } = JSON.parse(await readFile(pkg), 'utf-8')
6670
console.error(`${chalk.blue(name)} ${chalk.green(version)}`)
6771
const zipFileName = `${name.split('/')[1] || name}-${version}.zip`
68-
if (await existsOnS3(zipFileName, bucket)) {
72+
if (!alwaysUpload && await existsOnS3(zipFileName, bucket)) {
6973
console.error(chalk.yellow(`s3://${bucket}/${zipFileName} exists`))
7074
return zipFileName
7175
}
7276
try {
7377
if (layer) {
7478
// For a Lambda layer, zip up the entire source tree. Don't install it.
79+
console.error(`${chalk.gray('Packaging as Lambda layer')}`)
7580
await ncp(sourcefolder, tempDir)
7681
} else {
7782
// For a Lambda function, zip up the file structure we expect
83+
console.error(`${chalk.gray('Packaging as Lambda function')}`)
7884
await ncp(pkg, path.join(tempDir, 'package.json'))
7985
await ncp(path.join(sourcefolder, 'package-lock.json'), path.join(tempDir, 'package-lock.json'))
8086
await ncp(path.join(sourcefolder, 'dist'), path.join(tempDir, 'dist'))
8187
// Install the package
8288
await run('npm', ['ci', '--ignore-scripts', '--only=prod'], { cwd: tempDir })
8389
}
90+
// For each package in this list, run 'npm install' to run certain scripts defined in its package.json,
91+
// as described in https://docs.npmjs.com/misc/scripts
92+
// Normally scripts aren't run, due to the --ignore-scripts option in the above "npm ci" command.
93+
// This gives the option to run install scripts required for some packages to work, such as 'sharp'.
94+
if (scriptInstallPackages) {
95+
for (let i = 0; i < scriptInstallPackages.length; i++) {
96+
console.error(`${chalk.gray('Installing with scripts:')} ${chalk.yellow(scriptInstallPackages[i])}`)
97+
await run('npm', ['install', '--only=prod', scriptInstallPackages[i]], { cwd: tempDir })
98+
}
99+
}
84100
console.error(`${chalk.gray('Uploading to S3:')} ${chalk.yellow(bucket)}${chalk.gray('/')}${chalk.yellow(zipFileName)}`)
85101
await publishToS3(zipFileName, tempDir, bucket)
86102
return zipFileName

0 commit comments

Comments
 (0)