Skip to content

Commit 5a941ae

Browse files
authored
feat(core): update prompt for installed template to present available options (#436)
1 parent 51c74ff commit 5a941ae

File tree

20 files changed

+308
-30
lines changed

20 files changed

+308
-30
lines changed

docs/core/generators/application.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Generate a dotnet project under the application directory.
1818

1919
- (string): A directory where the project is placed
2020

21-
### <span className="required">template</span>
21+
### template
2222

2323
- (string): The template to instantiate when the command is invoked. Each template might have specific options you can pass.
2424

docs/core/generators/library.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Generate a dotnet project under the library directory.
1818

1919
- (string): A directory where the project is placed
2020

21-
### <span className="required">template</span>
21+
### template
2222

2323
- (string): The template to instantiate when the command is invoked. Each template might have specific options you can pass.
2424

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"@types/node": "17.0.18",
6363
"@types/react": "17",
6464
"@types/rimraf": "^3.0.2",
65+
"@types/semver": "^7.3.9",
6566
"@types/tmp": "^0.2.3",
6667
"@types/yargs-parser": "^20.2.1",
6768
"@typescript-eslint/eslint-plugin": "5.12.1",

packages/core/src/generators/app/schema.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@
2727
},
2828
"template": {
2929
"type": "string",
30-
"description": "The template to instantiate when the command is invoked. Each template might have specific options you can pass.",
31-
"x-prompt": "What template should the project be initialized with? (https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new#template-options)"
30+
"description": "The template to instantiate when the command is invoked. Each template might have specific options you can pass."
3231
},
3332
"language": {
3433
"type": "string",
@@ -80,5 +79,5 @@
8079
"aliases": ["solution", "s"]
8180
}
8281
},
83-
"required": ["name", "template", "language"]
82+
"required": ["name", "language"]
8483
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
} from '@nrwl/devkit';
99

1010
import { DotNetClient, dotnetFactory } from '@nx-dotnet/dotnet';
11-
import { CONFIG_FILE_PATH, NxDotnetConfig } from '@nx-dotnet/utils';
11+
import { CONFIG_FILE_PATH, isDryRun, NxDotnetConfig } from '@nx-dotnet/utils';
1212

