@ -38,7 +38,7 @@ export function runMain(
|
||||
// API extractor doesn't always support the version of TypeScript used in the repo
|
||||
// example: at the moment it is not compatable with 3.2
|
||||
// to use the internal TypeScript we shall not create a program but rather pass a parsed tsConfig.
|
||||
const parsedTsConfig = parsedConfig !.config as any;
|
||||
const parsedTsConfig = parsedConfig!.config as any;
|
||||
const compilerOptions = parsedTsConfig.compilerOptions;
|
||||
for (const [key, values] of Object.entries<string[]>(compilerOptions.paths)) {
|
||||
if (key === '*') {
|
||||
@ -113,8 +113,8 @@ api-extractor: running with
|
||||
const dtsBundleOuts = dtsBundleOut.split(',');
|
||||
|
||||
if (entryPoints.length !== entryPoints.length) {
|
||||
throw new Error(
|
||||
`Entry points count (${entryPoints.length}) does not match Bundle out count (${dtsBundleOuts.length})`);
|
||||
throw new Error(`Entry points count (${entryPoints.length}) does not match Bundle out count (${
|
||||
dtsBundleOuts.length})`);
|
||||
}
|
||||
|
||||
for (let i = 0; i < entryPoints.length; i++) {
|
||||
|
@ -9,12 +9,12 @@
|
||||
/// <reference types='node'/>
|
||||
|
||||
import {spawn} from 'child_process';
|
||||
import {copyFileSync, existsSync, readFileSync, readdirSync, statSync, unlinkSync, writeFileSync} from 'fs';
|
||||
import {copyFileSync, existsSync, readdirSync, readFileSync, statSync, unlinkSync, writeFileSync} from 'fs';
|
||||
import {platform} from 'os';
|
||||
import {dirname, join, normalize} from 'path';
|
||||
|
||||
export type Executable = 'bazel' | 'ibazel';
|
||||
export type Command = 'build' | 'test' | 'run' | 'coverage' | 'query';
|
||||
export type Executable = 'bazel'|'ibazel';
|
||||
export type Command = 'build'|'test'|'run'|'coverage'|'query';
|
||||
|
||||
/**
|
||||
* Spawn the Bazel process. Trap SINGINT to make sure Bazel process is killed.
|
||||
|
@ -13,27 +13,29 @@ import {JsonObject} from '@angular-devkit/core';
|
||||
import {checkInstallation, copyBazelFiles, deleteBazelFiles, getTemplateDir, runBazel} from './bazel';
|
||||
import {Schema} from './schema';
|
||||
|
||||
async function _bazelBuilder(options: JsonObject & Schema, context: BuilderContext, ):
|
||||
Promise<BuilderOutput> {
|
||||
const {logger, workspaceRoot} = context;
|
||||
const {bazelCommand, leaveBazelFilesOnDisk, targetLabel, watch} = options;
|
||||
const executable = watch ? 'ibazel' : 'bazel';
|
||||
const binary = checkInstallation(executable, workspaceRoot);
|
||||
const templateDir = getTemplateDir(workspaceRoot);
|
||||
const bazelFiles = copyBazelFiles(workspaceRoot, templateDir);
|
||||
async function _bazelBuilder(
|
||||
options: JsonObject&Schema,
|
||||
context: BuilderContext,
|
||||
): Promise<BuilderOutput> {
|
||||
const {logger, workspaceRoot} = context;
|
||||
const {bazelCommand, leaveBazelFilesOnDisk, targetLabel, watch} = options;
|
||||
const executable = watch ? 'ibazel' : 'bazel';
|
||||
const binary = checkInstallation(executable, workspaceRoot);
|
||||
const templateDir = getTemplateDir(workspaceRoot);
|
||||
const bazelFiles = copyBazelFiles(workspaceRoot, templateDir);
|
||||
|
||||
try {
|
||||
const flags: string[] = [];
|
||||
await runBazel(workspaceRoot, binary, bazelCommand, targetLabel, flags);
|
||||
return {success: true};
|
||||
} catch (err) {
|
||||
logger.error(err.message);
|
||||
return {success: false};
|
||||
} finally {
|
||||
if (!leaveBazelFilesOnDisk) {
|
||||
deleteBazelFiles(bazelFiles); // this will never throw
|
||||
}
|
||||
}
|
||||
try {
|
||||
const flags: string[] = [];
|
||||
await runBazel(workspaceRoot, binary, bazelCommand, targetLabel, flags);
|
||||
return {success: true};
|
||||
} catch (err) {
|
||||
logger.error(err.message);
|
||||
return {success: false};
|
||||
} finally {
|
||||
if (!leaveBazelFilesOnDisk) {
|
||||
deleteBazelFiles(bazelFiles); // this will never throw
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default createBuilder(_bazelBuilder);
|
||||
|
@ -22,7 +22,9 @@ function main(args: string[]): number {
|
||||
const paramFilePath = args[0];
|
||||
|
||||
// Bazel params may be surrounded with quotes
|
||||
function unquoteParameter(s: string) { return s.replace(/^'(.*)'$/, '$1'); }
|
||||
function unquoteParameter(s: string) {
|
||||
return s.replace(/^'(.*)'$/, '$1');
|
||||
}
|
||||
|
||||
// Parameters are specified in the file one per line.
|
||||
const params = fs.readFileSync(paramFilePath, 'utf-8').split('\n').map(unquoteParameter);
|
||||
@ -109,7 +111,7 @@ function main(args: string[]): number {
|
||||
* @param inputPath Path to the file in the input tree.
|
||||
* @param fileContent Content of the file.
|
||||
*/
|
||||
function writeFileFromInputPath(inputPath: string, fileContent: string | Buffer) {
|
||||
function writeFileFromInputPath(inputPath: string, fileContent: string|Buffer) {
|
||||
// We want the relative path from the given file to its ancestor "root" directory.
|
||||
// This root depends on whether the file lives in the source tree (srcDir) as a basic file
|
||||
// input to ng_package, the bin output tree (binDir) as the output of another rule, or
|
||||
@ -164,9 +166,15 @@ function main(args: string[]): number {
|
||||
esm2015.forEach(file => writeEsmFile(file, '', 'esm2015'));
|
||||
esm5.forEach(file => writeEsmFile(file, '.esm5', 'esm5'));
|
||||
|
||||
bundles.forEach(bundle => { copyFile(bundle, out, 'bundles'); });
|
||||
fesm2015.forEach(file => { copyFile(file, out, 'fesm2015'); });
|
||||
fesm5.forEach(file => { copyFile(file, out, 'fesm5'); });
|
||||
bundles.forEach(bundle => {
|
||||
copyFile(bundle, out, 'bundles');
|
||||
});
|
||||
fesm2015.forEach(file => {
|
||||
copyFile(file, out, 'fesm2015');
|
||||
});
|
||||
fesm5.forEach(file => {
|
||||
copyFile(file, out, 'fesm5');
|
||||
});
|
||||
|
||||
// Copy all type definitions into the package. This is necessary so that developers can use
|
||||
// the package with type definitions.
|
||||
@ -419,14 +427,16 @@ export * from '${srcDirRelative(inputPath, typingsFile.replace(/\.d\.tsx?$/, '')
|
||||
* Normalizes the specified path by replacing backslash separators with Posix
|
||||
* forward slash separators.
|
||||
*/
|
||||
function normalizeSeparators(path: string): string { return path.replace(/\\/g, '/'); }
|
||||
function normalizeSeparators(path: string): string {
|
||||
return path.replace(/\\/g, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewires metadata to point to the flattened dts file.
|
||||
*
|
||||
* @param metadataPath the metadata file path
|
||||
* @param typingsPath the typings bundle entrypoint
|
||||
*/
|
||||
* Rewires metadata to point to the flattened dts file.
|
||||
*
|
||||
* @param metadataPath the metadata file path
|
||||
* @param typingsPath the typings bundle entrypoint
|
||||
*/
|
||||
function rewireMetadata(metadataPath: string, typingsPath: string): string {
|
||||
const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf-8'));
|
||||
|
||||
@ -470,7 +480,7 @@ export function newArray<T>(size: number, value: T): T[];
|
||||
export function newArray<T>(size: number, value?: T): T[] {
|
||||
const list: T[] = [];
|
||||
for (let i = 0; i < size; i++) {
|
||||
list.push(value !);
|
||||
list.push(value!);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import * as ng from '@angular/compiler-cli';
|
||||
import {BazelOptions, CachedFileLoader, CompilerHost, FileCache, FileLoader, UncachedFileLoader, constructManifest, debug, parseTsconfig, resolveNormalizedPath, runAsWorker, runWorkerLoop} from '@bazel/typescript';
|
||||
import {BazelOptions, CachedFileLoader, CompilerHost, constructManifest, debug, FileCache, FileLoader, parseTsconfig, resolveNormalizedPath, runAsWorker, runWorkerLoop, UncachedFileLoader} from '@bazel/typescript';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as tsickle from 'tsickle';
|
||||
@ -123,7 +123,12 @@ export function runOneBuild(args: string[], inputs?: {[path: string]: string}):
|
||||
const {diagnostics} = compile({
|
||||
allDepsCompiledWithBazel: ALL_DEPS_COMPILED_WITH_BAZEL,
|
||||
useManifestPathsAsModuleName: _useManifestPathsAsModuleName,
|
||||
expectedOuts: expectedOut, compilerOpts, tsHost, bazelOpts, files, inputs,
|
||||
expectedOuts: expectedOut,
|
||||
compilerOpts,
|
||||
tsHost,
|
||||
bazelOpts,
|
||||
files,
|
||||
inputs,
|
||||
});
|
||||
if (diagnostics.length) {
|
||||
console.error(ng.formatDiagnostics(diagnostics));
|
||||
@ -142,16 +147,24 @@ export function relativeToRootDirs(filePath: string, rootDirs: string[]): string
|
||||
return filePath;
|
||||
}
|
||||
|
||||
export function compile({allDepsCompiledWithBazel = true, useManifestPathsAsModuleName,
|
||||
compilerOpts, tsHost, bazelOpts, files, inputs, expectedOuts,
|
||||
gatherDiagnostics, bazelHost}: {
|
||||
export function compile({
|
||||
allDepsCompiledWithBazel = true,
|
||||
useManifestPathsAsModuleName,
|
||||
compilerOpts,
|
||||
tsHost,
|
||||
bazelOpts,
|
||||
files,
|
||||
inputs,
|
||||
expectedOuts,
|
||||
gatherDiagnostics,
|
||||
bazelHost
|
||||
}: {
|
||||
allDepsCompiledWithBazel?: boolean,
|
||||
useManifestPathsAsModuleName?: boolean,
|
||||
compilerOpts: ng.CompilerOptions,
|
||||
tsHost: ts.CompilerHost, inputs?: {[path: string]: string},
|
||||
bazelOpts: BazelOptions,
|
||||
files: string[],
|
||||
expectedOuts: string[],
|
||||
useManifestPathsAsModuleName?: boolean, compilerOpts: ng.CompilerOptions, tsHost: ts.CompilerHost,
|
||||
inputs?: {[path: string]: string},
|
||||
bazelOpts: BazelOptions,
|
||||
files: string[],
|
||||
expectedOuts: string[],
|
||||
gatherDiagnostics?: (program: ng.Program) => ng.Diagnostics,
|
||||
bazelHost?: CompilerHost,
|
||||
}): {diagnostics: ng.Diagnostics, program: ng.Program} {
|
||||
@ -362,7 +375,7 @@ export function compile({allDepsCompiledWithBazel = true, useManifestPathsAsModu
|
||||
|
||||
if ((compilerOpts.module === ts.ModuleKind.UMD || compilerOpts.module === ts.ModuleKind.AMD) &&
|
||||
ngHost.amdModuleName) {
|
||||
return ngHost.amdModuleName({ fileName: importedFilePath } as ts.SourceFile);
|
||||
return ngHost.amdModuleName({fileName: importedFilePath} as ts.SourceFile);
|
||||
}
|
||||
|
||||
// If no AMD module name has been set for the source file by the `@bazel/typescript` compiler
|
||||
@ -434,8 +447,10 @@ export function compile({allDepsCompiledWithBazel = true, useManifestPathsAsModu
|
||||
const {diagnostics, emitResult, program} = ng.performCompilation({
|
||||
rootNames: files,
|
||||
options: compilerOpts,
|
||||
host: ngHost, emitCallback,
|
||||
mergeEmitResultsCallback: tsickle.mergeEmitResults, gatherDiagnostics
|
||||
host: ngHost,
|
||||
emitCallback,
|
||||
mergeEmitResultsCallback: tsickle.mergeEmitResults,
|
||||
gatherDiagnostics
|
||||
});
|
||||
const tsickleEmitResult = emitResult as tsickle.EmitResult;
|
||||
let externs = '/** @externs */\n';
|
||||
@ -512,9 +527,9 @@ function convertToForwardSlashPath(filePath: string): string {
|
||||
|
||||
function gatherDiagnosticsForInputsOnly(
|
||||
options: ng.CompilerOptions, bazelOpts: BazelOptions,
|
||||
ngProgram: ng.Program): (ng.Diagnostic | ts.Diagnostic)[] {
|
||||
ngProgram: ng.Program): (ng.Diagnostic|ts.Diagnostic)[] {
|
||||
const tsProgram = ngProgram.getTsProgram();
|
||||
const diagnostics: (ng.Diagnostic | ts.Diagnostic)[] = [];
|
||||
const diagnostics: (ng.Diagnostic|ts.Diagnostic)[] = [];
|
||||
// These checks mirror ts.getPreEmitDiagnostics, with the important
|
||||
// exception of avoiding b/30708240, which is that if you call
|
||||
// program.getDeclarationDiagnostics() it somehow corrupts the emit.
|
||||
|
@ -10,7 +10,6 @@ import {HostTree} from '@angular-devkit/schematics';
|
||||
import {SchematicTestRunner, UnitTestTree} from '@angular-devkit/schematics/testing';
|
||||
|
||||
describe('ng-add schematic', () => {
|
||||
|
||||
const defaultOptions = {name: 'demo'};
|
||||
let host: UnitTestTree;
|
||||
let schematicRunner: SchematicTestRunner;
|
||||
@ -61,7 +60,7 @@ describe('ng-add schematic', () => {
|
||||
new SchematicTestRunner('@angular/bazel', require.resolve('../collection.json'));
|
||||
});
|
||||
|
||||
it('throws if package.json is not found', async() => {
|
||||
it('throws if package.json is not found', async () => {
|
||||
expect(host.files).toContain('/package.json');
|
||||
host.delete('/package.json');
|
||||
|
||||
@ -76,7 +75,7 @@ describe('ng-add schematic', () => {
|
||||
expect(message).toBe('Could not read package.json.');
|
||||
});
|
||||
|
||||
it('throws if angular.json is not found', async() => {
|
||||
it('throws if angular.json is not found', async () => {
|
||||
expect(host.files).toContain('/angular.json');
|
||||
host.delete('/angular.json');
|
||||
|
||||
@ -91,7 +90,7 @@ describe('ng-add schematic', () => {
|
||||
expect(message).toBe('Could not find angular.json');
|
||||
});
|
||||
|
||||
it('should add @angular/bazel to package.json dependencies', async() => {
|
||||
it('should add @angular/bazel to package.json dependencies', async () => {
|
||||
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
|
||||
const {files} = host;
|
||||
expect(files).toContain('/package.json');
|
||||
@ -106,7 +105,7 @@ describe('ng-add schematic', () => {
|
||||
expect(Object.keys(json.devDependencies)).toContain(bazel);
|
||||
});
|
||||
|
||||
it('should add @bazel/* dev dependencies', async() => {
|
||||
it('should add @bazel/* dev dependencies', async () => {
|
||||
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
|
||||
const content = host.readContent('/package.json');
|
||||
const json = JSON.parse(content);
|
||||
@ -118,7 +117,7 @@ describe('ng-add schematic', () => {
|
||||
expect(devDeps).toContain('@bazel/typescript');
|
||||
});
|
||||
|
||||
it('should replace an existing dev dependency', async() => {
|
||||
it('should replace an existing dev dependency', async () => {
|
||||
expect(host.files).toContain('/package.json');
|
||||
const packageJson = JSON.parse(host.readContent('/package.json'));
|
||||
packageJson.devDependencies['@angular/bazel'] = '4.2.42';
|
||||
@ -126,12 +125,12 @@ describe('ng-add schematic', () => {
|
||||
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
|
||||
const content = host.readContent('/package.json');
|
||||
// It is possible that a dep gets added twice if the package already exists.
|
||||
expect(content.match(/@angular\/bazel/g) !.length).toEqual(1);
|
||||
expect(content.match(/@angular\/bazel/g)!.length).toEqual(1);
|
||||
const json = JSON.parse(content);
|
||||
expect(json.devDependencies['@angular/bazel']).toBe('1.2.3');
|
||||
});
|
||||
|
||||
it('should remove an existing dependency', async() => {
|
||||
it('should remove an existing dependency', async () => {
|
||||
expect(host.files).toContain('/package.json');
|
||||
const packageJson = JSON.parse(host.readContent('/package.json'));
|
||||
packageJson.dependencies['@angular/bazel'] = '4.2.42';
|
||||
@ -144,7 +143,7 @@ describe('ng-add schematic', () => {
|
||||
expect(json.devDependencies['@angular/bazel']).toBe('1.2.3');
|
||||
});
|
||||
|
||||
it('should remove unneeded dependencies', async() => {
|
||||
it('should remove unneeded dependencies', async () => {
|
||||
const packageJson = JSON.parse(host.readContent('/package.json'));
|
||||
packageJson.devDependencies['@angular-devkit/build-angular'] = '1.2.3';
|
||||
host.overwrite('/package.json', JSON.stringify(packageJson));
|
||||
@ -154,7 +153,7 @@ describe('ng-add schematic', () => {
|
||||
expect(json.devDependencies['angular-devkit/build-angular']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should append to scripts.postinstall if it already exists', async() => {
|
||||
it('should append to scripts.postinstall if it already exists', async () => {
|
||||
const packageJson = JSON.parse(host.readContent('/package.json'));
|
||||
packageJson['scripts'] = {
|
||||
postinstall: 'angular rocks',
|
||||
@ -167,7 +166,7 @@ describe('ng-add schematic', () => {
|
||||
.toBe('angular rocks; ngcc --properties es2015 browser module main');
|
||||
});
|
||||
|
||||
it('should update ngcc in scripts.postinstall if it already exists', async() => {
|
||||
it('should update ngcc in scripts.postinstall if it already exists', async () => {
|
||||
const packageJson = JSON.parse(host.readContent('/package.json'));
|
||||
packageJson['scripts'] = {
|
||||
postinstall:
|
||||
@ -180,14 +179,14 @@ describe('ng-add schematic', () => {
|
||||
expect(json.scripts['postinstall']).toBe('ngcc --properties es2015 browser module main');
|
||||
});
|
||||
|
||||
it('should not create Bazel workspace file', async() => {
|
||||
it('should not create Bazel workspace file', async () => {
|
||||
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
|
||||
const {files} = host;
|
||||
expect(files).not.toContain('/WORKSPACE');
|
||||
expect(files).not.toContain('/BUILD.bazel');
|
||||
});
|
||||
|
||||
it('should produce main.dev.ts and main.prod.ts for AOT', async() => {
|
||||
it('should produce main.dev.ts and main.prod.ts for AOT', async () => {
|
||||
host.create('/src/main.ts', 'generated by CLI');
|
||||
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
|
||||
const {files} = host;
|
||||
@ -199,7 +198,7 @@ describe('ng-add schematic', () => {
|
||||
expect(files).toContain('/src/main.ts');
|
||||
});
|
||||
|
||||
it('should not overwrite index.html with script tags', async() => {
|
||||
it('should not overwrite index.html with script tags', async () => {
|
||||
host.create('/src/index.html', '<html>Hello World</html>');
|
||||
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
|
||||
const {files} = host;
|
||||
@ -209,14 +208,14 @@ describe('ng-add schematic', () => {
|
||||
expect(content).not.toMatch('<script src="/bundle.min.js"></script>');
|
||||
});
|
||||
|
||||
it('should generate main.dev.ts and main.prod.ts', async() => {
|
||||
it('should generate main.dev.ts and main.prod.ts', async () => {
|
||||
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
|
||||
const {files} = host;
|
||||
expect(files).toContain('/src/main.dev.ts');
|
||||
expect(files).toContain('/src/main.prod.ts');
|
||||
});
|
||||
|
||||
it('should overwrite .gitignore for bazel-out directory', async() => {
|
||||
it('should overwrite .gitignore for bazel-out directory', async () => {
|
||||
host.create('.gitignore', '\n# compiled output\n');
|
||||
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
|
||||
const {files} = host;
|
||||
@ -225,7 +224,7 @@ describe('ng-add schematic', () => {
|
||||
expect(content).toMatch('\n# compiled output\n/bazel-out\n');
|
||||
});
|
||||
|
||||
it('should create a backup for original angular.json', async() => {
|
||||
it('should create a backup for original angular.json', async () => {
|
||||
expect(host.files).toContain('/angular.json');
|
||||
const original = host.readContent('/angular.json');
|
||||
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
|
||||
@ -235,7 +234,7 @@ describe('ng-add schematic', () => {
|
||||
expect(content).toMatch(original);
|
||||
});
|
||||
|
||||
it('should update angular.json to use Bazel builder', async() => {
|
||||
it('should update angular.json to use Bazel builder', async () => {
|
||||
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
|
||||
const {files} = host;
|
||||
expect(files).toContain('/angular.json');
|
||||
@ -256,7 +255,7 @@ describe('ng-add schematic', () => {
|
||||
expect(lint.builder).toBe('@angular-devkit/build-angular:tslint');
|
||||
});
|
||||
|
||||
it('should get defaultProject if name is not provided', async() => {
|
||||
it('should get defaultProject if name is not provided', async () => {
|
||||
const options = {};
|
||||
host = await schematicRunner.runSchematicAsync('ng-add', options, host).toPromise();
|
||||
const content = host.readContent('/angular.json');
|
||||
@ -281,7 +280,7 @@ describe('ng-add schematic', () => {
|
||||
['~7.0.1', false],
|
||||
];
|
||||
for (const [version, upgrade] of cases) {
|
||||
it(`should ${upgrade ? '' : 'not '}upgrade v${version}')`, async() => {
|
||||
it(`should ${upgrade ? '' : 'not '}upgrade v${version}')`, async () => {
|
||||
host.overwrite('package.json', JSON.stringify({
|
||||
name: 'demo',
|
||||
dependencies: {
|
||||
@ -305,7 +304,7 @@ describe('ng-add schematic', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should add a postinstall step to package.json', async() => {
|
||||
it('should add a postinstall step to package.json', async () => {
|
||||
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
|
||||
expect(host.files).toContain('/package.json');
|
||||
const content = host.readContent('/package.json');
|
||||
@ -313,7 +312,7 @@ describe('ng-add schematic', () => {
|
||||
expect(json.scripts.postinstall).toBe('ngcc --properties es2015 browser module main');
|
||||
});
|
||||
|
||||
it('should work when run on a minimal project (without test and e2e targets)', async() => {
|
||||
it('should work when run on a minimal project (without test and e2e targets)', async () => {
|
||||
host.overwrite('angular.json', JSON.stringify({
|
||||
projects: {
|
||||
'demo': {
|
||||
@ -338,5 +337,4 @@ describe('ng-add schematic', () => {
|
||||
|
||||
expect(error).toBeNull();
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -8,8 +8,9 @@
|
||||
* @fileoverview Schematics for ng-new project that builds with Bazel.
|
||||
*/
|
||||
|
||||
import {Rule, Tree, chain, externalSchematic, schematic} from '@angular-devkit/schematics';
|
||||
import {chain, externalSchematic, Rule, schematic, Tree} from '@angular-devkit/schematics';
|
||||
import {validateProjectName} from '@schematics/angular/utility/validation';
|
||||
|
||||
import {Schema} from './schema';
|
||||
|
||||
export default function(options: Schema): Rule {
|
||||
|
@ -9,14 +9,16 @@
|
||||
import {SchematicTestRunner} from '@angular-devkit/schematics/testing';
|
||||
|
||||
describe('ng-new schematic', () => {
|
||||
const schematicRunner =
|
||||
new SchematicTestRunner('@angular/bazel', require.resolve('../collection.json'), );
|
||||
const schematicRunner = new SchematicTestRunner(
|
||||
'@angular/bazel',
|
||||
require.resolve('../collection.json'),
|
||||
);
|
||||
const defaultOptions = {
|
||||
name: 'demo',
|
||||
version: '7.0.0',
|
||||
};
|
||||
|
||||
it('should call external @schematics/angular', async() => {
|
||||
it('should call external @schematics/angular', async () => {
|
||||
const options = {...defaultOptions};
|
||||
const host = await schematicRunner.runSchematicAsync('ng-new', options).toPromise();
|
||||
const {files} = host;
|
||||
@ -25,7 +27,7 @@ describe('ng-new schematic', () => {
|
||||
expect(files).toContain('/demo/package.json');
|
||||
});
|
||||
|
||||
it('should call ng-add to generate additional files needed by Bazel', async() => {
|
||||
it('should call ng-add to generate additional files needed by Bazel', async () => {
|
||||
const options = {...defaultOptions};
|
||||
const host = await schematicRunner.runSchematicAsync('ng-new', options).toPromise();
|
||||
const {files} = host;
|
||||
|
12
packages/bazel/src/schematics/ng-new/schema.d.ts
vendored
12
packages/bazel/src/schematics/ng-new/schema.d.ts
vendored
@ -86,8 +86,8 @@ export interface Schema {
|
||||
viewEncapsulation?: ViewEncapsulation;
|
||||
}
|
||||
/**
|
||||
* Initial git repository commit information.
|
||||
*/
|
||||
* Initial git repository commit information.
|
||||
*/
|
||||
export declare type CommitUnion = boolean | CommitObject;
|
||||
export interface CommitObject {
|
||||
email: string;
|
||||
@ -95,16 +95,16 @@ export interface CommitObject {
|
||||
name: string;
|
||||
}
|
||||
/**
|
||||
* The file extension or preprocessor to use for style files.
|
||||
*/
|
||||
* The file extension or preprocessor to use for style files.
|
||||
*/
|
||||
export declare enum Style {
|
||||
Css = 'css',
|
||||
Sass = 'sass',
|
||||
Scss = 'scss',
|
||||
}
|
||||
/**
|
||||
* The view encapsulation strategy to use in the initial project.
|
||||
*/
|
||||
* The view encapsulation strategy to use in the initial project.
|
||||
*/
|
||||
export declare enum ViewEncapsulation {
|
||||
Emulated = 'Emulated',
|
||||
Native = 'Native',
|
||||
|
@ -42,7 +42,7 @@ export function removeKeyValueInAstObject(
|
||||
let length = end - start;
|
||||
const match = content.slice(end).match(/^[,\s]+/);
|
||||
if (match) {
|
||||
length += match.pop() !.length;
|
||||
length += match.pop()!.length;
|
||||
}
|
||||
recorder.remove(start, length);
|
||||
if (i === node.properties.length - 1) { // last property
|
||||
@ -60,6 +60,6 @@ export function removeKeyValueInAstObject(
|
||||
/**
|
||||
* Returns true if the specified 'node' is a JsonAstObject, false otherwise.
|
||||
*/
|
||||
export function isJsonAstObject(node: JsonAstNode | null): node is JsonAstObject {
|
||||
export function isJsonAstObject(node: JsonAstNode|null): node is JsonAstObject {
|
||||
return !!node && node.kind === 'object';
|
||||
}
|
||||
|
@ -12,9 +12,10 @@ import {UnitTestTree} from '@angular-devkit/schematics/testing';
|
||||
import {isJsonAstObject, removeKeyValueInAstObject, replacePropertyInAstObject} from './json-utils';
|
||||
|
||||
describe('JsonUtils', () => {
|
||||
|
||||
let tree: UnitTestTree;
|
||||
beforeEach(() => { tree = new UnitTestTree(new HostTree()); });
|
||||
beforeEach(() => {
|
||||
tree = new UnitTestTree(new HostTree());
|
||||
});
|
||||
|
||||
describe('replacePropertyInAstObject', () => {
|
||||
it('should replace property', () => {
|
||||
|
@ -30,8 +30,9 @@ describe('@angular/common ng_package', () => {
|
||||
});
|
||||
// regression test for https://github.com/angular/angular/issues/23217
|
||||
// Note, we don't have an e2e test that covers this
|
||||
it('doesn\'t pass require in a way that breaks webpack static analysis',
|
||||
() => { expect(shx.cat('locales/fr.js')).not.toContain('factory(require, exports)'); });
|
||||
it('doesn\'t pass require in a way that breaks webpack static analysis', () => {
|
||||
expect(shx.cat('locales/fr.js')).not.toContain('factory(require, exports)');
|
||||
});
|
||||
});
|
||||
|
||||
it('should have right bundle files', () => {
|
||||
@ -59,8 +60,9 @@ describe('@angular/common ng_package', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should reference core using global symbol in umd',
|
||||
() => { expect(shx.cat('bundles/common.umd.js')).toContain('global.ng.core'); });
|
||||
it('should reference core using global symbol in umd', () => {
|
||||
expect(shx.cat('bundles/common.umd.js')).toContain('global.ng.core');
|
||||
});
|
||||
|
||||
it('should have right fesm files', () => {
|
||||
const expected = [
|
||||
|
@ -41,8 +41,9 @@ describe('@angular/core ng_package', () => {
|
||||
describe('package.json', () => {
|
||||
const packageJson = 'package.json';
|
||||
|
||||
it('should have a package.json file',
|
||||
() => { expect(shx.grep('"name":', packageJson)).toContain(`@angular/core`); });
|
||||
it('should have a package.json file', () => {
|
||||
expect(shx.grep('"name":', packageJson)).toContain(`@angular/core`);
|
||||
});
|
||||
|
||||
it('should contain correct version number with the PLACEHOLDER string replaced', () => {
|
||||
expect(shx.grep('"version":', packageJson)).toMatch(/\d+\.\d+\.\d+(?!-PLACEHOLDER)/);
|
||||
@ -66,16 +67,20 @@ describe('@angular/core ng_package', () => {
|
||||
|
||||
describe('typescript support', () => {
|
||||
if (ivyEnabled) {
|
||||
it('should have an index d.ts file',
|
||||
() => { expect(shx.cat('core.d.ts')).toContain(`export *`); });
|
||||
it('should have an index d.ts file', () => {
|
||||
expect(shx.cat('core.d.ts')).toContain(`export *`);
|
||||
});
|
||||
|
||||
it('should not have amd module names',
|
||||
() => { expect(shx.cat('public_api.d.ts')).not.toContain('<amd-module name'); });
|
||||
it('should not have amd module names', () => {
|
||||
expect(shx.cat('public_api.d.ts')).not.toContain('<amd-module name');
|
||||
});
|
||||
} else {
|
||||
it('should have an index d.ts file',
|
||||
() => { expect(shx.cat('core.d.ts')).toContain('export declare'); });
|
||||
it('should have an r3_symbols d.ts file',
|
||||
() => { expect(shx.cat('src/r3_symbols.d.ts')).toContain('export declare'); });
|
||||
it('should have an index d.ts file', () => {
|
||||
expect(shx.cat('core.d.ts')).toContain('export declare');
|
||||
});
|
||||
it('should have an r3_symbols d.ts file', () => {
|
||||
expect(shx.cat('src/r3_symbols.d.ts')).toContain('export declare');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -87,15 +92,18 @@ describe('@angular/core ng_package', () => {
|
||||
|
||||
obsoleteInIvy('metadata files are no longer needed or produced in Ivy')
|
||||
.describe('angular metadata', () => {
|
||||
it('should have metadata.json files',
|
||||
() => { expect(shx.cat('core.metadata.json')).toContain(`"__symbolic":"module"`); });
|
||||
it('should not have self-references in metadata.json',
|
||||
() => { expect(shx.cat('core.metadata.json')).not.toContain(`"from":"./core"`); });
|
||||
it('should have metadata.json files', () => {
|
||||
expect(shx.cat('core.metadata.json')).toContain(`"__symbolic":"module"`);
|
||||
});
|
||||
it('should not have self-references in metadata.json', () => {
|
||||
expect(shx.cat('core.metadata.json')).not.toContain(`"from":"./core"`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fesm2015', () => {
|
||||
it('should have a fesm15 file in the /fesm2015 directory',
|
||||
() => { expect(shx.cat('fesm2015/core.js')).toContain(`export {`); });
|
||||
it('should have a fesm15 file in the /fesm2015 directory', () => {
|
||||
expect(shx.cat('fesm2015/core.js')).toContain(`export {`);
|
||||
});
|
||||
|
||||
it('should have a source map', () => {
|
||||
expect(shx.cat('fesm2015/core.js.map'))
|
||||
@ -114,8 +122,9 @@ describe('@angular/core ng_package', () => {
|
||||
});
|
||||
|
||||
describe('fesm5', () => {
|
||||
it('should have a fesm5 file in the /fesm5 directory',
|
||||
() => { expect(shx.cat('fesm5/core.js')).toContain(`export {`); });
|
||||
it('should have a fesm5 file in the /fesm5 directory', () => {
|
||||
expect(shx.cat('fesm5/core.js')).toContain(`export {`);
|
||||
});
|
||||
|
||||
it('should have a source map', () => {
|
||||
expect(shx.cat('fesm5/core.js.map')).toContain(`{"version":3,"file":"core.js","sources":`);
|
||||
@ -131,12 +140,14 @@ describe('@angular/core ng_package', () => {
|
||||
expect(shx.cat('fesm5/core.js')).toContain('.ɵprov = ');
|
||||
});
|
||||
} else {
|
||||
it('should have decorators',
|
||||
() => { expect(shx.cat('fesm5/core.js')).toContain('__decorate'); });
|
||||
it('should have decorators', () => {
|
||||
expect(shx.cat('fesm5/core.js')).toContain('__decorate');
|
||||
});
|
||||
|
||||
// See: https://github.com/angular/angular/pull/32069
|
||||
it('should retain access to const',
|
||||
() => { expect(shx.cat('fesm5/core.js')).toContain('!ivyEnabled'); });
|
||||
it('should retain access to const', () => {
|
||||
expect(shx.cat('fesm5/core.js')).toContain('!ivyEnabled');
|
||||
});
|
||||
}
|
||||
|
||||
it('should load tslib from external bundle', () => {
|
||||
@ -145,8 +156,9 @@ describe('@angular/core ng_package', () => {
|
||||
});
|
||||
|
||||
obsoleteInIvy('we no longer need to export private symbols')
|
||||
.it('should have been built from the generated bundle index',
|
||||
() => { expect(shx.cat('fesm5/core.js')).toMatch('export {.*makeParamDecorator'); });
|
||||
.it('should have been built from the generated bundle index', () => {
|
||||
expect(shx.cat('fesm5/core.js')).toMatch('export {.*makeParamDecorator');
|
||||
});
|
||||
});
|
||||
|
||||
describe('esm2015', () => {
|
||||
@ -160,25 +172,31 @@ describe('@angular/core ng_package', () => {
|
||||
});
|
||||
|
||||
describe('esm5', () => {
|
||||
it('should not contain any *.ngfactory.js files',
|
||||
() => { expect(shx.find('esm5').filter(f => f.endsWith('.ngfactory.js'))).toEqual([]); });
|
||||
it('should not contain any *.ngfactory.js files', () => {
|
||||
expect(shx.find('esm5').filter(f => f.endsWith('.ngfactory.js'))).toEqual([]);
|
||||
});
|
||||
|
||||
it('should not contain any *.ngsummary.js files',
|
||||
() => { expect(shx.find('esm5').filter(f => f.endsWith('.ngsummary.js'))).toEqual([]); });
|
||||
it('should not contain any *.ngsummary.js files', () => {
|
||||
expect(shx.find('esm5').filter(f => f.endsWith('.ngsummary.js'))).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('umd', () => {
|
||||
it('should have a umd file in the /bundles directory',
|
||||
() => { expect(shx.ls('bundles/core.umd.js').length).toBe(1, 'File not found'); });
|
||||
it('should have a umd file in the /bundles directory', () => {
|
||||
expect(shx.ls('bundles/core.umd.js').length).toBe(1, 'File not found');
|
||||
});
|
||||
|
||||
it('should have a source map next to the umd file',
|
||||
() => { expect(shx.ls('bundles/core.umd.js.map').length).toBe(1, 'File not found'); });
|
||||
it('should have a source map next to the umd file', () => {
|
||||
expect(shx.ls('bundles/core.umd.js.map').length).toBe(1, 'File not found');
|
||||
});
|
||||
|
||||
it('should have a minified umd file in the /bundles directory',
|
||||
() => { expect(shx.ls('bundles/core.umd.min.js').length).toBe(1, 'File not found'); });
|
||||
it('should have a minified umd file in the /bundles directory', () => {
|
||||
expect(shx.ls('bundles/core.umd.min.js').length).toBe(1, 'File not found');
|
||||
});
|
||||
|
||||
it('should have a source map next to the minified umd file',
|
||||
() => { expect(shx.ls('bundles/core.umd.min.js.map').length).toBe(1, 'File not found'); });
|
||||
it('should have a source map next to the minified umd file', () => {
|
||||
expect(shx.ls('bundles/core.umd.min.js.map').length).toBe(1, 'File not found');
|
||||
});
|
||||
|
||||
it('should have the version info in the header', () => {
|
||||
expect(shx.cat('bundles/core.umd.js'))
|
||||
@ -189,22 +207,25 @@ describe('@angular/core ng_package', () => {
|
||||
expect(shx.cat('bundles/core.umd.js')).toContain('function __extends');
|
||||
expect(shx.cat('bundles/core.umd.js')).not.toContain('undefined.__extends');
|
||||
});
|
||||
it('should have an AMD name',
|
||||
() => { expect(shx.cat('bundles/core.umd.js')).toContain('define(\'@angular/core\''); });
|
||||
it('should define ng global symbols',
|
||||
() => { expect(shx.cat('bundles/core.umd.js')).toContain('global.ng.core = {}'); });
|
||||
it('should have an AMD name', () => {
|
||||
expect(shx.cat('bundles/core.umd.js')).toContain('define(\'@angular/core\'');
|
||||
});
|
||||
it('should define ng global symbols', () => {
|
||||
expect(shx.cat('bundles/core.umd.js')).toContain('global.ng.core = {}');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('secondary entry-point', () => {
|
||||
describe('package.json', () => {
|
||||
const packageJson = p `testing/package.json`;
|
||||
const packageJson = p`testing/package.json`;
|
||||
|
||||
it('should have a package.json file',
|
||||
() => { expect(shx.grep('"name":', packageJson)).toContain(`@angular/core/testing`); });
|
||||
it('should have a package.json file', () => {
|
||||
expect(shx.grep('"name":', packageJson)).toContain(`@angular/core/testing`);
|
||||
});
|
||||
|
||||
it('should have its module resolution mappings defined in the nested package.json', () => {
|
||||
const packageJson = p `testing/package.json`;
|
||||
const packageJson = p`testing/package.json`;
|
||||
expect(shx.grep('"main":', packageJson)).toContain(`../bundles/core-testing.umd.js`);
|
||||
expect(shx.grep('"module":', packageJson)).toContain(`../fesm5/testing.js`);
|
||||
expect(shx.grep('"es2015":', packageJson)).toContain(`../fesm2015/testing.js`);
|
||||
@ -216,13 +237,15 @@ describe('@angular/core ng_package', () => {
|
||||
|
||||
describe('typings', () => {
|
||||
if (ivyEnabled) {
|
||||
const typingsFile = p `testing/index.d.ts`;
|
||||
it('should have a typings file',
|
||||
() => { expect(shx.cat(typingsFile)).toContain(`export * from './public_api';`); });
|
||||
const typingsFile = p`testing/index.d.ts`;
|
||||
it('should have a typings file', () => {
|
||||
expect(shx.cat(typingsFile)).toContain(`export * from './public_api';`);
|
||||
});
|
||||
} else {
|
||||
const typingsFile = p `testing/testing.d.ts`;
|
||||
it('should have a typings file',
|
||||
() => { expect(shx.cat(typingsFile)).toContain('export declare'); });
|
||||
const typingsFile = p`testing/testing.d.ts`;
|
||||
it('should have a typings file', () => {
|
||||
expect(shx.cat(typingsFile)).toContain('export declare');
|
||||
});
|
||||
}
|
||||
|
||||
obsoleteInIvy(
|
||||
@ -242,8 +265,9 @@ describe('@angular/core ng_package', () => {
|
||||
});
|
||||
|
||||
describe('fesm2015', () => {
|
||||
it('should have a fesm15 file in the /fesm2015 directory',
|
||||
() => { expect(shx.cat('fesm2015/testing.js')).toContain(`export {`); });
|
||||
it('should have a fesm15 file in the /fesm2015 directory', () => {
|
||||
expect(shx.cat('fesm2015/testing.js')).toContain(`export {`);
|
||||
});
|
||||
|
||||
it('should have a source map', () => {
|
||||
expect(shx.cat('fesm2015/testing.js.map'))
|
||||
@ -257,8 +281,9 @@ describe('@angular/core ng_package', () => {
|
||||
});
|
||||
|
||||
describe('fesm5', () => {
|
||||
it('should have a fesm5 file in the /fesm5 directory',
|
||||
() => { expect(shx.cat('fesm5/testing.js')).toContain(`export {`); });
|
||||
it('should have a fesm5 file in the /fesm5 directory', () => {
|
||||
expect(shx.cat('fesm5/testing.js')).toContain(`export {`);
|
||||
});
|
||||
|
||||
it('should have a source map', () => {
|
||||
expect(shx.cat('fesm5/testing.js.map'))
|
||||
@ -267,8 +292,9 @@ describe('@angular/core ng_package', () => {
|
||||
});
|
||||
|
||||
describe('umd', () => {
|
||||
it('should have a umd file in the /bundles directory',
|
||||
() => { expect(shx.ls('bundles/core-testing.umd.js').length).toBe(1, 'File not found'); });
|
||||
it('should have a umd file in the /bundles directory', () => {
|
||||
expect(shx.ls('bundles/core-testing.umd.js').length).toBe(1, 'File not found');
|
||||
});
|
||||
|
||||
it('should have a source map next to the umd file', () => {
|
||||
expect(shx.ls('bundles/core-testing.umd.js.map').length).toBe(1, 'File not found');
|
||||
|
@ -11,7 +11,6 @@ import {existsSync, readFileSync} from 'fs';
|
||||
import {dirname, join} from 'path';
|
||||
|
||||
describe('flat_module ng_module', () => {
|
||||
|
||||
let packageOutput: string;
|
||||
let flatModuleOutFile: string;
|
||||
|
||||
@ -21,11 +20,11 @@ describe('flat_module ng_module', () => {
|
||||
flatModuleOutFile = join(packageOutput, 'flat_module.js');
|
||||
});
|
||||
|
||||
it('should have a flat module out file',
|
||||
() => { expect(existsSync(flatModuleOutFile)).toBe(true); });
|
||||
it('should have a flat module out file', () => {
|
||||
expect(existsSync(flatModuleOutFile)).toBe(true);
|
||||
});
|
||||
|
||||
describe('flat module out file', () => {
|
||||
|
||||
obsoleteInIvy('Ngtsc computes the AMD module name differently than NGC')
|
||||
.it('should have a proper AMD module name', () => {
|
||||
expect(readFileSync(flatModuleOutFile, 'utf8'))
|
||||
|
@ -11,7 +11,6 @@ import * as path from 'path';
|
||||
import {setup} from './test_support';
|
||||
|
||||
describe('ngc_wrapped', () => {
|
||||
|
||||
it('should work', () => {
|
||||
const {read, write, runOneBuild, writeConfig, shouldExist, basePath, typesRoots} = setup();
|
||||
|
||||
|
@ -19,7 +19,9 @@ export interface TestSupport {
|
||||
angularCorePath: string;
|
||||
typesRoots: string;
|
||||
writeConfig({
|
||||
srcTargetPath, depPaths, pathMapping,
|
||||
srcTargetPath,
|
||||
depPaths,
|
||||
pathMapping,
|
||||
}: {
|
||||
srcTargetPath: string,
|
||||
depPaths?: string[],
|
||||
@ -33,13 +35,13 @@ export interface TestSupport {
|
||||
runOneBuild(): boolean;
|
||||
}
|
||||
|
||||
export function setup(
|
||||
{
|
||||
bazelBin = 'bazel-bin', tsconfig = 'tsconfig.json',
|
||||
}: {
|
||||
bazelBin?: string,
|
||||
tsconfig?: string,
|
||||
} = {}): TestSupport {
|
||||
export function setup({
|
||||
bazelBin = 'bazel-bin',
|
||||
tsconfig = 'tsconfig.json',
|
||||
}: {
|
||||
bazelBin?: string,
|
||||
tsconfig?: string,
|
||||
} = {}): TestSupport {
|
||||
const runfilesPath = process.env['TEST_SRCDIR'];
|
||||
|
||||
const basePath = makeTempDir(runfilesPath);
|
||||
@ -93,12 +95,17 @@ export function setup(
|
||||
}
|
||||
|
||||
function writeFiles(...mockDirs: {[fileName: string]: string}[]) {
|
||||
mockDirs.forEach(
|
||||
(dir) => { Object.keys(dir).forEach((fileName) => { write(fileName, dir[fileName]); }); });
|
||||
mockDirs.forEach((dir) => {
|
||||
Object.keys(dir).forEach((fileName) => {
|
||||
write(fileName, dir[fileName]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function writeConfig({
|
||||
srcTargetPath, depPaths = [], pathMapping = [],
|
||||
srcTargetPath,
|
||||
depPaths = [],
|
||||
pathMapping = [],
|
||||
}: {
|
||||
srcTargetPath: string,
|
||||
depPaths?: string[],
|
||||
@ -133,7 +140,8 @@ export function setup(
|
||||
defaultTsConfig: emptyTsConfig.config,
|
||||
rootDir: basePath,
|
||||
target: target,
|
||||
outDir: bazelBinPath, compilationTargetSrc,
|
||||
outDir: bazelBinPath,
|
||||
compilationTargetSrc,
|
||||
files: files,
|
||||
pathMapping: pathMappingObj,
|
||||
});
|
||||
@ -153,7 +161,9 @@ export function setup(
|
||||
}
|
||||
}
|
||||
|
||||
function runOneBuildImpl(): boolean { return runOneBuild(['@' + tsConfigJsonPath]); }
|
||||
function runOneBuildImpl(): boolean {
|
||||
return runOneBuild(['@' + tsConfigJsonPath]);
|
||||
}
|
||||
}
|
||||
|
||||
function makeTempDir(baseDir: string): string {
|
||||
|
Reference in New Issue
Block a user