Skip to content

Commit f087146

Browse files
authored
fix(misc): make workspace tsc executor to handle dependencies (#6475)
1 parent 1655f4b commit f087146

File tree

2 files changed

+76
-20
lines changed

2 files changed

+76
-20
lines changed

packages/workspace/src/executors/tsc/tsc.impl.spec.ts

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,44 @@
1+
jest.mock('../../core/project-graph');
2+
jest.mock('../../utilities/assets');
3+
jest.mock('../../utilities/buildable-libs-utils');
4+
jest.mock('../../utilities/fileutils');
5+
jest.mock('../../utilities/typescript/compilation');
6+
17
import { ExecutorContext } from '@nrwl/devkit';
28
import { join } from 'path';
39
import { copyAssets } from '../../utilities/assets';
10+
import {
11+
calculateProjectDependencies,
12+
checkDependentProjectsHaveBeenBuilt,
13+
createTmpTsConfig,
14+
} from '../../utilities/buildable-libs-utils';
415
import { readJsonFile, writeJsonFile } from '../../utilities/fileutils';
516
import { compileTypeScript } from '../../utilities/typescript/compilation';
617
import { TypeScriptExecutorOptions } from './schema';
718
import { tscExecutor } from './tsc.impl';
819

9-
const defaultPackageJson = { name: 'workspacelib', version: '0.0.1' };
10-
jest.mock('../../utilities/fileutils', () => ({
11-
...jest.requireActual<any>('../../utilities/fileutils'),
12-
writeJsonFile: jest.fn(),
13-
readJsonFile: jest.fn(() => ({ ...defaultPackageJson })),
14-
}));
15-
const readJsonFileMock = readJsonFile as jest.Mock<any>;
16-
jest.mock('../../utilities/typescript/compilation');
17-
const compileTypeScriptMock = compileTypeScript as jest.Mock<{
18-
success: boolean;
19-
}>;
20-
jest.mock('../../utilities/assets');
21-
2220
describe('executor: tsc', () => {
2321
const assets = ['some-file.md'];
2422
let context: ExecutorContext;
2523
let normalizedOptions: TypeScriptExecutorOptions;
2624
let options: TypeScriptExecutorOptions;
25+
const defaultPackageJson = { name: 'workspacelib', version: '0.0.1' };
26+
const compileTypeScriptMock = compileTypeScript as jest.Mock;
27+
const readJsonFileMock = readJsonFile as jest.Mock;
2728

2829
beforeEach(() => {
30+
jest.clearAllMocks();
31+
32+
(calculateProjectDependencies as jest.Mock).mockImplementation(() => ({
33+
target: { data: { root: 'libs/workspacelib' } },
34+
dependencies: [],
35+
}));
36+
(createTmpTsConfig as jest.Mock).mockImplementation(
37+
() => '/my-app/tsconfig.app.generated.json'
38+
);
39+
(checkDependentProjectsHaveBeenBuilt as jest.Mock).mockReturnValue(true);
40+
readJsonFileMock.mockImplementation(() => ({ ...defaultPackageJson }));
41+
2942
context = {
3043
cwd: '/root',
3144
root: '/root',
@@ -54,8 +67,19 @@ describe('executor: tsc', () => {
5467
outputPath: join(context.root, options.outputPath),
5568
tsConfig: join(context.root, options.tsConfig),
5669
};
70+
});
5771

58-
jest.clearAllMocks();
72+
it('should return { success: false } when dependent projects have not been built', async () => {
73+
(calculateProjectDependencies as jest.Mock).mockImplementation(() => ({
74+
target: { data: { root: 'libs/workspacelib' } },
75+
dependencies: [{}],
76+
}));
77+
(checkDependentProjectsHaveBeenBuilt as jest.Mock).mockReturnValue(false);
78+
79+
const result = await tscExecutor(options, context);
80+
81+
expect(result).toEqual({ success: false });
82+
expect(compileTypeScriptMock).not.toHaveBeenCalled();
5983
});
6084

6185
it('should return typescript compilation result', async () => {

packages/workspace/src/executors/tsc/tsc.impl.ts

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,51 @@
1-
import { ExecutorContext, logger, normalizePath } from '@nrwl/devkit';
1+
import { ExecutorContext, normalizePath } from '@nrwl/devkit';
22
import { basename, dirname, join, relative } from 'path';
3+
import { readCachedProjectGraph } from '../../core/project-graph';
34
import { copyAssets } from '../../utilities/assets';
4-
import { readJsonFile, writeJsonFile } from '../../utilities/fileutils';
55
import {
6-
compileTypeScript,
7-
TypescriptWatchChangeEvent,
8-
} from '../../utilities/typescript/compilation';
6+
calculateProjectDependencies,
7+
checkDependentProjectsHaveBeenBuilt,
8+
createTmpTsConfig,
9+
} from '../../utilities/buildable-libs-utils';
10+
import { readJsonFile, writeJsonFile } from '../../utilities/fileutils';
11+
import { compileTypeScript } from '../../utilities/typescript/compilation';
912
import { TypeScriptExecutorOptions } from './schema';
1013

1114
export async function tscExecutor(
1215
options: TypeScriptExecutorOptions,
1316
context: ExecutorContext
1417
) {
1518
const normalizedOptions = normalizeOptions(options, context);
16-
const projectRoot = context.workspace.projects[context.projectName].root;
19+
// const projectRoot = context.workspace.projects[context.projectName].root;
20+
21+
const projectGraph = readCachedProjectGraph();
22+
const { target, dependencies } = calculateProjectDependencies(
23+
projectGraph,
24+
context.root,
25+
context.projectName,
26+
context.targetName,
27+
context.configurationName
28+
);
29+
const projectRoot = target.data.root;
30+
31+
if (dependencies.length > 0) {
32+
const areDependentProjectsBuilt = checkDependentProjectsHaveBeenBuilt(
33+
context.root,
34+
context.projectName,
35+
context.targetName,
36+
dependencies
37+
);
38+
if (!areDependentProjectsBuilt) {
39+
return { success: false };
40+
}
41+
42+
normalizedOptions.tsConfig = createTmpTsConfig(
43+
join(context.root, options.tsConfig),
44+
context.root,
45+
projectRoot,
46+
dependencies
47+
);
48+
}
1749

1850
// this has to happen first so the folder is created where the assets are copied into
1951
const result = compileTypeScript({

0 commit comments

Comments
 (0)