Skip to content

Commit 0e5b73d

Browse files
authored
fix(core): options should be read correctly for project inference (#785)
1 parent eab2d48 commit 0e5b73d

File tree

7 files changed

+90
-40
lines changed

7 files changed

+90
-40
lines changed

packages/core/src/generators/import-projects/generator.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ async function checkIfTestProject(host: Tree, path: string): Promise<boolean> {
118118
});
119119
return isTestProject;
120120
}
121+
121122
function getDirectoriesWithProjectJson(host: Tree) {
122123
const nxProjects = getProjects(host);
123124
const collected: string[] = [];

packages/core/src/generators/init/generator.spec.ts

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import * as devkit from '@nx/devkit';
2-
import { readJson, Tree, writeJson } from '@nx/devkit';
2+
import { readJson, readNxJson, Tree, writeJson } from '@nx/devkit';
33
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
44

55
import { DotNetClient, mockDotnetFactory } from '@nx-dotnet/dotnet';
6-
import { CONFIG_FILE_PATH, NxDotnetConfig } from '@nx-dotnet/utils';
76

87
import generator from './generator';
98

@@ -24,16 +23,42 @@ describe('init generator', () => {
2423
writeJson(tree, 'package.json', packageJson);
2524
});
2625

27-
it('should create config', async () => {
26+
it('should add @nx-dotnet/core to plugins array', async () => {
27+
writeJson(tree, 'nx.json', {});
2828
await generator(tree, null, dotnetClient);
29-
const config = tree.isFile(CONFIG_FILE_PATH);
30-
expect(config).toBeTruthy();
29+
expect(readNxJson(tree)?.plugins).toMatchInlineSnapshot(`
30+
[
31+
"@nx-dotnet/core",
32+
]
33+
`);
3134
});
3235

33-
it('should put dependency array inside config', async () => {
36+
it('should add duplicate @nx-dotnet/core entries to plugins array', async () => {
37+
writeJson(tree, 'nx.json', { plugins: ['@nx-dotnet/core'] });
3438
await generator(tree, null, dotnetClient);
35-
const config: NxDotnetConfig = readJson(tree, CONFIG_FILE_PATH);
36-
expect(config.nugetPackages).toBeDefined();
39+
expect(readNxJson(tree)?.plugins).toMatchInlineSnapshot(`
40+
[
41+
"@nx-dotnet/core",
42+
]
43+
`);
44+
});
45+
46+
it('should add duplicate @nx-dotnet/core entries to plugins array (object)', async () => {
47+
writeJson(tree, 'nx.json', {
48+
plugins: [
49+
{
50+
plugin: '@nx-dotnet/core',
51+
},
52+
],
53+
});
54+
await generator(tree, null, dotnetClient);
55+
expect(readNxJson(tree)?.plugins).toMatchInlineSnapshot(`
56+
[
57+
{
58+
"plugin": "@nx-dotnet/core",
59+
},
60+
]
61+
`);
3762
});
3863

3964
it('should create tool manifest', async () => {

packages/core/src/generators/init/generator.ts

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
Tree,
1010
writeJson,
1111
NX_VERSION,
12+
readNxJson,
1213
} from '@nx/devkit';
1314

1415
import { DotNetClient, dotnetFactory } from '@nx-dotnet/dotnet';
@@ -19,38 +20,47 @@ import {
1920
resolve,
2021
} from '@nx-dotnet/utils';
2122
import * as path from 'path';
23+
import { major } from 'semver';
2224

2325
const noop = () => void 0;
2426

2527
export async function initGenerator(
2628
host: Tree,
27-
_: null, // Nx will populate this with options, which are currently unused.
29+
_: unknown, // Nx will populate this with options, which are currently unused.
2830
dotnetClient = new DotNetClient(dotnetFactory()),
2931
) {
3032
const tasks: GeneratorCallback[] = [];
31-
const initialized = host.isFile(CONFIG_FILE_PATH);
3233

33-
const configObject: NxDotnetConfig = initialized
34-
? readJson(host, CONFIG_FILE_PATH)
35-
: {
36-
nugetPackages: {},
37-
};
34+
// Prior to Nx 17, nx-dotnet had a custom config file.
35+
if (major(NX_VERSION) < 17) {
36+
const configObject: NxDotnetConfig = host.isFile(CONFIG_FILE_PATH)
37+
? readJson(host, CONFIG_FILE_PATH)
38+
: {
39+
nugetPackages: {},
40+
};
3841

39-
configObject.nugetPackages = configObject.nugetPackages || {};
42+
configObject.nugetPackages = configObject.nugetPackages || {};
4043

41-
host.write(CONFIG_FILE_PATH, JSON.stringify(configObject, null, 2));
44+
host.write(CONFIG_FILE_PATH, JSON.stringify(configObject, null, 2));
45+
}
4246

43-
updateNxJson(host);
47+
const nxJson = readNxJson(host);
4448

45-
if (!initialized) {
46-
addPrepareScript(host);
47-
tasks.push(installNpmPackages(host));
48-
}
49+
// Adds a `dotnet restore` operation to the prepare script.
50+
addPrepareScript(host);
51+
52+
// Adds @nx-dotnet/core to nxJson
53+
updateNxJson(host, nxJson);
4954

55+
// Setups up the .config/dotnet-tools.json for managing local .NET tools.
5056
initToolManifest(host, dotnetClient);
5157

58+
// Creates Directory.Build.* to customize default C# builds.
5259
initBuildCustomization(host);
5360

61+
// Adds @nx/js to package.json
62+
tasks.push(installNpmPackages(host));
63+
5464
return async () => {
5565
for (const task of tasks) {
5666
await task();
@@ -74,13 +84,19 @@ function installNpmPackages(host: Tree): GeneratorCallback {
7484
}
7585
}
7686

77-
function updateNxJson(host: Tree) {
78-
const nxJson: NxJsonConfiguration = readJson(host, 'nx.json');
79-
nxJson.plugins = nxJson.plugins || [];
80-
if (!nxJson.plugins.some((x) => x === '@nx-dotnet/core')) {
87+
function hasPluginInNxJson(nxJson: NxJsonConfiguration | null): boolean {
88+
return !!nxJson?.plugins?.some((x) => {
89+
const plugin = typeof x === 'string' ? x : x.plugin;
90+
return plugin === '@nx-dotnet/core';
91+
});
92+
}
93+
94+
function updateNxJson(host: Tree, nxJson: NxJsonConfiguration | null) {
95+
if (nxJson && !hasPluginInNxJson(nxJson)) {
96+
nxJson.plugins = nxJson.plugins || [];
8197
nxJson.plugins.push('@nx-dotnet/core');
98+
writeJson(host, 'nx.json', nxJson);
8299
}
83-
writeJson(host, 'nx.json', nxJson);
84100
}
85101

86102
function initToolManifest(host: Tree, dotnetClient: DotNetClient) {

packages/core/src/generators/nuget-reference/generator.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export default async function (
2727
const projectFilePath = await getProjectFileForNxProject(project);
2828

2929
const config = readConfig(host);
30+
config.nugetPackages ??= {};
3031
const configuredPkgVersion = config.nugetPackages[packageName];
3132
const resolvedVersion = await resolveVersionMismatch(
3233
options.version,

packages/core/src/generators/sync/generator.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { updateDependencyVersions } from '../utils/update-dependency-version';
1515

1616
export default async function (host: Tree) {
1717
const config = readConfig(host);
18+
config.nugetPackages ??= {};
1819
const projects = await getNxDotnetProjects(host);
1920

2021
for (const [projectName, configuration] of projects.entries()) {

packages/core/src/graph/create-nodes.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,7 @@ import {
88
import { readFileSync } from 'fs';
99
import { dirname, resolve } from 'path';
1010

11-
import {
12-
DefaultConfigValues,
13-
NxDotnetConfig,
14-
readConfig,
15-
} from '@nx-dotnet/utils';
11+
import { NxDotnetConfig, readConfig } from '@nx-dotnet/utils';
1612

1713
import {
1814
GetBuildExecutorConfiguration,
@@ -76,9 +72,7 @@ export const createNodes: CreateNodesCompat<NxDotnetConfig> = [
7672
ctxOrOpts: CreateNodesContext | NxDotnetConfig | undefined,
7773
maybeCtx: CreateNodesContext | undefined,
7874
) => {
79-
const options: NxDotnetConfig =
80-
((maybeCtx ? ctxOrOpts : readConfig()) as NxDotnetConfig) ??
81-
DefaultConfigValues;
75+
const options: NxDotnetConfig = readConfig();
8276

8377
if (!options.inferProjects) {
8478
return {};

packages/utils/src/lib/utility-functions/config.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ export const DefaultConfigValues: NxDotnetConfig = {
2323
export function readConfig(host?: Tree): NxDotnetConfig {
2424
const configFromFile = readConfigFromRCFile(host);
2525
const configFromNxJson = readConfigFromNxJson(host);
26-
return {
27-
...DefaultConfigValues,
28-
...configFromFile,
29-
...configFromNxJson,
30-
};
26+
return mergeConfigValues(
27+
DefaultConfigValues,
28+
configFromFile,
29+
configFromNxJson,
30+
);
3131
}
3232

3333
export function updateConfig(host: Tree, value: NxDotnetConfig) {
@@ -112,3 +112,15 @@ export function readConfigFromNxJson(host?: Tree): NxDotnetConfig | null {
112112
return null;
113113
}
114114
}
115+
116+
export function mergeConfigValues(
117+
...configs: (Partial<NxDotnetConfig> | null)[]
118+
): NxDotnetConfig {
119+
return configs.reduce(
120+
(acc, config) => ({
121+
...acc,
122+
...config,
123+
}),
124+
DefaultConfigValues,
125+
) as NxDotnetConfig;
126+
}

0 commit comments

Comments
 (0)