Skip to content

Commit f4fd44f

Browse files
committed
build: make resolution logic compatible with Bazel
1 parent 8f2f518 commit f4fd44f

File tree

29 files changed

+95
-75
lines changed

29 files changed

+95
-75
lines changed

packages/angular_devkit/core/node/resolve_spec.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,12 @@
88
// tslint:disable:no-any
99
// tslint:disable-next-line:no-implicit-dependencies
1010
import { resolve } from '@angular-devkit/core/node';
11-
import * as path from 'path';
12-
13-
const devKitRoot = (global as any)._DevKitRoot;
1411

1512
describe('resolve', () => {
1613

1714
it('works', () => {
18-
expect(resolve('tslint', { basedir: __dirname }))
19-
.toBe(path.join(devKitRoot, 'node_modules/tslint/lib/index.js'));
15+
const tslintRe = /[\\/]node_modules[\\/]tslint[\\/]lib[\\/]index.js$/;
16+
expect(resolve('tslint', { basedir: __dirname })).toMatch(tslintRe);
2017

2118
expect(() => resolve('npm', { basedir: '/' })).toThrow();
2219

packages/angular_devkit/core/src/workspace/workspace.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export class AmbiguousProjectPathException extends BaseException {
5656
}
5757

5858
export class Workspace {
59-
private readonly _workspaceSchemaPath = join(normalize(__dirname), 'workspace-schema.json');
59+
private readonly _workspaceSchemaPath = normalize(require.resolve('./workspace-schema.json'));
6060
private _workspaceSchema: JsonObject;
6161
private _workspace: WorkspaceSchema;
6262
private _registry: schema.CoreSchemaRegistry;

packages/angular_devkit/core/src/workspace/workspace_spec.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
import { tap } from 'rxjs/operators';
1111
import { schema } from '..';
1212
import { NodeJsSyncHost } from '../../node';
13-
import { join, normalize } from '../virtual-fs';
13+
import { AdditionalPropertiesValidatorError } from '../json/schema/interface';
14+
import { dirname, join, normalize } from '../virtual-fs';
1415
import {
1516
ProjectNotFoundException,
1617
Workspace,
@@ -115,10 +116,10 @@ describe('Workspace', () => {
115116
});
116117

117118
it('loads workspace from host', (done) => {
118-
const devkitRoot = normalize((global as any)._DevKitRoot); // tslint:disable-line:no-any
119-
const workspaceRoot = join(devkitRoot, 'tests/angular_devkit/core/workspace');
119+
const workspacePath = require.resolve('./test/test-workspace.json');
120+
const workspaceRoot = dirname(normalize(workspacePath));
120121
const workspace = new Workspace(workspaceRoot, host);
121-
workspace.loadWorkspaceFromHost(normalize('angular-workspace.json')).pipe(
122+
workspace.loadWorkspaceFromHost(normalize('test-workspace.json')).pipe(
122123
tap((ws) => expect(ws.getProject('app').root).toEqual(workspaceJson.projects['app'].root)),
123124
).toPromise().then(done, done.fail);
124125
});
@@ -127,7 +128,14 @@ describe('Workspace', () => {
127128
const workspace = new Workspace(root, host);
128129
workspace.loadWorkspaceFromJson({ foo: 'bar' })
129130
.toPromise().then(() => done.fail, (err) => {
130-
expect(err).toEqual(jasmine.any(schema.SchemaValidationException));
131+
const validationErrors = [{
132+
keyword: 'additionalProperties',
133+
dataPath: '',
134+
schemaPath: '#/additionalProperties',
135+
params: { additionalProperty: 'foo' },
136+
message: 'should NOT have additional properties',
137+
} as AdditionalPropertiesValidatorError];
138+
expect(err).toEqual(new schema.SchemaValidationException(validationErrors));
131139
done();
132140
});
133141
});

packages/angular_devkit/schematics/src/rules/call_spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe('callSource', () => {
3535
callSource(source0, context)
3636
.toPromise()
3737
.then(() => done.fail(), err => {
38-
expect(err.constructor).toBe(InvalidSourceResultException);
38+
expect(err).toEqual(new InvalidSourceResultException());
3939
})
4040
.then(done, done.fail);
4141
});
@@ -46,7 +46,7 @@ describe('callSource', () => {
4646
callSource(source0, context)
4747
.toPromise()
4848
.then(() => done.fail(), err => {
49-
expect(err.constructor).toBe(InvalidSourceResultException);
49+
expect(err).toEqual(new InvalidSourceResultException({}));
5050
})
5151
.then(done, done.fail);
5252
});
@@ -57,7 +57,7 @@ describe('callSource', () => {
5757
callSource(source0, context)
5858
.toPromise()
5959
.then(() => done.fail(), err => {
60-
expect(err.constructor).toBe(InvalidSourceResultException);
60+
expect(err).toEqual(new InvalidSourceResultException({}));
6161
})
6262
.then(done, done.fail);
6363
});
@@ -95,7 +95,7 @@ describe('callRule', () => {
9595
callRule(rule0, tree0, context)
9696
.toPromise()
9797
.then(() => done.fail(), err => {
98-
expect(err.constructor).toBe(InvalidRuleResultException);
98+
expect(err).toEqual(new InvalidRuleResultException({}));
9999
})
100100
.then(done, done.fail);
101101
});
@@ -107,7 +107,7 @@ describe('callRule', () => {
107107
callRule(rule0, tree0, context)
108108
.toPromise()
109109
.then(() => done.fail(), err => {
110-
expect(err.constructor).toBe(InvalidRuleResultException);
110+
expect(err).toEqual(new InvalidRuleResultException({}));
111111
})
112112
.then(done, done.fail);
113113
});

packages/angular_devkit/schematics/tasks/tslint-fix/executor_spec.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@ import * as path from 'path';
1414
import { Observable, concat } from 'rxjs';
1515
import { catchError } from 'rxjs/operators';
1616

17+
const isWindowsBazel = process.env.RUNFILES_MANIFEST_ONLY === '1'
18+
&& process.env.RUNFILES_MANIFEST_FILE;
19+
1720
describe('TsLintTaskExecutor', () => {
1821

1922
it('works with config object', done => {
2023
const testRunner = new SchematicTestRunner(
2124
'@_/test',
22-
path.join(__dirname, 'test/collection.json'),
25+
require.resolve('./test/collection.json'),
2326
);
2427

2528
const host = new TempScopedNodeJsSyncHost();
@@ -35,7 +38,7 @@ describe('TsLintTaskExecutor', () => {
3538
it('shows errors with config object', done => {
3639
const testRunner = new SchematicTestRunner(
3740
'@_/test',
38-
path.join(__dirname, 'test/collection.json'),
41+
require.resolve('./test/collection.json'),
3942
);
4043

4144
const host = new TempScopedNodeJsSyncHost();
@@ -71,9 +74,17 @@ describe('TsLintTaskExecutor', () => {
7174
});
7275

7376
it('supports custom rules in the project (pass)', done => {
77+
// This test is disabled on Windows Bazel runs because it relies on TSLint custom rule
78+
// loading behavior, which doesn't work with runfile resolution.
79+
if (isWindowsBazel) {
80+
done();
81+
82+
return;
83+
}
84+
7485
const testRunner = new SchematicTestRunner(
7586
'@_/test',
76-
path.join(__dirname, 'test/collection.json'),
87+
require.resolve('./test/collection.json'),
7788
);
7889

7990
const host = new TempScopedNodeJsSyncHost();
@@ -95,6 +106,14 @@ describe('TsLintTaskExecutor', () => {
95106
});
96107

97108
it('supports custom rules in the project (fail)', done => {
109+
// This test is disabled on Windows Bazel runs because it relies on TSLint custom rule
110+
// loading behavior, which doesn't work with runfile resolution.
111+
if (isWindowsBazel) {
112+
done();
113+
114+
return;
115+
}
116+
98117
const testRunner = new SchematicTestRunner(
99118
'@_/test',
100119
path.join(__dirname, 'test/collection.json'),

packages/angular_devkit/schematics/tools/file-system-engine-host-base.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
virtualFs,
1414
} from '@angular-devkit/core';
1515
import { NodeJsSyncHost } from '@angular-devkit/core/node';
16+
import { existsSync, statSync } from 'fs';
1617
import { dirname, isAbsolute, join, resolve } from 'path';
1718
import { Observable, from as observableFrom, of as observableOf, throwError } from 'rxjs';
1819
import { mergeMap } from 'rxjs/operators';
@@ -220,7 +221,6 @@ export abstract class FileSystemEngineHostBase implements
220221
throw new FactoryCannotBeResolvedException(name);
221222
}
222223

223-
const { path } = resolvedRef;
224224
let schema = partialDesc.schema;
225225
let schemaJson: JsonObject | undefined = undefined;
226226
if (schema) {
@@ -230,6 +230,15 @@ export abstract class FileSystemEngineHostBase implements
230230
schemaJson = readJsonFile(schema) as JsonObject;
231231
}
232232

233+
// The schematic path is used to resolve URLs.
234+
// We should be able to just do `dirname(resolvedRef.path)` but for compatibility with
235+
// Bazel under Windows this directory needs to be resolved from the collection instead.
236+
// This is needed because on Bazel under Windows the data files (such as the collection or
237+
// url files) are not in the same place as the compiled JS.
238+
const maybePath = join(collectionPath, partialDesc.factory);
239+
const path = existsSync(maybePath) && statSync(maybePath).isDirectory()
240+
? maybePath : dirname(maybePath);
241+
233242
return this._transformSchematicDescription(name, collection, {
234243
...partialDesc,
235244
schema,
@@ -248,9 +257,7 @@ export abstract class FileSystemEngineHostBase implements
248257
return (context: FileSystemSchematicContext) => {
249258
// Resolve all file:///a/b/c/d from the schematic's own path, and not the current
250259
// path.
251-
const root = normalize(
252-
resolve(dirname(context.schematic.description.path), url.path || ''),
253-
);
260+
const root = normalize(resolve(context.schematic.description.path, url.path || ''));
254261

255262
return new HostCreateTree(new virtualFs.ScopedHost(new NodeJsSyncHost(), root));
256263
};

packages/angular_devkit/schematics/tools/file-system-engine-host.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,22 @@ export class FileSystemEngineHost extends FileSystemEngineHostBase {
2626
constructor(protected _root: string) { super(); }
2727

2828
protected _resolveCollectionPath(name: string): string {
29-
// Allow `${_root}/${name}.json` as a collection.
30-
if (existsSync(join(this._root, name + '.json'))) {
31-
return join(this._root, name + '.json');
32-
}
29+
try {
30+
// Allow `${_root}/${name}.json` as a collection.
31+
const maybePath = require.resolve(join(this._root, name + '.json'));
32+
if (existsSync(maybePath)) {
33+
return maybePath;
34+
}
35+
} catch (error) { }
36+
37+
try {
38+
// Allow `${_root}/${name}/collection.json.
39+
const maybePath = require.resolve(join(this._root, name, 'collection.json'));
40+
if (existsSync(maybePath)) {
41+
return maybePath;
42+
}
43+
} catch (error) { }
3344

34-
// Allow `${_root}/${name}/collection.json.
35-
if (existsSync(join(this._root, name, 'collection.json'))) {
36-
return join(this._root, name, 'collection.json');
37-
}
3845

3946
throw new CollectionCannotBeResolvedException(name);
4047
}

packages/angular_devkit/schematics/tools/file-system-engine-host_spec.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@ import { of as observableOf } from 'rxjs';
1414

1515

1616
describe('FileSystemEngineHost', () => {
17-
const devkitRoot = (global as any)._DevKitRoot;
18-
const root = path.join(
19-
devkitRoot,
20-
'tests/angular_devkit/schematics/tools/file-system-engine-host',
21-
);
17+
// We need to resolve a file that actually exists, and not just a folder.
18+
// tslint:disable-next-line:max-line-length
19+
const root = path.join(path.dirname(require.resolve(__filename)), '../../../../tests/angular_devkit/schematics/tools/file-system-engine-host');
2220

2321
it('works', () => {
2422
const engineHost = new FileSystemEngineHost(root);

packages/schematics/angular/app-shell/index_spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
9-
import * as path from 'path';
109
import { Schema as ApplicationOptions } from '../application/schema';
1110
import { Schema as WorkspaceOptions } from '../workspace/schema';
1211
import { Schema as AppShellOptions } from './schema';
@@ -15,7 +14,7 @@ import { Schema as AppShellOptions } from './schema';
1514
describe('App Shell Schematic', () => {
1615
const schematicRunner = new SchematicTestRunner(
1716
'@schematics/angular',
18-
path.join(__dirname, '../collection.json'),
17+
require.resolve('../collection.json'),
1918
);
2019
const defaultOptions: AppShellOptions = {
2120
name: 'foo',

packages/schematics/angular/application/index_spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
*/
88
// tslint:disable:no-big-function
99
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
10-
import * as path from 'path';
1110
import { latestVersions } from '../utility/latest-versions';
1211
import { Schema as WorkspaceOptions } from '../workspace/schema';
1312
import { Schema as ApplicationOptions } from './schema';
@@ -16,7 +15,7 @@ import { Schema as ApplicationOptions } from './schema';
1615
describe('Application Schematic', () => {
1716
const schematicRunner = new SchematicTestRunner(
1817
'@schematics/angular',
19-
path.join(__dirname, '../collection.json'),
18+
require.resolve('../collection.json'),
2019
);
2120

2221
const workspaceOptions: WorkspaceOptions = {

packages/schematics/angular/class/index_spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
9-
import * as path from 'path';
109
import { Schema as ApplicationOptions } from '../application/schema';
1110
import { Schema as WorkspaceOptions } from '../workspace/schema';
1211
import { Schema as ClassOptions } from './schema';
@@ -15,7 +14,7 @@ import { Schema as ClassOptions } from './schema';
1514
describe('Class Schematic', () => {
1615
const schematicRunner = new SchematicTestRunner(
1716
'@schematics/angular',
18-
path.join(__dirname, '../collection.json'),
17+
require.resolve('../collection.json'),
1918
);
2019
const defaultOptions: ClassOptions = {
2120
name: 'foo',

packages/schematics/angular/component/index_spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
*/
88
// tslint:disable:no-big-function
99
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
10-
import * as path from 'path';
1110
import { Schema as ApplicationOptions } from '../application/schema';
1211
import { createAppModule } from '../utility/test';
1312
import { Schema as WorkspaceOptions } from '../workspace/schema';
@@ -17,7 +16,7 @@ import { Schema as ComponentOptions } from './schema';
1716
describe('Component Schematic', () => {
1817
const schematicRunner = new SchematicTestRunner(
1918
'@schematics/angular',
20-
path.join(__dirname, '../collection.json'),
19+
require.resolve('../collection.json'),
2120
);
2221
const defaultOptions: ComponentOptions = {
2322
name: 'foo',

packages/schematics/angular/directive/index_spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
9-
import * as path from 'path';
109
import { Schema as ApplicationOptions } from '../application/schema';
1110
import { Schema as WorkspaceOptions } from '../workspace/schema';
1211
import { Schema as DirectiveOptions } from './schema';
@@ -15,7 +14,7 @@ import { Schema as DirectiveOptions } from './schema';
1514
describe('Directive Schematic', () => {
1615
const schematicRunner = new SchematicTestRunner(
1716
'@schematics/angular',
18-
path.join(__dirname, '../collection.json'),
17+
require.resolve('../collection.json'),
1918
);
2019
const defaultOptions: DirectiveOptions = {
2120
name: 'foo',

packages/schematics/angular/e2e/index_spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
9-
import * as path from 'path';
109
import { Schema as WorkspaceOptions } from '../workspace/schema';
1110
import { Schema as E2eOptions } from './schema';
1211

1312
// tslint:disable:max-line-length
1413
describe('Application Schematic', () => {
1514
const schematicRunner = new SchematicTestRunner(
1615
'@schematics/angular',
17-
path.join(__dirname, '../collection.json'),
16+
require.resolve('../collection.json'),
1817
);
1918

2019
const workspaceOptions: WorkspaceOptions = {

packages/schematics/angular/enum/index_spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
9-
import * as path from 'path';
109
import { Schema as ApplicationOptions } from '../application/schema';
1110
import { Schema as WorkspaceOptions } from '../workspace/schema';
1211
import { Schema as EnumOptions } from './schema';
@@ -15,7 +14,7 @@ import { Schema as EnumOptions } from './schema';
1514
describe('Enum Schematic', () => {
1615
const schematicRunner = new SchematicTestRunner(
1716
'@schematics/angular',
18-
path.join(__dirname, '../collection.json'),
17+
require.resolve('../collection.json'),
1918
);
2019
const defaultOptions: EnumOptions = {
2120
name: 'foo',

packages/schematics/angular/guard/index_spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
9-
import * as path from 'path';
109
import { Schema as ApplicationOptions } from '../application/schema';
1110
import { Schema as WorkspaceOptions } from '../workspace/schema';
1211
import { Schema as GuardOptions } from './schema';
@@ -15,7 +14,7 @@ import { Schema as GuardOptions } from './schema';
1514
describe('Guard Schematic', () => {
1615
const schematicRunner = new SchematicTestRunner(
1716
'@schematics/angular',
18-
path.join(__dirname, '../collection.json'),
17+
require.resolve('../collection.json'),
1918
);
2019
const defaultOptions: GuardOptions = {
2120
name: 'foo',

0 commit comments

Comments
 (0)