refactor(compiler-cli): add removeDir()
to FileSystem
(#35079)
PR Close #35079
This commit is contained in:
parent
16e15f50d2
commit
2e52fcf1eb
@ -32,6 +32,7 @@ ts_library(
|
|||||||
"@npm//@bazel/typescript",
|
"@npm//@bazel/typescript",
|
||||||
"@npm//@types/chokidar",
|
"@npm//@types/chokidar",
|
||||||
"@npm//@types/node",
|
"@npm//@types/node",
|
||||||
|
"@npm//fs-extra",
|
||||||
"@npm//minimist",
|
"@npm//minimist",
|
||||||
"@npm//reflect-metadata",
|
"@npm//reflect-metadata",
|
||||||
"@npm//tsickle",
|
"@npm//tsickle",
|
||||||
|
@ -47,6 +47,7 @@ const requiredNodeModules = {
|
|||||||
'tslib': resolveNpmTreeArtifact('npm/node_modules/tslib'),
|
'tslib': resolveNpmTreeArtifact('npm/node_modules/tslib'),
|
||||||
'domino': resolveNpmTreeArtifact('npm/node_modules/domino'),
|
'domino': resolveNpmTreeArtifact('npm/node_modules/domino'),
|
||||||
'xhr2': resolveNpmTreeArtifact('npm/node_modules/xhr2'),
|
'xhr2': resolveNpmTreeArtifact('npm/node_modules/xhr2'),
|
||||||
|
'fs-extra': resolveNpmTreeArtifact('npm/node_modules/fs-extra'),
|
||||||
|
|
||||||
// Fine grained dependencies which are used by the integration test Angular modules, and
|
// Fine grained dependencies which are used by the integration test Angular modules, and
|
||||||
// need to be symlinked so that they can be resolved by NodeJS or NGC.
|
// need to be symlinked so that they can be resolved by NodeJS or NGC.
|
||||||
|
@ -9,7 +9,9 @@ ts_library(
|
|||||||
]),
|
]),
|
||||||
deps = [
|
deps = [
|
||||||
"//packages:types",
|
"//packages:types",
|
||||||
|
"@npm//@types/fs-extra",
|
||||||
"@npm//@types/node",
|
"@npm//@types/node",
|
||||||
|
"@npm//fs-extra",
|
||||||
"@npm//typescript",
|
"@npm//typescript",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -88,6 +88,17 @@ export class CachedFileSystem implements FileSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeDeep(path: AbsoluteFsPath): void {
|
||||||
|
this.delegate.removeDeep(path);
|
||||||
|
// Clear out all children of this directory from the exists cache.
|
||||||
|
for (const p of this.existsCache.keys()) {
|
||||||
|
if (p.startsWith(path)) {
|
||||||
|
this.existsCache.set(path, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
lstat(path: AbsoluteFsPath): FileStats {
|
lstat(path: AbsoluteFsPath): FileStats {
|
||||||
const stat = this.delegate.lstat(path);
|
const stat = this.delegate.lstat(path);
|
||||||
// if the `path` does not exist then `lstat` will thrown an error.
|
// if the `path` does not exist then `lstat` will thrown an error.
|
||||||
|
@ -30,6 +30,7 @@ export class InvalidFileSystem implements FileSystem {
|
|||||||
copyFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void { throw makeError(); }
|
copyFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void { throw makeError(); }
|
||||||
moveFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void { throw makeError(); }
|
moveFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void { throw makeError(); }
|
||||||
ensureDir(path: AbsoluteFsPath): void { throw makeError(); }
|
ensureDir(path: AbsoluteFsPath): void { throw makeError(); }
|
||||||
|
removeDeep(path: AbsoluteFsPath): void { throw makeError(); }
|
||||||
isCaseSensitive(): boolean { throw makeError(); }
|
isCaseSensitive(): boolean { throw makeError(); }
|
||||||
resolve(...paths: string[]): AbsoluteFsPath { throw makeError(); }
|
resolve(...paths: string[]): AbsoluteFsPath { throw makeError(); }
|
||||||
dirname<T extends PathString>(file: T): T { throw makeError(); }
|
dirname<T extends PathString>(file: T): T { throw makeError(); }
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
/// <reference types="node" />
|
/// <reference types="node" />
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
import * as fsExtra from 'fs-extra';
|
||||||
import * as p from 'path';
|
import * as p from 'path';
|
||||||
import {absoluteFrom, relativeFrom} from './helpers';
|
import {absoluteFrom, relativeFrom} from './helpers';
|
||||||
import {AbsoluteFsPath, FileStats, FileSystem, PathSegment, PathString} from './types';
|
import {AbsoluteFsPath, FileStats, FileSystem, PathSegment, PathString} from './types';
|
||||||
@ -40,6 +41,7 @@ export class NodeJSFileSystem implements FileSystem {
|
|||||||
this.safeMkdir(parents.pop() !);
|
this.safeMkdir(parents.pop() !);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
removeDeep(path: AbsoluteFsPath): void { fsExtra.removeSync(path); }
|
||||||
isCaseSensitive(): boolean {
|
isCaseSensitive(): boolean {
|
||||||
if (this._caseSensitive === undefined) {
|
if (this._caseSensitive === undefined) {
|
||||||
this._caseSensitive = this.exists(togglePathCase(__filename));
|
this._caseSensitive = this.exists(togglePathCase(__filename));
|
||||||
|
@ -49,6 +49,7 @@ export interface FileSystem {
|
|||||||
copyFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void;
|
copyFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void;
|
||||||
moveFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void;
|
moveFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void;
|
||||||
ensureDir(path: AbsoluteFsPath): void;
|
ensureDir(path: AbsoluteFsPath): void;
|
||||||
|
removeDeep(path: AbsoluteFsPath): void;
|
||||||
isCaseSensitive(): boolean;
|
isCaseSensitive(): boolean;
|
||||||
isRoot(path: AbsoluteFsPath): boolean;
|
isRoot(path: AbsoluteFsPath): boolean;
|
||||||
isRooted(path: string): boolean;
|
isRooted(path: string): boolean;
|
||||||
|
@ -12,6 +12,7 @@ ts_library(
|
|||||||
"//packages:types",
|
"//packages:types",
|
||||||
"//packages/compiler-cli/src/ngtsc/file_system",
|
"//packages/compiler-cli/src/ngtsc/file_system",
|
||||||
"//packages/compiler-cli/src/ngtsc/file_system/testing",
|
"//packages/compiler-cli/src/ngtsc/file_system/testing",
|
||||||
|
"@npm//@types/fs-extra",
|
||||||
"@npm//typescript",
|
"@npm//typescript",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -272,4 +272,23 @@ describe('CachedFileSystem', () => {
|
|||||||
expect(existsSpy).not.toHaveBeenCalled();
|
expect(existsSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('removeDeep()', () => {
|
||||||
|
it('should call delegate', () => {
|
||||||
|
const spy = spyOn(delegate, 'removeDeep');
|
||||||
|
fs.removeDeep(abcPath);
|
||||||
|
expect(spy).toHaveBeenCalledWith(abcPath);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update the exists cache', () => {
|
||||||
|
spyOn(delegate, 'removeDeep');
|
||||||
|
const existsSpy = spyOn(delegate, 'exists').and.returnValue(true);
|
||||||
|
expect(fs.exists(abcPath)).toBe(true);
|
||||||
|
existsSpy.calls.reset();
|
||||||
|
|
||||||
|
fs.removeDeep(abcPath);
|
||||||
|
expect(fs.exists(abcPath)).toBeFalsy();
|
||||||
|
expect(existsSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
import * as realFs from 'fs';
|
import * as realFs from 'fs';
|
||||||
|
import * as fsExtra from 'fs-extra';
|
||||||
import {absoluteFrom, dirname, relativeFrom, setFileSystem} from '../src/helpers';
|
import {absoluteFrom, dirname, relativeFrom, setFileSystem} from '../src/helpers';
|
||||||
import {NodeJSFileSystem} from '../src/node_js_file_system';
|
import {NodeJSFileSystem} from '../src/node_js_file_system';
|
||||||
import {AbsoluteFsPath} from '../src/types';
|
import {AbsoluteFsPath} from '../src/types';
|
||||||
@ -148,6 +149,14 @@ describe('NodeJSFileSystem', () => {
|
|||||||
expect(mkdirCalls).toEqual([xPath, xyPath, xyzPath]);
|
expect(mkdirCalls).toEqual([xPath, xyPath, xyzPath]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('removeDeep()', () => {
|
||||||
|
it('should delegate to fsExtra.remove()', () => {
|
||||||
|
const spy = spyOn(fsExtra, 'removeSync');
|
||||||
|
fs.removeDeep(abcPath);
|
||||||
|
expect(spy).toHaveBeenCalledWith(abcPath);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should not fail if a directory (that did not exist before) does exist when trying to create it',
|
it('should not fail if a directory (that did not exist before) does exist when trying to create it',
|
||||||
() => {
|
() => {
|
||||||
let abcPathExists = false;
|
let abcPathExists = false;
|
||||||
|
@ -131,6 +131,17 @@ export abstract class MockFileSystem implements FileSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeDeep(path: AbsoluteFsPath): void {
|
||||||
|
const [folderPath, basename] = this.splitIntoFolderAndFile(path);
|
||||||
|
const {entity} = this.findFromPath(folderPath);
|
||||||
|
if (entity === null || !isFolder(entity)) {
|
||||||
|
throw new MockFileSystemError(
|
||||||
|
'ENOENT', path,
|
||||||
|
`Unable to remove folder "${path}". The containing folder does not exist.`);
|
||||||
|
}
|
||||||
|
delete entity[basename];
|
||||||
|
}
|
||||||
|
|
||||||
isRoot(path: AbsoluteFsPath): boolean { return this.dirname(path) === path; }
|
isRoot(path: AbsoluteFsPath): boolean { return this.dirname(path) === path; }
|
||||||
|
|
||||||
extname(path: AbsoluteFsPath|PathSegment): string {
|
extname(path: AbsoluteFsPath|PathSegment): string {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user