fix(ngcc): correctly invalidate cache when moving/removing files/directories (#35106)
One particular scenario where this was causing problems was when the [BackupFileCleaner][1] restored a file (such as a `.d.ts` file) by [moving the backup file][2] to its original location, but the modified content was kept in the cache. [1]: https://github.com/angular/angular/blob/4d36b2f6e/packages/compiler-cli/ngcc/src/writing/cleaning/cleaning_strategies.ts#L54 [2]: https://github.com/angular/angular/blob/4d36b2f6e/packages/compiler-cli/ngcc/src/writing/cleaning/cleaning_strategies.ts#L61 Fixes #35095 PR Close #35106
This commit is contained in:
parent
3c30474417
commit
523c785e8f
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* **Usage:**
|
||||
* ```sh
|
||||
* node mock-ngcc-version-marker <entry-point> <mock-ngcc-version>
|
||||
*
|
||||
* # Example:
|
||||
* # node mock-ngcc-version-marker @angular/material/button 3.0.0
|
||||
* ```
|
||||
*
|
||||
* Ngcc marks entry-points as processed by adding marker properties in their `package.json`. It uses
|
||||
* a version as a marker in order to be able to distinguish entry-points processed by a different
|
||||
* ngcc version (e.g. an older version after an update) and perform the necessary clean-up.
|
||||
*
|
||||
* This script replaces the ngcc version marker in an entry-point's `package.json` to make it appear
|
||||
* as if it were processed by a different version of ngcc. This allows testing the clean-up logic
|
||||
* without the overhead of actually installing a different ngcc version, compiling the dependencies,
|
||||
* then installing the current version and compiling again.
|
||||
*/
|
||||
|
||||
const {writeFileSync} = require('fs');
|
||||
const {basename} = require('path');
|
||||
|
||||
const entryPointName = process.argv[2];
|
||||
const mockNgccVersion = process.argv[3];
|
||||
const actualNgccVersion = require('@angular/compiler-cli/package.json').version;
|
||||
|
||||
if (!entryPointName || !mockNgccVersion) {
|
||||
throw new Error(
|
||||
'Missing required argument(s).\n' +
|
||||
`Usage: node ${basename(__filename)} <entry-point> <mock-ngcc-version>\n`);
|
||||
}
|
||||
|
||||
const entryPointPkgJsonPath = require.resolve(`${entryPointName}/package.json`);
|
||||
const entryPointPkgJson = require(entryPointPkgJsonPath);
|
||||
const processedMarkers = entryPointPkgJson.__processed_by_ivy_ngcc__;
|
||||
|
||||
Object.keys(processedMarkers).forEach(key => processedMarkers[key] = mockNgccVersion);
|
||||
writeFileSync(entryPointPkgJsonPath, JSON.stringify(entryPointPkgJson, null, 2));
|
||||
|
||||
console.log(
|
||||
`Successfully mocked ngcc version marker in '${entryPointName}': ` +
|
||||
`${actualNgccVersion} --> ${mockNgccVersion}`);
|
|
@ -3,7 +3,7 @@
|
|||
# Do not immediately exit on error to allow the `assertSucceeded` function to handle the error.
|
||||
#
|
||||
# NOTE:
|
||||
# Each statement should be followed by an `assertSucceeded`/`assertFailed` or `exit 1` statement.
|
||||
# Each statement should be followed by an `assert*` or `exit 1` statement.
|
||||
set +e -x
|
||||
|
||||
PATH=$PATH:$(npm bin)
|
||||
|
@ -22,6 +22,26 @@ function assertSucceeded {
|
|||
fi
|
||||
}
|
||||
|
||||
function assertEquals {
|
||||
local value1=$1;
|
||||
local value2=$2;
|
||||
|
||||
if [[ "$value1" != "$value2" ]]; then
|
||||
echo "FAIL: Expected '$value1' to equal '$value2'."
|
||||
exit 1;
|
||||
fi
|
||||
}
|
||||
|
||||
function assertNotEquals {
|
||||
local value1=$1;
|
||||
local value2=$2;
|
||||
|
||||
if [[ "$value1" == "$value2" ]]; then
|
||||
echo "FAIL: Expected '$value1' not to equal '$value2'."
|
||||
exit 1;
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
ngcc --help
|
||||
assertSucceeded "Expected 'ngcc --help' to succeed."
|
||||
|
@ -140,6 +160,27 @@ assertSucceeded "Expected 'ngcc' to log 'Compiling'."
|
|||
assertSucceeded "Expected 'ngcc' to not add trailing commas to factory function parameters in UMD."
|
||||
|
||||
|
||||
# Can it correctly clean up and re-compile when dependencies are already compiled by a different version?
|
||||
readonly actualNgccVersion=`node --print "require('@angular/compiler-cli/package.json').version"`
|
||||
readonly mockNgccVersion="3.0.0"
|
||||
|
||||
# Mock the ngcc version marker on a package to make it appear as if it is compiled by a different ngcc version.
|
||||
node mock-ngcc-version-marker @angular/material/button $mockNgccVersion
|
||||
assertSucceeded "Expected to successfully mock the 'ngcc' version marker in '@angular/material/button'."
|
||||
assertEquals $mockNgccVersion `node --print "require('@angular/material/button/package.json').__processed_by_ivy_ngcc__.main"`
|
||||
assertEquals 1 `cat node_modules/@angular/material/button/button.d.ts | grep 'import \* as ɵngcc0' | wc -l`
|
||||
|
||||
# Re-compile packages (which requires cleaning up those compiled by a different ngcc version).
|
||||
# (Use sync mode to ensure all tasks share the same `CachedFileSystem` instance.)
|
||||
ngcc --no-async --properties main
|
||||
assertSucceeded "Expected 'ngcc' to successfully re-compile the packages."
|
||||
|
||||
# Ensure previously compiled packages were correctly cleaned up (i.e. no multiple
|
||||
# `import ... ɵngcc0` statements) and re-compiled by the current ngcc version.
|
||||
assertEquals $actualNgccVersion `node --print "require('@angular/material/button/package.json').__processed_by_ivy_ngcc__.main"`
|
||||
assertEquals 1 `cat node_modules/@angular/material/button/button.d.ts | grep 'import \* as ɵngcc0' | wc -l`
|
||||
|
||||
|
||||
# Can it compile `@angular/platform-server` in UMD + typings without errors?
|
||||
# (The CLI prefers the `main` property (which maps to UMD) over `module` when compiling `@angular/platform-server`.
|
||||
# See https://github.com/angular/angular-cli/blob/e36853338/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/server.ts#L34)
|
||||
|
@ -151,6 +192,7 @@ assertSucceeded "Expected 'ngcc' to log 'Compiling'."
|
|||
ngcc --properties main --target @angular/platform-server
|
||||
assertSucceeded "Expected 'ngcc' to successfully compile '@angular/platform-server' (main)."
|
||||
|
||||
|
||||
# Can it be safely run again (as a noop)?
|
||||
# And check that it logged skipping compilation as expected
|
||||
ngcc -l debug | grep 'Skipping'
|
||||
|
|
|
@ -19,9 +19,10 @@
|
|||
version "9.0.0-rc.1"
|
||||
dependencies:
|
||||
canonical-path "1.0.0"
|
||||
chokidar "^2.1.1"
|
||||
chokidar "^3.0.0"
|
||||
convert-source-map "^1.5.1"
|
||||
dependency-graph "^0.7.2"
|
||||
fs-extra "4.0.2"
|
||||
magic-string "^0.25.0"
|
||||
minimist "^1.2.0"
|
||||
reflect-metadata "^0.1.2"
|
||||
|
@ -154,6 +155,14 @@ anymatch@^2.0.0:
|
|||
micromatch "^3.1.4"
|
||||
normalize-path "^2.1.1"
|
||||
|
||||
anymatch@~3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142"
|
||||
integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==
|
||||
dependencies:
|
||||
normalize-path "^3.0.0"
|
||||
picomatch "^2.0.4"
|
||||
|
||||
aproba@^1.0.3:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
|
||||
|
@ -248,11 +257,6 @@ async-each@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
|
||||
integrity sha1-GdOGodntxufByF04iu28xW0zYC0=
|
||||
|
||||
async-each@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.2.tgz#8b8a7ca2a658f927e9f307d6d1a42f4199f0f735"
|
||||
integrity sha512-6xrbvN0MOBKSJDdonmSSz2OwFSgxRaVtBDes26mj9KIGtDo+g9xosFRSC+i1gQh2oAN/tQ62AI/pGZGQjVOiRg==
|
||||
|
||||
async-limiter@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
|
||||
|
@ -348,6 +352,11 @@ binary-extensions@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14"
|
||||
integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==
|
||||
|
||||
binary-extensions@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
|
||||
integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==
|
||||
|
||||
blob@0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683"
|
||||
|
@ -377,7 +386,7 @@ braces@^1.8.2:
|
|||
preserve "^0.2.0"
|
||||
repeat-element "^1.1.2"
|
||||
|
||||
braces@^2.3.0, braces@^2.3.1, braces@^2.3.2:
|
||||
braces@^2.3.0, braces@^2.3.1:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729"
|
||||
integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==
|
||||
|
@ -393,6 +402,13 @@ braces@^2.3.0, braces@^2.3.1, braces@^2.3.2:
|
|||
split-string "^3.0.2"
|
||||
to-regex "^3.0.1"
|
||||
|
||||
braces@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
||||
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
||||
dependencies:
|
||||
fill-range "^7.0.1"
|
||||
|
||||
browser-sync-client@^2.26.2:
|
||||
version "2.26.2"
|
||||
resolved "https://registry.yarnpkg.com/browser-sync-client/-/browser-sync-client-2.26.2.tgz#dd0070c80bdc6d9021e89f7837ee70ed0a8acf91"
|
||||
|
@ -560,24 +576,20 @@ chokidar@^2.0.4:
|
|||
optionalDependencies:
|
||||
fsevents "^1.2.2"
|
||||
|
||||
chokidar@^2.1.1:
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.5.tgz#0ae8434d962281a5f56c72869e79cb6d9d86ad4d"
|
||||
integrity sha512-i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A==
|
||||
chokidar@^3.0.0:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450"
|
||||
integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==
|
||||
dependencies:
|
||||
anymatch "^2.0.0"
|
||||
async-each "^1.0.1"
|
||||
braces "^2.3.2"
|
||||
glob-parent "^3.1.0"
|
||||
inherits "^2.0.3"
|
||||
is-binary-path "^1.0.0"
|
||||
is-glob "^4.0.0"
|
||||
normalize-path "^3.0.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
readdirp "^2.2.1"
|
||||
upath "^1.1.1"
|
||||
anymatch "~3.1.1"
|
||||
braces "~3.0.2"
|
||||
glob-parent "~5.1.0"
|
||||
is-binary-path "~2.1.0"
|
||||
is-glob "~4.0.1"
|
||||
normalize-path "~3.0.0"
|
||||
readdirp "~3.3.0"
|
||||
optionalDependencies:
|
||||
fsevents "^1.2.7"
|
||||
fsevents "~2.1.2"
|
||||
|
||||
chownr@^1.0.1:
|
||||
version "1.1.1"
|
||||
|
@ -1119,6 +1131,13 @@ fill-range@^4.0.0:
|
|||
repeat-string "^1.6.1"
|
||||
to-regex-range "^2.1.0"
|
||||
|
||||
fill-range@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
|
||||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
finalhandler@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5"
|
||||
|
@ -1201,6 +1220,15 @@ fs-extra@3.0.1:
|
|||
jsonfile "^3.0.0"
|
||||
universalify "^0.1.0"
|
||||
|
||||
fs-extra@4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.2.tgz#f91704c53d1b461f893452b0c307d9997647ab6b"
|
||||
integrity sha1-+RcExT0bRh+JNFKwwwfZmXZHq2s=
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
jsonfile "^4.0.0"
|
||||
universalify "^0.1.0"
|
||||
|
||||
fs-minipass@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d"
|
||||
|
@ -1221,13 +1249,10 @@ fsevents@^1.2.2:
|
|||
nan "^2.9.2"
|
||||
node-pre-gyp "^0.10.0"
|
||||
|
||||
fsevents@^1.2.7:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.7.tgz#4851b664a3783e52003b3c66eb0eee1074933aa4"
|
||||
integrity sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==
|
||||
dependencies:
|
||||
nan "^2.9.2"
|
||||
node-pre-gyp "^0.10.0"
|
||||
fsevents@~2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805"
|
||||
integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==
|
||||
|
||||
gauge@~2.7.3:
|
||||
version "2.7.4"
|
||||
|
@ -1295,6 +1320,13 @@ glob-parent@^3.1.0:
|
|||
is-glob "^3.1.0"
|
||||
path-dirname "^1.0.0"
|
||||
|
||||
glob-parent@~5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2"
|
||||
integrity sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
glob@^7.0.3, glob@^7.0.5, glob@^7.0.6:
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
|
||||
|
@ -1488,7 +1520,7 @@ inflight@^1.0.4:
|
|||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3:
|
||||
inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@~2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
|
@ -1534,6 +1566,13 @@ is-binary-path@^1.0.0:
|
|||
dependencies:
|
||||
binary-extensions "^1.0.0"
|
||||
|
||||
is-binary-path@~2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
|
||||
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
|
||||
dependencies:
|
||||
binary-extensions "^2.0.0"
|
||||
|
||||
is-buffer@^1.1.5:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||
|
@ -1645,6 +1684,13 @@ is-glob@^4.0.0:
|
|||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
is-glob@^4.0.1, is-glob@~4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
|
||||
integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
|
||||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
is-number-like@^1.0.3:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/is-number-like/-/is-number-like-1.0.8.tgz#2e129620b50891042e44e9bbbb30593e75cfbbe3"
|
||||
|
@ -1671,6 +1717,11 @@ is-number@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff"
|
||||
integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==
|
||||
|
||||
is-number@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
||||
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
||||
|
||||
is-path-cwd@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
|
||||
|
@ -1810,6 +1861,13 @@ jsonfile@^3.0.0:
|
|||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsonfile@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
|
||||
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsprim@^1.2.2:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
|
||||
|
@ -2189,7 +2247,7 @@ normalize-path@^2.0.1, normalize-path@^2.1.1:
|
|||
dependencies:
|
||||
remove-trailing-separator "^1.0.1"
|
||||
|
||||
normalize-path@^3.0.0:
|
||||
normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||
|
@ -2479,6 +2537,11 @@ performance-now@^2.1.0:
|
|||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
||||
|
||||
picomatch@^2.0.4, picomatch@^2.0.7:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a"
|
||||
integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==
|
||||
|
||||
pify@^2.0.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
||||
|
@ -2520,7 +2583,7 @@ process-nextick-args@~2.0.0:
|
|||
integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==
|
||||
|
||||
"protractor@file:../../node_modules/protractor":
|
||||
version "5.4.2"
|
||||
version "5.4.3"
|
||||
dependencies:
|
||||
"@types/q" "^0.0.32"
|
||||
"@types/selenium-webdriver" "^3.0.0"
|
||||
|
@ -2640,7 +2703,7 @@ readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@~2.3.6:
|
|||
string_decoder "~1.1.1"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
readdirp@^2.0.0, readdirp@^2.2.1:
|
||||
readdirp@^2.0.0:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525"
|
||||
integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==
|
||||
|
@ -2649,6 +2712,13 @@ readdirp@^2.0.0, readdirp@^2.2.1:
|
|||
micromatch "^3.1.10"
|
||||
readable-stream "^2.0.2"
|
||||
|
||||
readdirp@~3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.3.0.tgz#984458d13a1e42e2e9f5841b129e162f369aff17"
|
||||
integrity sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==
|
||||
dependencies:
|
||||
picomatch "^2.0.7"
|
||||
|
||||
reflect-metadata@^0.1.2:
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.12.tgz#311bf0c6b63cd782f228a81abe146a2bfa9c56f2"
|
||||
|
@ -3276,6 +3346,13 @@ to-regex-range@^2.1.0:
|
|||
is-number "^3.0.0"
|
||||
repeat-string "^1.6.1"
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
||||
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
|
||||
dependencies:
|
||||
is-number "^7.0.0"
|
||||
|
||||
to-regex@^3.0.1, to-regex@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce"
|
||||
|
@ -3317,7 +3394,7 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
|||
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
||||
|
||||
"typescript@file:../../node_modules/typescript":
|
||||
version "3.6.4"
|
||||
version "3.7.4"
|
||||
|
||||
ua-parser-js@0.7.17:
|
||||
version "0.7.17"
|
||||
|
@ -3362,11 +3439,6 @@ upath@^1.0.5:
|
|||
resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd"
|
||||
integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==
|
||||
|
||||
upath@^1.1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068"
|
||||
integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==
|
||||
|
||||
urix@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
|
||||
|
|
|
@ -72,12 +72,16 @@ export class CachedFileSystem implements FileSystem {
|
|||
|
||||
moveFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void {
|
||||
this.delegate.moveFile(from, to);
|
||||
|
||||
this.existsCache.set(from, false);
|
||||
this.existsCache.set(to, true);
|
||||
|
||||
if (this.readFileCache.has(from)) {
|
||||
this.readFileCache.set(to, this.readFileCache.get(from));
|
||||
this.readFileCache.delete(from);
|
||||
} else {
|
||||
this.readFileCache.delete(to);
|
||||
}
|
||||
this.existsCache.set(to, true);
|
||||
}
|
||||
|
||||
ensureDir(path: AbsoluteFsPath): void {
|
||||
|
@ -90,10 +94,18 @@ export class CachedFileSystem implements FileSystem {
|
|||
|
||||
removeDeep(path: AbsoluteFsPath): void {
|
||||
this.delegate.removeDeep(path);
|
||||
// Clear out all children of this directory from the exists cache.
|
||||
|
||||
// Clear out this directory and all its children from the `exists` cache.
|
||||
for (const p of this.existsCache.keys()) {
|
||||
if (p.startsWith(path)) {
|
||||
this.existsCache.set(path, false);
|
||||
this.existsCache.set(p, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear out this directory and all its children from the `readFile` cache.
|
||||
for (const p of this.readFileCache.keys()) {
|
||||
if (p.startsWith(path)) {
|
||||
this.readFileCache.delete(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {CachedFileSystem} from '../src/cached_file_system';
|
||||
import {absoluteFrom, setFileSystem} from '../src/helpers';
|
||||
import {absoluteFrom, join, setFileSystem} from '../src/helpers';
|
||||
import {NodeJSFileSystem} from '../src/node_js_file_system';
|
||||
import {AbsoluteFsPath, FileSystem} from '../src/types';
|
||||
|
||||
|
@ -236,7 +236,7 @@ describe('CachedFileSystem', () => {
|
|||
expect(readFileSpy).toHaveBeenCalledWith(abcPath);
|
||||
});
|
||||
|
||||
it('should update the `to` "readFile" cache', () => {
|
||||
it('should update the `to` "readFile" cache (if `from` was cached)', () => {
|
||||
spyOn(delegate, 'moveFile');
|
||||
const readFileSpy = spyOn(delegate, 'readFile');
|
||||
|
||||
|
@ -252,6 +252,24 @@ describe('CachedFileSystem', () => {
|
|||
expect(fs.readFile(xyzPath)).toEqual('abc content');
|
||||
expect(readFileSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should delete the `to` "readFile" cache (if `from` was not cached)', () => {
|
||||
spyOn(delegate, 'moveFile');
|
||||
const readFileSpy = spyOn(delegate, 'readFile');
|
||||
|
||||
// Fill the xyz "readFile" cache
|
||||
readFileSpy.and.returnValue('xyz content');
|
||||
fs.readFile(xyzPath);
|
||||
readFileSpy.calls.reset();
|
||||
|
||||
// Move the file
|
||||
fs.moveFile(abcPath, xyzPath);
|
||||
|
||||
// Show that the cache was not hit for the xyz file
|
||||
readFileSpy.and.returnValue('abc content');
|
||||
expect(fs.readFile(xyzPath)).toBe('abc content');
|
||||
expect(readFileSpy).toHaveBeenCalledWith(xyzPath);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ensureDir()', () => {
|
||||
|
@ -281,14 +299,41 @@ describe('CachedFileSystem', () => {
|
|||
});
|
||||
|
||||
it('should update the exists cache', () => {
|
||||
spyOn(delegate, 'writeFile');
|
||||
spyOn(delegate, 'removeDeep');
|
||||
const existsSpy = spyOn(delegate, 'exists').and.returnValue(true);
|
||||
expect(fs.exists(abcPath)).toBe(true);
|
||||
existsSpy.calls.reset();
|
||||
|
||||
// Create a file inside `/a/b/c`.
|
||||
const abcdPath = join(abcPath, 'd');
|
||||
fs.writeFile(abcdPath, 'content');
|
||||
expect(fs.exists(abcdPath)).toBe(true);
|
||||
expect(existsSpy).not.toHaveBeenCalled();
|
||||
|
||||
// Remove the `/a/b/c` directory and ensure it is removed from cache (along with its content).
|
||||
fs.removeDeep(abcPath);
|
||||
expect(fs.exists(abcPath)).toBeFalsy();
|
||||
expect(fs.exists(abcdPath)).toBeFalsy();
|
||||
expect(existsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should update the readFile cache', () => {
|
||||
spyOn(delegate, 'writeFile');
|
||||
spyOn(delegate, 'removeDeep');
|
||||
spyOn(delegate, 'lstat').and.throwError('ENOENT: no such file or directory');
|
||||
const readFileSpy = spyOn(delegate, 'readFile');
|
||||
|
||||
// Create a file inside `/a/b/c`.
|
||||
const abcdPath = join(abcPath, 'd');
|
||||
fs.writeFile(abcdPath, 'content from cache');
|
||||
expect(fs.readFile(abcdPath)).toBe('content from cache');
|
||||
expect(readFileSpy).not.toHaveBeenCalled();
|
||||
|
||||
// Remove the `/a/b/c` directory and ensure it is removed from cache (along with its content).
|
||||
fs.removeDeep(abcPath);
|
||||
expect(() => fs.readFile(abcdPath)).toThrowError('ENOENT: no such file or directory');
|
||||
expect(() => fs.readFile(abcPath)).toThrowError('ENOENT: no such file or directory');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue