From 74e47c503a0618dad026e88ae517f661a2e6a865 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Tue, 10 Mar 2020 10:49:16 +0000 Subject: [PATCH] refactor(ngcc): expose a hash of the project configuration (#35931) This will be used in the entry-point manifest since a change to configuration might change the entry-points that are found. PR Close #35931 --- .../ngcc/src/packages/configuration.ts | 7 +++ .../ngcc/test/packages/configuration_spec.ts | 54 +++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/packages/compiler-cli/ngcc/src/packages/configuration.ts b/packages/compiler-cli/ngcc/src/packages/configuration.ts index eef16381b2..133d1ad2a8 100644 --- a/packages/compiler-cli/ngcc/src/packages/configuration.ts +++ b/packages/compiler-cli/ngcc/src/packages/configuration.ts @@ -5,6 +5,7 @@ * 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 {createHash} from 'crypto'; import {satisfies} from 'semver'; import * as vm from 'vm'; import {AbsoluteFsPath, FileSystem, dirname, join, resolve} from '../../../src/ngtsc/file_system'; @@ -159,10 +160,12 @@ export class NgccConfiguration { private defaultConfig: NgccProjectConfig; private projectConfig: NgccProjectConfig; private cache = new Map(); + readonly hash: string; constructor(private fs: FileSystem, baseDir: AbsoluteFsPath) { this.defaultConfig = this.processProjectConfig(baseDir, DEFAULT_NGCC_CONFIG); this.projectConfig = this.processProjectConfig(baseDir, this.loadProjectConfig(baseDir)); + this.hash = this.computeHash(); } /** @@ -283,6 +286,10 @@ export class NgccConfiguration { ] : [packagePathAndVersion, undefined]; } + + private computeHash(): string { + return createHash('md5').update(JSON.stringify(this.projectConfig)).digest('hex'); + } } function findSatisfactoryVersion( diff --git a/packages/compiler-cli/ngcc/test/packages/configuration_spec.ts b/packages/compiler-cli/ngcc/test/packages/configuration_spec.ts index 875c1aa149..c74a2d2f87 100644 --- a/packages/compiler-cli/ngcc/test/packages/configuration_spec.ts +++ b/packages/compiler-cli/ngcc/test/packages/configuration_spec.ts @@ -5,6 +5,8 @@ * 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 {createHash} from 'crypto'; + import {FileSystem, absoluteFrom, getFileSystem} from '../../../src/ngtsc/file_system'; import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing'; import {loadTestFiles} from '../../../test/helpers'; @@ -30,6 +32,58 @@ runInEachFileSystem(() => { }); }); + describe('hash', () => { + it('should compute a hash from the loaded and processed project configuration', () => { + const project1 = _Abs('/project-1'); + const project1Config = fs.resolve(project1, 'ngcc.config.js'); + const project1NodeModules = fs.resolve(project1, 'node_modules'); + const project1Package1 = fs.resolve(project1NodeModules, 'package-1'); + const project1Package1EntryPoint1 = fs.resolve(project1Package1, 'entry-point-1'); + + loadTestFiles([{ + name: project1Config, + contents: ` + module.exports = { + packages: { + 'package-1': {entryPoints: {'./entry-point-1': {}}}, + }, + };` + }]); + const project1Conf = new NgccConfiguration(fs, project1); + const expectedProject1Config = + `{"packages":{"${project1Package1}":[{"entryPoints":{"${project1Package1EntryPoint1}":{}},"versionRange":"*"}]}}`; + expect(project1Conf.hash) + .toEqual(createHash('md5').update(expectedProject1Config).digest('hex')); + + const project2 = _Abs('/project-2'); + const project2Config = fs.resolve(project2, 'ngcc.config.js'); + const project2NodeModules = fs.resolve(project2, 'node_modules'); + const project2Package1 = fs.resolve(project2NodeModules, 'package-1'); + const project2Package1EntryPoint1 = fs.resolve(project2Package1, 'entry-point-1'); + + loadTestFiles([{ + name: project2Config, + contents: ` + module.exports = { + packages: { + 'package-1': {entryPoints: {'./entry-point-1': {ignore: true}}}, + }, + };` + }]); + const project2Conf = new NgccConfiguration(fs, project2); + const expectedProject2Config = + `{"packages":{"${project2Package1}":[{"entryPoints":{"${project2Package1EntryPoint1}":{"ignore":true}},"versionRange":"*"}]}}`; + expect(project2Conf.hash) + .toEqual(createHash('md5').update(expectedProject2Config).digest('hex')); + }); + + it('should compute a hash even if there is no project configuration', () => { + loadTestFiles([{name: _Abs('/project-1/empty.js'), contents: ``}]); + const configuration = new NgccConfiguration(fs, _Abs('/project-1')); + expect(configuration.hash).toEqual('87c535c3ce0eac2a54c246892e0e21a1'); + }); + }); + describe('getConfig()', () => { describe('at the package level', () => { it('should return configuration for a package found in a package level file, with a matching version',