Skip to content

Commit

Permalink
feat(core): add argument forwarding to dotnet new (#722)
Browse files Browse the repository at this point in the history
  • Loading branch information
Soulusions committed Sep 20, 2023
1 parent 63cf4b4 commit cdc3654
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 7 deletions.
8 changes: 8 additions & 0 deletions docs/core/generators/application.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,11 @@ Generate a dotnet project under the application directory.
### useNxPluginOpenAPI

- (boolean): If using a codegen project, use openapi-generator

### args

- (array): Additional arguments to pass to the dotnet command. For example: "nx g @nx-dotnet/core:app myapp --args='--no-restore'" Arguments can also be appended to the end of the command using '--'. For example, 'nx g @nx-dotnet/core:app myapp -- --no-restore'.

### **unparsed**

- (array):
21 changes: 17 additions & 4 deletions e2e/core-e2e/tests/nx-dotnet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@ import {
uniq,
updateFile,
} from '@nrwl/nx-plugin/testing';
import { runCommandUntil } from '../../utils';
import { Workspaces } from '@nrwl/tao/src/shared/workspace';

import { exec, execSync } from 'child_process';
import { unlinkSync, writeFileSync } from 'fs';
import { ensureDirSync } from 'fs-extra';
import { join } from 'path';
import { XmlDocument } from 'xmldoc';

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 { runCommandUntil } from '../../utils';

const e2eDir = tmpProjPath();

Expand Down Expand Up @@ -117,6 +118,18 @@ describe('nx-dotnet e2e', () => {
).toThrow();
});

it('should generate an app without launchSettings.json', async () => {
const app = uniq('app');
await runNxCommandAsync(
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --args="--exclude-launch-settings=true"`,
);

expect(() => checkFilesExist(`apps/${app}`)).not.toThrow();
expect(() =>
checkFilesExist(`apps/${app}/Properties/launchSettings.json`),
).toThrow();
});

it('should build and test an app', async () => {
const app = uniq('app');
const testProj = `${app}-test`;
Expand Down
20 changes: 20 additions & 0 deletions packages/core/src/generators/app/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,27 @@
"useNxPluginOpenAPI": {
"type": "boolean",
"description": "If using a codegen project, use openapi-generator"
},
"args": {
"type": "array",
"description": "Additional arguments to pass to the dotnet command. For example: \"nx g @nx-dotnet/core:app myapp --args='--no-restore'\" Arguments can also be appended to the end of the command using '--'. For example, 'nx g @nx-dotnet/core:app myapp -- --no-restore'.",
"items": {
"type": "string"
},
"default": []
},
"__unparsed__": {
"hidden": true,
"type": "array",
"items": {
"type": "string"
},
"$default": {
"$source": "unparsed"
},
"x-priority": "internal"
}
},
"additionalProperties": true,
"required": ["name", "language"]
}
17 changes: 16 additions & 1 deletion packages/core/src/generators/utils/generate-project.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import { readProjectConfiguration, Tree, writeJson } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';

import { DotNetClient, mockDotnetFactory } from '@nx-dotnet/dotnet';
import path = require('path');

import { NxDotnetProjectGeneratorSchema } from '../../models';
import { GenerateProject } from './generate-project';
import * as mockedGenerateTestProject from './generate-test-project';

import path = require('path');

// eslint-disable-next-line @typescript-eslint/no-empty-function
jest.spyOn(console, 'log').mockImplementation(() => {});

Expand Down Expand Up @@ -38,6 +39,8 @@ describe('nx-dotnet project generator', () => {
skipSwaggerLib: true,
projectType: 'application',
pathScheme: 'nx',
__unparsed__: [],
args: [],
};

jest.spyOn(dotnetClient, 'listInstalledTemplates').mockReturnValue([
Expand Down Expand Up @@ -126,6 +129,18 @@ describe('nx-dotnet project generator', () => {
expect(nameFlag).toBe('Proj.SubDir.Test');
});

it('should forward args to dotnet new', async () => {
options.__unparsed__ = ['--foo', 'bar'];
options.args = ['--help'];
const spy = jest.spyOn(dotnetClient, 'new');
await GenerateProject(appTree, options, dotnetClient, 'library');
const [, , additionalArguments] = spy.mock.calls[spy.mock.calls.length - 1];
expect(additionalArguments).toEqual(
expect.arrayContaining(['--help', '--foo', 'bar']),
);
expect(additionalArguments).toHaveLength(3);
});

describe('swagger library', () => {
it('should generate swagger backed project', async () => {
options.name = 'api';
Expand Down
16 changes: 15 additions & 1 deletion packages/core/src/generators/utils/generate-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export interface NormalizedSchema
namespaceName: string;
nxProjectName: string;
projectType?: ProjectType;
args: string[];
__unparsed__: string[];
}

export async function normalizeOptions(
Expand All @@ -70,6 +72,8 @@ export async function normalizeOptions(
const template = await getTemplate(options, client);
const namespaceName = getNamespaceFromSchema(host, options, projectDirectory);
const nxProjectName = names(options.name).fileName;
const __unparsed__ = options.__unparsed__ || [];
const args = options.args || [];

return {
...options,
Expand All @@ -83,6 +87,8 @@ export async function normalizeOptions(
projectTemplate: template as KnownDotnetTemplates,
namespaceName,
nxProjectName,
args,
__unparsed__,
projectType: projectType ?? options.projectType ?? 'library',
};
}
Expand Down Expand Up @@ -209,11 +215,19 @@ export async function GenerateProject(
output: normalizedOptions.projectRoot,
};

const additionalArguments = normalizedOptions.args.concat(
normalizedOptions.__unparsed__,
);

if (isDryRun()) {
newParams['dryRun'] = true;
}

dotnetClient.new(normalizedOptions.projectTemplate, newParams);
dotnetClient.new(
normalizedOptions.projectTemplate,
newParams,
additionalArguments,
);
if (!isDryRun()) {
addToSolutionFile(
host,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ describe('nx-dotnet test project generator', () => {
namespaceName: 'Domain.ExistingApp',
nxProjectName: 'domain-existing-app',
pathScheme: 'nx',
args: [],
__unparsed__: [],
};
testProjectName = options.name + '-test';
});
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/models/project-generator-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ export interface NxDotnetProjectGeneratorSchema {
skipSwaggerLib: boolean;
pathScheme: 'nx' | 'dotnet';
useNxPluginOpenAPI?: boolean;
args?: string[];
__unparsed__?: string[];
}
7 changes: 6 additions & 1 deletion packages/dotnet/src/lib/core/dotnet.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,17 @@ import { LoadedCLI } from './dotnet.factory';
export class DotNetClient {
constructor(private cliCommand: LoadedCLI, public cwd?: string) {}

new(template: KnownDotnetTemplates, parameters?: dotnetNewOptions): void {
new(
template: KnownDotnetTemplates,
parameters?: dotnetNewOptions,
additionalArguments?: string[],
): void {
const params = [`new`, template];
if (parameters) {
parameters = swapKeysUsingMap(parameters, newKeyMap);
params.push(...getSpawnParameterArray(parameters));
}
params.push(...(additionalArguments || []));
return this.logAndExecute(params);
}

Expand Down

0 comments on commit cdc3654

Please sign in to comment.