forked from stdlib-js/stdlib
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add rule to require angle-bracketed links to include a protocol
- Loading branch information
Showing
9 changed files
with
861 additions
and
0 deletions.
There are no files selected for viewing
138 changes: 138 additions & 0 deletions
138
...dules/@stdlib/_tools/eslint/rules/jsdoc-no-auto-link-without-protocol/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
# Link Protocol | ||
|
||
> [ESLint rule][eslint-rules] to require angle-bracketed Markdown links to contain protocols in JSDoc descriptions. | ||
<section class="intro"> | ||
|
||
</section> | ||
|
||
<!-- /.intro --> | ||
|
||
<section class="usage"> | ||
|
||
## Usage | ||
|
||
```javascript | ||
var rule = require( '@stdlib/_tools/eslint/rules/jsdoc-no-auto-link-without-protocol' ); | ||
``` | ||
|
||
#### rule | ||
|
||
[ESLint rule][eslint-rules] to require angle-bracketed Markdown links to contain protocols in JSDoc descriptions. | ||
|
||
**Bad**: | ||
|
||
<!-- eslint-disable stdlib/jsdoc-no-auto-link-without-protocol, stdlib/jsdoc-markdown-remark --> | ||
|
||
```javascript | ||
/** | ||
* Beep. | ||
* | ||
* <foo@bar.com> | ||
* | ||
* @returns {string} a value | ||
* | ||
* @example | ||
* var str = beep(); | ||
* // returns 'boop' | ||
*/ | ||
function beep() { | ||
return 'boop'; | ||
} | ||
``` | ||
|
||
**Good**: | ||
|
||
```javascript | ||
/** | ||
* Beep. | ||
* | ||
* <mailto:foo@bar.com> | ||
* | ||
* @returns {string} a value | ||
* | ||
* @example | ||
* var str = beep(); | ||
* // returns 'boop' | ||
*/ | ||
function beep() { | ||
return 'boop'; | ||
} | ||
``` | ||
|
||
</section> | ||
|
||
<!-- /.usage --> | ||
|
||
<section class="examples"> | ||
|
||
## Examples | ||
|
||
<!-- eslint no-undef: "error" --> | ||
|
||
```javascript | ||
var Linter = require( 'eslint' ).Linter; | ||
var rule = require( '@stdlib/_tools/eslint/rules/jsdoc-no-auto-link-without-protocol' ); | ||
|
||
var linter = new Linter(); | ||
var result; | ||
var code; | ||
|
||
// Generate our source code: | ||
code = [ | ||
'/**', | ||
'* Beep boop.', | ||
'*', | ||
'* <foo@bar.com>', | ||
'*', | ||
'*', | ||
'* @param {string} str - input value', | ||
'* @returns {string} output value', | ||
'*', | ||
'* @example', | ||
'* var out = beep( "boop" );', | ||
'* // returns "beepboop"', | ||
'*/', | ||
'function beep( str ) {', | ||
'\treturn "beep" + str;', | ||
'}' | ||
].join( '\n' ); | ||
|
||
// Register the ESLint rule: | ||
linter.defineRule( 'jsdoc-no-auto-link-without-protocol', rule ); | ||
|
||
// Lint the code: | ||
result = linter.verify( code, { | ||
'rules': { | ||
'jsdoc-no-auto-link-without-protocol': 'error' | ||
} | ||
}); | ||
console.log( result ); | ||
/* => | ||
[ | ||
{ | ||
'ruleId': 'jsdoc-no-auto-link-without-protocol', | ||
'severity': 2, | ||
'message': 'All automatic links must start with a protocol', | ||
'line': 4, | ||
'column': 3, | ||
'nodeType': null, | ||
'source': '* <foo@bar.com>', | ||
'endLine': 13, | ||
'endColumn': 3 | ||
} | ||
] | ||
*/ | ||
``` | ||
|
||
</section> | ||
|
||
<!-- /.examples --> | ||
|
||
<section class="links"> | ||
|
||
[eslint-rules]: https://eslint.org/docs/developer-guide/working-with-rules | ||
|
||
</section> | ||
|
||
<!-- /.links --> |
54 changes: 54 additions & 0 deletions
54
...modules/@stdlib/_tools/eslint/rules/jsdoc-no-auto-link-without-protocol/examples/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
'use strict'; | ||
|
||
var Linter = require( 'eslint' ).Linter; | ||
var rule = require( './../lib' ); | ||
|
||
var linter = new Linter(); | ||
var result; | ||
var code; | ||
|
||
// Generate our source code: | ||
code = [ | ||
'/**', | ||
'* Beep boop.', | ||
'*', | ||
'* <foo@bar.com>', | ||
'*', | ||
'*', | ||
'* @param {string} str - input value', | ||
'* @returns {string} output value', | ||
'*', | ||
'* @example', | ||
'* var out = beep( "boop" );', | ||
'* // returns "beepboop"', | ||
'*/', | ||
'function beep( str ) {', | ||
'\treturn "beep" + str;', | ||
'}' | ||
].join( '\n' ); | ||
|
||
// Register the ESLint rule: | ||
linter.defineRule( 'jsdoc-no-auto-link-without-protocol', rule ); | ||
|
||
// Lint the code: | ||
result = linter.verify( code, { | ||
'rules': { | ||
'jsdoc-no-auto-link-without-protocol': 'error' | ||
} | ||
}); | ||
console.log( result ); | ||
/* => | ||
[ | ||
{ | ||
'ruleId': 'jsdoc-no-auto-link-without-protocol', | ||
'severity': 2, | ||
'message': 'All automatic links must start with a protocol', | ||
'line': 4, | ||
'column': 3, | ||
'nodeType': null, | ||
'source': '* <foo@bar.com>', | ||
'endLine': 13, | ||
'endColumn': 3 | ||
} | ||
] | ||
*/ |
21 changes: 21 additions & 0 deletions
21
...node_modules/@stdlib/_tools/eslint/rules/jsdoc-no-auto-link-without-protocol/lib/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
'use strict'; | ||
|
||
/** | ||
* ESLint rule to require angle-bracketed Markdown links to contain protocols in JSDoc descriptions. | ||
* | ||
* @module @stdlib/_tools/eslint/rules/jsdoc-no-auto-link-without-protocol | ||
* | ||
* @example | ||
* var rule = require( '@stdlib/_tools/eslint/rules/jsdoc-no-auto-link-without-protocol' ); | ||
* | ||
* console.log( rule ); | ||
*/ | ||
|
||
// MODULES // | ||
|
||
var main = require( './main.js' ); | ||
|
||
|
||
// EXPORTS // | ||
|
||
module.exports = main; |
143 changes: 143 additions & 0 deletions
143
lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-no-auto-link-without-protocol/lib/main.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
'use strict'; | ||
|
||
// MODULES // | ||
|
||
var parseJSDoc = require( 'doctrine' ).parse; | ||
var remark = require( 'remark' ); | ||
var remarkLint = require( 'remark-lint' ); | ||
var remarkPlugin = require( 'remark-lint-no-auto-link-without-protocol' ); | ||
var isObject = require( '@stdlib/assert/is-object' ); | ||
var findJSDoc = require( '@stdlib/_tools/eslint/utils/find-jsdoc' ); | ||
|
||
|
||
// VARIABLES // | ||
|
||
var DOPTS = { | ||
'sloppy': true, | ||
'unwrap': true | ||
}; | ||
|
||
|
||
// MAIN // | ||
|
||
/** | ||
* Rule to require angle-bracketed Markdown links to contain protocols in JSDoc descriptions. | ||
* | ||
* @param {Object} context - ESLint context | ||
* @returns {Object} validators | ||
*/ | ||
function main( context ) { | ||
var source; | ||
var config; | ||
var lint; | ||
|
||
config = { | ||
'plugins': [ | ||
remarkLint, | ||
[ remarkPlugin, 'error' ] | ||
] | ||
}; | ||
lint = remark().use( config ).processSync; | ||
source = context.getSourceCode(); | ||
|
||
return { | ||
'FunctionExpression:exit': validate, | ||
'FunctionDeclaration:exit': validate, | ||
'VariableDeclaration:exit': validate, | ||
'ExpressionStatement:exit': validate | ||
}; | ||
|
||
/** | ||
* Lints JSDoc descriptions. | ||
* | ||
* @private | ||
* @param {ASTNode} node - AST node | ||
*/ | ||
function validate( node ) { | ||
var jsdoc; | ||
var vfile; | ||
var ast; | ||
|
||
jsdoc = findJSDoc( source, node ); | ||
if ( isObject( jsdoc ) ) { | ||
ast = parseJSDoc( jsdoc.value, DOPTS ); | ||
if ( ast.description ) { | ||
vfile = lint( ast.description ); | ||
if ( vfile.messages.length ) { | ||
reportErrors( vfile.messages, jsdoc.loc ); | ||
} | ||
} | ||
} | ||
} // end FUNCTION validate() | ||
|
||
/** | ||
* Reports Markdown lint errors. | ||
* | ||
* @private | ||
* @param {ObjectArray} errors - Markdown lint errors | ||
* @param {Object} location - JSDoc location information | ||
*/ | ||
function reportErrors( errors, location ) { | ||
var err; | ||
var msg; | ||
var loc; | ||
var i; | ||
|
||
for ( i = 0; i < errors.length; i++ ) { | ||
err = errors[ i ]; | ||
msg = err.message; | ||
loc = copyLocationInfo( location ); | ||
loc.start.line = err.location.start.line + 1; // Note: we assume `/**` is on its own line | ||
loc.start.column = err.location.start.column + 1; // Note: we assume that 1 space separates `*` from JSDoc description content (e.g., `* ## Beep`) | ||
report( msg, loc ); | ||
} | ||
} // end FUNCTION reportErrors() | ||
|
||
/** | ||
* Copies AST node location info. | ||
* | ||
* @private | ||
* @param {Object} loc - AST node location | ||
* @returns {Object} copied location info | ||
*/ | ||
function copyLocationInfo( loc ) { | ||
return { | ||
'start': { | ||
'line': loc.start.line, | ||
'column': loc.start.column | ||
}, | ||
'end': { | ||
'line': loc.end.line, | ||
'column': loc.end.column | ||
} | ||
}; | ||
} // end FUNCTION copyLocationInfo() | ||
|
||
/** | ||
* Reports an error message. | ||
* | ||
* @private | ||
* @param {string} msg - error message | ||
* @param {Object} loc - error location info | ||
*/ | ||
function report( msg, loc ) { | ||
context.report({ | ||
'node': null, | ||
'message': msg, | ||
'loc': loc | ||
}); | ||
} // end FUNCTION report() | ||
} // end FUNCTION main() | ||
|
||
|
||
// EXPORTS // | ||
|
||
module.exports = { | ||
'meta': { | ||
'docs': { | ||
'description': 'require angle-bracketed Markdown links to contain protocols in JSDoc descriptions' | ||
}, | ||
'schema': [] | ||
}, | ||
'create': main | ||
}; |
Oops, something went wrong.