From 8376f07f71f4fb643a0c8fbf1187d3691c6194cd Mon Sep 17 00:00:00 2001 From: Nathan Hammond Date: Wed, 13 Mar 2019 11:17:07 -0700 Subject: [PATCH] Sketch of lockfile generation. --- lib/broccoli/fastboot-config.js | 101 ++++++++++++++++++++++++++++---- package.json | 1 + yarn.lock | 7 +++ 3 files changed, 99 insertions(+), 10 deletions(-) diff --git a/lib/broccoli/fastboot-config.js b/lib/broccoli/fastboot-config.js index 0f7e5b659..60a470b17 100644 --- a/lib/broccoli/fastboot-config.js +++ b/lib/broccoli/fastboot-config.js @@ -3,11 +3,12 @@ const fs = require('fs'); const fmt = require('util').format; -const uniq = require('ember-cli-lodash-subset').uniq; const merge = require('ember-cli-lodash-subset').merge; const md5Hex = require('md5-hex'); const path = require('path'); const Plugin = require('broccoli-plugin'); +const child_process = require('child_process'); +const rimraf = require('rimraf'); const stringify = require('json-stable-stringify'); @@ -47,13 +48,15 @@ module.exports = class FastBootConfig extends Plugin { * and write it to `package.json`. */ build() { - this.buildConfig(); - this.buildDependencies(); - this.buildManifest(); - this.buildHostWhitelist(); - - let outputPath = path.join(this.outputPath, 'package.json'); - this.writeFileIfContentChanged(outputPath, this.toJSONString()); + return Promise.all([ + this.buildConfig(), + this.buildDependencies(), + this.buildManifest(), + this.buildHostWhitelist() + ]).then(() => { + let packageOutputPath = path.join(this.outputPath, 'package.json'); + this.writeFileIfContentChanged(packageOutputPath, this.toJSONString()); + }); } writeFileIfContentChanged(outputPath, content) { @@ -124,8 +127,86 @@ module.exports = class FastBootConfig extends Plugin { }); } - this.dependencies = dependencies; - this.moduleWhitelist = uniq(moduleWhitelist); + return this.updateDependencies(dependencies, moduleWhitelist); + } + + updateDependencies(dependencies, moduleWhitelist) { + if (this.dependenciesChanged(dependencies)) { + return this.getPackageLock(dependencies).then(() => { + this.dependencies = dependencies; + this.moduleWhitelist = moduleWhitelist; + }); + } else { + this.dependencies = dependencies; + this.moduleWhitelist = moduleWhitelist; + } + } + + dependenciesChanged(dependencies) { + return stringify(dependencies) !== stringify(this.dependencies); + } + + getPackageLock(dependencies) { + let packagePath = path.join(this.project.root, 'package.json'); + let lockfilePath = path.join(this.project.root, 'package-lock.json'); + let tmpFolder = path.join(this.outputPath, 'package-lock-generator'); + + fs.mkdirSync(tmpFolder); + fs.symlinkSync(packagePath, path.join(tmpFolder, 'package.json')); + fs.symlinkSync(lockfilePath, path.join(tmpFolder, 'package-lock.json')); + + const firstInstall = new Promise((resolve, reject) => { + this.ui.writeLine('FastBoot: Building node module cache.'); + child_process.exec('npm install --cache=tmp', { cwd: tmpFolder }, (error) => { + if (error) { + reject(error); + } else { + resolve(); + } + }); + }) + + return firstInstall + .then(() => { + this.ui.writeLine('FastBoot: Generating lockfile.'); + + fs.unlinkSync(path.join(tmpFolder, 'package.json')); + fs.unlinkSync(path.join(tmpFolder, 'package-lock.json')); + + fs.writeFileSync(path.join(tmpFolder, 'package.json'), stringify({ dependencies })); + + const secondInstall = new Promise((resolve, reject) => { + child_process.exec('npm install --cache=tmp --offline', { cwd: tmpFolder }, (error) => { + if (error) { + reject(error); + } else { + resolve(); + } + }); + }); + + return secondInstall; + }) + .then(() => { + this.ui.writeLine('FastBoot: Removing node module cache.'); + + fs.renameSync( + path.join(tmpFolder, 'package-lock.json'), + path.join(this.outputPath, 'package-lock.json') + ); + + const removeTmpFolder = new Promise((resolve, reject) => { + rimraf(tmpFolder, (error) => { + if (error) { + reject(error); + } else { + resolve(); + } + }); + }); + + return removeTmpFolder; + }); } updateFastBootManifest(manifest) { diff --git a/package.json b/package.json index a03b84e2d..830bbb1e7 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "fs-extra": "^7.0.0", "json-stable-stringify": "^1.0.1", "md5-hex": "^2.0.0", + "rimraf": "^2.6.3", "silent-error": "^1.1.0" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index d3a10f694..4b00a8dd6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6154,6 +6154,13 @@ rimraf@^2.2.8, rimraf@^2.3.4, rimraf@^2.4.3, rimraf@^2.4.4, rimraf@^2.5.3, rimra dependencies: glob "^7.0.5" +rimraf@^2.6.3: + version "2.6.3" + resolved "https://artifacts.apple.com/api/npm/npm-private/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha1-stEE/g2Psnz54KHNqCYt04M8bKs= + dependencies: + glob "^7.1.3" + rimraf@~2.2.6: version "2.2.8" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582"