Paul Gschwendtner 44acf6734b build: allow custom module resolution for ts-circular-deps tests (#36226)
Currently the `ts-circular-deps` tool uses a hard-coded module resolver
that only works in the `angular/angular` repository.

If the tool is consumed in other repositories through the shared
dev-infra package, the module resolution won't work, and a few
resolvable imports (usually cross-entry-points) are accidentally
skipped. For each test, the resolution might differ, so tests can
now configure their module resolution in a configuration file.

Note that we intentionally don't rely on tsconfig's for module
resolution as parsing their mappings rather complicates the
circular dependency tool. Additionally, not every test has a
corresponding tsconfig file.

Also, hard-coding mappings to `@angular/*` while accepting a
path to the packages folder would work, but it would mean
that the circular deps tool is no longer self-contained. Rather,
and also for better flexibility, a custom resolver should be
specified.

PR Close #36226
2020-03-27 11:14:49 -07:00

60 lines
2.0 KiB
TypeScript

/**
* @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 {dirname, isAbsolute, resolve} from 'path';
import {ModuleResolver} from './analyzer';
/** Configuration for a circular dependencies test. */
export interface CircularDependenciesTestConfig {
/** Base directory used for shortening paths in the golden file. */
baseDir: string;
/** Path to the golden file that is used for checking and approving. */
goldenFile: string;
/** Glob that resolves source files which should be checked. */
glob: string
/**
* Optional module resolver function that can be used to resolve modules
* to absolute file paths.
*/
resolveModule?: ModuleResolver;
/**
* Optional command that will be displayed if the golden check failed. This can be used
* to consistently use script aliases for checking/approving the golden.
*/
approveCommand?: string;
}
/**
* Loads the configuration for the circular dependencies test. If the config cannot be
* loaded, an error will be printed and the process exists with a non-zero exit code.
*/
export function loadTestConfig(configPath: string): CircularDependenciesTestConfig {
const configBaseDir = dirname(configPath);
const resolveRelativePath = (relativePath: string) => resolve(configBaseDir, relativePath);
try {
const config = require(configPath) as CircularDependenciesTestConfig;
if (!isAbsolute(config.baseDir)) {
config.baseDir = resolveRelativePath(config.baseDir);
}
if (!isAbsolute(config.goldenFile)) {
config.goldenFile = resolveRelativePath(config.goldenFile);
}
if (!isAbsolute(config.glob)) {
config.glob = resolveRelativePath(config.glob);
}
return config;
} catch (e) {
console.error('Could not load test configuration file at: ' + configPath);
console.error(`Failed with: ${e.message}`);
process.exit(1);
}
}