Rename folders since the template package generator now creates a package for "dotnet new" as well as Yeoman

This commit is contained in:
SteveSandersonMS
2016-08-18 10:58:04 -07:00
parent 1019026943
commit d928ef4f12
22 changed files with 3 additions and 3 deletions

3
templates/package-builder/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
/node_modules/
/built/
/dist/

View File

@@ -0,0 +1,5 @@
To generator the Yeoman generator, execute:
npm run build
Output will appear in the `generator-aspnetcore-spa` directory.

View File

@@ -0,0 +1,23 @@
{
"name": "generator-aspnetcore-spa-generator",
"version": "1.0.0",
"description": "Creates the Yeoman generator and 'dotnet new' package for ASP.NET Core SPA templates",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "tsc && node ./tmp/build/build.js"
},
"author": "Microsoft",
"license": "Apache-2.0",
"dependencies": {
"diff": "^2.2.2",
"gitignore-parser": "0.0.2",
"glob": "^7.0.3",
"lodash": "^4.11.1",
"mkdirp": "^0.5.1",
"rimraf": "^2.5.2"
},
"devDependencies": {
"typescript": "^1.8.10"
}
}

View File

@@ -0,0 +1,160 @@
import * as glob from 'glob';
import * as gitignore from 'gitignore-parser';
import * as fs from 'fs';
import * as path from 'path';
import * as _ from 'lodash';
import * as mkdirp from 'mkdirp';
import * as rimraf from 'rimraf';
import * as childProcess from 'child_process';
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 yeomanGeneratorSource = './src/yeoman';
const templates: { [key: string]: { dir: string, dotNetNewId: string, displayName: string } } = {
'angular-2': { dir: '../../templates/Angular2Spa/', dotNetNewId: 'Angular', displayName: 'Angular 2' },
'knockout': { dir: '../../templates/KnockoutSpa/', dotNetNewId: 'Knockout', displayName: 'Knockout.js' },
'react-redux': { dir: '../../templates/ReactReduxSpa/', dotNetNewId: 'ReactRedux', displayName: 'React.js and Redux' },
'react': { dir: '../../templates/ReactSpa/', dotNetNewId: 'React', displayName: 'React.js' }
};
function isTextFile(filename: string): boolean {
return textFileExtensions.indexOf(path.extname(filename).toLowerCase()) >= 0;
}
function writeFileEnsuringDirExists(root: string, filename: string, contents: string | Buffer) {
let fullPath = path.join(root, filename);
mkdirp.sync(path.dirname(fullPath));
fs.writeFileSync(fullPath, contents);
}
function listFilesExcludingGitignored(root: string): string[] {
// Note that the gitignore files, prior to be written by the generator, are called 'template_gitignore'
// instead of '.gitignore'. This is a workaround for Yeoman doing strange stuff with .gitignore files
// (it renames them to .npmignore, which is not helpful).
let gitIgnorePath = path.join(root, 'template_gitignore');
let gitignoreEvaluator = fs.existsSync(gitIgnorePath)
? gitignore.compile(fs.readFileSync(gitIgnorePath, 'utf8'))
: { accepts: () => true };
return glob.sync('**/*', { cwd: root, dot: true, nodir: true })
.filter(fn => gitignoreEvaluator.accepts(fn));
}
function writeTemplate(sourceRoot: string, destRoot: string, contentReplacements: { from: RegExp, to: string }[], filenameReplacements: { from: RegExp, to: string }[]) {
listFilesExcludingGitignored(sourceRoot).forEach(fn => {
let sourceContent = fs.readFileSync(path.join(sourceRoot, fn));
// For text files, replace hardcoded values with template tags
if (isTextFile(fn)) {
let sourceText = sourceContent.toString('utf8');
contentReplacements.forEach(replacement => {
sourceText = sourceText.replace(replacement.from, replacement.to);
});
sourceContent = new Buffer(sourceText, 'utf8');
}
// Also apply replacements in filenames
filenameReplacements.forEach(replacement => {
fn = fn.replace(replacement.from, replacement.to);
});
writeFileEnsuringDirExists(destRoot, fn, sourceContent);
});
}
function copyRecursive(sourceRoot: string, destRoot: string, matchGlob: string) {
glob.sync(matchGlob, { cwd: sourceRoot, dot: true, nodir: true })
.forEach(fn => {
const sourceContent = fs.readFileSync(path.join(sourceRoot, fn));
writeFileEnsuringDirExists(destRoot, fn, sourceContent);
});
}
function buildYeomanNpmPackage() {
const outputRoot = './dist/generator-aspnetcore-spa';
const outputTemplatesRoot = path.join(outputRoot, 'app/templates');
rimraf.sync(outputTemplatesRoot);
// Copy template files
const filenameReplacements = [
{ from: /.*\.xproj$/, to: 'tokenreplace-namePascalCase.xproj' }
];
const contentReplacements = [
{ from: /\bWebApplicationBasic\b/g, to: '<%= namePascalCase %>' },
{ from: /<ProjectGuid>[0-9a-f\-]{36}<\/ProjectGuid>/g, to: '<ProjectGuid><%= projectGuid %></ProjectGuid>' },
{ from: /<RootNamespace>.*?<\/RootNamespace>/g, to: '<RootNamespace><%= namePascalCase %></RootNamespace>'},
{ from: /\s*<BaseIntermediateOutputPath.*?<\/BaseIntermediateOutputPath>/g, to: '' },
{ from: /\s*<OutputPath.*?<\/OutputPath>/g, to: '' },
];
_.forEach(templates, (templateConfig, templateName) => {
const outputDir = path.join(outputTemplatesRoot, templateName);
writeTemplate(templateConfig.dir, outputDir, contentReplacements, filenameReplacements);
});
// Also copy the generator files (that's the compiled .js files, plus all other non-.ts files)
const tempRoot = './tmp';
copyRecursive(path.join(tempRoot, 'yeoman'), outputRoot, '**/*.js');
copyRecursive(yeomanGeneratorSource, outputRoot, '**/!(*.ts)');
// Clean up
rimraf.sync(tempRoot);
}
function buildDotNetNewNuGetPackage() {
const outputRoot = './dist/dotnetnew';
rimraf.sync(outputRoot);
// Copy template files
const sourceProjectName = 'WebApplicationBasic';
const projectGuid = '00000000-0000-0000-0000-000000000000';
const filenameReplacements = [
{ from: /.*\.xproj$/, to: `${sourceProjectName}.xproj` },
{ from: /\btemplate_gitignore$/, to: '.gitignore' }
];
const contentReplacements = [
{ from: /<ProjectGuid>[0-9a-f\-]{36}<\/ProjectGuid>/g, to: `<ProjectGuid>${projectGuid}</ProjectGuid>` },
{ from: /<RootNamespace>.*?<\/RootNamespace>/g, to: `<RootNamespace>${sourceProjectName}</RootNamespace>`},
{ from: /\s*<BaseIntermediateOutputPath.*?<\/BaseIntermediateOutputPath>/g, to: '' },
{ from: /\s*<OutputPath.*?<\/OutputPath>/g, to: '' },
];
_.forEach(templates, (templateConfig, templateName) => {
const templateOutputDir = path.join(outputRoot, 'templates', templateName);
const templateOutputProjectDir = path.join(templateOutputDir, sourceProjectName);
writeTemplate(templateConfig.dir, templateOutputProjectDir, contentReplacements, filenameReplacements);
// Add a .netnew.json file
fs.writeFileSync(path.join(templateOutputDir, '.netnew.json'), JSON.stringify({
author: 'Microsoft',
classifications: [ 'Standard>>Quick Starts' ],
name: `ASP.NET Core SPA with ${templateConfig.displayName}`,
groupIdentity: `Microsoft.AspNetCore.Spa.${templateConfig.dotNetNewId}`,
identity: `Microsoft.AspNetCore.Spa.${templateConfig.dotNetNewId}`,
shortName: `aspnetcorespa-${templateConfig.dotNetNewId.toLowerCase()}`,
tags: { language: 'C#' },
guids: [ projectGuid ],
sourceName: sourceProjectName
}, null, 2));
});
// Invoke NuGet to create the final package
const yeomanPackageVersion = JSON.parse(fs.readFileSync(path.join(yeomanGeneratorSource, 'package.json'), 'utf8')).version;
writeTemplate('./src/dotnetnew', outputRoot, [
{ from: /\{version\}/g, to: yeomanPackageVersion },
], []);
const nugetExe = path.join(process.cwd(), './bin/NuGet.exe');
const nugetStartInfo = { cwd: outputRoot, stdio: 'inherit' };
if (isWindows) {
// Invoke NuGet.exe directly
childProcess.spawnSync(nugetExe, ['pack'], nugetStartInfo);
} else {
// Invoke via Mono (relying on that being available)
childProcess.spawnSync('mono', [nugetExe, 'pack'], nugetStartInfo);
}
// Clean up
rimraf.sync('./tmp');
}
buildYeomanNpmPackage();
buildDotNetNewNuGetPackage();

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
<id>Microsoft.AspNetCore.Spa.Templates</id>
<version>{version}</version>
<title>Class Library and Console Application Templates for .NET Core</title>
<authors>Microsoft</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>My package description.</description>
<dependencies>
<group targetFramework=".NETCoreApp,Version=v1.0">
<dependency id="Microsoft.TemplateEngine.Orchestrator.RunnableProjects" version="1.0.0" />
</group>
</dependencies>
</metadata>
<files>
<file src="templates/**" />
</files>
</package>

