refactor(ngcc): do not crash if package build version is outdated (#35079)
Now `hasBeenProcessed()` will no longer throw if there is an entry-point that has been built with an outdated version of ngcc. Instead it just returns `false`, which will include it in this processing run. This is a precursor to adding functionality that will automatically revert outdate build artifacts. PR Close #35079
This commit is contained in:
parent
171a79d04f
commit
cc43bfa725
|
@ -198,7 +198,7 @@ export function mainNgcc(
|
||||||
|
|
||||||
for (const entryPoint of entryPoints) {
|
for (const entryPoint of entryPoints) {
|
||||||
const packageJson = entryPoint.packageJson;
|
const packageJson = entryPoint.packageJson;
|
||||||
const hasProcessedTypings = hasBeenProcessed(packageJson, 'typings', entryPoint.path);
|
const hasProcessedTypings = hasBeenProcessed(packageJson, 'typings');
|
||||||
const {propertiesToProcess, equivalentPropertiesMap} =
|
const {propertiesToProcess, equivalentPropertiesMap} =
|
||||||
getPropertiesToProcess(packageJson, supportedPropertiesToConsider, compileAllFormats);
|
getPropertiesToProcess(packageJson, supportedPropertiesToConsider, compileAllFormats);
|
||||||
let processDts = !hasProcessedTypings;
|
let processDts = !hasProcessedTypings;
|
||||||
|
@ -263,7 +263,7 @@ export function mainNgcc(
|
||||||
}
|
}
|
||||||
|
|
||||||
// The format-path which the property maps to is already processed - nothing to do.
|
// The format-path which the property maps to is already processed - nothing to do.
|
||||||
if (hasBeenProcessed(packageJson, formatProperty, entryPoint.path)) {
|
if (hasBeenProcessed(packageJson, formatProperty)) {
|
||||||
logger.debug(`Skipping ${entryPoint.name} : ${formatProperty} (already compiled).`);
|
logger.debug(`Skipping ${entryPoint.name} : ${formatProperty} (already compiled).`);
|
||||||
onTaskCompleted(task, TaskProcessingOutcome.AlreadyProcessed);
|
onTaskCompleted(task, TaskProcessingOutcome.AlreadyProcessed);
|
||||||
return;
|
return;
|
||||||
|
@ -411,7 +411,7 @@ function hasProcessedTargetEntryPoint(
|
||||||
for (const property of propertiesToConsider) {
|
for (const property of propertiesToConsider) {
|
||||||
if (packageJson[property]) {
|
if (packageJson[property]) {
|
||||||
// Here is a property that should be processed
|
// Here is a property that should be processed
|
||||||
if (hasBeenProcessed(packageJson, property as EntryPointJsonProperty, targetPath)) {
|
if (hasBeenProcessed(packageJson, property as EntryPointJsonProperty)) {
|
||||||
if (!compileAllFormats) {
|
if (!compileAllFormats) {
|
||||||
// It has been processed and we only need one, so we are done.
|
// It has been processed and we only need one, so we are done.
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
* 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
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
import {AbsoluteFsPath, basename, dirname, isRoot} from '../../../src/ngtsc/file_system';
|
import {AbsoluteFsPath} from '../../../src/ngtsc/file_system';
|
||||||
import {PackageJsonUpdater} from '../writing/package_json_updater';
|
import {PackageJsonUpdater} from '../writing/package_json_updater';
|
||||||
import {EntryPointPackageJson, PackageJsonFormatProperties} from './entry_point';
|
import {EntryPointPackageJson, PackageJsonFormatProperties} from './entry_point';
|
||||||
|
|
||||||
|
@ -14,33 +14,15 @@ export const NGCC_VERSION = '0.0.0-PLACEHOLDER';
|
||||||
/**
|
/**
|
||||||
* Check whether ngcc has already processed a given entry-point format.
|
* Check whether ngcc has already processed a given entry-point format.
|
||||||
*
|
*
|
||||||
* The entry-point is defined by the package.json contents provided.
|
|
||||||
* The format is defined by the provided property name of the path to the bundle in the package.json
|
|
||||||
*
|
|
||||||
* @param packageJson The parsed contents of the package.json file for the entry-point.
|
* @param packageJson The parsed contents of the package.json file for the entry-point.
|
||||||
* @param format The entry-point format property in the package.json to check.
|
* @param format The entry-point format property in the package.json to check.
|
||||||
* @returns true if the entry-point and format have already been processed with this ngcc version.
|
* @returns true if the `format` in the entry-point has already been processed by this ngcc version,
|
||||||
* @throws Error if the `packageJson` property is not an object.
|
* false otherwise.
|
||||||
* @throws Error if the entry-point has already been processed with a different ngcc version.
|
|
||||||
*/
|
*/
|
||||||
export function hasBeenProcessed(
|
export function hasBeenProcessed(
|
||||||
packageJson: EntryPointPackageJson, format: PackageJsonFormatProperties,
|
packageJson: EntryPointPackageJson, format: PackageJsonFormatProperties): boolean {
|
||||||
entryPointPath: AbsoluteFsPath): boolean {
|
return packageJson.__processed_by_ivy_ngcc__ !== undefined &&
|
||||||
if (!packageJson.__processed_by_ivy_ngcc__) {
|
packageJson.__processed_by_ivy_ngcc__[format] === NGCC_VERSION;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (Object.keys(packageJson.__processed_by_ivy_ngcc__)
|
|
||||||
.some(property => packageJson.__processed_by_ivy_ngcc__ ![property] !== NGCC_VERSION)) {
|
|
||||||
let nodeModulesFolderPath = entryPointPath;
|
|
||||||
while (!isRoot(nodeModulesFolderPath) && basename(nodeModulesFolderPath) !== 'node_modules') {
|
|
||||||
nodeModulesFolderPath = dirname(nodeModulesFolderPath);
|
|
||||||
}
|
|
||||||
throw new Error(
|
|
||||||
`The ngcc compiler has changed since the last ngcc build.\n` +
|
|
||||||
`Please remove "${isRoot(nodeModulesFolderPath) ? entryPointPath : nodeModulesFolderPath}" and try again.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return packageJson.__processed_by_ivy_ngcc__[format] === NGCC_VERSION;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
* 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
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
import {AbsoluteFsPath, absoluteFrom, getFileSystem} from '../../../src/ngtsc/file_system';
|
import {absoluteFrom, getFileSystem} from '../../../src/ngtsc/file_system';
|
||||||
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
|
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
|
||||||
import {loadTestFiles} from '../../../test/helpers';
|
import {loadTestFiles} from '../../../test/helpers';
|
||||||
import {hasBeenProcessed, markAsProcessed} from '../../src/packages/build_marker';
|
import {hasBeenProcessed, markAsProcessed} from '../../src/packages/build_marker';
|
||||||
|
@ -177,97 +177,22 @@ runInEachFileSystem(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('hasBeenProcessed', () => {
|
describe('hasBeenProcessed', () => {
|
||||||
let entryPointPath: AbsoluteFsPath;
|
|
||||||
let nodeModulesPath: AbsoluteFsPath;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
entryPointPath = _('/node_modules/test');
|
|
||||||
nodeModulesPath = _('/node_modules');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true if the marker exists for the given format property', () => {
|
it('should return true if the marker exists for the given format property', () => {
|
||||||
expect(hasBeenProcessed(
|
expect(hasBeenProcessed(
|
||||||
{name: 'test', __processed_by_ivy_ngcc__: {'fesm2015': '0.0.0-PLACEHOLDER'}},
|
{name: 'test', __processed_by_ivy_ngcc__: {'fesm2015': '0.0.0-PLACEHOLDER'}},
|
||||||
'fesm2015', entryPointPath))
|
'fesm2015'))
|
||||||
.toBe(true);
|
.toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false if the marker does not exist for the given format property', () => {
|
it('should return false if the marker does not exist for the given format property', () => {
|
||||||
expect(hasBeenProcessed(
|
expect(hasBeenProcessed(
|
||||||
{name: 'test', __processed_by_ivy_ngcc__: {'fesm2015': '0.0.0-PLACEHOLDER'}},
|
{name: 'test', __processed_by_ivy_ngcc__: {'fesm2015': '0.0.0-PLACEHOLDER'}},
|
||||||
'module', entryPointPath))
|
'module'))
|
||||||
.toBe(false);
|
.toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false if no markers exist',
|
it('should return false if no markers exist',
|
||||||
() => { expect(hasBeenProcessed({name: 'test'}, 'module', entryPointPath)).toBe(false); });
|
() => { expect(hasBeenProcessed({name: 'test'}, 'module')).toBe(false); });
|
||||||
|
|
||||||
it('should throw an Error if the format has been compiled with a different version.', () => {
|
|
||||||
expect(
|
|
||||||
() => hasBeenProcessed(
|
|
||||||
{name: 'test', __processed_by_ivy_ngcc__: {'fesm2015': '8.0.0'}}, 'fesm2015',
|
|
||||||
entryPointPath))
|
|
||||||
.toThrowError(
|
|
||||||
'The ngcc compiler has changed since the last ngcc build.\n' +
|
|
||||||
`Please remove "${nodeModulesPath}" and try again.`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw an Error if any format has been compiled with a different version.', () => {
|
|
||||||
expect(
|
|
||||||
() => hasBeenProcessed(
|
|
||||||
{name: 'test', __processed_by_ivy_ngcc__: {'fesm2015': '8.0.0'}}, 'module',
|
|
||||||
entryPointPath))
|
|
||||||
.toThrowError(
|
|
||||||
'The ngcc compiler has changed since the last ngcc build.\n' +
|
|
||||||
`Please remove "${nodeModulesPath}" and try again.`);
|
|
||||||
expect(
|
|
||||||
() => hasBeenProcessed(
|
|
||||||
{
|
|
||||||
name: 'test',
|
|
||||||
__processed_by_ivy_ngcc__: {'module': '0.0.0-PLACEHOLDER', 'fesm2015': '8.0.0'}
|
|
||||||
},
|
|
||||||
'module', entryPointPath))
|
|
||||||
.toThrowError(
|
|
||||||
'The ngcc compiler has changed since the last ngcc build.\n' +
|
|
||||||
`Please remove "${nodeModulesPath}" and try again.`);
|
|
||||||
expect(
|
|
||||||
() => hasBeenProcessed(
|
|
||||||
{
|
|
||||||
name: 'test',
|
|
||||||
__processed_by_ivy_ngcc__: {'module': '0.0.0-PLACEHOLDER', 'fesm2015': '8.0.0'}
|
|
||||||
},
|
|
||||||
'fesm2015', entryPointPath))
|
|
||||||
.toThrowError(
|
|
||||||
'The ngcc compiler has changed since the last ngcc build.\n' +
|
|
||||||
`Please remove "${nodeModulesPath}" and try again.`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw an Error, with the appropriate path to remove, if the format has been compiled with a different version',
|
|
||||||
() => {
|
|
||||||
expect(
|
|
||||||
() => hasBeenProcessed(
|
|
||||||
{name: 'test', __processed_by_ivy_ngcc__: {'fesm2015': '8.0.0'}}, 'fesm2015',
|
|
||||||
_('/node_modules/test')))
|
|
||||||
.toThrowError(
|
|
||||||
'The ngcc compiler has changed since the last ngcc build.\n' +
|
|
||||||
`Please remove "${_('/node_modules')}" and try again.`);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
() => hasBeenProcessed(
|
|
||||||
{name: 'nested', __processed_by_ivy_ngcc__: {'fesm2015': '8.0.0'}}, 'fesm2015',
|
|
||||||
_('/node_modules/test/node_modules/nested')))
|
|
||||||
.toThrowError(
|
|
||||||
'The ngcc compiler has changed since the last ngcc build.\n' +
|
|
||||||
`Please remove "${_('/node_modules/test/node_modules')}" and try again.`);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
() => hasBeenProcessed(
|
|
||||||
{name: 'test', __processed_by_ivy_ngcc__: {'fesm2015': '8.0.0'}}, 'fesm2015',
|
|
||||||
_('/dist/test')))
|
|
||||||
.toThrowError(
|
|
||||||
'The ngcc compiler has changed since the last ngcc build.\n' +
|
|
||||||
`Please remove "${_('/dist/test')}" and try again.`);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue