mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-22 17:47:53 +00:00
generator-aspnetcore-spa support for selecting between project.json and .csproj
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
"author": "Microsoft",
|
"author": "Microsoft",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/chalk": "^0.4.31",
|
||||||
"@types/semver": "^5.3.30",
|
"@types/semver": "^5.3.30",
|
||||||
"diff": "^2.2.2",
|
"diff": "^2.2.2",
|
||||||
"gitignore-parser": "0.0.2",
|
"gitignore-parser": "0.0.2",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import * as rimraf from 'rimraf';
|
|||||||
import * as childProcess from 'child_process';
|
import * as childProcess from 'child_process';
|
||||||
|
|
||||||
const isWindows = /^win/.test(process.platform);
|
const isWindows = /^win/.test(process.platform);
|
||||||
const textFileExtensions = ['.gitignore', 'template_gitignore', '.config', '.cs', '.cshtml', 'Dockerfile', '.html', '.js', '.json', '.jsx', '.md', '.nuspec', '.ts', '.tsx', '.xproj'];
|
const textFileExtensions = ['.gitignore', 'template_gitignore', '.config', '.cs', '.cshtml', '.csproj', 'Dockerfile', '.html', '.js', '.json', '.jsx', '.md', '.nuspec', '.ts', '.tsx', '.xproj'];
|
||||||
const yeomanGeneratorSource = './src/yeoman';
|
const yeomanGeneratorSource = './src/yeoman';
|
||||||
|
|
||||||
// For the Angular 2 template, we want to bundle prebuilt dist dev-mode files, because the VS template can't auto-run
|
// For the Angular 2 template, we want to bundle prebuilt dist dev-mode files, because the VS template can't auto-run
|
||||||
@@ -88,14 +88,19 @@ function buildYeomanNpmPackage() {
|
|||||||
|
|
||||||
// Copy template files
|
// Copy template files
|
||||||
const filenameReplacements = [
|
const filenameReplacements = [
|
||||||
{ from: /.*\.xproj$/, to: 'tokenreplace-namePascalCase.xproj' }
|
{ from: /.*\.xproj$/, to: 'tokenreplace-namePascalCase.xproj' },
|
||||||
|
{ from: /.*\.csproj$/, to: 'tokenreplace-namePascalCase.csproj' }
|
||||||
];
|
];
|
||||||
const contentReplacements = [
|
const contentReplacements = [
|
||||||
|
// .xproj items
|
||||||
{ from: /\bWebApplicationBasic\b/g, to: '<%= namePascalCase %>' },
|
{ from: /\bWebApplicationBasic\b/g, to: '<%= namePascalCase %>' },
|
||||||
{ from: /<ProjectGuid>[0-9a-f\-]{36}<\/ProjectGuid>/g, to: '<ProjectGuid><%= projectGuid %></ProjectGuid>' },
|
{ from: /<ProjectGuid>[0-9a-f\-]{36}<\/ProjectGuid>/g, to: '<ProjectGuid><%= projectGuid %></ProjectGuid>' },
|
||||||
{ from: /<RootNamespace>.*?<\/RootNamespace>/g, to: '<RootNamespace><%= namePascalCase %></RootNamespace>'},
|
{ from: /<RootNamespace>.*?<\/RootNamespace>/g, to: '<RootNamespace><%= namePascalCase %></RootNamespace>'},
|
||||||
{ from: /\s*<BaseIntermediateOutputPath.*?<\/BaseIntermediateOutputPath>/g, to: '' },
|
{ from: /\s*<BaseIntermediateOutputPath.*?<\/BaseIntermediateOutputPath>/g, to: '' },
|
||||||
{ from: /\s*<OutputPath.*?<\/OutputPath>/g, to: '' },
|
{ from: /\s*<OutputPath.*?<\/OutputPath>/g, to: '' },
|
||||||
|
|
||||||
|
// global.json items
|
||||||
|
{ from: /1\.0\.0-preview2-1-003177/, to: '<%= sdkVersion %>' }
|
||||||
];
|
];
|
||||||
_.forEach(templates, (templateConfig, templateName) => {
|
_.forEach(templates, (templateConfig, templateName) => {
|
||||||
const outputDir = path.join(outputTemplatesRoot, templateName);
|
const outputDir = path.join(outputTemplatesRoot, templateName);
|
||||||
@@ -119,6 +124,7 @@ function buildDotNetNewNuGetPackage() {
|
|||||||
const sourceProjectName = 'WebApplicationBasic';
|
const sourceProjectName = 'WebApplicationBasic';
|
||||||
const projectGuid = '00000000-0000-0000-0000-000000000000';
|
const projectGuid = '00000000-0000-0000-0000-000000000000';
|
||||||
const filenameReplacements = [
|
const filenameReplacements = [
|
||||||
|
// TODO: For dotnetnew templates, switch to csproj. No need for SDK choice as it can be Preview3+ only.
|
||||||
{ from: /.*\.xproj$/, to: `${sourceProjectName}.xproj` },
|
{ from: /.*\.xproj$/, to: `${sourceProjectName}.xproj` },
|
||||||
{ from: /\btemplate_gitignore$/, to: '.gitignore' }
|
{ from: /\btemplate_gitignore$/, to: '.gitignore' }
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import * as yeoman from 'yeoman-generator';
|
|||||||
import * as uuid from 'node-uuid';
|
import * as uuid from 'node-uuid';
|
||||||
import * as glob from 'glob';
|
import * as glob from 'glob';
|
||||||
import * as semver from 'semver';
|
import * as semver from 'semver';
|
||||||
|
import * as chalk from 'chalk';
|
||||||
import { execSync } from 'child_process';
|
import { execSync } from 'child_process';
|
||||||
import npmWhich = require('npm-which');
|
import npmWhich = require('npm-which');
|
||||||
const yosay = require('yosay');
|
const yosay = require('yosay');
|
||||||
@@ -42,6 +43,20 @@ const templates = [
|
|||||||
{ value: 'react-redux', name: 'React with Redux', tests: false }
|
{ value: 'react-redux', name: 'React with Redux', tests: false }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Once everyone is on .csproj-compatible tooling, we might be able to remove the global.json files and eliminate
|
||||||
|
// this SDK choice altogether. That would be good because then it would work with whatever SDK version you have
|
||||||
|
// installed. For now, we need to specify an SDK version explicitly, because there's no support for wildcards, and
|
||||||
|
// preview3+ tooling doesn't support project.json at all.
|
||||||
|
const sdkChoices = [{
|
||||||
|
value: '1.0.0-preview2-1-003177', // Current released version
|
||||||
|
name: 'project.json' + chalk.gray(' (compatible with .NET Core tooling preview 2 and Visual Studio 2015)'),
|
||||||
|
includeFiles: [/^project.json$/, /\.xproj$/]
|
||||||
|
}, {
|
||||||
|
value: '1.0.0-preview3-004056', // Version that ships with VS2017RC
|
||||||
|
name: '.csproj' + chalk.gray(' (compatible with .NET Core tooling preview 3 and Visual Studio 2017)'),
|
||||||
|
includeFiles: [/\.csproj$/]
|
||||||
|
}];
|
||||||
|
|
||||||
class MyGenerator extends yeoman.Base {
|
class MyGenerator extends yeoman.Base {
|
||||||
private _answers: any;
|
private _answers: any;
|
||||||
private _optionOrPrompt: YeomanPrompt;
|
private _optionOrPrompt: YeomanPrompt;
|
||||||
@@ -65,8 +80,13 @@ class MyGenerator extends yeoman.Base {
|
|||||||
name: 'framework',
|
name: 'framework',
|
||||||
message: 'Framework',
|
message: 'Framework',
|
||||||
choices: templates
|
choices: templates
|
||||||
}], frameworkAnswer => {
|
}, {
|
||||||
const frameworkChoice = templates.filter(t => t.value === frameworkAnswer.framework)[0];
|
type: 'list',
|
||||||
|
name: 'sdkVersion',
|
||||||
|
message: 'What type of project do you want to create?',
|
||||||
|
choices: sdkChoices
|
||||||
|
}], firstAnswers => {
|
||||||
|
const frameworkChoice = templates.filter(t => t.value === firstAnswers.framework)[0];
|
||||||
const furtherQuestions = [{
|
const furtherQuestions = [{
|
||||||
type: 'input',
|
type: 'input',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
@@ -84,9 +104,10 @@ class MyGenerator extends yeoman.Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._optionOrPrompt(furtherQuestions, answers => {
|
this._optionOrPrompt(furtherQuestions, answers => {
|
||||||
answers.framework = frameworkAnswer.framework;
|
answers.framework = firstAnswers.framework;
|
||||||
this._answers = answers;
|
this._answers = answers;
|
||||||
this._answers.framework = frameworkAnswer.framework;
|
this._answers.framework = firstAnswers.framework;
|
||||||
|
this._answers.sdkVersion = firstAnswers.sdkVersion;
|
||||||
this._answers.namePascalCase = toPascalCase(answers.name);
|
this._answers.namePascalCase = toPascalCase(answers.name);
|
||||||
this._answers.projectGuid = this.options['projectguid'] || uuid.v4();
|
this._answers.projectGuid = this.options['projectguid'] || uuid.v4();
|
||||||
done();
|
done();
|
||||||
@@ -95,7 +116,8 @@ class MyGenerator extends yeoman.Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
writing() {
|
writing() {
|
||||||
var templateRoot = this.templatePath(this._answers.framework);
|
const templateRoot = this.templatePath(this._answers.framework);
|
||||||
|
const chosenSdk = sdkChoices.filter(sdk => sdk.value === this._answers.sdkVersion)[0];
|
||||||
glob.sync('**/*', { cwd: templateRoot, dot: true, nodir: true }).forEach(fn => {
|
glob.sync('**/*', { cwd: templateRoot, dot: true, nodir: true }).forEach(fn => {
|
||||||
// Token replacement in filenames
|
// Token replacement in filenames
|
||||||
let outputFn = fn.replace(/tokenreplace\-([^\.\/]*)/g, (substr, token) => this._answers[token]);
|
let outputFn = fn.replace(/tokenreplace\-([^\.\/]*)/g, (substr, token) => this._answers[token]);
|
||||||
@@ -105,9 +127,14 @@ class MyGenerator extends yeoman.Base {
|
|||||||
outputFn = path.join(path.dirname(fn), '.gitignore');
|
outputFn = path.join(path.dirname(fn), '.gitignore');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exclude test-specific files (unless the user has said they want tests)
|
// Decide whether to emit this file
|
||||||
const isTestSpecificFile = testSpecificPaths.some(regex => regex.test(outputFn));
|
const isTestSpecificFile = testSpecificPaths.some(regex => regex.test(outputFn));
|
||||||
if (this._answers.tests || !isTestSpecificFile) {
|
const isSdkSpecificFile = sdkChoices.some(sdk => sdk.includeFiles.some(regex => regex.test(outputFn)));
|
||||||
|
const matchesChosenSdk = chosenSdk.includeFiles.some(regex => regex.test(outputFn));
|
||||||
|
const emitFile = (matchesChosenSdk || !isSdkSpecificFile)
|
||||||
|
&& (this._answers.tests || !isTestSpecificFile);
|
||||||
|
|
||||||
|
if (emitFile) {
|
||||||
let inputFullPath = path.join(templateRoot, fn);
|
let inputFullPath = path.join(templateRoot, fn);
|
||||||
let destinationFullPath = this.destinationPath(outputFn);
|
let destinationFullPath = this.destinationPath(outputFn);
|
||||||
if (path.basename(fn) === 'package.json') {
|
if (path.basename(fn) === 'package.json') {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
"url": "https://github.com/aspnet/JavaScriptServices.git"
|
"url": "https://github.com/aspnet/JavaScriptServices.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"chalk": "^1.1.3",
|
||||||
"glob": "^7.0.3",
|
"glob": "^7.0.3",
|
||||||
"node-uuid": "^1.4.7",
|
"node-uuid": "^1.4.7",
|
||||||
"npm-which": "^3.0.1",
|
"npm-which": "^3.0.1",
|
||||||
|
|||||||
Reference in New Issue
Block a user