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

Commit

Permalink
Refactor Rules and make IReporter injectable
Browse files Browse the repository at this point in the history
  • Loading branch information
jhm-ciberman committed Mar 2, 2018
1 parent b58d1a2 commit d2bb6c8
Show file tree
Hide file tree
Showing 22 changed files with 251 additions and 213 deletions.
26 changes: 11 additions & 15 deletions inversify.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,38 +15,34 @@ import IDocumentationExtractor from "./src/generator/interfaces/IDocumentationEx
import IJSDocParser from "./src/parser/interfaces/IJSDocParser";
import JSDocParser from "./src/parser/JSDocParser";

import IRule from "./src/validation/interfaces/IRule";
import ConsoleReporter from "./src/reporter/ConsoleReporter";
import IReporter from "./src/reporter/interfaces/IReporter";
import IRuleValidator from "./src/validation/interfaces/IRuleValidator";
import IScriptValidator from "./src/validation/interfaces/IScriptValidator";
import IValidableScript from "./src/validation/interfaces/IValidableScript";
import RuleMismatchingArguments from "./src/validation/rules/RuleMismatchingArguments";
import RuleMismatchingFunctionName from "./src/validation/rules/RuleMismatchingFunctionName";
import RuleNoDescription from "./src/validation/rules/RuleNoDescription";
import RulePrivate from "./src/validation/rules/RulePrivate";
import RuleUndocumented from "./src/validation/rules/RuleUndocumented";
import RuleUndocumentedArguments from "./src/validation/rules/RuleUndocumentedArguments";
import RuleValidator from "./src/validation/RuleValidator";
import ScriptValidator from "./src/validation/ScriptValidator";

/* tslint:disable:max-line-length */
const container = new Container();

// Validation
container.bind<IScriptValidator>(TYPES.IScriptValidator).to(ScriptValidator);
container.bind<IRuleValidator>(TYPES.IRuleValidator).to(RuleValidator);

// Generator
container.bind<IDocumentationExtractor>(TYPES.IDocumentationExtractor).to(DocumentationExtractor);

// Parser
container.bind<IJSDocParser>(TYPES.IJSDocParser).to(JSDocParser);
container.bind<IDocProjectGenerator>(TYPES.IDocProjectGenerator).to(DocProjectGenerator);

// Config
container.bind<IConfigManager>(TYPES.IConfigManager).to(ConfigManager);

// Cli
container.bind<ICliGenerateFacade>(TYPES.ICliGenerateFacade).to(CliGenerateFacade);

// Rules
container.bind<IRule<IValidableScript>>(TYPES.RuleMismatchingArguments).to(RuleMismatchingArguments);
container.bind<IRule<IValidableScript>>(TYPES.RuleMismatchingFunctionName).to(RuleMismatchingFunctionName);
container.bind<IRule<IValidableScript>>(TYPES.RuleNoDescription).to(RuleNoDescription);
container.bind<IRule<IValidableScript>>(TYPES.RulePrivate).to(RulePrivate);
container.bind<IRule<IValidableScript>>(TYPES.RuleUndocumented).to(RuleUndocumented);
container.bind<IRule<IValidableScript>>(TYPES.RuleUndocumentedArguments).to(RuleUndocumentedArguments);
// Reporter
container.bind<IReporter>(TYPES.IReporter).to(ConsoleReporter);

export default container;
62 changes: 36 additions & 26 deletions src/cli/Cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as program from "commander";
import { inject } from "inversify";
import * as os from "os";
import IConfigManager from "../config/interfaces/IConfigManager";
import ReporterManager from "../reporter/ReporterManager";
import IReporter from "../reporter/interfaces/IReporter";
import ICliGenerateFacade from "./interfaces/ICliGenerateFacade.d";

