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

Commit

Permalink
feat(generators): generators for page, component, directive, pipe, pr…
Browse files Browse the repository at this point in the history
…ovider

generators for page, component, directive, pipe, provider
  • Loading branch information
danbucholtz committed Feb 20, 2017
1 parent 333c7d0 commit e2a45e4
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 29 deletions.
22 changes: 19 additions & 3 deletions src/generators.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
import { Logger} from './logger/logger';
import { generateContext } from './util/config';
import * as Constants from './util/constants';
import { BuildContext, GeneratorOption, GeneratorRequest } from './util/interfaces';
import { BuildContext } from './util/interfaces';
import { applyTemplates, filterOutTemplates, GeneratorOption, GeneratorRequest, hydrateRequest, readTemplates, writeGeneratedFiles } from './generators/util';

export { GeneratorOption };
export { GeneratorRequest };

export function generateNonTab(request: GeneratorRequest) {
const context = generateContext();
return processNonTabRequest(context, request);
}

function processNonTabRequest(context: BuildContext, request: GeneratorRequest) {

function processNonTabRequest(context: BuildContext, request: GeneratorRequest): Promise<string[]> {
Logger.debug('[Generators] processNonTabRequest: Hydrating the request with project data ...');
const hydratedRequest = hydrateRequest(context, request);
Logger.debug('[Generators] processNonTabRequest: Reading templates ...');
return readTemplates(hydratedRequest.dirToRead).then((map: Map<string, string>) => {
Logger.debug('[Generators] processNonTabRequest: Filtering out NgModule and Specs if needed ...');
return filterOutTemplates(hydratedRequest, map);
}).then((filteredMap: Map<string, string>) => {
Logger.debug('[Generators] processNonTabRequest: Applying tempaltes ...');
const appliedTemplateMap = applyTemplates(hydratedRequest, filteredMap);
Logger.debug('[Generators] processNonTabRequest: Writing generated files to disk ...');
return writeGeneratedFiles(hydratedRequest, appliedTemplateMap);
});
}

export function listOptions() {
Expand All @@ -20,6 +35,7 @@ export function listOptions() {
list.push({type: Constants.PIPE, multiple: false});
list.push({type: Constants.PROVIDER, multiple: false});
list.push({type: Constants.TABS, multiple: true});
return list;
}


Expand Down
1 change: 1 addition & 0 deletions src/generators/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const CLASSNAME_VARIABLE = '$CLASSNAME';
export const FILENAME_VARIABLE = '$FILENAME';
export const SUPPLIEDNAME_VARIABLE = '$SUPPLIEDNAME';

export const KNOWN_FILE_EXTENSION = '.tmpl';

Expand Down
60 changes: 59 additions & 1 deletion src/generators/util.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,28 +177,86 @@ export class $CLASSNAMEComponent {
`;

const fileFive = '/Users/dan/fileFive';
const fileFiveContent = `
import { NgModule } from '@angular/core';
import { $CLASSNAME } from './$FILENAME';
import { IonicModule } from 'ionic-angular';
@NgModule({
declarations: [
$CLASSNAME,
],
imports: [
IonicModule.forChild($CLASSNAME)
],
entryComponents: [
$CLASSNAME
],
providers: []
})
export class $CLASSNAMEModule {}
`;

const fileSix = '/Users/dan/fileSix';
const fileSixContent = `
<!--
Generated template for the $CLASSNAME page.
See http://ionicframework.com/docs/v2/components/#navigation for more info on
Ionic pages and navigation.
-->
<ion-header>
<ion-navbar>
<ion-title>$SUPPLIEDNAME</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
</ion-content>
`;

const map = new Map<string, string>();
map.set(fileOne, fileOneContent);
map.set(fileTwo, fileTwoContent);
map.set(fileThree, fileThreeContent);
map.set(fileFour, fileFourContent);
map.set(fileFive, fileFiveContent);
map.set(fileSix, fileSixContent);

const className = 'SettingsView';
const fileName = 'settings-view';
const suppliedName = 'settings view';

const results = util.applyTemplates({ className: className, fileName: fileName}, map);
const results = util.applyTemplates({ name: suppliedName, className: className, fileName: fileName}, map);
const modifiedContentOne = results.get(fileOne);
const modifiedContentTwo = results.get(fileTwo);
const modifiedContentThree = results.get(fileThree);
const modifiedContentFour = results.get(fileFour);
const modifiedContentFive = results.get(fileFive);
const modifiedContentSix = results.get(fileSix);
expect(modifiedContentOne.indexOf(GeneratorConstants.CLASSNAME_VARIABLE)).toEqual(-1);
expect(modifiedContentOne.indexOf(GeneratorConstants.FILENAME_VARIABLE)).toEqual(-1);
expect(modifiedContentOne.indexOf(GeneratorConstants.SUPPLIEDNAME_VARIABLE)).toEqual(-1);
expect(modifiedContentTwo.indexOf(GeneratorConstants.CLASSNAME_VARIABLE)).toEqual(-1);
expect(modifiedContentTwo.indexOf(GeneratorConstants.FILENAME_VARIABLE)).toEqual(-1);
expect(modifiedContentTwo.indexOf(GeneratorConstants.SUPPLIEDNAME_VARIABLE)).toEqual(-1);
expect(modifiedContentThree.indexOf(GeneratorConstants.CLASSNAME_VARIABLE)).toEqual(-1);
expect(modifiedContentThree.indexOf(GeneratorConstants.FILENAME_VARIABLE)).toEqual(-1);
expect(modifiedContentThree.indexOf(GeneratorConstants.SUPPLIEDNAME_VARIABLE)).toEqual(-1);
expect(modifiedContentFour.indexOf(GeneratorConstants.CLASSNAME_VARIABLE)).toEqual(-1);
expect(modifiedContentFour.indexOf(GeneratorConstants.FILENAME_VARIABLE)).toEqual(-1);
expect(modifiedContentFour.indexOf(GeneratorConstants.SUPPLIEDNAME_VARIABLE)).toEqual(-1);
expect(modifiedContentFive.indexOf(GeneratorConstants.CLASSNAME_VARIABLE)).toEqual(-1);
expect(modifiedContentFive.indexOf(GeneratorConstants.FILENAME_VARIABLE)).toEqual(-1);
expect(modifiedContentFive.indexOf(GeneratorConstants.SUPPLIEDNAME_VARIABLE)).toEqual(-1);
expect(modifiedContentSix.indexOf(GeneratorConstants.CLASSNAME_VARIABLE)).toEqual(-1);
expect(modifiedContentSix.indexOf(GeneratorConstants.FILENAME_VARIABLE)).toEqual(-1);
expect(modifiedContentSix.indexOf(GeneratorConstants.SUPPLIEDNAME_VARIABLE)).toEqual(-1);
});
});

Expand Down
38 changes: 33 additions & 5 deletions src/generators/util.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { basename, join } from 'path';
import { basename, dirname, join } from 'path';
import { readdirSync} from 'fs';

import { paramCase, pascalCase } from 'change-case';

import * as Constants from '../util/constants';
import * as GeneratorConstants from './constants';
import { getPropertyValue, readFileAsync, replaceAll, writeFileAsync } from '../util/helpers';
import { BuildContext, GeneratorRequest, HydratedGeneratorRequest } from '../util/interfaces';
import { getPropertyValue, mkDirpAsync, readFileAsync, replaceAll, writeFileAsync } from '../util/helpers';
import { BuildContext } from '../util/interfaces';

export function hydrateRequest(context: BuildContext, request: GeneratorRequest) {
const hydrated = Object.assign({}, request) as HydratedGeneratorRequest;
Expand All @@ -32,6 +32,7 @@ export function readTemplates(pathToRead: string): Promise<Map<string, string>>
promise.then((fileContent: string) => {
filePathToContent.set(absolutePath, fileContent);
});
return promise;
});
return Promise.all(promises).then(() => {
return filePathToContent;
Expand All @@ -55,7 +56,8 @@ export function applyTemplates(request: HydratedGeneratorRequest, templates: Map
templates.forEach((fileContent: string, filePath: string) => {
const classnameRemovedContent = replaceAll(fileContent, GeneratorConstants.CLASSNAME_VARIABLE, request.className);
const fileNameRemovedContent = replaceAll(classnameRemovedContent, GeneratorConstants.FILENAME_VARIABLE, request.fileName);
appliedTemplateMap.set(filePath, fileNameRemovedContent);
const suppliedNameRemovedContent = replaceAll(fileNameRemovedContent, GeneratorConstants.SUPPLIEDNAME_VARIABLE, request.name);
appliedTemplateMap.set(filePath, suppliedNameRemovedContent);
});
return appliedTemplateMap;
}
Expand All @@ -68,13 +70,20 @@ export function writeGeneratedFiles(request: HydratedGeneratorRequest, processed
const newFileName = `${request.fileName}.${newFileExtension}`;
const fileToWrite = join(request.dirToWrite, newFileName);
createdFileList.push(fileToWrite);
promises.push(writeFileAsync(fileToWrite, fileContent));
promises.push(createDirAndWriteFile(fileToWrite, fileContent));
});
return Promise.all(promises).then(() => {
return createdFileList;
});
}

function createDirAndWriteFile(filePath: string, fileContent: string) {
const directory = dirname(filePath);
return mkDirpAsync(directory).then(() => {
return writeFileAsync(filePath, fileContent);
});
}

export function getDirToWriteToByType(context: BuildContext, type: string) {
if (type === Constants.COMPONENT) {
return context.componentsDir;
Expand All @@ -89,3 +98,22 @@ export function getDirToWriteToByType(context: BuildContext, type: string) {
}
throw new Error(`Unknown Generator Type: ${type}`);
}

export interface GeneratorOption {
type: string;
multiple: boolean;
};

export interface GeneratorRequest {
type?: string;
name?: string;
includeSpec?: boolean;
includeNgModule?: boolean;
};

export interface HydratedGeneratorRequest extends GeneratorRequest {
fileName?: string;
className?: string;
dirToRead?: string;
dirToWrite?: string;
};
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export * from './util/config';
export * from './util/helpers';
export * from './util/interfaces';

export * from './generators';

import { generateContext } from './util/config';
import { getAppScriptsVersion } from './util/helpers';
import { Logger } from './logger/logger';
Expand Down
13 changes: 12 additions & 1 deletion src/util/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { randomBytes } from 'crypto';
import { basename, dirname, extname, join } from 'path';
import { createReadStream, createWriteStream, readdir, readFile, readFileSync, readJsonSync, remove, unlink, writeFile } from 'fs-extra';
import { createReadStream, createWriteStream, ensureDir, readdir, readFile, readFileSync, readJsonSync, remove, unlink, writeFile } from 'fs-extra';
import * as osName from 'os-name';

import * as Constants from './constants';
Expand Down Expand Up @@ -184,6 +184,17 @@ export function copyFileAsync(srcPath: string, destPath: string) {
});
}

export function mkDirpAsync(directoryPath: string) {
return new Promise((resolve, reject) => {
ensureDir(directoryPath, (err: Error) => {
if (err) {
return reject(err);
}
return resolve();
});
});
}

export function readDirAsync(pathToDir: string) {
return new Promise<string[]>((resolve, reject) => {
readdir(pathToDir, (err: Error, fileNames: string[]) => {
Expand Down
19 changes: 0 additions & 19 deletions src/util/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,22 +189,3 @@ export interface WebpackModule {
export interface WebpackDependency {
moduleIdentifier: string;
};

export interface GeneratorOption {
type: string;
multiple: boolean;
};

export interface GeneratorRequest {
type?: string;
name?: string;
includeSpec?: boolean;
includeNgModule?: boolean;
};

export interface HydratedGeneratorRequest extends GeneratorRequest {
fileName?: string;
className?: string;
dirToRead?: string;
dirToWrite?: string;
};

0 comments on commit e2a45e4

Please sign in to comment.