Joey Perrott d1ea1f4c7f build: update license headers to reference Google LLC ()
Update the license headers throughout the repository to reference Google LLC
rather than Google Inc, for the required license headers.

PR Close 
2020-05-26 14:26:58 -04:00

164 lines
7.5 KiB
JavaScript

/**
* @license
* Copyright Google LLC 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
*/
const child_process = require('child_process');
const fs = require('fs');
const path = require('path');
const shx = require('shelljs');
/** Manifest path that refers to the Bazel package that contains all test sources. */
const baseManifestPath = 'angular/packages/compiler-cli/integrationtest';
/**
* Temporary directory which will be used to build and run the integration tests. Note that
* this environment variable is automatically set by Bazel for such test actions.
*/
const tmpDir = process.env.TEST_TMPDIR;
/** Fine grained node modules which are required in order to run the integration test. */
const requiredNodeModules = {
'@angular/animations': resolveNpmTreeArtifact('angular/packages/animations/npm_package'),
'@angular/common': resolveNpmTreeArtifact('angular/packages/common/npm_package'),
'@angular/compiler': resolveNpmTreeArtifact('angular/packages/compiler/npm_package'),
'@angular/compiler-cli': resolveNpmTreeArtifact('angular/packages/compiler-cli/npm_package'),
'@angular/core': resolveNpmTreeArtifact('angular/packages/core/npm_package'),
'@angular/forms': resolveNpmTreeArtifact('angular/packages/forms/npm_package'),
'@angular/platform-browser':
resolveNpmTreeArtifact('angular/packages/platform-browser/npm_package'),
'@angular/platform-browser-dynamic':
resolveNpmTreeArtifact('angular/packages/platform-browser-dynamic/npm_package'),
'@angular/platform-server':
resolveNpmTreeArtifact('angular/packages/platform-server/npm_package'),
'@angular/router': resolveNpmTreeArtifact('angular/packages/router/npm_package'),
// Note, @bazel/typescript does not appear here because it's not listed as a dependency of
// @angular/compiler-cli
'@types/jasmine': resolveNpmTreeArtifact('npm/node_modules/@types/jasmine'),
'@types/node': resolveNpmTreeArtifact('npm/node_modules/@types/node'),
// Transitive dependencies which need to be specified because the Angular NPM packages
// depend on these without the Angular NPM packages being part of the Bazel managed deps.
// This means that transitive dependencies need to be manually declared as required.
'tslib': resolveNpmTreeArtifact('npm/node_modules/tslib'),
'domino': resolveNpmTreeArtifact('npm/node_modules/domino'),
'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
// need to be symlinked so that they can be resolved by NodeJS or NGC.
'buffer-from': resolveNpmTreeArtifact('npm/node_modules/buffer-from'),
'reflect-metadata': resolveNpmTreeArtifact('npm/node_modules/reflect-metadata'),
'rxjs': resolveNpmTreeArtifact('npm/node_modules/rxjs'),
'source-map': resolveNpmTreeArtifact('npm/node_modules/source-map'),
'source-map-support': resolveNpmTreeArtifact('npm/node_modules/source-map-support'),
'typescript': resolveNpmTreeArtifact('npm/node_modules/typescript'),
'zone.js': resolveNpmTreeArtifact('angular/packages/zone.js/npm_package'),
};
/** Sets up the temporary test directory and returns the path to the directory. */
exports.setupTestDirectory = function() {
copySourceFilesToTempDir();
symlinkNodeModules();
return tmpDir;
};
/**
* Runs a given binary with the specified command line arguments. The working directory for
* the spawned process will be the temporary directory.
*/
exports.runCommand = function runCommand(binary, args = []) {
const ngcProcess = child_process.spawnSync(binary, args, {
stdio: 'inherit',
cwd: tmpDir,
env: {
...process.env,
// We need to set the "NODE_PATH" here because the built Angular NPM packages are symlinks
// which NodeJS resolves into the output location. This is problematic because the output
// location does not have the required dependencies of these NPM packages installed. This
// could be fixed by setting the NodeJS "--preserve-symlinks" option, but this would mean
// that transitive dependencies of fine-grained dependencies cannot be resolved either.
NODE_PATH: path.join(tmpDir, 'node_modules/')
}
});
if (ngcProcess.status !== 0) {
console.error(`Command ${binary} failed with arguments: "${args.join(' ')}". See error above.`);
process.exit(1);
}
};
/**
* Symlinks the specified node modules within the temporary directory. This is necessary because
* this test is an integration test and we don't want to rely on any path-mapped module resolution.
* Additionally, NGC expects types and imported packages to be within the project's root dir.
*/
function symlinkNodeModules() {
Object.keys(requiredNodeModules).forEach(importName => {
const outputPath = path.join(tmpDir, 'node_modules', importName);
const moduleDir = requiredNodeModules[importName];
shx.mkdir('-p', path.dirname(outputPath));
fs.symlinkSync(moduleDir, outputPath, 'junction');
});
}
/**
* Copies all source files for the integration test to a temporary directory. This
* is necessary because runfiles resolve on Windows to the original source location,
* and we don't want to pollute the workspace sources. This breaks hermeticity.
*/
function copySourceFilesToTempDir() {
getSourceFilesFromRunfiles().forEach(({realPath, relativeFilePath}) => {
const tmpFilePath = path.join(tmpDir, relativeFilePath);
shx.mkdir('-p', path.dirname(tmpFilePath));
shx.cp(realPath, tmpFilePath);
});
}
/**
* Gets all source files for the integration test by querying the Bazel runfiles.
* In case there is a runfiles manifest (e.g. on Windows), the source files are resolved
* through the manifest because on these platforms the runfiles are not symlinked and
* cannot be searched within the real filesystem.
*/
function getSourceFilesFromRunfiles() {
// Path to the Bazel runfiles manifest if present. This file is present if runfiles are
// not symlinked into the runfiles directory.
const runfilesManifestPath = process.env.RUNFILES_MANIFEST_FILE;
if (!runfilesManifestPath) {
const packageRunfilesDir = path.join(process.env.RUNFILES, baseManifestPath);
return findFilesWithinDirectory(packageRunfilesDir).map(filePath => ({
realPath: filePath,
relativeFilePath: path.relative(
packageRunfilesDir, filePath)
}));
}
return fs.readFileSync(runfilesManifestPath, 'utf8')
.split('\n')
.map(mapping => mapping.split(' '))
.filter(([runfilePath]) => runfilePath.startsWith(baseManifestPath))
.map(
([runfilePath, realPath]) =>
({realPath, relativeFilePath: path.relative(baseManifestPath, runfilePath)}));
}
/**
* Resolves a NPM package from the Bazel runfiles. We need to resolve the Bazel tree
* artifacts using a "resolve file" because the NodeJS module resolution does not allow
* resolving to directory paths.
*/
function resolveNpmTreeArtifact(manifestPath, resolveFile = 'package.json') {
return path.dirname(require.resolve(path.posix.join(manifestPath, resolveFile)));
}
/** Finds all files within a specified directory. */
function findFilesWithinDirectory(directoryPath) {
return shx.find(directoryPath).filter(filePath => !fs.lstatSync(filePath).isDirectory());
}