From 38359b166e3d8f7f86ab3594892c9f700a1db390 Mon Sep 17 00:00:00 2001 From: George Kalpakas Date: Mon, 12 Aug 2019 16:38:42 +0300 Subject: [PATCH] fix(ngcc): only back up the original `prepublishOnly` script and not the overwritten one (#32427) In order to prevent `ngcc`'d packages (e.g. libraries) from getting accidentally published, `ngcc` overwrites the `prepublishOnly` npm script to log a warning and exit with an error. In case we want to restore the original script (e.g. "undo" `ngcc` processing), we keep a backup of the original `prepublishOnly` script. Previously, running `ngcc` a second time (e.g. for a different format) would create a backup of the overwritten `prepublishOnly` script (if there was originally no `prepublishOnly` script). As a result, if we ever tried to "undo" `ngcc` processing and restore the original `prepublishOnly` script, the error-throwing script would be restored instead. This commit fixes it by ensuring that we only back up a `prepublishOnly` script, iff it is not the one we created ourselves (i.e. the error-throwing one). PR Close #32427 --- .../ngcc/src/packages/build_marker.ts | 12 +++++++---- .../ngcc/test/packages/build_marker_spec.ts | 20 +++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/packages/compiler-cli/ngcc/src/packages/build_marker.ts b/packages/compiler-cli/ngcc/src/packages/build_marker.ts index 3703183d63..d9b99ff651 100644 --- a/packages/compiler-cli/ngcc/src/packages/build_marker.ts +++ b/packages/compiler-cli/ngcc/src/packages/build_marker.ts @@ -59,16 +59,20 @@ export function markAsProcessed( } const scripts = packageJson.scripts || (packageJson.scripts = {}); - scripts.prepublishOnly__ivy_ngcc_bak = - scripts.prepublishOnly__ivy_ngcc_bak || scripts.prepublishOnly; - - scripts.prepublishOnly = 'node --eval \"console.error(\'' + + const oldPrepublishOnly = scripts.prepublishOnly; + const newPrepublishOnly = 'node --eval \"console.error(\'' + 'ERROR: Trying to publish a package that has been compiled by NGCC. This is not allowed.\\n' + 'Please delete and rebuild the package, without compiling with NGCC, before attempting to publish.\\n' + 'Note that NGCC may have been run by importing this package into another project that is being built with Ivy enabled.\\n' + '\')\" ' + '&& exit 1'; + if (oldPrepublishOnly && (oldPrepublishOnly !== newPrepublishOnly)) { + scripts.prepublishOnly__ivy_ngcc_bak = oldPrepublishOnly; + } + + scripts.prepublishOnly = newPrepublishOnly; + // Just in case this package.json was synthesized due to a custom configuration // we will ensure that the path to the containing folder exists before we write the file. fs.ensureDir(dirname(packageJsonPath)); diff --git a/packages/compiler-cli/ngcc/test/packages/build_marker_spec.ts b/packages/compiler-cli/ngcc/test/packages/build_marker_spec.ts index 5ce34281aa..1eeb377d1b 100644 --- a/packages/compiler-cli/ngcc/test/packages/build_marker_spec.ts +++ b/packages/compiler-cli/ngcc/test/packages/build_marker_spec.ts @@ -147,6 +147,26 @@ runInEachFileSystem(() => { expect(pkg.scripts.prepublishOnly).toContain('This is not allowed'); expect(pkg.scripts.prepublishOnly__ivy_ngcc_bak).toBe(prepublishOnly); }); + + it(`should not keep backup of overwritten 'prepublishOnly' script`, () => { + const COMMON_PACKAGE_PATH = _('/node_modules/@angular/common/package.json'); + const fs = getFileSystem(); + let pkg = JSON.parse(fs.readFile(COMMON_PACKAGE_PATH)); + + markAsProcessed(fs, pkg, COMMON_PACKAGE_PATH, ['fesm2015']); + + pkg = JSON.parse(fs.readFile(COMMON_PACKAGE_PATH)); + expect(pkg.scripts.prepublishOnly).toContain('This is not allowed'); + expect(pkg.scripts.prepublishOnly__ivy_ngcc_bak).toBeUndefined(); + + // Running again, now that there is `prepublishOnly` script (created by `ngcc`), it should + // still not back it up as `prepublishOnly__ivy_ngcc_bak`. + markAsProcessed(fs, pkg, COMMON_PACKAGE_PATH, ['fesm2015']); + + pkg = JSON.parse(fs.readFile(COMMON_PACKAGE_PATH)); + expect(pkg.scripts.prepublishOnly).toContain('This is not allowed'); + expect(pkg.scripts.prepublishOnly__ivy_ngcc_bak).toBeUndefined(); + }); }); describe('hasBeenProcessed', () => {