View File

@@ -0,0 +1 @@
/node_modules/

View File

@@ -0,0 +1,77 @@
import * as path from 'path';
import * as yeoman from 'yeoman-generator';
import * as uuid from 'node-uuid';
import * as glob from 'glob';
const yosay = require('yosay');
const toPascalCase = require('to-pascal-case');
const templates = [
{ value: 'angular-2', name: 'Angular 2' },
{ value: 'knockout', name: 'Knockout' },
{ value: 'react', name: 'React' },
{ value: 'react-redux', name: 'React with Redux' }
];
class MyGenerator extends yeoman.Base {
private _answers: any;
constructor(args: string | string[], options: any) {
super(args, options);
this.log(yosay('Welcome to the ASP.NET Core Single-Page App generator!'));
}
prompting() {
const done = this.async();
this.prompt([{
type: 'list',
name: 'framework',
message: 'Framework',
choices: templates
}, {
type: 'input',
name: 'name',
message: 'Your project name',
default: this.appname
}], answers => {
this._answers = answers;
this._answers.namePascalCase = toPascalCase(answers.name);
this._answers.projectGuid = uuid.v4();
done();
});
}
writing() {
var templateRoot = this.templatePath(this._answers.framework);
glob.sync('**/*', { cwd: templateRoot, dot: true, nodir: true }).forEach(fn => {
// Token replacement in filenames
let outputFn = fn.replace(/tokenreplace\-([^\.\/]*)/g, (substr, token) => this._answers[token]);
// Rename template_gitignore to .gitignore in output
if (path.basename(fn) === 'template_gitignore') {
outputFn = path.join(path.dirname(fn), '.gitignore');
}
this.fs.copyTpl(
path.join(templateRoot, fn),
this.destinationPath(outputFn),
this._answers
);
});
}
installingDeps() {
this.installDependencies({
npm: true,
bower: false,
callback: () => {
this.spawnCommandSync('dotnet', ['restore']);
this.spawnCommandSync('./node_modules/.bin/webpack', ['--config', 'webpack.config.vendor.js']);
this.spawnCommandSync('./node_modules/.bin/webpack');
}
});
}
}
declare var module: any;
(module).exports = MyGenerator;