// tslint:disable-next-line: no-var-requires
Expand All @@ -17,12 +17,34 @@ const packageJSON = require("../package.json");
export default class Cli {

/**
* Creates a new Cli instance
* @param f The injected CLIGenerateFacade
* The reporter
*/
constructor(
@inject(TYPES.ICliGenerateFacade) f: ICliGenerateFacade,
) {
@inject(TYPES.IReporter)
private _reporter: IReporter;

/**
* The CliGenerateFacade instance
*/
@inject(TYPES.ICliGenerateFacade)
private _cliGenerateFacade: ICliGenerateFacade;

/**
* Parses the arguments and shows the CLI on screen.
* @param argv The argv array (normally process.argv)
*/
public parse(argv: string[]): void {
this._initializeProgram();
program.parse(argv);

if (!argv.slice(2).length) {
program.help();
}
}

/**
* Inits the commander program instance
*/
private _initializeProgram() {

program
.version(packageJSON.version);
Expand All @@ -39,42 +61,30 @@ export default class Cli {
.option(
"--design <name>",
"The design name. If empty, it will use the first design in the designs list.",
(value) => { f.design = value; },
(value) => { this._cliGenerateFacade.design = value; },
)
.option(
"--template <name>",
"The template name to use",
(value) => { f.template = value; },
(value) => { this._cliGenerateFacade.template = value; },
)
.option(
"--outputFolder <path>",
"The output folder of the documentation",
(value) => { f.outputFolder = value; },
(value) => { this._cliGenerateFacade.outputFolder = value; },
)
.option(
"-p, --pattern <glob>",
"The glob pattern to use to include files in the project documentation",
(value) => { f.pattern = value; },
(value) => { this._cliGenerateFacade.pattern = value; },
)
.action((folder) => {
f.generate(folder).catch((err) => {
ReporterManager.reporter.error(err);
this._cliGenerateFacade.generate(folder).catch((err) => {
this._reporter.error(err);
});
});
}

/**
* Parses the arguments and shows the CLI on screen.
* @param argv The argv array (normally process.argv)
*/
public parse(argv: string[]): void {
program.parse(argv);

if (!argv.slice(2).length) {
program.help();
}
}

/**
* Exports the docs_gm config json and output the instructions to the screen.
*/
Expand All @@ -83,7 +93,7 @@ export default class Cli {
const userDir = os.homedir();
configManager.exportConfig(userDir)
.then((file) => this._outputConfigInstructions(file))
.catch((err) => ReporterManager.reporter.error(err));
.catch((err) => this._reporter.error(err));
}

/**
Expand Down Expand Up @@ -112,7 +122,7 @@ export default class Cli {
];

for (const str of strings) {
ReporterManager.reporter.info(str);
this._reporter.info(str);
}
}

Expand Down
26 changes: 13 additions & 13 deletions src/cli/CliGenerateFacade.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import open = require("open");
import * as path from "path";

import { injectable } from "inversify";
import { inject, injectable } from "inversify";
import container from "../../inversify.config";
import { TYPES } from "../../types";

Expand All @@ -11,7 +11,6 @@ import ProjectConfig from "../config/ProjectConfig";
import DocumentationGenerator from "../generator/DocumentationGenerator";
import ProjectLoader from "../gm_project/ProjectLoader";
import IReporter from "../reporter/interfaces/IReporter";
import ReporterManager from "../reporter/ReporterManager";
import ICliGenerateFacade from "./interfaces/ICliGenerateFacade.d";

/**
Expand All @@ -25,11 +24,6 @@ export default class CliGenerateFacade implements ICliGenerateFacade {
*/
public open: (url: string) => void = open;

/**
* The reporter used (used for dependency injection)
*/
public reporter: IReporter = ReporterManager.reporter;

/**
* The overridden design
*/
Expand All @@ -50,37 +44,43 @@ export default class CliGenerateFacade implements ICliGenerateFacade {
*/
public pattern: string | undefined;

/**
* The reporter used (used for dependency injection)
*/
@inject(TYPES.IReporter)
private _reporter: IReporter;

/**
* Generates the documentation for a given project
* @param projectPath The path to the project
* @param opts The option object to override
*/
public async generate(projectPath: string = "."): Promise<void> {

this.reporter.info("Loading Project...");
this._reporter.info("Loading Project...");

const loader = new ProjectLoader(projectPath);
const project = await loader.load();

this.reporter.info("Loading project configuration...");
this._reporter.info("Loading project configuration...");

const configManager = container.get<IConfigManager>(TYPES.IConfigManager);
let config = await configManager.loadConfig(projectPath);

if (!config) {
this.reporter.info("Configuration not found. Using default configuration.");
this._reporter.info("Configuration not found. Using default configuration.");
config = new ProjectConfig();
}
config = this._overrideConfig(config);

this.reporter.info("Generating documentation... ");
this._reporter.info("Generating documentation... ");
const docsGenerator = new DocumentationGenerator();
const outFolder = await docsGenerator.generate(project, config);

this.reporter.info("Ready!");
this._reporter.info("Ready!");

const url = path.resolve(outFolder, "index.html");
this.reporter.info(`Opening ${url}`);
this._reporter.info(`Opening ${url}`);
this.open(url);
}

Expand Down
2 changes: 0 additions & 2 deletions src/cli/interfaces/ICliGenerateFacade.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ export default interface ICliGenerateFacade {

open: (url: string) => void;

reporter: IReporter;

design: string | undefined;

template: string | undefined;
Expand Down
9 changes: 5 additions & 4 deletions src/parser/JSDocParser.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import parse = require("comment-parser");
import { injectable } from "inversify";
import { inject, injectable } from "inversify";
import { TYPES } from "../../types";
import DocScript from "../doc_models/DocScript";
import IReporter from "../reporter/interfaces/IReporter";
import ReporterManager from "../reporter/ReporterManager";
import DocScriptFactory from "./DocScriptFactory";
import IJSDocParser from "./interfaces/IJSDocParser";

Expand All @@ -20,7 +20,8 @@ export default class JSDocParser implements IJSDocParser {
/**
* The reporter to use
*/
public reporter: IReporter = ReporterManager.reporter;
@inject(TYPES.IReporter)
private _reporter: IReporter;

/**
* Parses a gml script string and extracts all the documentation for a passed script
Expand Down Expand Up @@ -82,7 +83,7 @@ export default class JSDocParser implements IJSDocParser {
break;
default:
if (this.warnUnrecognizedTags) {
this.reporter.warn(`Unrecognized tag "${ tag.tag.toLowerCase() }" at script "${ name }"`);
this._reporter.warn(`Unrecognized tag "${ tag.tag.toLowerCase() }" at script "${ name }"`);
}
}
}
Expand Down
1 change: 0 additions & 1 deletion src/parser/interfaces/IJSDocParser.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@ import IReporter from "../../reporter/interfaces/IReporter";

export default interface IJSDocParser {
warnUnrecognizedTags: boolean;
reporter: IReporter;
parse(name: string, text: string): DocScript;
}
41 changes: 41 additions & 0 deletions src/reporter/ConsoleReporter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { injectable } from "inversify";
import IReporter from "./interfaces/IReporter";

/**
* The standard console reporter
*/
@injectable()
export default class ConsoleReporter implements IReporter {
/**
* Show a debug message
* @param str The message
*/
public debug(...str: any[]): void {
// tslint:disable-next-line:no-console
console.debug(...str);
}
/**
* Show a info message
* @param str The message
*/
public info(...str: any[]): void {
// tslint:disable-next-line:no-console
console.info(...str);
}
/**
* Show a warn message
* @param str The message
*/
public warn(...str: any[]): void {
// tslint:disable-next-line:no-console
console.warn(...str);
}
/**
* Show a error message
* @param str The message
*/
public error(...str: any[]): void {
// tslint:disable-next-line:no-console
console.error(...str);
}
}
13 changes: 0 additions & 13 deletions src/reporter/ReporterManager.ts

This file was deleted.

36 changes: 36 additions & 0 deletions src/validation/RuleValidator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { inject, injectable } from "inversify";
import { TYPES } from "../../types";
import IValidationRuleConfig from "../config/interfaces/IValidationRuleConfig";
import IReporter from "../reporter/interfaces/IReporter";
import IRule from "./interfaces/IRule";
import IValidableScript from "./interfaces/IValidableScript";

/**
* This class validates a single IRule against a ValidableScript with a rule configuration.
*/
@injectable()
export default class RuleValidator {

/**
* Reporter used by the class to warn about validations.
*/
@inject(TYPES.IReporter)
private _reporter: IReporter;

/**
* Validates a single rule against a ValidableScript
* @param element The element to check the rule against
* @param ruleConfig The rule configuration
*/
public validate(rule: IRule, script: IValidableScript, config: IValidationRuleConfig): boolean {
if (!rule.isValid(script)) {
// Rule is invalid
if (config.warn) {
// Should warn about invalid rule
this._reporter.warn(rule.getWarnMessage(script));
}
return !(config.ignore);
}
return true;
}
}
Loading

0 comments on commit d2bb6c8

Please sign in to comment.