Skip to content
This repository was archived by the owner on Apr 8, 2020. It is now read-only.

Commit 1019026

Browse files
Build NuGet package containing dotnetnew templates
1 parent 0981599 commit 1019026

File tree

4 files changed

+115
-35
lines changed

4 files changed

+115
-35
lines changed

templates/yeoman/.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
/node_modules/
22
/built/
3-
/generator-aspnetcore-spa/
3+
/dist/

templates/yeoman/src/build/build.ts

Lines changed: 94 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,19 @@ import * as path from 'path';
55
import * as _ from 'lodash';
66
import * as mkdirp from 'mkdirp';
77
import * as rimraf from 'rimraf';
8+
import * as childProcess from 'child_process';
89

9-
const textFileExtensions = ['.gitignore', 'template_gitignore', '.config', '.cs', '.cshtml', 'Dockerfile', '.html', '.js', '.json', '.jsx', '.md', '.ts', '.tsx', '.xproj'];
10+
const isWindows = /^win/.test(process.platform);
11+
const textFileExtensions = ['.gitignore', 'template_gitignore', '.config', '.cs', '.cshtml', 'Dockerfile', '.html', '.js', '.json', '.jsx', '.md', '.nuspec', '.ts', '.tsx', '.xproj'];
12+
const yeomanGeneratorSource = './src/generator';
1013