View File

@@ -0,0 +1,20 @@
{
"name": "generator-aspnetcore-spa",
"version": "0.2.3",
"description": "Single-Page App templates for ASP.NET Core",
"author": "Microsoft",
"license": "Apache-2.0",
"files": [
"app"
],
"keywords": [
"yeoman-generator"
],
"dependencies": {
"glob": "^7.0.3",
"node-uuid": "^1.4.7",
"to-pascal-case": "^1.0.0",
"yeoman-generator": "^0.20.2",
"yosay": "^1.1.1"
}
}

View File

@@ -0,0 +1,12 @@
{
"compilerOptions": {
"moduleResolution": "node",
"target": "es5",
"outDir": "tmp",
"sourceMap": false
},
"exclude": [
"node_modules",
"dist"
]
}

View File

@@ -0,0 +1,39 @@
{
"version": "v4",
"repo": "borisyankov/DefinitelyTyped",
"ref": "master",
"path": "typings",
"bundle": "typings/tsd.d.ts",
"installed": {
"yeoman-generator/yeoman-generator.d.ts": {
"commit": "544a35a10866b32afda9c7f029c0764558563f4f"
},
"node/node.d.ts": {
"commit": "08ed4e9f1869e37e29514d862e0158b40e550232"
},
"glob/glob.d.ts": {
"commit": "544a35a10866b32afda9c7f029c0764558563f4f"
},
"minimatch/minimatch.d.ts": {
"commit": "544a35a10866b32afda9c7f029c0764558563f4f"
},
"lodash/lodash.d.ts": {
"commit": "544a35a10866b32afda9c7f029c0764558563f4f"
},
"mkdirp/mkdirp.d.ts": {
"commit": "544a35a10866b32afda9c7f029c0764558563f4f"
},
"rimraf/rimraf.d.ts": {
"commit": "544a35a10866b32afda9c7f029c0764558563f4f"
},
"node-uuid/node-uuid.d.ts": {
"commit": "08ed4e9f1869e37e29514d862e0158b40e550232"
},
"node-uuid/node-uuid-base.d.ts": {
"commit": "08ed4e9f1869e37e29514d862e0158b40e550232"
},
"node-uuid/node-uuid-cjs.d.ts": {
"commit": "08ed4e9f1869e37e29514d862e0158b40e550232"
}
}
}

