refactor(compiler-cli): support Buffer files in `FileSystem` (#36843)
Adding `readFileBuffer()` method and allowing `writeFile()` to accept a Buffer object will be useful when reading and writing non-text files, such as is done in the `@angular/localize` package. PR Close #36843
This commit is contained in:
parent
352b9c78e0
commit
5d12c19ce9
|
@ -22,7 +22,10 @@ export class InvalidFileSystem implements FileSystem {
|
||||||
readFile(path: AbsoluteFsPath): string {
|
readFile(path: AbsoluteFsPath): string {
|
||||||
throw makeError();
|
throw makeError();
|
||||||
}
|
}
|
||||||
writeFile(path: AbsoluteFsPath, data: string, exclusive?: boolean): void {
|
readFileBuffer(path: AbsoluteFsPath): Buffer {
|
||||||
|
throw makeError();
|
||||||
|
}
|
||||||
|
writeFile(path: AbsoluteFsPath, data: string|Buffer, exclusive?: boolean): void {
|
||||||
throw makeError();
|
throw makeError();
|
||||||
}
|
}
|
||||||
removeFile(path: AbsoluteFsPath): void {
|
removeFile(path: AbsoluteFsPath): void {
|
||||||
|
|
|
@ -23,7 +23,10 @@ export class NodeJSFileSystem implements FileSystem {
|
||||||
readFile(path: AbsoluteFsPath): string {
|
readFile(path: AbsoluteFsPath): string {
|
||||||
return fs.readFileSync(path, 'utf8');
|
return fs.readFileSync(path, 'utf8');
|
||||||
}
|
}
|
||||||
writeFile(path: AbsoluteFsPath, data: string, exclusive: boolean = false): void {
|
readFileBuffer(path: AbsoluteFsPath): Buffer {
|
||||||
|
return fs.readFileSync(path);
|
||||||
|
}
|
||||||
|
writeFile(path: AbsoluteFsPath, data: string|Buffer, exclusive: boolean = false): void {
|
||||||
fs.writeFileSync(path, data, exclusive ? {flag: 'wx'} : undefined);
|
fs.writeFileSync(path, data, exclusive ? {flag: 'wx'} : undefined);
|
||||||
}
|
}
|
||||||
removeFile(path: AbsoluteFsPath): void {
|
removeFile(path: AbsoluteFsPath): void {
|
||||||
|
|
|
@ -37,7 +37,8 @@ export type PathSegment = BrandedPath<'PathSegment'>;
|
||||||
export interface FileSystem {
|
export interface FileSystem {
|
||||||
exists(path: AbsoluteFsPath): boolean;
|
exists(path: AbsoluteFsPath): boolean;
|
||||||
readFile(path: AbsoluteFsPath): string;
|
readFile(path: AbsoluteFsPath): string;
|
||||||
writeFile(path: AbsoluteFsPath, data: string, exclusive?: boolean): void;
|
readFileBuffer(path: AbsoluteFsPath): Buffer;
|
||||||
|
writeFile(path: AbsoluteFsPath, data: string|Buffer, exclusive?: boolean): void;
|
||||||
removeFile(path: AbsoluteFsPath): void;
|
removeFile(path: AbsoluteFsPath): void;
|
||||||
symlink(target: AbsoluteFsPath, path: AbsoluteFsPath): void;
|
symlink(target: AbsoluteFsPath, path: AbsoluteFsPath): void;
|
||||||
readdir(path: AbsoluteFsPath): PathSegment[];
|
readdir(path: AbsoluteFsPath): PathSegment[];
|
||||||
|
|
|
@ -44,6 +44,16 @@ describe('NodeJSFileSystem', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('readFileBuffer()', () => {
|
||||||
|
it('should delegate to fs.readFileSync()', () => {
|
||||||
|
const buffer = new Buffer('Some contents');
|
||||||
|
const spy = spyOn(realFs, 'readFileSync').and.returnValue(buffer);
|
||||||
|
const result = fs.readFileBuffer(abcPath);
|
||||||
|
expect(result).toBe(buffer);
|
||||||
|
expect(spy).toHaveBeenCalledWith(abcPath);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('writeFile()', () => {
|
describe('writeFile()', () => {
|
||||||
it('should delegate to fs.writeFileSync()', () => {
|
it('should delegate to fs.writeFileSync()', () => {
|
||||||
const spy = spyOn(realFs, 'writeFileSync');
|
const spy = spyOn(realFs, 'writeFileSync');
|
||||||
|
|
|
@ -32,13 +32,22 @@ export abstract class MockFileSystem implements FileSystem {
|
||||||
readFile(path: AbsoluteFsPath): string {
|
readFile(path: AbsoluteFsPath): string {
|
||||||
const {entity} = this.findFromPath(path);
|
const {entity} = this.findFromPath(path);
|
||||||
if (isFile(entity)) {
|
if (isFile(entity)) {
|
||||||
return entity;
|
return entity.toString();
|
||||||
} else {
|
} else {
|
||||||
throw new MockFileSystemError('ENOENT', path, `File "${path}" does not exist.`);
|
throw new MockFileSystemError('ENOENT', path, `File "${path}" does not exist.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFile(path: AbsoluteFsPath, data: string, exclusive: boolean = false): void {
|
readFileBuffer(path: AbsoluteFsPath): Buffer {
|
||||||
|
const {entity} = this.findFromPath(path);
|
||||||
|
if (isFile(entity)) {
|
||||||
|
return Buffer.isBuffer(entity) ? entity : new Buffer(entity);
|
||||||
|
} else {
|
||||||
|
throw new MockFileSystemError('ENOENT', path, `File "${path}" does not exist.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeFile(path: AbsoluteFsPath, data: string|Buffer, exclusive: boolean = false): void {
|
||||||
const [folderPath, basename] = this.splitIntoFolderAndFile(path);
|
const [folderPath, basename] = this.splitIntoFolderAndFile(path);
|
||||||
const {entity} = this.findFromPath(folderPath);
|
const {entity} = this.findFromPath(folderPath);
|
||||||
if (entity === null || !isFolder(entity)) {
|
if (entity === null || !isFolder(entity)) {
|
||||||
|
@ -286,7 +295,7 @@ export type Entity = Folder|File|SymLink;
|
||||||
export interface Folder {
|
export interface Folder {
|
||||||
[pathSegments: string]: Entity;
|
[pathSegments: string]: Entity;
|
||||||
}
|
}
|
||||||
export type File = string;
|
export type File = string|Buffer;
|
||||||
export class SymLink {
|
export class SymLink {
|
||||||
constructor(public path: AbsoluteFsPath) {}
|
constructor(public path: AbsoluteFsPath) {}
|
||||||
}
|
}
|
||||||
|
@ -311,7 +320,7 @@ class MockFileSystemError extends Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isFile(item: Entity|null): item is File {
|
export function isFile(item: Entity|null): item is File {
|
||||||
return typeof item === 'string';
|
return Buffer.isBuffer(item) || typeof item === 'string';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isSymLink(item: Entity|null): item is SymLink {
|
export function isSymLink(item: Entity|null): item is SymLink {
|
||||||
|
|
Loading…
Reference in New Issue