Skip to content
This repository has been archived by the owner on Feb 27, 2024. It is now read-only.

Commit

Permalink
Refactor Template system
Browse files Browse the repository at this point in the history
  • Loading branch information
jhm-ciberman committed Mar 3, 2018
1 parent 4eb9a6e commit 17d945a
Show file tree
Hide file tree
Showing 27 changed files with 450 additions and 604 deletions.
21 changes: 21 additions & 0 deletions inversify.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,22 @@ import IDocumentationExtractor from "./src/generator/interfaces/IDocumentationEx
import IJSDocParser from "./src/parser/interfaces/IJSDocParser";
import JSDocParser from "./src/parser/JSDocParser";

import { getInstalledPath } from "get-installed-path";
import DocumentationGenerator from "./src/generator/DocumentationGenerator";
import IDocumentationGenerator from "./src/generator/interfaces/IDocumentationGenerator";
import { IGetInstalledPath } from "./src/npmmodules";
import ConsoleReporter from "./src/reporter/ConsoleReporter";
import IReporter from "./src/reporter/interfaces/IReporter";
import DesignRenderer from "./src/template/DesignRenderer";
import IDesignRenderer from "./src/template/interfaces/IDesignRenderer";
import IModuleFinder from "./src/template/interfaces/IModuleFinder";
import IPageFeeder from "./src/template/interfaces/IPageFeeder";
import IRenderablePageGenerator from "./src/template/interfaces/IRenderablePageGenerator";
import ITemplateLoader from "./src/template/interfaces/ITemplateLoader";
import ModuleFinder from "./src/template/ModuleFinder";
import PageFeeder from "./src/template/PageFeeder";
import RenderablePageGenerator from "./src/template/RenderablePageGenerator";
import TemplateLoader from "./src/template/TemplateLoader";
import IRuleValidator from "./src/validation/interfaces/IRuleValidator";
import IScriptValidator from "./src/validation/interfaces/IScriptValidator";
import RuleValidator from "./src/validation/RuleValidator";
Expand Down Expand Up @@ -48,4 +60,13 @@ container.bind<ICliGenerateFacade>(TYPES.ICliGenerateFacade).to(CliGenerateFacad
// Reporter
container.bind<IReporter>(TYPES.IReporter).to(ConsoleReporter);

// Template
container.bind<IModuleFinder>(TYPES.IModuleFinder).to(ModuleFinder);
container.bind<IRenderablePageGenerator>(TYPES.IRenderablePageGenerator).to(RenderablePageGenerator);
container.bind<IPageFeeder>(TYPES.IPageFeeder).to(PageFeeder);
container.bind<IDesignRenderer>(TYPES.IDesignRenderer).to(DesignRenderer);
container.bind<ITemplateLoader>(TYPES.ITemplateLoader).to(TemplateLoader);

// npm modules
container.bind<IGetInstalledPath>(TYPES.IGetInstalledPath).toFunction(getInstalledPath);
export default container;
38 changes: 28 additions & 10 deletions src/generator/DocumentationGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,42 @@ import IProjectConfig from "../config/interfaces/IProjectConfig";
import IGMProject from "../gm_project/interfaces/IGMProject";

import ProjectConfig from "../config/entities/ProjectConfig";
import TemplateLoader from "../template/TemplateLoader";
import IDesignRenderer from "../template/interfaces/IDesignRenderer";
import IModuleFinder from "../template/interfaces/IModuleFinder";
import ITemplateLoader from "../template/interfaces/ITemplateLoader";
import IDocProjectGenerator from "./interfaces/IDocProjectGenerator";
import IDocumentationGenerator from "./interfaces/IDocumentationGenerator";

/**
* Generates the documentation.
*/
@injectable()
export default class DocumentationGenerator {
export default class DocumentationGenerator implements IDocumentationGenerator {

/**
* The project config
* The doc project generator
*/
@inject(TYPES.IDocProjectGenerator)
private _generator: IDocProjectGenerator;

/**
* The module finder
*/
@inject(TYPES.IModuleFinder)
private _moduleFinder: IModuleFinder;

/**
* The design renderer
*/
@inject(TYPES.IDesignRenderer)
private _designRenderer: IDesignRenderer;

/**
* The template loader
*/
@inject(TYPES.ITemplateLoader)
private _templateLoader: ITemplateLoader;

/**
* Generates the documentation files for the project.
* @return Promise with the path of the output folder
Expand All @@ -36,24 +57,21 @@ export default class DocumentationGenerator {
throw new Error(`Design "${designName}" not found`);
}
const outputFolder = config.output.outputFolder;
const design = template.getDesign(config.output.design);
await design.renderPages(outputFolder, docProject);
await design.copyFiles(outputFolder);

const design = template.getDesign(config.output.design) || template.defaultDesign;
await this._designRenderer.render(design, docProject, outputFolder);
return outputFolder;
}

/**
* Loads the template
*/
private async _loadTemplate(output: IOutputConfig) {
const templateLoader = new TemplateLoader();
let folder;
if (output.templatesFolder !== "") {
folder = path.resolve(output.templatesFolder, output.template);
} else {
folder = await templateLoader.getTemplateModulePath(output.template);
folder = await this._moduleFinder.find("docs_gm-" + output.template);
}
return await templateLoader.loadFrom(folder);
return await this._templateLoader.loadFrom(folder);
}
}
8 changes: 8 additions & 0 deletions src/npmmodules.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { getInstalledPath } from "get-installed-path";


/*
This file contains all the external (mockable) npm modules types
*/

export type IGetInstalledPath = typeof getInstalledPath;
88 changes: 0 additions & 88 deletions src/template/Design.ts

This file was deleted.

58 changes: 58 additions & 0 deletions src/template/DesignRenderer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { inject, injectable } from "inversify";
import { TYPES } from "../../types";

import * as fse from "fs-extra";
import * as globby from "globby";
import * as nunjucks from "nunjucks";
import * as path from "path";

import DocProject from "../doc_models/DocProject";
import Design from "./entities/Design";
import IDesignRenderer from "./interfaces/IDesignRenderer";
import IRenderablePageGenerator from "./interfaces/IRenderablePageGenerator";

/**
* This class renders a given design and writes the files to an output folder.
* It also copy the other files needed by the Design
*/
@injectable()
export default class DesignRenderer implements IDesignRenderer {

/**
* The renderable page generator
*/
@inject(TYPES.IRenderablePageGenerator)
private _renderablePageGenerator: IRenderablePageGenerator;

/**
* Renders the documentation HTML files for the specified docProject.
* @param outputFolder The output folder
* @param docProject The docProject to generate the documentation for
*/
public async render(design: Design, docProject: DocProject, outputFolder: string): Promise<void> {
const env = nunjucks.configure(design.template.folder, { autoescape: false });
for (const page of design.pages) {
const nunjucksTemplate = env.getTemplate(page.in, true);
for (const rp of this._renderablePageGenerator.getPages(page, docProject)) {
const content = nunjucksTemplate.render(rp.encodedData);
const filename = path.resolve(outputFolder, rp.outputFile);
await fse.outputFile(filename, content);
}
}
await this._copyFiles(outputFolder, design);
}

/**
* Copy the Design files inside the outputFolder. By default, it will copy
* all files except the package.json, template.json and *.njk files.
* @param outputFolder The output folder
*/
private async _copyFiles(outputFolder: string, design: Design) {
const files = await globby(design.copy, { cwd: design.template.folder });
for (const file of files) {
const outputFile = path.resolve(outputFolder, file);
const inputFile = path.resolve(design.template.folder, file);
await fse.copy(inputFile, outputFile);
}
}
}
36 changes: 36 additions & 0 deletions src/template/ModuleFinder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

import { inject, injectable } from "inversify";
import pkgDir = require("pkg-dir");
import { TYPES } from "../../types";
import { IGetInstalledPath } from "../npmmodules";
import IModuleFinder from "./interfaces/IModuleFinder";

/**
* Finds a module installed locally or globally and returns his path
*/
@injectable()
export default class ModuleFinder implements IModuleFinder {

/**
* The "getInstalledPath" npm module
*/
@inject(TYPES.IGetInstalledPath)
private _getInstalledPath: IGetInstalledPath;

/**
* Gets the path of a template npm module from a global installation or local installation.
* @param templateName The name of the template to find
*/
public async find(moduleName: string): Promise<string> {
try {
return await this._getInstalledPath(moduleName);
} catch (e) {
try {
const cwd = await pkgDir() as string;
return await this._getInstalledPath(moduleName, { local: true, cwd });
} catch (e) {
throw new Error(`Cannot find the module ${moduleName}`);
}
}
}
}
69 changes: 0 additions & 69 deletions src/template/Page.ts

This file was deleted.

Loading

0 comments on commit 17d945a

Please sign in to comment.