View File

@@ -0,0 +1,3 @@
declare module 'gitignore-parser' {
export function compile(gitignoreContents: string): any;
}

View File

@@ -0,0 +1,112 @@
// Type definitions for Glob 5.0.10
// Project: https://github.com/isaacs/node-glob
// Definitions by: vvakame <https://github.com/vvakame/>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference path="../node/node.d.ts" />
/// <reference path="../minimatch/minimatch.d.ts" />
declare module "glob" {
import events = require("events");
import fs = require('fs');
import minimatch = require("minimatch");
function G(pattern: string, cb: (err: Error, matches: string[]) => void): void;
function G(pattern: string, options: G.IOptions, cb: (err: Error, matches: string[]) => void): void;
namespace G {
function sync(pattern: string, options?: IOptions): string[];
function hasMagic(pattern: string, options?: IOptions): boolean;
var Glob: IGlobStatic;
var GlobSync: IGlobSyncStatic;
interface IOptions extends minimatch.IOptions {
cwd?: string;
root?: string;
dot?: boolean;
nomount?: boolean;
mark?: boolean;
nosort?: boolean;
stat?: boolean;
silent?: boolean;
strict?: boolean;
cache?: { [path: string]: any /* boolean | string | string[] */ };
statCache?: { [path: string]: fs.Stats };
symlinks?: any;
sync?: boolean;
nounique?: boolean;
nonull?: boolean;
debug?: boolean;
nobrace?: boolean;
noglobstar?: boolean;
noext?: boolean;
nocase?: boolean;
matchBase?: any;
nodir?: boolean;
ignore?: any; /* string | string[] */
follow?: boolean;
realpath?: boolean;
nonegate?: boolean;
nocomment?: boolean;
/** Deprecated. */
globDebug?: boolean;
}
interface IGlobStatic extends events.EventEmitter {
new (pattern: string, cb?: (err: Error, matches: string[]) => void): IGlob;
new (pattern: string, options: IOptions, cb?: (err: Error, matches: string[]) => void): IGlob;
prototype: IGlob;
}
interface IGlobSyncStatic {
new (pattern: string, options?: IOptions): IGlobBase
prototype: IGlobBase;
}
interface IGlobBase {
minimatch: minimatch.IMinimatch;
options: IOptions;
aborted: boolean;
cache: { [path: string]: any /* boolean | string | string[] */ };
statCache: { [path: string]: fs.Stats };
symlinks: { [path: string]: boolean };
realpathCache: { [path: string]: string };
found: string[];
}
interface IGlob extends IGlobBase, events.EventEmitter {
pause(): void;
resume(): void;
abort(): void;
/** Deprecated. */
EOF: any;
/** Deprecated. */
paused: boolean;
/** Deprecated. */
maxDepth: number;
/** Deprecated. */
maxLength: number;
/** Deprecated. */
changedCwd: boolean;
/** Deprecated. */
cwd: string;
/** Deprecated. */
root: string;
/** Deprecated. */
error: any;
/** Deprecated. */
matches: string[];
/** Deprecated. */
log(...args: any[]): void;
/** Deprecated. */
emitMatch(m: any): void;
}
}
export = G;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,64 @@
// Type definitions for Minimatch 2.0.8
// Project: https://github.com/isaacs/minimatch
// Definitions by: vvakame <https://github.com/vvakame/>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare module "minimatch" {
function M(target: string, pattern: string, options?: M.IOptions): boolean;
namespace M {
function match(list: string[], pattern: string, options?: IOptions): string[];
function filter(pattern: string, options?: IOptions): (element: string, indexed: number, array: string[]) => boolean;
function makeRe(pattern: string, options?: IOptions): RegExp;
var Minimatch: IMinimatchStatic;
interface IOptions {
debug?: boolean;
nobrace?: boolean;
noglobstar?: boolean;
dot?: boolean;
noext?: boolean;
nocase?: boolean;
nonull?: boolean;
matchBase?: boolean;
nocomment?: boolean;
nonegate?: boolean;
flipNegate?: boolean;
}
interface IMinimatchStatic {
new (pattern: string, options?: IOptions): IMinimatch;
prototype: IMinimatch;
}
interface IMinimatch {
pattern: string;
options: IOptions;
/** 2-dimensional array of regexp or string expressions. */
set: any[][]; // (RegExp | string)[][]
regexp: RegExp;
negate: boolean;
comment: boolean;
empty: boolean;
makeRe(): RegExp; // regexp or boolean
match(fname: string): boolean;
matchOne(files: string[], pattern: string[], partial: boolean): boolean;
/** Deprecated. For internal use. */
debug(): void;
/** Deprecated. For internal use. */
make(): void;
/** Deprecated. For internal use. */
parseNegate(): void;
/** Deprecated. For internal use. */
braceExpand(pattern: string, options: IOptions): void;
/** Deprecated. For internal use. */
parse(pattern: string, isSub?: boolean): void;
}
}
export = M;
}

