1
0
mirror of https://github.com/angular/angular-cli.git synced 2025-05-28 02:58:04 +08:00

build: make resolution logic compatible with Bazel

This commit is contained in:
Filipe Silva 2018-08-20 12:35:01 +01:00 committed by Hans
parent f08ec443ff
commit 9720077a4b
29 changed files with 95 additions and 75 deletions

@ -8,15 +8,12 @@
// tslint:disable:no-any
// tslint:disable-next-line:no-implicit-dependencies
import { resolve } from '@angular-devkit/core/node';
import * as path from 'path';
const devKitRoot = (global as any)._DevKitRoot;
describe('resolve', () => {
it('works', () => {
expect(resolve('tslint', { basedir: __dirname }))
.toBe(path.join(devKitRoot, 'node_modules/tslint/lib/index.js'));
const tslintRe = /[\\/]node_modules[\\/]tslint[\\/]lib[\\/]index.js$/;
expect(resolve('tslint', { basedir: __dirname })).toMatch(tslintRe);
expect(() => resolve('npm', { basedir: '/' })).toThrow();

@ -56,7 +56,7 @@ export class AmbiguousProjectPathException extends BaseException {
}
export class Workspace {
private readonly _workspaceSchemaPath = join(normalize(__dirname), 'workspace-schema.json');
private readonly _workspaceSchemaPath = normalize(require.resolve('./workspace-schema.json'));
private _workspaceSchema: JsonObject;
private _workspace: WorkspaceSchema;
private _registry: schema.CoreSchemaRegistry;

@ -10,7 +10,8 @@
import { tap } from 'rxjs/operators';
import { schema } from '..';
import { NodeJsSyncHost } from '../../node';
import { join, normalize } from '../virtual-fs';
import { AdditionalPropertiesValidatorError } from '../json/schema/interface';
import { dirname, join, normalize } from '../virtual-fs';
import {
ProjectNotFoundException,
Workspace,
@ -115,10 +116,10 @@ describe('Workspace', () => {
});
it('loads workspace from host', (done) => {
const devkitRoot = normalize((global as any)._DevKitRoot); // tslint:disable-line:no-any
const workspaceRoot = join(devkitRoot, 'tests/angular_devkit/core/workspace');
const workspacePath = require.resolve('./test/test-workspace.json');
const workspaceRoot = dirname(normalize(workspacePath));
const workspace = new Workspace(workspaceRoot, host);
workspace.loadWorkspaceFromHost(normalize('angular-workspace.json')).pipe(
workspace.loadWorkspaceFromHost(normalize('test-workspace.json')).pipe(
tap((ws) => expect(ws.getProject('app').root).toEqual(workspaceJson.projects['app'].root)),
).toPromise().then(done, done.fail);
});
@ -127,7 +128,14 @@ describe('Workspace', () => {
const workspace = new Workspace(root, host);
workspace.loadWorkspaceFromJson({ foo: 'bar' })
.toPromise().then(() => done.fail, (err) => {
expect(err).toEqual(jasmine.any(schema.SchemaValidationException));
const validationErrors = [{
keyword: 'additionalProperties',
dataPath: '',
schemaPath: '#/additionalProperties',
params: { additionalProperty: 'foo' },
message: 'should NOT have additional properties',
} as AdditionalPropertiesValidatorError];
expect(err).toEqual(new schema.SchemaValidationException(validationErrors));
done();
});
});

@ -35,7 +35,7 @@ describe('callSource', () => {
callSource(source0, context)
.toPromise()
.then(() => done.fail(), err => {
expect(err.constructor).toBe(InvalidSourceResultException);
expect(err).toEqual(new InvalidSourceResultException());
})
.then(done, done.fail);
});
@ -46,7 +46,7 @@ describe('callSource', () => {
callSource(source0, context)
.toPromise()
.then(() => done.fail(), err => {
expect(err.constructor).toBe(InvalidSourceResultException);
expect(err).toEqual(new InvalidSourceResultException({}));
})
.then(done, done.fail);
});
@ -57,7 +57,7 @@ describe('callSource', () => {
callSource(source0, context)
.toPromise()
.then(() => done.fail(), err => {
expect(err.constructor).toBe(InvalidSourceResultException);
expect(err).toEqual(new InvalidSourceResultException({}));
})
.then(done, done.fail);
});
@ -95,7 +95,7 @@ describe('callRule', () => {
callRule(rule0, tree0, context)
.toPromise()
.then(() => done.fail(), err => {
expect(err.constructor).toBe(InvalidRuleResultException);
expect(err).toEqual(new InvalidRuleResultException({}));
})
.then(done, done.fail);
});
@ -107,7 +107,7 @@ describe('callRule', () => {
callRule(rule0, tree0, context)
.toPromise()
.then(() => done.fail(), err => {
expect(err.constructor).toBe(InvalidRuleResultException);
expect(err).toEqual(new InvalidRuleResultException({}));
})
.then(done, done.fail);
});

@ -14,12 +14,15 @@ import * as path from 'path';
import { Observable, concat } from 'rxjs';
import { catchError } from 'rxjs/operators';
const isWindowsBazel = process.env.RUNFILES_MANIFEST_ONLY === '1'
&& process.env.RUNFILES_MANIFEST_FILE;
describe('TsLintTaskExecutor', () => {
it('works with config object', done => {
const testRunner = new SchematicTestRunner(
'@_/test',
path.join(__dirname, 'test/collection.json'),
require.resolve('./test/collection.json'),
);
const host = new TempScopedNodeJsSyncHost();
@ -35,7 +38,7 @@ describe('TsLintTaskExecutor', () => {
it('shows errors with config object', done => {
const testRunner = new SchematicTestRunner(
'@_/test',
path.join(__dirname, 'test/collection.json'),
require.resolve('./test/collection.json'),
);
const host = new TempScopedNodeJsSyncHost();
@ -71,9 +74,17 @@ describe('TsLintTaskExecutor', () => {
});
it('supports custom rules in the project (pass)', done => {
// This test is disabled on Windows Bazel runs because it relies on TSLint custom rule
// loading behavior, which doesn't work with runfile resolution.
if (isWindowsBazel) {
done();
return;
}
const testRunner = new SchematicTestRunner(
'@_/test',
path.join(__dirname, 'test/collection.json'),
require.resolve('./test/collection.json'),
);
const host = new TempScopedNodeJsSyncHost();
@ -95,6 +106,14 @@ describe('TsLintTaskExecutor', () => {
});
it('supports custom rules in the project (fail)', done => {
// This test is disabled on Windows Bazel runs because it relies on TSLint custom rule
// loading behavior, which doesn't work with runfile resolution.
if (isWindowsBazel) {
done();
return;
}
const testRunner = new SchematicTestRunner(
'@_/test',
path.join(__dirname, 'test/collection.json'),

@ -13,6 +13,7 @@ import {
virtualFs,
} from '@angular-devkit/core';
import { NodeJsSyncHost } from '@angular-devkit/core/node';
import { existsSync, statSync } from 'fs';
import { dirname, isAbsolute, join, resolve } from 'path';
import { Observable, from as observableFrom, of as observableOf, throwError } from 'rxjs';
import { mergeMap } from 'rxjs/operators';
@ -220,7 +221,6 @@ export abstract class FileSystemEngineHostBase implements
throw new FactoryCannotBeResolvedException(name);
}
const { path } = resolvedRef;
let schema = partialDesc.schema;
let schemaJson: JsonObject | undefined = undefined;
if (schema) {
@ -230,6 +230,15 @@ export abstract class FileSystemEngineHostBase implements
schemaJson = readJsonFile(schema) as JsonObject;
}
// The schematic path is used to resolve URLs.
// We should be able to just do `dirname(resolvedRef.path)` but for compatibility with
// Bazel under Windows this directory needs to be resolved from the collection instead.
// This is needed because on Bazel under Windows the data files (such as the collection or
// url files) are not in the same place as the compiled JS.
const maybePath = join(collectionPath, partialDesc.factory);
const path = existsSync(maybePath) && statSync(maybePath).isDirectory()
? maybePath : dirname(maybePath);
return this._transformSchematicDescription(name, collection, {
...partialDesc,
schema,
@ -248,9 +257,7 @@ export abstract class FileSystemEngineHostBase implements
return (context: FileSystemSchematicContext) => {
// Resolve all file:///a/b/c/d from the schematic's own path, and not the current
// path.
const root = normalize(
resolve(dirname(context.schematic.description.path), url.path || ''),
);
const root = normalize(resolve(context.schematic.description.path, url.path || ''));
return new HostCreateTree(new virtualFs.ScopedHost(new NodeJsSyncHost(), root));
};

@ -26,15 +26,22 @@ export class FileSystemEngineHost extends FileSystemEngineHostBase {
constructor(protected _root: string) { super(); }
protected _resolveCollectionPath(name: string): string {
// Allow `${_root}/${name}.json` as a collection.
if (existsSync(join(this._root, name + '.json'))) {
return join(this._root, name + '.json');
}
try {
// Allow `${_root}/${name}.json` as a collection.
const maybePath = require.resolve(join(this._root, name + '.json'));
if (existsSync(maybePath)) {
return maybePath;
}
} catch (error) { }
try {
// Allow `${_root}/${name}/collection.json.
const maybePath = require.resolve(join(this._root, name, 'collection.json'));
if (existsSync(maybePath)) {
return maybePath;
}
} catch (error) { }
// Allow `${_root}/${name}/collection.json.
if (existsSync(join(this._root, name, 'collection.json'))) {
return join(this._root, name, 'collection.json');
}
throw new CollectionCannotBeResolvedException(name);
}

@ -14,11 +14,9 @@ import { of as observableOf } from 'rxjs';
describe('FileSystemEngineHost', () => {
const devkitRoot = (global as any)._DevKitRoot;
const root = path.join(
devkitRoot,
'tests/angular_devkit/schematics/tools/file-system-engine-host',
);
// We need to resolve a file that actually exists, and not just a folder.
// tslint:disable-next-line:max-line-length
const root = path.join(path.dirname(require.resolve(__filename)), '../../../../tests/angular_devkit/schematics/tools/file-system-engine-host');
it('works', () => {
const engineHost = new FileSystemEngineHost(root);

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { Schema as ApplicationOptions } from '../application/schema';
import { Schema as WorkspaceOptions } from '../workspace/schema';
import { Schema as AppShellOptions } from './schema';
@ -15,7 +14,7 @@ import { Schema as AppShellOptions } from './schema';
describe('App Shell Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const defaultOptions: AppShellOptions = {
name: 'foo',

@ -7,7 +7,6 @@
*/
// tslint:disable:no-big-function
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { latestVersions } from '../utility/latest-versions';
import { Schema as WorkspaceOptions } from '../workspace/schema';
import { Schema as ApplicationOptions } from './schema';
@ -16,7 +15,7 @@ import { Schema as ApplicationOptions } from './schema';
describe('Application Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const workspaceOptions: WorkspaceOptions = {

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { Schema as ApplicationOptions } from '../application/schema';
import { Schema as WorkspaceOptions } from '../workspace/schema';
import { Schema as ClassOptions } from './schema';
@ -15,7 +14,7 @@ import { Schema as ClassOptions } from './schema';
describe('Class Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const defaultOptions: ClassOptions = {
name: 'foo',

@ -7,7 +7,6 @@
*/
// tslint:disable:no-big-function
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { Schema as ApplicationOptions } from '../application/schema';
import { createAppModule } from '../utility/test';
import { Schema as WorkspaceOptions } from '../workspace/schema';
@ -17,7 +16,7 @@ import { Schema as ComponentOptions } from './schema';
describe('Component Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const defaultOptions: ComponentOptions = {
name: 'foo',

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { Schema as ApplicationOptions } from '../application/schema';
import { Schema as WorkspaceOptions } from '../workspace/schema';
import { Schema as DirectiveOptions } from './schema';
@ -15,7 +14,7 @@ import { Schema as DirectiveOptions } from './schema';
describe('Directive Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const defaultOptions: DirectiveOptions = {
name: 'foo',

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { Schema as WorkspaceOptions } from '../workspace/schema';
import { Schema as E2eOptions } from './schema';
@ -14,7 +13,7 @@ import { Schema as E2eOptions } from './schema';
describe('Application Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const workspaceOptions: WorkspaceOptions = {

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { Schema as ApplicationOptions } from '../application/schema';
import { Schema as WorkspaceOptions } from '../workspace/schema';
import { Schema as EnumOptions } from './schema';
@ -15,7 +14,7 @@ import { Schema as EnumOptions } from './schema';
describe('Enum Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const defaultOptions: EnumOptions = {
name: 'foo',

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { Schema as ApplicationOptions } from '../application/schema';
import { Schema as WorkspaceOptions } from '../workspace/schema';
import { Schema as GuardOptions } from './schema';
@ -15,7 +14,7 @@ import { Schema as GuardOptions } from './schema';
describe('Guard Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const defaultOptions: GuardOptions = {
name: 'foo',

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { Schema as ApplicationOptions } from '../application/schema';
import { Schema as WorkspaceOptions } from '../workspace/schema';
import { Schema as InterfaceOptions } from './schema';
@ -15,7 +14,7 @@ import { Schema as InterfaceOptions } from './schema';
describe('Interface Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const defaultOptions: InterfaceOptions = {
name: 'foo',

@ -7,7 +7,6 @@
*/
// tslint:disable:no-big-function
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { getFileContent } from '../../angular/utility/test';
import { Schema as ComponentOptions } from '../component/schema';
import { latestVersions } from '../utility/latest-versions';
@ -22,7 +21,7 @@ function getJsonFileContent(tree: UnitTestTree, path: string) {
describe('Library Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/ng_packagr',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const defaultOptions: GenerateLibrarySchema = {
name: 'foo',

@ -9,14 +9,13 @@
import { JsonObject } from '@angular-devkit/core';
import { EmptyTree } from '@angular-devkit/schematics';
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { latestVersions } from '../../utility/latest-versions';
describe('Migration to v6', () => {
const schematicRunner = new SchematicTestRunner(
'migrations',
path.join(__dirname, '../migration-collection.json'),
require.resolve('../migration-collection.json'),
);
// tslint:disable-next-line:no-any

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { Schema as ApplicationOptions } from '../application/schema';
import { Schema as WorkspaceOptions } from '../workspace/schema';
import { Schema as ModuleOptions } from './schema';
@ -15,7 +14,7 @@ import { Schema as ModuleOptions } from './schema';
describe('Module Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const defaultOptions: ModuleOptions = {
name: 'foo',

@ -6,14 +6,13 @@
* found in the LICENSE file at https://angular.io/license
*/
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { Schema as NgNewOptions } from './schema';
describe('Ng New Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const defaultOptions: NgNewOptions = {
name: 'foo',

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { Schema as ApplicationOptions } from '../application/schema';
import { createAppModule, getFileContent } from '../utility/test';
import { Schema as WorkspaceOptions } from '../workspace/schema';
@ -16,7 +15,7 @@ import { Schema as PipeOptions } from './schema';
describe('Pipe Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const defaultOptions: PipeOptions = {
name: 'foo',

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { Schema as ApplicationOptions } from '../application/schema';
import { Schema as WorkspaceOptions } from '../workspace/schema';
import { Schema as ServiceWorkerOptions } from './schema';
@ -15,7 +14,7 @@ import { Schema as ServiceWorkerOptions } from './schema';
describe('Service Worker Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const defaultOptions: ServiceWorkerOptions = {
project: 'bar',

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { Schema as ApplicationOptions } from '../application/schema';
import { Schema as WorkspaceOptions } from '../workspace/schema';
import { Schema as ServiceOptions } from './schema';
@ -15,7 +14,7 @@ import { Schema as ServiceOptions } from './schema';
describe('Service Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const defaultOptions: ServiceOptions = {
name: 'foo',

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { Schema as ApplicationOptions } from '../application/schema';
import { Schema as WorkspaceOptions } from '../workspace/schema';
import { Schema as UniversalOptions } from './schema';
@ -14,7 +13,7 @@ import { Schema as UniversalOptions } from './schema';
describe('Universal Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const defaultOptions: UniversalOptions = {
clientProject: 'bar',

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
import * as path from 'path';
import { latestVersions } from '../utility/latest-versions';
import { Schema as WorkspaceOptions } from './schema';
@ -14,7 +13,7 @@ import { Schema as WorkspaceOptions } from './schema';
describe('Workspace Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
path.join(__dirname, '../collection.json'),
require.resolve('../collection.json'),
);
const defaultOptions: WorkspaceOptions = {
name: 'foo',

@ -14,7 +14,8 @@ import { _coerceVersionNumber } from './index';
describe('@schematics/update:migrate', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/update', __dirname + '/../collection.json',
'@schematics/update',
require.resolve('../collection.json'),
);
let host: virtualFs.test.TestHost;
let appTree: UnitTestTree = new UnitTestTree(new HostTree());
@ -30,7 +31,7 @@ describe('@schematics/update:migrate', () => {
// migrate schematic actually do work appropriately, in a separate test.
schematicRunner.runSchematicAsync('migrate', {
package: 'test',
collection: __dirname + '/test/migration.json',
collection: require.resolve('./test/migration.json'),
from: '1.0.0',
to: '2.0.0',
}, appTree).pipe(

@ -35,7 +35,8 @@ describe('angularMajorCompatGuarantee', () => {
describe('@schematics/update', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/update', __dirname + '/../collection.json',
'@schematics/update',
require.resolve('../collection.json'),
);
let host: virtualFs.test.TestHost;
let appTree: UnitTestTree = new UnitTestTree(new HostTree());