2017-05-28 00:38:50 +02:00
"use strict" ;
/ * *
* @ license
* Copyright 2013 Palantir Technologies , Inc .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
2018-09-20 02:56:13 +02:00
var tslib _1 = require ( "tslib" ) ;
2017-05-28 00:38:50 +02:00
var fs = require ( "fs" ) ;
var path = require ( "path" ) ;
var error _1 = require ( "./error" ) ;
var utils _1 = require ( "./utils" ) ;
2018-09-20 02:56:13 +02:00
var CORE _RULES _DIRECTORY = path . resolve ( _ _dirname , "rules" ) ;
2017-05-28 00:38:50 +02:00
var cachedRules = new Map ( ) ;
function loadRules ( ruleOptionsList , rulesDirectories , isJs ) {
if ( isJs === void 0 ) { isJs = false ; }
var rules = [ ] ;
var notFoundRules = [ ] ;
var notAllowedInJsRules = [ ] ;
for ( var _i = 0 , ruleOptionsList _1 = ruleOptionsList ; _i < ruleOptionsList _1 . length ; _i ++ ) {
var ruleOptions = ruleOptionsList _1 [ _i ] ;
if ( ruleOptions . ruleSeverity === "off" ) {
// Perf: don't bother finding the rule if it's disabled.
continue ;
}
var ruleName = ruleOptions . ruleName ;
var Rule = findRule ( ruleName , rulesDirectories ) ;
if ( Rule === undefined ) {
notFoundRules . push ( ruleName ) ;
}
else if ( isJs && Rule . metadata !== undefined && Rule . metadata . typescriptOnly ) {
notAllowedInJsRules . push ( ruleName ) ;
}
else {
var rule = new Rule ( ruleOptions ) ;
if ( rule . isEnabled ( ) ) {
rules . push ( rule ) ;
}
2017-12-10 21:51:33 +01:00
if ( Rule . metadata !== undefined && Boolean ( Rule . metadata . deprecationMessage ) ) {
2017-05-28 00:38:50 +02:00
error _1 . showWarningOnce ( Rule . metadata . ruleName + " is deprecated. " + Rule . metadata . deprecationMessage ) ;
}
}
}
if ( notFoundRules . length > 0 ) {
2018-09-20 02:56:13 +02:00
var warning = utils _1 . dedent ( templateObject _1 || ( templateObject _1 = tslib _1 . _ _makeTemplateObject ( [ "\n Could not find implementations for the following rules specified in the configuration:\n " , "\n Try upgrading TSLint and/or ensuring that you have all necessary custom rules installed.\n If TSLint was recently upgraded, you may have old rules configured which need to be cleaned up.\n " ] , [ "\n Could not find implementations for the following rules specified in the configuration:\n " , "\n Try upgrading TSLint and/or ensuring that you have all necessary custom rules installed.\n If TSLint was recently upgraded, you may have old rules configured which need to be cleaned up.\n " ] ) ) , notFoundRules . join ( "\n " ) ) ;
2017-05-28 00:38:50 +02:00
error _1 . showWarningOnce ( warning ) ;
}
if ( notAllowedInJsRules . length > 0 ) {
2018-09-20 02:56:13 +02:00
var warning = utils _1 . dedent ( templateObject _2 || ( templateObject _2 = tslib _1 . _ _makeTemplateObject ( [ "\n Following rules specified in configuration couldn't be applied to .js or .jsx files:\n " , "\n Make sure to exclude them from \"jsRules\" section of your tslint.json.\n " ] , [ "\n Following rules specified in configuration couldn't be applied to .js or .jsx files:\n " , "\n Make sure to exclude them from \"jsRules\" section of your tslint.json.\n " ] ) ) , notAllowedInJsRules . join ( "\n " ) ) ;
2017-05-28 00:38:50 +02:00
error _1 . showWarningOnce ( warning ) ;
}
if ( rules . length === 0 ) {
2018-09-20 02:56:13 +02:00
var fileType = isJs ? "JavaScript" : "TypeScript" ;
error _1 . showWarningOnce ( "No valid rules have been specified for " + fileType + " files" ) ;
2017-05-28 00:38:50 +02:00
}
return rules ;
}
exports . loadRules = loadRules ;
2018-09-20 02:56:13 +02:00
/** @internal private API */
2017-05-28 00:38:50 +02:00
function findRule ( name , rulesDirectories ) {
var camelizedName = transformName ( name ) ;
// first check for core rules
var Rule = loadCachedRule ( CORE _RULES _DIRECTORY , camelizedName ) ;
return Rule !== undefined ? Rule :
// then check for rules within the first level of rulesDirectory
utils _1 . find ( utils _1 . arrayify ( rulesDirectories ) , function ( dir ) { return loadCachedRule ( dir , camelizedName , true ) ; } ) ;
}
exports . findRule = findRule ;
function transformName ( name ) {
// camelize strips out leading and trailing underscores and dashes, so make sure they aren't passed to camelize
// the regex matches the groups (leading underscores and dashes)(other characters)(trailing underscores and dashes)
var nameMatch = name . match ( /^([-_]*)(.*?)([-_]*)$/ ) ;
if ( nameMatch === null ) {
return name + "Rule" ;
}
return "" + nameMatch [ 1 ] + utils _1 . camelize ( nameMatch [ 2 ] ) + nameMatch [ 3 ] + "Rule" ;
}
/ * *
* @ param directory - An absolute path to a directory of rules
* @ param ruleName - A name of a rule in filename format . ex ) "someLintRule"
* /
function loadRule ( directory , ruleName ) {
2018-09-20 02:56:13 +02:00
var ruleFullPath ;
2017-10-14 18:40:54 +02:00
try {
2018-09-20 02:56:13 +02:00
// Resolve using node's path resolution to allow developers to write custom rules in TypeScript which can be loaded by TS-Node
ruleFullPath = require . resolve ( path . join ( directory , ruleName ) ) ;
2017-10-14 18:40:54 +02:00
}
2018-09-20 02:56:13 +02:00
catch ( _a ) {
return "not-found" ;
2017-10-14 18:40:54 +02:00
}
2018-09-20 02:56:13 +02:00
return require ( ruleFullPath ) . Rule ;
2017-10-14 18:40:54 +02:00
}
2017-05-28 00:38:50 +02:00
function loadCachedRule ( directory , ruleName , isCustomPath ) {
// use cached value if available
var fullPath = path . join ( directory , ruleName ) ;
var cachedRule = cachedRules . get ( fullPath ) ;
if ( cachedRule !== undefined ) {
return cachedRule === "not-found" ? undefined : cachedRule ;
}
2018-09-20 02:56:13 +02:00
// treat directory as a relative path (which needs to be resolved) if it's a custom rule directory
2017-05-28 00:38:50 +02:00
var absolutePath = directory ;
if ( isCustomPath ) {
2018-09-20 02:56:13 +02:00
absolutePath = path . resolve ( directory ) ;
if ( ! fs . existsSync ( absolutePath ) ) {
throw new error _1 . FatalError ( "Could not find custom rule directory: " + absolutePath ) ;
2017-05-28 00:38:50 +02:00
}
}
2018-09-20 02:56:13 +02:00
var Rule = loadRule ( absolutePath , ruleName ) ;
2017-05-28 00:38:50 +02:00
cachedRules . set ( fullPath , Rule ) ;
return Rule === "not-found" ? undefined : Rule ;
}
2018-09-20 02:56:13 +02:00
var templateObject _1 , templateObject _2 ;