1313
export async function initGenerator(
1414
host: Tree,
@@ -73,7 +73,7 @@ function updateNxJson(host: Tree) {
7373

7474
function initToolManifest(host: Tree, dotnetClient: DotNetClient) {
7575
const initialized = host.exists('.config/dotnet-tools.json');
76-
if (!initialized) {
76+
if (!initialized && !isDryRun()) {
7777
console.log('Tool Manifest created for managing local .NET tools');
7878
dotnetClient.new('tool-manifest');
7979
}

packages/core/src/generators/lib/schema.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@
2727
},
2828
"template": {
2929
"type": "string",
30-
"description": "The template to instantiate when the command is invoked. Each template might have specific options you can pass.",
31-
"x-prompt": "What template should the project be initialized with? (https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new#template-options)"
30+
"description": "The template to instantiate when the command is invoked. Each template might have specific options you can pass."
3231
},
3332
"language": {
3433
"type": "string",
@@ -74,5 +73,5 @@
7473
"aliases": ["solution", "s"]
7574
}
7675
},
77-
"required": ["name", "template", "language", "testTemplate"]
76+
"required": ["name", "language", "testTemplate"]
7877
}

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { normalizeOptions } from '../utils/generate-project';
77
import { GenerateTestProject } from '../utils/generate-test-project';
88
import { NxDotnetGeneratorSchema } from './schema';
99

10-
export default function (
10+
export default async function (
1111
host: Tree,
1212
options: NxDotnetGeneratorSchema,
1313
dotnetClient = new DotNetClient(dotnetFactory()),
@@ -34,7 +34,10 @@ export default function (
3434
projectType: project.projectType ?? 'library',
3535
};
3636

37-
const normalizedOptions = normalizeOptions(host, projectGeneratorOptions);
37+
const normalizedOptions = await normalizeOptions(
38+
host,
39+
projectGeneratorOptions,
40+
);
3841

3942
return GenerateTestProject(host, normalizedOptions, dotnetClient);
4043
}

packages/core/src/generators/utils/generate-project.spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ describe('nx-dotnet project generator', () => {
3232
standalone: false,
3333
projectType: 'application',
3434
};
35+
36+
jest.spyOn(dotnetClient, 'listInstalledTemplates').mockReturnValue([
37+
{
38+
shortNames: ['classlib'],
39+
templateName: 'Class Library',
40+
languages: ['C#'],
41+
tags: [],
42+
},
43+
]);
3544
});
3645

3746
afterEach(async () => {

packages/core/src/generators/utils/generate-project.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ import { readFileSync, writeFileSync } from 'fs';
1717
import { dirname, relative } from 'path';
1818
import { XmlDocument } from 'xmldoc';
1919

20-
import { DotNetClient, dotnetNewOptions } from '@nx-dotnet/dotnet';
20+
import {
21+
DotNetClient,
22+
dotnetNewOptions,
23+
KnownDotnetTemplates,
24+
} from '@nx-dotnet/dotnet';
2125
import { findProjectFileInPath, isDryRun, resolve } from '@nx-dotnet/utils';
2226

2327
import {
@@ -29,24 +33,27 @@ import {
2933
import initSchematic from '../init/generator';
3034
import { GenerateTestProject } from './generate-test-project';
3135
import { addToSolutionFile } from './add-to-sln';
36+
import { promptForTemplate } from './prompt-for-template';
3237

33-
export interface NormalizedSchema extends NxDotnetProjectGeneratorSchema {
38+
export interface NormalizedSchema
39+
extends Omit<NxDotnetProjectGeneratorSchema, 'template'> {
3440
projectName: string;
3541
projectRoot: string;
3642
projectDirectory: string;
3743
projectLanguage: string;
38-
projectTemplate: string;
44+
projectTemplate: KnownDotnetTemplates;
3945
parsedTags: string[];
4046
className: string;
4147
namespaceName: string;
4248
projectType?: ProjectType;
4349
}
4450

45-
export function normalizeOptions(
51+
export async function normalizeOptions(
4652
host: Tree,
4753
options: NxDotnetProjectGeneratorSchema,
54+
client?: DotNetClient,
4855
projectType?: ProjectType,
49-
): NormalizedSchema {
56+
): Promise<NormalizedSchema> {
5057
const name = names(options.name).fileName;
5158
const className = names(options.name).className;
5259
const projectDirectory = options.directory
@@ -62,6 +69,10 @@ export function normalizeOptions(
6269
? options.tags.split(',').map((s) => s.trim())
6370
: [];
6471

72+
const template = client
73+
? await promptForTemplate(client, options.template, options.language)
74+
: options.template;
75+
6576
const npmScope = names(
6677
readWorkspaceConfiguration(host).npmScope || '',
6778
).className;
@@ -81,7 +92,7 @@ export function normalizeOptions(
8192
projectDirectory,
8293
parsedTags,
8394
projectLanguage: options.language,
84-
projectTemplate: options.template,
95+
projectTemplate: template as KnownDotnetTemplates,
8596
namespaceName,
8697
projectType: projectType ?? options.projectType ?? 'library',
8798
};
@@ -113,7 +124,12 @@ export async function GenerateProject(
113124

114125
options.testTemplate = options.testTemplate ?? 'none';
115126

116-
const normalizedOptions = normalizeOptions(host, options, projectType);
127+
const normalizedOptions = await normalizeOptions(
128+
host,
129+
options,
130+
dotnetClient,
131+
projectType,
132+
);
117133

118134
const projectConfiguration: ProjectConfiguration = {
119135
root: normalizedOptions.projectRoot,
@@ -146,7 +162,7 @@ export async function GenerateProject(
146162
newParams['dryRun'] = true;
147163
}
148164

149-
dotnetClient.new(normalizedOptions.template, newParams);
165+
dotnetClient.new(normalizedOptions.projectTemplate, newParams);
150166
if (!isDryRun()) {
151167
addToSolutionFile(
152168
host,

packages/core/src/generators/utils/generate-test-project.spec.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ describe('nx-dotnet test project generator', () => {
7474

7575
options = {
7676
name: 'domain-existing-app',
77-
template: 'xunit',
7877
testTemplate: 'xunit',
7978
language: 'C#',
8079
skipOutputPathManipulation: true,

0 commit comments

Comments
 (0)