11-
const templates = {
12-
'angular-2': '../../templates/Angular2Spa/',
13-
'knockout': '../../templates/KnockoutSpa/',
14-
'react-redux': '../../templates/ReactReduxSpa/',
15-
'react': '../../templates/ReactSpa/'
14+
const templates: { [key: string]: { dir: string, dotNetNewId: string, displayName: string } } = {
15+
'angular-2': { dir: '../../templates/Angular2Spa/', dotNetNewId: 'Angular', displayName: 'Angular 2' },
16+
'knockout': { dir: '../../templates/KnockoutSpa/', dotNetNewId: 'Knockout', displayName: 'Knockout.js' },
17+
'react-redux': { dir: '../../templates/ReactReduxSpa/', dotNetNewId: 'ReactRedux', displayName: 'React.js and Redux' },
18+
'react': { dir: '../../templates/ReactSpa/', dotNetNewId: 'React', displayName: 'React.js' }
1619
};
1720

18-
const contentReplacements: { from: RegExp, to: string }[] = [
19-
{ from: /\bWebApplicationBasic\b/g, to: '<%= namePascalCase %>' },
20-
{ from: /<ProjectGuid>[0-9a-f\-]{36}<\/ProjectGuid>/g, to: '<ProjectGuid><%= projectGuid %></ProjectGuid>' },
21-
{ from: /<RootNamespace>.*?<\/RootNamespace>/g, to: '<RootNamespace><%= namePascalCase %></RootNamespace>'},
22-
{ from: /\s*<BaseIntermediateOutputPath.*?<\/BaseIntermediateOutputPath>/g, to: '' },
23-
{ from: /\s*<OutputPath.*?<\/OutputPath>/g, to: '' },
24-
];
25-
26-
const filenameReplacements: { from: RegExp, to: string }[] = [
27-
{ from: /.*\.xproj$/, to: 'tokenreplace-namePascalCase.xproj' }
28-
];
29-
3021
function isTextFile(filename: string): boolean {
3122
return textFileExtensions.indexOf(path.extname(filename).toLowerCase()) >= 0;
3223
}
@@ -49,7 +40,7 @@ function listFilesExcludingGitignored(root: string): string[] {
4940
.filter(fn => gitignoreEvaluator.accepts(fn));
5041
}
5142

52-
function writeTemplate(sourceRoot: string, destRoot: string) {
43+
function writeTemplate(sourceRoot: string, destRoot: string, contentReplacements: { from: RegExp, to: string }[], filenameReplacements: { from: RegExp, to: string }[]) {
5344
listFilesExcludingGitignored(sourceRoot).forEach(fn => {
5445
let sourceContent = fs.readFileSync(path.join(sourceRoot, fn));
5546

@@ -80,20 +71,90 @@ function copyRecursive(sourceRoot: string, destRoot: string, matchGlob: string)
8071
});
8172
}
8273

83-
const outputRoot = './generator-aspnetcore-spa';
84-
const outputTemplatesRoot = path.join(outputRoot, 'app/templates');
85-
rimraf.sync(outputTemplatesRoot);
74+
function buildYeomanNpmPackage() {
75+
const outputRoot = './dist/generator-aspnetcore-spa';
76+
const outputTemplatesRoot = path.join(outputRoot, 'app/templates');
77+
rimraf.sync(outputTemplatesRoot);
78+
79+
// Copy template files
80+
const filenameReplacements = [
81+
{ from: /.*\.xproj$/, to: 'tokenreplace-namePascalCase.xproj' }
82+
];
83+
const contentReplacements = [
84+
{ from: /\bWebApplicationBasic\b/g, to: '<%= namePascalCase %>' },
85+
{ from: /<ProjectGuid>[0-9a-f\-]{36}<\/ProjectGuid>/g, to: '<ProjectGuid><%= projectGuid %></ProjectGuid>' },
86+
{ from: /<RootNamespace>.*?<\/RootNamespace>/g, to: '<RootNamespace><%= namePascalCase %></RootNamespace>'},
87+
{ from: /\s*<BaseIntermediateOutputPath.*?<\/BaseIntermediateOutputPath>/g, to: '' },
88+
{ from: /\s*<OutputPath.*?<\/OutputPath>/g, to: '' },
89+
];
90+
_.forEach(templates, (templateConfig, templateName) => {
91+
const outputDir = path.join(outputTemplatesRoot, templateName);
92+
writeTemplate(templateConfig.dir, outputDir, contentReplacements, filenameReplacements);
93+
});
94+
95+
// Also copy the generator files (that's the compiled .js files, plus all other non-.ts files)
96+
const tempRoot = './tmp';
97+
copyRecursive(path.join(tempRoot, 'generator'), outputRoot, '**/*.js');
98+
copyRecursive(yeomanGeneratorSource, outputRoot, '**/!(*.ts)');
8699

87-
// Copy template files
88-
_.forEach(templates, (templateRootDir, templateName) => {
89-
const outputDir = path.join(outputTemplatesRoot, templateName);
90-
writeTemplate(templateRootDir, outputDir);
91-
});
100+
// Clean up
101+
rimraf.sync(tempRoot);
102+
}
103+
104+
function buildDotNetNewNuGetPackage() {
105+
const outputRoot = './dist/dotnetnew';
106+
rimraf.sync(outputRoot);
107+
108+
// Copy template files
109+
const sourceProjectName = 'WebApplicationBasic';
110+
const projectGuid = '00000000-0000-0000-0000-000000000000';
111+
const filenameReplacements = [
112+
{ from: /.*\.xproj$/, to: `${sourceProjectName}.xproj` },
113+
{ from: /\btemplate_gitignore$/, to: '.gitignore' }
114+
];
115+
const contentReplacements = [
116+
{ from: /<ProjectGuid>[0-9a-f\-]{36}<\/ProjectGuid>/g, to: `<ProjectGuid>${projectGuid}</ProjectGuid>` },
117+
{ from: /<RootNamespace>.*?<\/RootNamespace>/g, to: `<RootNamespace>${sourceProjectName}</RootNamespace>`},
118+
{ from: /\s*<BaseIntermediateOutputPath.*?<\/BaseIntermediateOutputPath>/g, to: '' },
119+
{ from: /\s*<OutputPath.*?<\/OutputPath>/g, to: '' },
120+
];
121+
_.forEach(templates, (templateConfig, templateName) => {
122+
const templateOutputDir = path.join(outputRoot, 'templates', templateName);
123+
const templateOutputProjectDir = path.join(templateOutputDir, sourceProjectName);
124+
writeTemplate(templateConfig.dir, templateOutputProjectDir, contentReplacements, filenameReplacements);
125+
126+
// Add a .netnew.json file
127+
fs.writeFileSync(path.join(templateOutputDir, '.netnew.json'), JSON.stringify({
128+
author: 'Microsoft',
129+
classifications: [ 'Standard>>Quick Starts' ],
130+
name: `ASP.NET Core SPA with ${templateConfig.displayName}`,
131+
groupIdentity: `Microsoft.AspNetCore.Spa.${templateConfig.dotNetNewId}`,
132+
identity: `Microsoft.AspNetCore.Spa.${templateConfig.dotNetNewId}`,
133+
shortName: `aspnetcorespa-${templateConfig.dotNetNewId.toLowerCase()}`,
134+
tags: { language: 'C#' },
135+
guids: [ projectGuid ],
136+
sourceName: sourceProjectName
137+
}, null, 2));
138+
});
92139

93-
// Also copy the generator files (that's the compiled .js files, plus all other non-.ts files)
94-
const tempRoot = './tmp';
95-
copyRecursive(path.join(tempRoot, 'generator'), outputRoot, '**/*.js');
96-
copyRecursive('./src/generator', outputRoot, '**/!(*.ts)');
140+
// Invoke NuGet to create the final package
141+
const yeomanPackageVersion = JSON.parse(fs.readFileSync(path.join(yeomanGeneratorSource, 'package.json'), 'utf8')).version;
142+
writeTemplate('./src/dotnetnew', outputRoot, [
143+
{ from: /\{version\}/g, to: yeomanPackageVersion },
144+
], []);
145+
const nugetExe = path.join(process.cwd(), './bin/NuGet.exe');
146+
const nugetStartInfo = { cwd: outputRoot, stdio: 'inherit' };
147+
if (isWindows) {
148+
// Invoke NuGet.exe directly
149+
childProcess.spawnSync(nugetExe, ['pack'], nugetStartInfo);
150+
} else {
151+
// Invoke via Mono (relying on that being available)
152+
childProcess.spawnSync('mono', [nugetExe, 'pack'], nugetStartInfo);
153+
}
154+
155+
// Clean up
156+
rimraf.sync('./tmp');
157+
}
97158

98-
// Clean up
99-
rimraf.sync(tempRoot);
159+
buildYeomanNpmPackage();
160+
buildDotNetNewNuGetPackage();
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
3+
<metadata>
4+
<id>Microsoft.AspNetCore.Spa.Templates</id>
5+
<version>{version}</version>
6+
<title>Class Library and Console Application Templates for .NET Core</title>
7+
<authors>Microsoft</authors>
8+
<requireLicenseAcceptance>false</requireLicenseAcceptance>
9+
<description>My package description.</description>
10+
<dependencies>
11+
<group targetFramework=".NETCoreApp,Version=v1.0">
12+
<dependency id="Microsoft.TemplateEngine.Orchestrator.RunnableProjects" version="1.0.0" />
13+
</group>
14+
</dependencies>
15+
</metadata>
16+
<files>
17+
<file src="templates/**" />
18+
</files>
19+
</package>

templates/yeoman/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
},
88
"exclude": [
99
"node_modules",
10-
"generator-aspnetcore-spa"
10+
"dist"
1111
]
1212
}

0 commit comments

Comments
 (0)