Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(core): all graph nodes should have targets block, even if its empty #18625

Merged
merged 1 commit into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions packages/nx/plugins/package-json-workspaces.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import * as memfs from 'memfs';

import '../src/utils/testing/mock-fs';
import { getNxPackageJsonWorkspacesPlugin } from './package-json-workspaces';

describe('nx package.json workspaces plugin', () => {
it('should build projects from package.json files', () => {
memfs.vol.fromJSON(
{
'package.json': JSON.stringify({
name: 'root',
scripts: { echo: 'echo root project' },
}),
'packages/lib-a/package.json': JSON.stringify({
name: 'lib-a',
scripts: { test: 'jest' },
}),
},
'/root'
);

const plugin = getNxPackageJsonWorkspacesPlugin('/root');

// Targets from package.json files are handled outside of `createNodes`,
// because they are recognized even if the package.json file is not included
// in the package manager workspaces configuration.
//
// If any project has a package.json file in its root directory, those scripts
// are targets regardless of this plugin. As such, all we have to do here is identify
// that the package.json represents an Nx project, and `normalizeProjectNodes`
// will handle the rest.
expect(plugin.createNodes[1]('package.json', null)).toMatchInlineSnapshot(`
{
"projects": {
"root": {
"name": "root",
"projectType": "library",
"root": ".",
"sourceRoot": ".",
},
},
}
`);
expect(plugin.createNodes[1]('packages/lib-a/package.json', null))
.toMatchInlineSnapshot(`
{
"projects": {
"lib-a": {
"name": "lib-a",
"projectType": "library",
"root": "packages/lib-a",
"sourceRoot": "packages/lib-a",
},
},
}
`);
});
});
55 changes: 55 additions & 0 deletions packages/nx/plugins/project-json.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import * as memfs from 'memfs';

import '../src/utils/testing/mock-fs';
import { getNxProjectJsonPlugin } from './project-json';

describe('nx project.json plugin', () => {
it('should build projects from project.json', () => {
memfs.vol.fromJSON(
{
'project.json': JSON.stringify({
name: 'root',
targets: { command: 'echo root project' },
}),
'packages/lib-a/project.json': JSON.stringify({
name: 'lib-a',
targets: {
executor: 'nx:run-commands',
options: {},
},
}),
},
'/root'
);

const plugin = getNxProjectJsonPlugin('/root');
expect(plugin.createNodes[1]('project.json', null)).toMatchInlineSnapshot(`
{
"projects": {
"root": {
"name": "root",
"root": ".",
"targets": {
"command": "echo root project",
},
},
},
}
`);
expect(plugin.createNodes[1]('packages/lib-a/project.json', null))
.toMatchInlineSnapshot(`
{
"projects": {
"lib-a": {
"name": "lib-a",
"root": "packages/lib-a",
"targets": {
"executor": "nx:run-commands",
"options": {},
},
},
},
}
`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,18 @@ export function normalizeProjectTargets(
targetDefaults: NxJsonConfiguration['targetDefaults'],
projectName: string
): Record<string, TargetConfiguration> {
const targets = project.targets;
// Any node on the graph will have a targets object, it just may be empty
const targets = project.targets ?? {};

for (const target in targets) {
// We need to know the executor for use in readTargetDefaultsForTarget,
// but we haven't resolved the `command` syntactic sugar yet.
const executor =
targets[target].executor ?? targets[target].command
? 'nx:run-commands'
: null;

// Allows things like { targetDefaults: { build: { command: tsc } } }
const defaults = resolveCommandSyntacticSugar(
readTargetDefaultsForTarget(target, targetDefaults, executor),
`targetDefaults:${target}`
Expand Down