View File

@@ -0,0 +1,15 @@
// Type definitions for mkdirp 0.3.0
// Project: http://github.com/substack/node-mkdirp
// Definitions by: Bart van der Schoor <https://github.com/Bartvds>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare module 'mkdirp' {
function mkdirp(dir: string, cb: (err: any, made: string) => void): void;
function mkdirp(dir: string, flags: any, cb: (err: any, made: string) => void): void;
namespace mkdirp {
function sync(dir: string, flags?: any): string;
}
export = mkdirp;
}

View File

@@ -0,0 +1,46 @@
// Type definitions for node-uuid.js
// Project: https://github.com/broofa/node-uuid
// Definitions by: Jeff May <https://github.com/jeffmay>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/** Common definitions for all environments */
declare namespace __NodeUUID {
interface UUIDOptions {
/**
* Node id as Array of 6 bytes (per 4.1.6).
* Default: Randomly generated ID. See note 1.
*/
node?: any[];
/**
* (Number between 0 - 0x3fff) RFC clock sequence.
* Default: An internally maintained clockseq is used.
*/
clockseq?: number;
/**
* (Number | Date) Time in milliseconds since unix Epoch.
* Default: The current time is used.
*/
msecs?: number|Date;
/**
* (Number between 0-9999) additional time, in 100-nanosecond units. Ignored if msecs is unspecified.
* Default: internal uuid counter is used, as per 4.2.1.2.
*/
nsecs?: number;
}
interface UUID {
v1(options?: UUIDOptions): string;
v1(options?: UUIDOptions, buffer?: number[], offset?: number): number[];
v4(options?: UUIDOptions): string;
v4(options?: UUIDOptions, buffer?: number[], offset?: number): number[];
parse(id: string, buffer?: number[], offset?: number): number[];
unparse(buffer: number[], offset?: number): string;
}
}

