diff --git a/.all-contributorsrc b/.all-contributorsrc index 5e4d8160..0338258a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -97,6 +97,16 @@ "contributions": [ "code" ] + }, + { + "login": "tzuge", + "name": "tzuge", + "avatar_url": "https://avatars.githubusercontent.com/u/47162374?v=4", + "profile": "https://github.com/tzuge", + "contributions": [ + "code", + "design" + ] } ], "contributorsPerLine": 7, diff --git a/CHANGELOG.md b/CHANGELOG.md index 06e5fdc8..59e75608 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# [1.14.0](https://github.com/nx-dotnet/nx-dotnet/compare/v1.13.4...v1.14.0) (2022-10-05) + +### Features + +- **core:** adding templates with default output path properties to init generator ([#526](https://github.com/nx-dotnet/nx-dotnet/issues/526)) ([c57fbd3](https://github.com/nx-dotnet/nx-dotnet/commit/c57fbd33dec87fe882617a8b39bc11e91d937615)) + ## [1.13.4](https://github.com/nx-dotnet/nx-dotnet/compare/v1.13.3...v1.13.4) (2022-09-07) ### Bug Fixes diff --git a/README.md b/README.md index 43f44304..033d0ae5 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,7 @@ # NxDotnet - -[![All Contributors](https://img.shields.io/badge/all_contributors-9-orange.svg?style=flat-square)](#contributors-) - +[![All Contributors](https://img.shields.io/badge/all_contributors-10-orange.svg?style=flat-square)](#contributors-) [![Join the chat at https://gitter.im/nx-dotnet-plugin/community](https://badges.gitter.im/nx-dotnet-plugin/community.svg)](https://gitter.im/nx-dotnet-plugin/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Run CI checks](https://github.com/nx-dotnet/nx-dotnet/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/nx-dotnet/nx-dotnet/actions/workflows/main.yml) @@ -96,19 +94,22 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d - - - - - - - - - - - - - + + + + + + + + + + + + + + + +

Craigory Coppola

💻 🎨 🤔

Ben Callaghan

💻 🎨 📓

Jordan Hall

💻 🎨 🤔

Lars Gyrup Brink Nielsen

📖 📓 🐛 📝 📹

Leon Chi

💻

Tom Davis

💻

Pedro Rodrigues

💻

Paulo Oliveira

📖 💻 🐛

dasco144

💻

Craigory Coppola

💻 🎨 🤔

Ben Callaghan

💻 🎨 📓

Jordan Hall

💻 🎨 🤔

Lars Gyrup Brink Nielsen

📖 📓 🐛 📝 📹

Leon Chi

💻

Tom Davis

💻

Pedro Rodrigues

💻

Paulo Oliveira

📖 💻 🐛

dasco144

💻

tzuge

