Pete Bacon Darwin 7186f9c016 refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921)
To improve cross platform support, all file access (and path manipulation)
is now done through a well known interface (`FileSystem`).

For testing a number of `MockFileSystem` implementations are provided.
These provide an in-memory file-system which emulates operating systems
like OS/X, Unix and Windows.

The current file system is always available via the static method,
`FileSystem.getFileSystem()`. This is also used by a number of static
methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass
`FileSystem` objects around all the time. The result of this is that one
must be careful to ensure that the file-system has been initialized before
using any of these static methods. To prevent this happening accidentally
the current file system always starts out as an instance of `InvalidFileSystem`,
which will throw an error if any of its methods are called.

You can set the current file-system by calling `FileSystem.setFileSystem()`.
During testing you can call the helper function `initMockFileSystem(os)`
which takes a string name of the OS to emulate, and will also monkey-patch
aspects of the TypeScript library to ensure that TS is also using the
current file-system.

Finally there is the `NgtscCompilerHost` to be used for any TypeScript
compilation, which uses a given file-system.

All tests that interact with the file-system should be tested against each
of the mock file-systems. A series of helpers have been provided to support
such tests:

* `runInEachFileSystem()` - wrap your tests in this helper to run all the
wrapped tests in each of the mock file-systems.
* `addTestFilesToFileSystem()` - use this to add files and their contents
to the mock file system for testing.
* `loadTestFilesFromDisk()` - use this to load a mirror image of files on
disk into the in-memory mock file-system.
* `loadFakeCore()` - use this to load a fake version of `@angular/core`
into the mock file-system.

All ngcc and ngtsc source and tests now use this virtual file-system setup.

PR Close #30921
2019-06-25 16:25:24 -07:00

81 lines
2.9 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
/**
* @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
*/
import * as yargs from 'yargs';
import {resolve, setFileSystem, NodeJSFileSystem} from '../src/ngtsc/file_system';
import {mainNgcc} from './src/main';
import {ConsoleLogger, LogLevel} from './src/logging/console_logger';
// CLI entry point
if (require.main === module) {
const args = process.argv.slice(2);
const options =
yargs
.option('s', {
alias: 'source',
describe:
'A path (relative to the working directory) of the `node_modules` folder to process.',
default: './node_modules'
})
.option('f', {alias: 'formats', hidden: true, array: true})
.option('p', {
alias: 'properties',
array: true,
describe:
'An array of names of properties in package.json to compile (e.g. `module` or `es2015`)\n' +
'Each of these properties should hold the path to a bundle-format.\n' +
'If provided, only the specified properties are considered for processing.\n' +
'If not provided, all the supported format properties (e.g. fesm2015, fesm5, es2015, esm2015, esm5, main, module) in the package.json are considered.'
})
.option('t', {
alias: 'target',
describe:
'A relative path (from the `source` path) to a single entry-point to process (plus its dependencies).',
})
.option('first-only', {
describe:
'If specified then only the first matching package.json property will be compiled.',
type: 'boolean'
})
.option('l', {
alias: 'loglevel',
describe: 'The lowest severity logging message that should be output.',
choices: ['debug', 'info', 'warn', 'error'],
})
.help()
.parse(args);
if (options['f'] && options['f'].length) {
console.error(
'The formats option (-f/--formats) has been removed. Consider the properties option (-p/--properties) instead.');
process.exit(1);
}
setFileSystem(new NodeJSFileSystem());
const baseSourcePath = resolve(options['s'] || './node_modules');
const propertiesToConsider: string[] = options['p'];
const targetEntryPointPath = options['t'] ? options['t'] : undefined;
const compileAllFormats = !options['first-only'];
const logLevel = options['l'] as keyof typeof LogLevel | undefined;
try {
mainNgcc({
basePath: baseSourcePath,
propertiesToConsider,
targetEntryPointPath,
compileAllFormats,
logger: logLevel && new ConsoleLogger(LogLevel[logLevel]),
});
process.exitCode = 0;
} catch (e) {
console.error(e.stack || e.message);
process.exitCode = 1;
}
}