From f34e91ff1c8d99dcdd11dc2fbe396c14c599e8f1 Mon Sep 17 00:00:00 2001 From: Kunihiko Toumura <30313213+k-toumura@users.noreply.github.com> Date: Fri, 21 Dec 2018 11:58:23 +0900 Subject: [PATCH] Created Design: Flow Linter (markdown) --- Design:-Flow-Linter.md | 115 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 Design:-Flow-Linter.md diff --git a/Design:-Flow-Linter.md b/Design:-Flow-Linter.md new file mode 100644 index 0000000..3a213bb --- /dev/null +++ b/Design:-Flow-Linter.md @@ -0,0 +1,115 @@ +# Purpose +Node-RED makes it easy to program by wiring nodes together. But sometimes, because of its less restrictive nature, programmer may write flows that are hard to understand. For example: +- Function node that has no name or description. The reader need to read internal JavaScript code to understand what the node do, +- Excessive amount of nodes in a single flow. + +And, some subtle differences in programming style cause readability low. +- Size of flow on Flow Editor +- Grid size +- JavaScript coding style in function nodes. + +The flow linter provides a framework that automatically checks whether a flow is compliant with rules and conventions. + +# Use cases +- To use the consistent coding rules in a team, the tool checks a flow before submit to a repository. +- To prevent bugs, the tool checks a flow when the programmer requests it, or continuously checks as a background task of Flow Editor. + - Editor displays suggestions to user: 'This HTTP-in node doesn't have corresponding HTTP-out node.', 'These nodes in this flow must preserve message properties set by HTTP-in', etc. +- To prevent move/edit/delete node accidentally, some node position or property change can be restricted by rules. + +# Requirements / ideas +- There are various rules/conventions, and each organization/community/etc. has different policies on it. Because of this, the rules has to be pluggable and customizable. +- Linter is used in both batch-style (e.g. command-line interface) and on-the-fly-style (e.g. integrated in Editor). The core service of linter can be used in both usages. +- Rule configuration can be exported as JSON format and can be included in flow.json so that developers can distribute flow templates with their own restrictions. +- Use compatible format with other linter/tester tools for result output. + +# User interface + +## Command-line interface (batch-style) +![External CLI](https://github.com/node-red-hitachi/node-red/wiki/images/linter/external-cli.png) + +## Integrated in Editor (in Sidebar, batch-style) +![Sidebar](https://github.com/node-red-hitachi/node-red/wiki/images/linter/sidebar.png) + + +# Architecture + +![Functional diagram](https://github.com/node-red-hitachi/node-red/wiki/images/linter/func-diagram.png) + +## Flow manipulation API +The flow manipulation API provides a highlevel interface to handle flow.json file. +Programmers need not to know about the format of flow.json and structure of flow object. + +## pluggable rules +Developer can create their own rules by writing plug-in module. + +Following code shows example of plug-in, that checks existance of name of function node. + +```javascript +function check (afs, conf, cxt) { + const funcs = [...afs] // extract all nodes + .filter(e => e.type==='function') // filter out unrelated nodes + .map(e => { + return {id:e.id, name:e.name}; // extract their node id and name + }); + const verified = funcs + .filter(e=> e.name === undefined || e.name === "") // check existance of name + .map(e=> { + return {rule:"no-func-name", id:e.id, result:conf}; // generate result + }); + + return verified; +} + +module.exports = { + check: check +}; + +``` +- Flow-check code in plug-in is used on both CLI (runs on node.js) and Editor (runs on browser). To use same code in both node.js and browser, there are tools for generate codes for both: + - [Browserify](http://browserify.org/): get all dependent npm modules and put in one script file. + - [Babel](https://babeljs.io/): convert modern JavaScript (ES2015+) code to (traditional) JavaScript code that can be executed on various browsers. + +## Configuration +Linter reads configuration files in following order: +1. Default configuration: nrlint.js in Node-RED install directory +2. Project-specific configuration: $HOME/.node-red/project/projectname/nrlint.js +3. Per-user configuration: $HOME/.node-red/nrlint.js +4. Command-line argument: nrlint --config nrlint.js / node-red --lintconfig nrlint.js + +If there is a conflict between them, latter definition overrides former one. + +- File format: + +```javascript +module.exports = { + "plugins": [ + "func-style" + ], + "rules": { + "func-style/no-func-name": "warn", + "func-style/eslint": { semi: 2 } + } +} +``` + +## Report format +- should be similar format with other linting tools (e.g. ESlint, JShint, ...) + +## Other Consideration +- When validation is invoked in Editor, validation codes should be executed in editor. API call to server-side is expencive, and it is need to add extra adminAPI in the core. + +# Implementation plan + +## First step +- Implement CLI version + - Considering future extention, e.g. use from Flow Editor, on-the-fly checking, etc. + +## Next steps +- Implement Editor-integrated version (in Sidebar, batch-style) +- Rule configuration UI +- Make rules be exported as JSON format and can be included in flow.json so that developers can distribute flow templates with their own restrictions. +- On-the-fly checking in Editor +![On the fly](https://github.com/node-red-hitachi/node-red/wiki/images/linter/on-the-fly.png) + +# Related works +- [Design: Flow Manipulation API](https://github.com/node-red/node-red/wiki/Design%3A-Flow-Manipulation-API)