💻 🎨
diff --git a/docs/core/generators/application.md b/docs/core/generators/application.md index 3d125124..68d0101c 100644 --- a/docs/core/generators/application.md +++ b/docs/core/generators/application.md @@ -30,10 +30,6 @@ Generate a dotnet project under the application directory. - (string): Which template should be used for creating the tests project? -### skipOutputPathManipulation - -- (boolean): Skip XML changes for default build path - ### standalone - (boolean): Should the project use project.json? If false, the project config is inside workspace.json diff --git a/docs/core/generators/test.md b/docs/core/generators/test.md index c892bdde..22140d31 100644 --- a/docs/core/generators/test.md +++ b/docs/core/generators/test.md @@ -22,10 +22,6 @@ Generate a .NET test project for an existing application or library - (string): What suffix should be used for the tests project name? -### skipOutputPathManipulation - -- (boolean): Skip XML changes for default build path - ### standalone - (boolean): Should the project use project.json? If false, the project config is inside workspace.json diff --git a/e2e/core-e2e/tests/nx-dotnet.spec.ts b/e2e/core-e2e/tests/nx-dotnet.spec.ts index 38f2a4bc..003616a5 100644 --- a/e2e/core-e2e/tests/nx-dotnet.spec.ts +++ b/e2e/core-e2e/tests/nx-dotnet.spec.ts @@ -17,16 +17,14 @@ import { } from '@nrwl/nx-plugin/testing'; import { runCommandUntil } from '../../utils'; -import { readFileSync, unlinkSync, writeFileSync } from 'fs'; +import { unlinkSync, writeFileSync } from 'fs'; import { join } from 'path'; import { XmlDocument } from 'xmldoc'; -import { findProjectFileInPathSync } from '@nx-dotnet/utils'; import { readDependenciesFromNxDepGraph } from '@nx-dotnet/utils/e2e'; import { exec, execSync } from 'child_process'; import { ensureDirSync } from 'fs-extra'; import { Workspaces } from '@nrwl/tao/src/shared/workspace'; -import { PackageJson } from 'nx/src/utils/package-json'; const e2eDir = tmpProjPath(); @@ -36,6 +34,14 @@ describe('nx-dotnet e2e', () => { initializeGitRepo(e2eDir); }, 1500000); + it('should initialize workspace build customization', async () => { + await runNxCommandAsync(`generate @nx-dotnet/core:init`); + + expect(() => + checkFilesExist('Directory.Build.props', 'Directory.Build.targets'), + ).not.toThrow(); + }); + it('should create apps, libs, and project references', async () => { const testApp = uniq('app'); const testLib = uniq('lib'); @@ -145,22 +151,6 @@ describe('nx-dotnet e2e', () => { expect(() => checkFilesExist(`dist/libs/${lib}`)).not.toThrow(); }); - it('should update output paths', async () => { - const app = uniq('app'); - await runNxCommandAsync( - `generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --skip-swagger-lib`, - ); - const configFilePath = findProjectFileInPathSync( - join(e2eDir, 'apps', app), - ); - const config = readFileSync(configFilePath).toString(); - const projectXml = new XmlDocument(config); - const outputPath = projectXml - .childNamed('PropertyGroup') - ?.childNamed('OutputPath')?.val as string; - expect(outputPath).toBeTruthy(); - }); - it('should lint', async () => { const app = uniq('app'); await runNxCommandAsync( diff --git a/package.json b/package.json index aed09419..0ce4677c 100644 --- a/package.json +++ b/package.json @@ -118,5 +118,5 @@ "type": "git", "url": "https://github.com/nx-dotnet/nx-dotnet.git" }, - "version": "1.13.4" + "version": "1.14.0" } diff --git a/packages/core/package.json b/packages/core/package.json index 36e45643..2a8243bd 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -41,5 +41,5 @@ "@nx-dotnet/dotnet" ] }, - "version": "1.13.4" + "version": "1.14.0" } diff --git a/packages/core/src/generators/app/generator.spec.ts b/packages/core/src/generators/app/generator.spec.ts index 18d75828..1057e93e 100644 --- a/packages/core/src/generators/app/generator.spec.ts +++ b/packages/core/src/generators/app/generator.spec.ts @@ -18,7 +18,6 @@ describe('nx-dotnet app generator', () => { language: 'C#', template: 'webapi', testTemplate: 'none', - skipOutputPathManipulation: false, projectType: 'application', standalone: false, skipSwaggerLib: true, diff --git a/packages/core/src/generators/app/schema.json b/packages/core/src/generators/app/schema.json index e4bd96f0..58816af5 100644 --- a/packages/core/src/generators/app/schema.json +++ b/packages/core/src/generators/app/schema.json @@ -55,11 +55,6 @@ ] } }, - "skipOutputPathManipulation": { - "type": "boolean", - "description": "Skip XML changes for default build path", - "default": false - }, "standalone": { "type": "boolean", "description": "Should the project use project.json? If false, the project config is inside workspace.json" diff --git a/packages/core/src/generators/import-projects/generator.spec.ts b/packages/core/src/generators/import-projects/generator.spec.ts index f495f654..e210c3b3 100644 --- a/packages/core/src/generators/import-projects/generator.spec.ts +++ b/packages/core/src/generators/import-projects/generator.spec.ts @@ -3,8 +3,10 @@ import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import * as fs from 'fs'; +import { DotNetClient, mockDotnetFactory } from '@nx-dotnet/dotnet'; import * as utils from '@nx-dotnet/utils'; +import * as mockedInitGenerator from '../init/generator'; import generator from './generator'; jest.mock('@nx-dotnet/utils', () => ({ @@ -34,20 +36,28 @@ const MOCK_TEST_PROJECT = ` `; +jest.mock('../init/generator', () => ({ + initGenerator: jest.fn(() => { + return Promise.resolve(jest.fn(() => Promise.resolve())); + }), +})); + describe('import-projects generator', () => { let appTree: Tree; + let dotnetClient: DotNetClient; beforeEach(() => { appTree = createTreeWithEmptyWorkspace(); + dotnetClient = new DotNetClient(mockDotnetFactory()); }); afterEach(() => { - jest.resetAllMocks(); + jest.clearAllMocks(); }); it('should run successfully if no new projects are found', async () => { jest.spyOn(utils, 'glob').mockResolvedValue([]); - const promise = generator(appTree); + const promise = generator(appTree, dotnetClient); const oldProjects = getProjects(appTree); await expect(promise).resolves.not.toThrow(); const newProjects = getProjects(appTree); @@ -72,7 +82,7 @@ describe('import-projects generator', () => { jest.spyOn(fs, 'readFileSync').mockReturnValue(MOCK_TEST_PROJECT); jest.spyOn(fs, 'writeFileSync').mockImplementation(() => null); appTree.write('apps/my-api/my-api.csproj', MOCK_API_PROJECT); - const promise = generator(appTree); + const promise = generator(appTree, dotnetClient); await expect(promise).resolves.not.toThrow(); expect(readProjectConfiguration(appTree, 'my-test-api')).toBeDefined(); }); @@ -95,7 +105,7 @@ describe('import-projects generator', () => { jest.spyOn(fs, 'readFileSync').mockReturnValue(MOCK_TEST_PROJECT); jest.spyOn(fs, 'writeFileSync').mockImplementation(() => null); appTree.write('apps/my-api-test/my-api-test.csproj', MOCK_TEST_PROJECT); - const promise = generator(appTree); + const promise = generator(appTree, dotnetClient); await expect(promise).resolves.not.toThrow(); expect(readProjectConfiguration(appTree, 'my-test-api-test')).toBeDefined(); expect( @@ -105,4 +115,14 @@ describe('import-projects generator', () => { readProjectConfiguration(appTree, 'my-test-api-test').targets?.serve, ).not.toBeDefined(); }); + + it('should call init generator', async () => { + const initGenerator = ( + mockedInitGenerator as jest.Mocked + ).initGenerator; + + jest.spyOn(utils, 'glob').mockResolvedValue([]); + await generator(appTree, dotnetClient); + expect(initGenerator).toHaveBeenCalledWith(appTree, null, dotnetClient); + }); }); diff --git a/packages/core/src/generators/import-projects/generator.ts b/packages/core/src/generators/import-projects/generator.ts index 44242f99..ccb259ef 100644 --- a/packages/core/src/generators/import-projects/generator.ts +++ b/packages/core/src/generators/import-projects/generator.ts @@ -13,6 +13,7 @@ import { import { basename, dirname } from 'path'; import { XmlDocument } from 'xmldoc'; +import { DotNetClient, dotnetFactory } from '@nx-dotnet/dotnet'; import { glob, iterateChildrenByPath, projPattern } from '@nx-dotnet/utils'; import { @@ -21,9 +22,14 @@ import { GetServeExecutorConfig, GetTestExecutorConfig, } from '../../models'; -import { manipulateXmlProjectFile } from '../utils/generate-project'; +import { initGenerator } from '../init/generator'; + +export default async function ( + host: Tree, + dotnetClient = new DotNetClient(dotnetFactory()), +) { + const installTask = await initGenerator(host, null, dotnetClient); -export default async function (host: Tree) { const projectFiles = await getProjectFilesInWorkspace(host); const existingProjectRoots = Array.from(getProjects(host).values()).map( (x) => x.root, @@ -40,7 +46,10 @@ export default async function (host: Tree) { logger.log('Found new application', projectFile); } } - return formatFiles(host); + return async () => { + await installTask(); + await formatFiles(host); + }; } async function addNewDotnetProject( @@ -71,10 +80,6 @@ async function addNewDotnetProject( configuration.targets.test = GetTestExecutorConfig(); } addProjectConfiguration(host, projectName, configuration); - await manipulateXmlProjectFile(host, { - projectName, - projectRoot, - }); } async function getProjectFilesInWorkspace(host: Tree) { diff --git a/packages/core/src/generators/init/generator.spec.ts b/packages/core/src/generators/init/generator.spec.ts index a6b41542..b9af9710 100644 --- a/packages/core/src/generators/init/generator.spec.ts +++ b/packages/core/src/generators/init/generator.spec.ts @@ -1,3 +1,4 @@ +import * as devkit from '@nrwl/devkit'; import { readJson, Tree, writeJson } from '@nrwl/devkit'; import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; @@ -6,6 +7,11 @@ import { CONFIG_FILE_PATH, NxDotnetConfig } from '@nx-dotnet/utils'; import generator from './generator'; +jest.mock('@nx-dotnet/utils', () => ({ + ...jest.requireActual('@nx-dotnet/utils'), + resolve: jest.fn(() => 'check-module-boundaries.js'), +})); + describe('init generator', () => { let appTree: Tree; let dotnetClient: DotNetClient; @@ -77,4 +83,27 @@ describe('init generator', () => { 'npm run clean && npm run build && nx g @nx-dotnet/core:restore', ); }); + + it('should add directory build props and targets files', async () => { + await generator(appTree, null, dotnetClient); + const hasPropsFile = appTree.isFile('Directory.Build.props'); + expect(hasPropsFile).toBeTruthy(); + + const hasTargetsFile = appTree.isFile('Directory.Build.targets'); + expect(hasTargetsFile).toBeTruthy(); + const hasPreBuildTask = appTree + .read('Directory.Build.targets', 'utf-8') + ?.includes('check-module-boundaries.js'); + expect(hasPreBuildTask).toBeTruthy(); + }); + + it('should not add directory build props and targets files if props file exists', async () => { + appTree.write('Directory.Build.props', ''); + const spy = jest.spyOn(devkit, 'generateFiles'); + await generator(appTree, null, dotnetClient); + + expect(spy).not.toHaveBeenCalled(); + const hasTargetsFile = appTree.isFile('Directory.Build.targets'); + expect(hasTargetsFile).toBeFalsy(); + }); }); diff --git a/packages/core/src/generators/init/generator.ts b/packages/core/src/generators/init/generator.ts index 0ff2ebbd..ac09af7c 100644 --- a/packages/core/src/generators/init/generator.ts +++ b/packages/core/src/generators/init/generator.ts @@ -1,5 +1,6 @@ import { addDependenciesToPackageJson, + generateFiles, GeneratorCallback, logger, NxJsonConfiguration, @@ -11,8 +12,15 @@ import { } from '@nrwl/devkit'; import { DotNetClient, dotnetFactory } from '@nx-dotnet/dotnet'; -import { CONFIG_FILE_PATH, isDryRun, NxDotnetConfig } from '@nx-dotnet/utils'; +import { + CONFIG_FILE_PATH, + isDryRun, + NxDotnetConfig, + resolve, +} from '@nx-dotnet/utils'; import type { PackageJson } from 'nx/src/utils/package-json'; +import * as path from 'path'; +import { normalize, relative } from 'path'; export async function initGenerator( host: Tree, @@ -42,6 +50,8 @@ export async function initGenerator( initToolManifest(host, dotnetClient); + initBuildCustomization(host); + return async () => { for (const task of tasks) { await task(); @@ -119,3 +129,20 @@ function addPrepareScript(host: Tree) { packageJson.scripts.prepare = prepareSteps.join(' && '); writeJson(host, 'package.json', packageJson); } + +function initBuildCustomization(host: Tree) { + const initialized = host.exists('Directory.Build.props'); + if (!initialized) { + const checkModuleBoundariesScriptPath = normalize( + relative( + host.root, + resolve('@nx-dotnet/core/src/tasks/check-module-boundaries'), + ), + ); + + generateFiles(host, path.join(__dirname, 'templates/root'), '.', { + tmpl: '', + checkModuleBoundariesScriptPath, + }); + } +} diff --git a/packages/core/src/generators/init/templates/root/Directory.Build.props__tmpl__ b/packages/core/src/generators/init/templates/root/Directory.Build.props__tmpl__ new file mode 100644 index 00000000..f3ba3896 --- /dev/null +++ b/packages/core/src/generators/init/templates/root/Directory.Build.props__tmpl__ @@ -0,0 +1,17 @@ + + + + + $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)')) + $([System.IO.Path]::GetRelativePath($(RepoRoot), $(MSBuildProjectDirectory))) + $(RepoRoot)dist/$(ProjectRelativePath) + $(BaseOutputPath) + true + + + false + + diff --git a/packages/core/src/generators/init/templates/root/Directory.Build.targets__tmpl__ b/packages/core/src/generators/init/templates/root/Directory.Build.targets__tmpl__ new file mode 100644 index 00000000..8418d767 --- /dev/null +++ b/packages/core/src/generators/init/templates/root/Directory.Build.targets__tmpl__ @@ -0,0 +1,13 @@ + + + + $([System.IO.Path]::GetRelativePath($(RepoRoot), $(MSBuildProjectDirectory))) + $([System.IO.Path]::GetRelativePath($(MSBuildProjectDirectory), $(RepoRoot))) + + + + + diff --git a/packages/core/src/generators/lib/generator.spec.ts b/packages/core/src/generators/lib/generator.spec.ts index eea48efc..cf4c5754 100644 --- a/packages/core/src/generators/lib/generator.spec.ts +++ b/packages/core/src/generators/lib/generator.spec.ts @@ -18,7 +18,6 @@ describe('nx-dotnet library generator', () => { language: 'C#', template: 'classlib', testTemplate: 'none', - skipOutputPathManipulation: true, standalone: false, projectType: 'library', skipSwaggerLib: true, diff --git a/packages/core/src/generators/test/generator.spec.ts b/packages/core/src/generators/test/generator.spec.ts index 5470a64f..8e2ff9ce 100644 --- a/packages/core/src/generators/test/generator.spec.ts +++ b/packages/core/src/generators/test/generator.spec.ts @@ -17,7 +17,6 @@ describe('nx-dotnet test generator', () => { name: 'existing', testTemplate: 'xunit', language: 'C#', - skipOutputPathManipulation: true, standalone: false, pathScheme: 'nx', }; diff --git a/packages/core/src/generators/test/generator.ts b/packages/core/src/generators/test/generator.ts index 17fe56e6..602899d0 100644 --- a/packages/core/src/generators/test/generator.ts +++ b/packages/core/src/generators/test/generator.ts @@ -25,7 +25,6 @@ export default async function ( testProjectNameSuffix: options.suffix, name, language: options.language, - skipOutputPathManipulation: options.skipOutputPathManipulation, testTemplate: options.testTemplate, directory, tags: project.tags?.join(','), diff --git a/packages/core/src/generators/test/schema.json b/packages/core/src/generators/test/schema.json index bfbfbb36..49101439 100644 --- a/packages/core/src/generators/test/schema.json +++ b/packages/core/src/generators/test/schema.json @@ -50,11 +50,6 @@ "type": "string" } }, - "skipOutputPathManipulation": { - "type": "boolean", - "description": "Skip XML changes for default build path", - "default": false - }, "standalone": { "type": "boolean", "description": "Should the project use project.json? If false, the project config is inside workspace.json" diff --git a/packages/core/src/generators/utils/generate-project.spec.ts b/packages/core/src/generators/utils/generate-project.spec.ts index b2a498b1..b9d4943c 100644 --- a/packages/core/src/generators/utils/generate-project.spec.ts +++ b/packages/core/src/generators/utils/generate-project.spec.ts @@ -7,10 +7,18 @@ import { DotNetClient, mockDotnetFactory } from '@nx-dotnet/dotnet'; import { NxDotnetProjectGeneratorSchema } from '../../models'; import { GenerateProject } from './generate-project'; +import * as mockedGenerateTestProject from './generate-test-project'; // eslint-disable-next-line @typescript-eslint/no-empty-function jest.spyOn(console, 'log').mockImplementation(() => {}); +jest.mock('@nx-dotnet/utils', () => ({ + ...jest.requireActual('@nx-dotnet/utils'), + resolve: jest.fn(() => 'check-module-boundaries.js'), +})); + +jest.mock('./generate-test-project'); + describe('nx-dotnet project generator', () => { let appTree: Tree; let dotnetClient: DotNetClient; @@ -28,7 +36,6 @@ describe('nx-dotnet project generator', () => { language: 'C#', template: 'classlib', testTemplate: 'none', - skipOutputPathManipulation: true, standalone: false, skipSwaggerLib: true, projectType: 'application', @@ -92,10 +99,19 @@ describe('nx-dotnet project generator', () => { }); it('should generate test project', async () => { + const generateTestProject = ( + mockedGenerateTestProject as jest.Mocked + ).GenerateTestProject; + options.testTemplate = 'nunit'; await GenerateProject(appTree, options, dotnetClient, 'application'); const config = readProjectConfiguration(appTree, 'test'); expect(config.targets?.serve).toBeDefined(); + expect(generateTestProject).toHaveBeenCalledWith( + appTree, + expect.objectContaining(options), + dotnetClient, + ); }); it('should include lint target', async () => { diff --git a/packages/core/src/generators/utils/generate-project.ts b/packages/core/src/generators/utils/generate-project.ts index 3eb780d8..f3070d62 100644 --- a/packages/core/src/generators/utils/generate-project.ts +++ b/packages/core/src/generators/utils/generate-project.ts @@ -9,12 +9,10 @@ import { ProjectType, readWorkspaceConfiguration, Tree, - workspaceRoot, } from '@nrwl/devkit'; // Files generated via `dotnet` are not available in the virtual fs -import { readFileSync, writeFileSync } from 'fs'; -import { dirname, relative } from 'path'; +import { relative } from 'path'; import { XmlDocument } from 'xmldoc'; import { @@ -22,7 +20,7 @@ import { dotnetNewOptions, KnownDotnetTemplates, } from '@nx-dotnet/dotnet'; -import { findProjectFileInPath, isDryRun, resolve } from '@nx-dotnet/utils'; +import { isDryRun, resolve } from '@nx-dotnet/utils'; import { GetBuildExecutorConfiguration, @@ -160,22 +158,6 @@ function getProjectNameFromSchema( return projectDirectory.replace(/\//g, '-'); } -export async function manipulateXmlProjectFile( - host: Tree, - options: Pick, -): Promise { - const projectFilePath = await findProjectFileInPath(options.projectRoot); - - const xml: XmlDocument = new XmlDocument( - readFileSync(projectFilePath).toString(), - ); - - setOutputPath(xml, options.projectRoot, projectFilePath); - addPrebuildMsbuildTask(host, options, xml); - - writeFileSync(projectFilePath, xml.toString()); -} - export async function GenerateProject( host: Tree, options: NxDotnetProjectGeneratorSchema, @@ -238,10 +220,6 @@ export async function GenerateProject( await GenerateTestProject(host, normalizedOptions, dotnetClient); } - if (!options.skipOutputPathManipulation && !isDryRun()) { - await manipulateXmlProjectFile(host, normalizedOptions); - } - if ( normalizedOptions.projectTemplate === 'webapi' && !normalizedOptions.skipSwaggerLib @@ -259,22 +237,6 @@ export async function GenerateProject( }; } -export function setOutputPath( - xml: XmlDocument, - projectRootPath: string, - projectFilePath: string, -) { - let outputPath = joinPathFragments( - relative(dirname(projectFilePath), workspaceRoot), - 'dist', - projectRootPath, - ); - outputPath = normalizePath(outputPath); // Forward slash works on windows, backslash does not work on mac/linux - - const fragment = new XmlDocument(`${outputPath}`); - xml.childNamed('PropertyGroup')?.children.push(fragment); -} - export function addPrebuildMsbuildTask( host: Tree, options: { projectRoot: string; projectName: string }, diff --git a/packages/core/src/generators/utils/generate-test-project.spec.ts b/packages/core/src/generators/utils/generate-test-project.spec.ts index e2a14603..eb6a5cd3 100644 --- a/packages/core/src/generators/utils/generate-test-project.spec.ts +++ b/packages/core/src/generators/utils/generate-test-project.spec.ts @@ -73,7 +73,6 @@ describe('nx-dotnet test project generator', () => { name: 'domain-existing-app', testTemplate: 'xunit', language: 'C#', - skipOutputPathManipulation: true, standalone: false, projectType: 'application', projectRoot: 'apps/domain/existing-app', diff --git a/packages/core/src/generators/utils/generate-test-project.ts b/packages/core/src/generators/utils/generate-test-project.ts index 27cbb591..1ca73db4 100644 --- a/packages/core/src/generators/utils/generate-test-project.ts +++ b/packages/core/src/generators/utils/generate-test-project.ts @@ -9,11 +9,7 @@ import { GetTestExecutorConfig, } from '../../models'; import { addToSolutionFile } from './add-to-sln'; -import { - manipulateXmlProjectFile, - NormalizedSchema, - normalizeOptions, -} from './generate-project'; +import { NormalizedSchema, normalizeOptions } from './generate-project'; export interface PathParts { suffix: string; separator: '.' | '-'; @@ -76,14 +72,7 @@ export async function GenerateTestProject( dotnetClient.new(schema.testTemplate, newParams); if (!isDryRun()) { addToSolutionFile(host, testRoot, dotnetClient, schema.solutionFile); - } - if (!isDryRun() && !schema.skipOutputPathManipulation) { - await manipulateXmlProjectFile(host, { - ...schema, - projectRoot: testRoot, - projectName: testProjectName, - }); const testCsProj = await findProjectFileInPath(testRoot); const baseCsProj = await findProjectFileInPath(schema.projectRoot); dotnetClient.addProjectReference(testCsProj, baseCsProj); diff --git a/packages/core/src/models/project-generator-schema.ts b/packages/core/src/models/project-generator-schema.ts index 57505afc..1235d47c 100644 --- a/packages/core/src/models/project-generator-schema.ts +++ b/packages/core/src/models/project-generator-schema.ts @@ -11,7 +11,6 @@ export interface NxDotnetProjectGeneratorSchema { language: string; testTemplate: 'nunit' | 'mstest' | 'xunit' | 'none'; testProjectNameSuffix?: string; - skipOutputPathManipulation: boolean; standalone: boolean; projectType?: ProjectType; solutionFile?: string | boolean; diff --git a/packages/core/src/models/test-generator-schema.ts b/packages/core/src/models/test-generator-schema.ts index 7a55ba7a..12375965 100644 --- a/packages/core/src/models/test-generator-schema.ts +++ b/packages/core/src/models/test-generator-schema.ts @@ -3,7 +3,6 @@ export interface NxDotnetTestGeneratorSchema { testTemplate: 'xunit' | 'nunit' | 'mstest'; language: string; suffix?: string; - skipOutputPathManipulation: boolean; standalone: boolean; pathScheme: 'nx' | 'dotnet'; } diff --git a/packages/core/src/tasks/check-module-boundaries.ts b/packages/core/src/tasks/check-module-boundaries.ts index d7968bba..35589e1a 100644 --- a/packages/core/src/tasks/check-module-boundaries.ts +++ b/packages/core/src/tasks/check-module-boundaries.ts @@ -9,7 +9,7 @@ import { import { Workspaces } from '@nrwl/tao/src/shared/workspace'; import { ESLint } from 'eslint'; -import { join } from 'path'; +import { join, relative } from 'path'; import { getDependantProjectsForNxProject, @@ -88,7 +88,7 @@ export async function loadModuleBoundaries( async function main() { const parser = await import('yargs-parser'); - const { project } = parser(process.argv.slice(2), { + const { project, projectRoot } = parser(process.argv.slice(2), { alias: { project: 'p', }, @@ -111,9 +111,30 @@ async function main() { } // End Nx v12 support + let nxProject = project; + // Find the associated nx project for the msbuild project directory. + if (!project && projectRoot) { + // Note that this returns the first matching project and would succeed for multiple (cs|fs...)proj under an nx project path, + // but getProjectFileForNxProject explicitly throws if it's not exactly one. + const [projectName] = + Object.entries(workspaceJson.projects).find(([, projectConfig]) => { + const relativePath = relative(projectConfig.root, projectRoot); + return relativePath?.startsWith('..') === false; + }) || []; + + if (projectName) { + nxProject = projectName; + } else { + console.error( + `Failed to find nx workspace project associated with dotnet project directory: ${projectRoot}`, + ); + process.exit(1); + } + } + console.log(`Checking module boundaries for ${project}`); const violations = await checkModuleBoundariesForProject( - project, + nxProject, workspaceJson, ); if (violations.length) { diff --git a/packages/dotnet/package.json b/packages/dotnet/package.json index 326e406c..7c00bf03 100644 --- a/packages/dotnet/package.json +++ b/packages/dotnet/package.json @@ -20,5 +20,5 @@ "url": "https://github.com/nx-dotnet/nx-dotnet" }, "homepage": "https://nx-dotnet.com/", - "version": "1.13.4" + "version": "1.14.0" } diff --git a/packages/nx-ghpages/package.json b/packages/nx-ghpages/package.json index 0f641e0d..74134660 100644 --- a/packages/nx-ghpages/package.json +++ b/packages/nx-ghpages/package.json @@ -24,5 +24,5 @@ "url": "https://github.com/nx-dotnet/nx-dotnet" }, "homepage": "https://nx-dotnet.com/", - "version": "1.13.4" + "version": "1.14.0" } diff --git a/packages/nxdoc/package.json b/packages/nxdoc/package.json index 0e0ed9f2..dfbe54a4 100644 --- a/packages/nxdoc/package.json +++ b/packages/nxdoc/package.json @@ -24,5 +24,5 @@ "type": "git", "url": "https://github.com/nx-dotnet/nx-dotnet" }, - "version": "1.13.4" + "version": "1.14.0" } diff --git a/packages/utils/package.json b/packages/utils/package.json index 3fadb1d9..aa8dc85b 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -24,5 +24,5 @@ "url": "https://github.com/nx-dotnet/nx-dotnet" }, "homepage": "https://nx-dotnet.com/", - "version": "1.13.4" + "version": "1.14.0" }