UNPKG

repolinter

Version:
116 lines (76 loc) 6.22 kB
# Development Repolinter is broken down into 7 main components, each of which is contained in a subfolder: - **Axioms** - located under [axioms](../axioms) - **CLI** - located under [bin](../bin) - **Rules** - located under [rules](../rules) - **Fixes** - located under [fixes](../fixes) - **Formatters** - located under [formatters](../formatters) - **Utilities** - located under [lib](../lib) - **Built-In Rulesets and Schema** - located under [rulesets](../rulesets) ## Axioms Axioms are registered in [axioms/axioms.js](../axioms/axioms.js) and in [rulesets/schema.json](../rulesets/schema.json). An axiom implementation consists of a module with the following interface: ```TypeScript async (fs: FileSystem) => Result ``` Where fs is a [`FileSystem`](../lib/file_system.js) scoped to the current repository. The contents of the result should be an array of targets where `t.path` is a target that the axiom has determined is valid (ex. for language detecting axiom a possible result could be `new Result('', [{ path: 'javascript' passed: true }, { path: 'typescript', passed: true}], true)`). If the axiom fails to execute, it should return a failing result with an error message included instead of throwing an error. ## Rules A rule consists of two parts: a JavaScript module, which determines the rule's functionality and a JSON schema, which validates the rule's configuration options in rulesets. Rules are registered in [rules/rules.js](../rules/rules.js) and [rulesets/schema.json](../rulesets/schema.json). Rules are also documented under [rules.md](./rules.md). ### Rule Configuration JSON Schema The configuration JSON schema determines how `rule.options` should be validated for this rule. All [JSON Schema](https://json-schema.org/) tools supported by [AJV](https://ajv.js.org/) all available, with a few important caveats: - The file itself should always be named `<rule-name>-config.json` and be located under the `rules` folder. - The top-level type should always be `object`. - The `$id` field should be an absolute raw.githubusercontent.com URL to where the schema is hosted on GitHub (ex. https://raw.githubusercontent.com/todogroup/repolinter/master/rules/apache-notice-config.json). This allows IDEs such as VSCode to apply the schema via a URL. To get started, you can use the following template: ```JSON { "$schema": "http://json-schema.org/draft-07/schema", "$id": "https://raw.githubusercontent.com/todogroup/repolinter/master/rules/<rule-name>-config.json", "type": "object", "properties": {} } ``` Due to limitations with JSON Schema, you also must register your rule configuration schema in [rulesets/schema.json](../rulesets/schema.json) by adding the following item to the list under `root.then.properties.rules.properties.rule.allOf`: ```JSON { "if": { "properties": { "type": { "const": "<rule-name>" } } }, "then": { "properties": { "options": { "$ref": "../rules/<rule-name>-config.json" } } } } ``` ### JavaScript Implementation A rule implementation consists of a module with the following interface: ```TypeScript async (fs: FileSystem, opts /* type determined by your JSON schema */) => Result ``` Where fs is a [`FileSystem`](../lib/file_system.js) scoped to the current repository and `opts` is the options provided by the ruleset. A rule implementation is encouraged to use `Result#targets` to show the individual files/patterns checked when processing the rule. Including filenames in `Result#message` is discouraged as it makes formatting difficult. If a rule fails to execute, it should throw an error. ## Fixes A fix, similar to a rule, consists of two parts: a JavaScript module, which determines the fix's functionality and a JSON schema, which validates the fix's configuration options in rulesets. Fixes are registered in [fixes/fixes.js](../fixes/fixes.js) and [rulesets/schema.json](../rulesets/schema.json). Fixes are also documented under [fixes.md](./fixes.md). ### Fix Configuration JSON Schema Fix JSON schemas work identically to [rule JSON schemas](#rule-configuration-json-schema), with the only difference the respective names and paths. To get started, you can use the following template: ```JSON { "$schema": "http://json-schema.org/draft-07/schema", "$id": "https://raw.githubusercontent.com/todogroup/repolinter/master/fixes/<fix-name>-config.json", "type": "object", "properties": {} } ``` Similar as with rules, you must register the fix schema in [rulesets/schema.json](../rulesets/schema.json) by adding the following item to the list under `root.then.properties.rules.properties.fix.allOf` (note that this is a different list than the rule registration list): ```JSON { "if": { "properties": { "type": { "const": "<fix-name>" } } }, "then": { "properties": { "options": { "$ref": "../rules/<fix-name>-config.json" } } } } ``` ### JavaScript Implementation Unlike rules, a fix implementation consists of a module with the following interface: ```TypeScript async (fs: FileSystem, options /* Type determined by your JSON schema */, targets: string[], dryRun: boolean) => Result ``` Where fs is a [`FileSystem`](../lib/file_system.js) scoped to the current repository, `opts` is the options provided by the ruleset, `targets` are filepaths which did not pass the rule associated with this fix, and `dryRun` determines if the fix is allowed to make changes to the repository. The fix implementation is encouraged to use `Result#targets` to show the individual files/patterns changed. If the fix fails to execute, it should either return a failed result or throw an error. ## Formatters Formatters are exported by [index.js](../index.js) and manually called by the [CLI](../bin/repolinter.js). A formatter implementation consists of the following interface: ```TypeScript interface Formatter { formatOutput(output: LintResult, dryRun: boolean): string } ``` Formatters do not print to `STDOUT` instead choosing to return the output as a string. If needed, a formatter can accept extra configuration from the ruleset through the `formatOptions` property, which will be directly passed through to `LintResult#formatOptions`. These options are not typed and are formatter dependent.