
When @angular/bazel is installed, a postinstall script is run to make sure that the npm version is *exactly* the same as the Angular repository install by Bazel. This check is overly stringent. Instead, it should enforce that the version satisfies the range check instead. This is consistent with the range defined in angular-cli/packages/schematics/angular/utility/latest-versions.ts. This commit also fixes the Bazel workspace to use the same Rxjs version if it's already installed. PR Close #27591
99 lines
3.3 KiB
TypeScript
99 lines
3.3 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
|
|
*
|
|
* @fileoverview Schematics for bazel-workspace
|
|
*/
|
|
|
|
import {strings} from '@angular-devkit/core';
|
|
import {Rule, SchematicContext, SchematicsException, Tree, apply, applyTemplates, mergeWith, move, url} from '@angular-devkit/schematics';
|
|
import {getWorkspace} from '@schematics/angular/utility/config';
|
|
import {latestVersions} from '@schematics/angular/utility/latest-versions';
|
|
import {validateProjectName} from '@schematics/angular/utility/validation';
|
|
|
|
import {Schema as BazelWorkspaceOptions} from './schema';
|
|
|
|
|
|
/**
|
|
* Look for package.json file for package with `packageName` in node_modules and
|
|
* extract its version.
|
|
*/
|
|
function findVersion(projectName: string, packageName: string, host: Tree): string|null {
|
|
// Need to look in multiple locations because we could be working in a subtree.
|
|
const candidates = [
|
|
`node_modules/${packageName}/package.json`,
|
|
`${projectName}/node_modules/${packageName}/package.json`,
|
|
];
|
|
for (const candidate of candidates) {
|
|
if (host.exists(candidate)) {
|
|
try {
|
|
const packageJson = JSON.parse(host.read(candidate).toString());
|
|
if (packageJson.name === packageName && packageJson.version) {
|
|
return packageJson.version;
|
|
}
|
|
} catch {
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Clean the version string and return version in the form "1.2.3". Return
|
|
* null if version string is invalid. This is similar to semver.clean() but
|
|
* takes characters like '^' and '~' into account.
|
|
*/
|
|
export function clean(version: string): string|null {
|
|
const matches = version.match(/(\d+\.\d+\.\d+)/);
|
|
return matches && matches.pop() || null;
|
|
}
|
|
|
|
export default function(options: BazelWorkspaceOptions): Rule {
|
|
return (host: Tree, context: SchematicContext) => {
|
|
if (!options.name) {
|
|
throw new SchematicsException(`Invalid options, "name" is required.`);
|
|
}
|
|
validateProjectName(options.name);
|
|
let newProjectRoot = '';
|
|
try {
|
|
const workspace = getWorkspace(host);
|
|
newProjectRoot = workspace.newProjectRoot || '';
|
|
} catch {
|
|
}
|
|
const appDir = `${newProjectRoot}/${options.name}`;
|
|
|
|
// If the project already has some deps installed, Bazel should use existing
|
|
// versions.
|
|
const existingVersions: {[k: string]: string | null} = {
|
|
Angular: findVersion(options.name, '@angular/core', host),
|
|
RxJs: findVersion(options.name, 'rxjs', host),
|
|
};
|
|
|
|
Object.keys(existingVersions).forEach((name: 'Angular' | 'RxJs') => {
|
|
const version = existingVersions[name];
|
|
if (version) {
|
|
context.logger.info(`Bazel will reuse existing version for ${name}: ${version}`);
|
|
}
|
|
});
|
|
|
|
const workspaceVersions = {
|
|
'ANGULAR_VERSION': existingVersions.Angular || clean(latestVersions.Angular),
|
|
'RXJS_VERSION': existingVersions.RxJs || clean(latestVersions.RxJs),
|
|
// TODO(kyliau): Consider moving this to latest-versions.ts
|
|
'RULES_SASS_VERSION': '1.15.1',
|
|
};
|
|
|
|
return mergeWith(apply(url('./files'), [
|
|
applyTemplates({
|
|
utils: strings,
|
|
...options,
|
|
'dot': '.', ...workspaceVersions,
|
|
}),
|
|
move(appDir),
|
|
]));
|
|
};
|
|
}
|