View File

@@ -0,0 +1,15 @@
// Type definitions for node-uuid.js
// Project: https://github.com/broofa/node-uuid
// Definitions by: Jeff May <https://github.com/jeffmay>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference path="./node-uuid-base.d.ts" />
/**
* Expose as CommonJS module
* For use in node environment or browser environment (using webpack or other module loaders)
*/
declare module "node-uuid" {
var uuid: __NodeUUID.UUID;
export = uuid;
}

View File

@@ -0,0 +1,36 @@
// Type definitions for node-uuid.js
// Project: https://github.com/broofa/node-uuid
// Definitions by: Jeff May <https://github.com/jeffmay>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference path="../node/node.d.ts" />
/// <reference path="./node-uuid-base.d.ts" />
/// <reference path="./node-uuid-cjs.d.ts" />
/**
* Definitions for use in node environment
*
* !! For browser enviroments, use node-uuid-global or node-uuid-cjs
*/
declare module __NodeUUID {
/**
* Overloads for node environment
* We need to duplicate some declarations because
* interface merging doesn't work with overloads
*/
interface UUID {
v1(options?: UUIDOptions): string;
v1(options?: UUIDOptions, buffer?: number[], offset?: number): number[];
v1(options?: UUIDOptions, buffer?: Buffer, offset?: number): Buffer;
v4(options?: UUIDOptions): string;
v4(options?: UUIDOptions, buffer?: number[], offset?: number): number[];
v4(options?: UUIDOptions, buffer?: Buffer, offset?: number): Buffer;
parse(id: string, buffer?: number[], offset?: number): number[];
parse(id: string, buffer?: Buffer, offset?: number): Buffer;
unparse(buffer: number[], offset?: number): string;
unparse(buffer: Buffer, offset?: number): string;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
// Type definitions for rimraf
// Project: https://github.com/isaacs/rimraf
// Definitions by: Carlos Ballesteros Velasco <https://github.com/soywiz>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// Imported from: https://github.com/soywiz/typescript-node-definitions/rimraf.d.ts
declare module "rimraf" {
function rimraf(path: string, callback: (error: Error) => void): void;
namespace rimraf {
export function sync(path: string): void;
export var EMFILE_MAX: number;
export var BUSYTRIES_MAX: number;
}
export = rimraf;
}

View File

@@ -0,0 +1,10 @@
/// <reference path="node/node.d.ts" />
/// <reference path="yeoman-generator/yeoman-generator.d.ts" />
/// <reference path="glob/glob.d.ts" />
/// <reference path="minimatch/minimatch.d.ts" />
/// <reference path="lodash/lodash.d.ts" />
/// <reference path="mkdirp/mkdirp.d.ts" />
/// <reference path="rimraf/rimraf.d.ts" />
/// <reference path="node-uuid/node-uuid-base.d.ts" />
/// <reference path="node-uuid/node-uuid-cjs.d.ts" />
/// <reference path="node-uuid/node-uuid.d.ts" />

View File

@@ -0,0 +1,250 @@
// Type definitions for yeoman-generator
// Project: https://github.com/yeoman/generator
// Definitions by: Kentaro Okuno <http://github.com/armorik83>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference path="../node/node.d.ts" />
declare namespace yo {
export interface IYeomanGenerator {
argument(name: string, config: IArgumentConfig): void;
composeWith(namespace: string, options: any, settings?: IComposeSetting): IYeomanGenerator;
defaultFor(name: string): void;
destinationRoot(rootPath?: string): string;
destinationPath(...path: string[]): string;
determineAppname(): void;
getCollisionFilter(): (output: any) => void;
hookFor(name: string, config: IHookConfig): void;
option(name: string, config: IYeomanGeneratorOption): void;
rootGeneratorName(): string;
run(args?: any): void;
run(args: any, callback?: Function): void;
runHooks(callback?: Function): void;
sourceRoot(rootPath?: string): string;
templatePath(...path: string[]): string;
prompt(opt: IPromptOptions | IPromptOptions[], callback: (answers: any) => void): void;
npmInstall(packages?: string[] | string, options?: any, cb?: Function): void;
installDependencies(options?: IInstallDependencyOptions): void;
spawnCommand(name: string, args?: string[], options?: Object): void;
spawnCommandSync(name: string, args?: string[], options?: Object): void;
options: { [key: string]: any };
fs: IMemFsEditor;
}
export class YeomanGeneratorBase implements IYeomanGenerator, NodeJS.EventEmitter {
argument(name: string, config: IArgumentConfig): void;
composeWith(namespace: string, options: any, settings?: IComposeSetting): IYeomanGenerator;
defaultFor(name: string): void;
destinationRoot(rootPath?: string): string;
destinationPath(...path: string[]): string;
determineAppname(): void;
getCollisionFilter(): (output: any) => void;
hookFor(name: string, config: IHookConfig): void;
option(name: string, config?: IYeomanGeneratorOption): void;
rootGeneratorName(): string;
run(args?: any): void;
run(args: any, callback?: Function): void;
runHooks(callback?: Function): void;
sourceRoot(rootPath?: string): string;
templatePath(...path: string[]): string;
addListener(event: string, listener: Function): this;
on(event: string, listener: Function): this;
once(event: string, listener: Function): this;
removeListener(event: string, listener: Function): this;
removeAllListeners(event?: string): this;
setMaxListeners(n: number): this;
getMaxListeners(): number;
listeners(event: string): Function[];
emit(event: string, ...args: any[]): boolean;
listenerCount(type: string): number;
async(): any;
prompt(opt: IPromptOptions | IPromptOptions[], callback: (answers: any) => void): void;
log(message: string) : void;
npmInstall(packages: string[], options?: any, cb?: Function) :void;
installDependencies(options?: IInstallDependencyOptions): void;
spawnCommand(name: string, args?: string[], options?: Object): void;
spawnCommandSync(name: string, args?: string[], options?: Object): void;
appname: string;
gruntfile: IGruntFileStatic;
options: { [key: string]: any };
fs: IMemFsEditor;
}
export interface IMemFsEditor {
read(filepath: string, options?: Object): string;
readJSON(filepath: string, defaults?: Object): Object;
write(filepath: string, contents: string): void;
writeJSON(filepath: string, contents: Object, replacer?: Function, space?: number): void;
delete(filepath: string, options?: Object): void;
copy(from: string, to: string, options?: Object): void;
copyTpl(from: string, to: string, context: Object, options?: Object): void;
move(from: string, to: string, options?: Object): void;
exists(filepath: string): boolean;
commit(callback: Function): void;
commit(filters: any[], callback: Function): void;
}
export interface IInstallDependencyOptions {
npm?: boolean;
bower?: boolean;
skipMessage?: boolean;
callback?: Function;
}
export interface IChoice {
name: string;
value: string;
short?: string;
}
export interface IPromptOptions{
type?: string;
name: string;
message: string | ((answers: Object) => string);
choices?: any[] | ((answers: Object) => any);
default?: string | number | string[] | number[] | ((answers: Object) => (string | number | string[] | number[]));
validate?: ((input: any) => boolean | string);
filter?: ((input: any) => any);
when?: ((answers: Object) => boolean) | boolean;
store?: boolean;
}
export interface IGruntFileStatic {
loadNpmTasks(pluginName: string): void;
insertConfig(name:string, config:any):void;
registerTask(name:string, tasks:any):void;
insertVariable(name:string, value:any):void;
prependJavaScript(code:string):void;
}
export interface IArgumentConfig {
desc: string;
required?: boolean;
optional?: boolean;
type: any;
defaults?: any;
}
export interface IComposeSetting {
local?: string;
link?: string;
}
export interface IHookConfig {
as: string;
args: any;
options: any;
}
export interface IYeomanGeneratorOption {
alias?: string;
defaults?: any;
desc?: string;
hide?: boolean;
type?: any;
}
export interface IQueueProps {
initializing: () => void;
prompting?: () => void;
configuring?: () => void;
default?: () => void;
writing: {
[target: string]: () => void;
};
conflicts?: () => void;
install?: () => void;
end: () => void;
}
export interface INamedBase extends IYeomanGenerator {
}
export interface IBase extends INamedBase {
}
export interface IAssert {
file(path: string): void;
file(paths: string[]): void;
fileContent(file: string, reg: RegExp): void;
/** @param {[String, RegExp][]} pairs */
fileContent(pairs: any[][]): void;
/** @param {[String, RegExp][]|String[]} pairs */
files(pairs: any[]): void;
/**
* @param {Object} subject
* @param {Object|Array} methods
*/
implement(subject: any, methods: any): void;
noFile(file: string): void;
noFileContent(file: string, reg: RegExp): void;
/** @param {[String, RegExp][]} pairs */
noFileContent(pairs: any[][]): void;
/**
* @param {Object} subject
* @param {Object|Array} methods
*/
noImplement(subject: any, methods: any): void;
textEqual(value: string, expected: string): void;
}
export interface ITestHelper {
createDummyGenerator(): IYeomanGenerator;
createGenerator(name: string, dependencies: any[], args: any, options: any): IYeomanGenerator;
decorate(context: any, method: string, replacement: Function, options: any): void;
gruntfile(options: any, done: Function): void;
mockPrompt(generator: IYeomanGenerator, answers: any): void;
registerDependencies(dependencies: string[]): void;
restore(): void;
/** @param {String|Function} generator */
run(generator: any): IRunContext;
}
export interface IRunContext {
async(): Function;
inDir(dirPath: string): IRunContext;
/** @param {String|String[]} args */
withArguments(args: any): IRunContext;
withGenerators(dependencies: string[]): IRunContext;
withOptions(options: any): IRunContext;
withPrompts(answers: any): IRunContext;
}
/** @type file file-utils */
var file: any;
var assert: IAssert;
var test: ITestHelper;
// "generators" is deprecated
namespace generators {
export class NamedBase extends YeomanGeneratorBase implements INamedBase {
constructor(args: string | string[], options: any);
}
export class Base extends NamedBase implements IBase {
static extend(protoProps: IQueueProps, staticProps?: any): IYeomanGenerator;
}
}
export class NamedBase extends YeomanGeneratorBase implements INamedBase {
constructor(args: string | string[], options: any);
}
export class Base extends NamedBase implements IBase {
static extend(protoProps: IQueueProps, staticProps?: any): IYeomanGenerator;
}
}
declare module "yeoman-generator" {
export = yo;
}