From d9042ad0813b02019ac2ccdae9ab57b540a43594 Mon Sep 17 00:00:00 2001 From: Martin Hradil Date: Tue, 2 Aug 2016 12:53:54 +0000 Subject: [PATCH 1/8] eslintrc - drop ES6 rules currently, we have no `.es6` files and no outstanding PRs introducing ones, and configuring eslint to base rules on file extensions is problematic so dropping this one for now, and we'll reintroduce when we move all *.js files to es6 --- .eslintrc.js | 12 ++---------- bin/eslint | 4 ---- package.json | 1 - 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 7dae67adae5..f056abe86c3 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,7 +6,6 @@ if (mode === undefined) { console.warn('MIQ_ESLINT=vanilla\tfor non-angular, non-es6, non-spec code'); console.warn('MIQ_ESLINT=angular\tfor angular code'); console.warn('MIQ_ESLINT=spec\tfor specs'); - console.warn('MIQ_ESLINT=es6\tfor .es6 files'); } if (!mode) { @@ -14,8 +13,7 @@ if (!mode) { } var plugins = []; -var xtends = []; -var ecmaVersion = 5; +var xtends = ['airbnb-es5']; var globals = { API: false, // local: miq_api.js @@ -148,12 +146,6 @@ switch (mode) { globals = Object.assign(globals, specGlobals); break; - case 'es6': - // note that eslint has to be run with --ext .es6 to pick these up - xtends.push('airbnb'); - ecmaVersion = 6; - break; - default: console.error('Unknown mode: ' + mode + " - sorry"); global.process.exit(1); @@ -167,7 +159,7 @@ module.exports = { jquery: true, }, parserOptions: { - ecmaVersion: ecmaVersion, + ecmaVersion: 5, sourceType: 'script', ecmaFeatures: { globalReturn: false, diff --git a/bin/eslint b/bin/eslint index 53791d360cd..c72d4e564d8 100755 --- a/bin/eslint +++ b/bin/eslint @@ -16,9 +16,5 @@ MIQ_ESLINT=angular $ESLINT "$@" \ app/assets/javascripts/services \ app/assets/javascripts/components -MIQ_ESLINT=es6 $ESLINT "$@" \ - --ext .es6 \ - app/assets/javascripts/ - MIQ_ESLINT=spec $ESLINT "$@" \ spec/javascripts/ diff --git a/package.json b/package.json index 61ffe2c1a94..71a4f7335f9 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,6 @@ "devDependencies": { "babel-eslint": "^6.0.4", "eslint": "^2.10.2", - "eslint-config-airbnb": "^9.0.1", "eslint-config-airbnb-es5": "^1.0.9", "eslint-config-angular": "^0.5.0", "eslint-plugin-angular": "^1.0.1", From 05399d7a4ee8b33c853197497f4bde36d652e7a7 Mon Sep 17 00:00:00 2001 From: Martin Hradil Date: Tue, 2 Aug 2016 12:59:04 +0000 Subject: [PATCH 2/8] eslintrc - move spec-specific rules to hierarchical config under spec/javascripts/ specs will still inherit all the base rules, but additionally allow more spec-specific globals --- .eslintrc.js | 20 -------------------- bin/eslint | 3 --- spec/javascripts/.eslintrc.json | 14 ++++++++++++++ 3 files changed, 14 insertions(+), 23 deletions(-) create mode 100644 spec/javascripts/.eslintrc.json diff --git a/.eslintrc.js b/.eslintrc.js index f056abe86c3..1f31974a497 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,7 +5,6 @@ if (mode === undefined) { console.warn('Please use the environmental variable MIQ_ESLINT to enable specific rulesets..'); console.warn('MIQ_ESLINT=vanilla\tfor non-angular, non-es6, non-spec code'); console.warn('MIQ_ESLINT=angular\tfor angular code'); - console.warn('MIQ_ESLINT=spec\tfor specs'); } if (!mode) { @@ -30,20 +29,6 @@ var globals = { sprintf: false, // bower: sprintf }; -var specGlobals = { - describe: false, - context: false, - it: false, - beforeEach: false, - afterEach: false, - inject: false, - spyOn: false, - expect: false, - jasmine: false, - setFixtures: false, -}; - - var rules = { 'indent': [ 'error', 2, { SwitchCase: 1, @@ -141,11 +126,6 @@ switch (mode) { break; - case 'spec': - xtends.push('airbnb-es5'); - globals = Object.assign(globals, specGlobals); - break; - default: console.error('Unknown mode: ' + mode + " - sorry"); global.process.exit(1); diff --git a/bin/eslint b/bin/eslint index c72d4e564d8..e27318cd0c0 100755 --- a/bin/eslint +++ b/bin/eslint @@ -15,6 +15,3 @@ MIQ_ESLINT=angular $ESLINT "$@" \ app/assets/javascripts/directives \ app/assets/javascripts/services \ app/assets/javascripts/components - -MIQ_ESLINT=spec $ESLINT "$@" \ - spec/javascripts/ diff --git a/spec/javascripts/.eslintrc.json b/spec/javascripts/.eslintrc.json new file mode 100644 index 00000000000..ac9f4e10367 --- /dev/null +++ b/spec/javascripts/.eslintrc.json @@ -0,0 +1,14 @@ +{ + "globals": { + "describe": false, + "context": false, + "it": false, + "beforeEach": false, + "afterEach": false, + "inject": false, + "spyOn": false, + "expect": false, + "jasmine": false, + "setFixtures": false + } +} From 9df3df785dbfca2f0106953ab957291b62c63761 Mon Sep 17 00:00:00 2001 From: Martin Hradil Date: Tue, 2 Aug 2016 13:01:18 +0000 Subject: [PATCH 3/8] eslintrc - move angular-specific rules to hierarchical config files under components/, controllers/, directives/ and services/ will get additional angular-related rules applied to them (components/ is currently empty, but won't be for long..) --- .eslintrc.js | 55 ------------------- .../javascripts/components/.eslintrc.json | 1 + .../javascripts/controllers/.eslintrc.json | 28 ++++++++++ .../javascripts/directives/.eslintrc.json | 1 + .../javascripts/services/.eslintrc.json | 1 + bin/eslint | 13 +---- 6 files changed, 32 insertions(+), 67 deletions(-) create mode 120000 app/assets/javascripts/components/.eslintrc.json create mode 100644 app/assets/javascripts/controllers/.eslintrc.json create mode 120000 app/assets/javascripts/directives/.eslintrc.json create mode 120000 app/assets/javascripts/services/.eslintrc.json diff --git a/.eslintrc.js b/.eslintrc.js index 1f31974a497..72e48396e40 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,16 +1,3 @@ -var mode; -mode = global.process.env.MIQ_ESLINT; - -if (mode === undefined) { - console.warn('Please use the environmental variable MIQ_ESLINT to enable specific rulesets..'); - console.warn('MIQ_ESLINT=vanilla\tfor non-angular, non-es6, non-spec code'); - console.warn('MIQ_ESLINT=angular\tfor angular code'); -} - -if (!mode) { - mode = "vanilla"; -} - var plugins = []; var xtends = ['airbnb-es5']; @@ -89,48 +76,6 @@ var rules = { 'padded-blocks': [ 'error', 'never' ], }; -switch (mode) { - case 'vanilla': - xtends.push('airbnb-es5'); - break; - - case 'angular': - plugins.push('angular'); - xtends.push('airbnb-es5'); - xtends.push('angular'); - - rules = Object.assign(rules, { - // eslint-plugin-angular - 'angular/module-setter': 0, - 'angular/foreach': 0, - 'angular/watchers-execution': [ 'warn', '$apply' ], // but allow $digest for specs - 'angular/json-functions': 0, - 'angular/definedundefined': 0, - 'angular/log': 0, - 'angular/no-service-method': 0, - 'angular/di': [ 'error', 'array' ], // strictDi - - // only warnings for now - 'angular/controller-as': 1, - 'angular/module-getter': 1, - 'angular/no-services': [ "warn", ['$http'] ], - - // prefer lodash for typechecks - 'angular/typecheck-array': 0, - 'angular/typecheck-date': 0, - 'angular/typecheck-function': 0, - 'angular/typecheck-number': 0, - 'angular/typecheck-object': 0, - 'angular/typecheck-string': 0, - }); - - break; - - default: - console.error('Unknown mode: ' + mode + " - sorry"); - global.process.exit(1); -} - module.exports = { installedESLint: true, diff --git a/app/assets/javascripts/components/.eslintrc.json b/app/assets/javascripts/components/.eslintrc.json new file mode 120000 index 00000000000..65c789b4ac7 --- /dev/null +++ b/app/assets/javascripts/components/.eslintrc.json @@ -0,0 +1 @@ +../controllers/.eslintrc.json \ No newline at end of file diff --git a/app/assets/javascripts/controllers/.eslintrc.json b/app/assets/javascripts/controllers/.eslintrc.json new file mode 100644 index 00000000000..1f874e9a725 --- /dev/null +++ b/app/assets/javascripts/controllers/.eslintrc.json @@ -0,0 +1,28 @@ +{ + "plugins": ["angular"], + "extends": ["angular"], + "rules": { + // eslint-plugin-angular + "angular/module-setter": 0, + "angular/foreach": 0, + "angular/watchers-execution": [ "warn", "$apply" ], + "angular/json-functions": 0, + "angular/definedundefined": 0, + "angular/log": 0, + "angular/no-service-method": 0, + "angular/di": [ "error", "array" ], // strictDi + + // only warnings for now + "angular/controller-as": 1, + "angular/module-getter": 1, + "angular/no-services": [ "warn", ["$http"] ], + + // prefer lodash for typechecks + "angular/typecheck-array": 0, + "angular/typecheck-date": 0, + "angular/typecheck-function": 0, + "angular/typecheck-number": 0, + "angular/typecheck-object": 0, + "angular/typecheck-string": 0 + } +} diff --git a/app/assets/javascripts/directives/.eslintrc.json b/app/assets/javascripts/directives/.eslintrc.json new file mode 120000 index 00000000000..65c789b4ac7 --- /dev/null +++ b/app/assets/javascripts/directives/.eslintrc.json @@ -0,0 +1 @@ +../controllers/.eslintrc.json \ No newline at end of file diff --git a/app/assets/javascripts/services/.eslintrc.json b/app/assets/javascripts/services/.eslintrc.json new file mode 120000 index 00000000000..65c789b4ac7 --- /dev/null +++ b/app/assets/javascripts/services/.eslintrc.json @@ -0,0 +1 @@ +../controllers/.eslintrc.json \ No newline at end of file diff --git a/bin/eslint b/bin/eslint index e27318cd0c0..6f7b1526606 100755 --- a/bin/eslint +++ b/bin/eslint @@ -3,15 +3,4 @@ ESLINT="node_modules/.bin/eslint" cd `dirname $0`/.. -MIQ_ESLINT=vanilla $ESLINT "$@" \ - --ignore-pattern '**/controllers/**/*' \ - --ignore-pattern '**/directives/**/*' \ - --ignore-pattern '**/services/**/*' \ - --ignore-pattern '**/components/**/*' \ - app/assets/javascripts/ - -MIQ_ESLINT=angular $ESLINT "$@" \ - app/assets/javascripts/controllers \ - app/assets/javascripts/directives \ - app/assets/javascripts/services \ - app/assets/javascripts/components +$ESLINT "$@" app/assets/javascripts/ spec/javascripts/ From f8ac46858f3531aa829933bd7ab7ece8acec13dc Mon Sep 17 00:00:00 2001 From: Martin Hradil Date: Tue, 2 Aug 2016 13:03:23 +0000 Subject: [PATCH 4/8] eslintrc - remove duplicate quotes rule --- .eslintrc.js | 1 - 1 file changed, 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index 72e48396e40..94fc2e08eec 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -26,7 +26,6 @@ var rules = { 'vars-on-top': 0, 'no-var': 0, 'linebreak-style': [ 'error', 'unix' ], - 'quotes': [ 'error', 'single' ], 'semi-spacing': ['error', { before: false, after: true, From 52dc69fea57a248704021514ef33c49983ee32e6 Mon Sep 17 00:00:00 2001 From: Martin Hradil Date: Tue, 2 Aug 2016 13:03:47 +0000 Subject: [PATCH 5/8] eslintrc - mark the toplevel config as root, to prevent bubbling up in the hierarchy --- .eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc.js b/.eslintrc.js index 94fc2e08eec..0652da7309c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -77,6 +77,7 @@ var rules = { module.exports = { + root: true, installedESLint: true, env: { browser: true, From 601d11a22986fcfea62d15b62f6b13b6d35a70cb Mon Sep 17 00:00:00 2001 From: Martin Hradil Date: Tue, 2 Aug 2016 13:06:28 +0000 Subject: [PATCH 6/8] eslintrc - simplify after splitting converted `var foo = {...}; module.exports = { foo: foo }` to `module.exports = { foo: {...} }` --- .eslintrc.js | 156 ++++++++++++++++++++++++--------------------------- 1 file changed, 74 insertions(+), 82 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 0652da7309c..b931545d42c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,81 +1,3 @@ -var plugins = []; -var xtends = ['airbnb-es5']; - -var globals = { - API: false, // local: miq_api.js - ManageIQ: false, // local: mig_global.js - Promise: false, // bower: es6-shim - _: false, // bower: lodash - __: false, // local: i18n.js - angular: false, // bower: angular - c3: false, // bower: c3 - d3: false, // bower: d3 - i18n: false, // gem: gettext_i18n_rails_js - moment: false, // bower: moment - numeral: false, // bower: numeral - sprintf: false, // bower: sprintf -}; - -var rules = { - 'indent': [ 'error', 2, { - SwitchCase: 1, - VariableDeclarator: 1, - }], - 'consistent-return': 1, - 'default-case': 1, - 'vars-on-top': 0, - 'no-var': 0, - 'linebreak-style': [ 'error', 'unix' ], - 'semi-spacing': ['error', { - before: false, - after: true, - }], - 'semi': [ 'error', 'always' ], - 'comma-dangle': [ 'warn', 'always-multiline' ], - 'space-unary-ops': [ 'error', { - words: true, - nonwords: false, - overrides: { - '!': true, - }, - }], - 'no-unused-vars': [ 'error', { - args: 'all', - argsIgnorePattern: '^_', - vars: 'local', - caughtErrors: 'all', - caughtErrorsIgnorePattern: '^_', - }], - 'no-console': 1, - 'no-alert': 2, - 'no-debugger': 2, - 'no-else-return': 1, - 'no-undef': [ 'warn', { - typeof: true, - }], - 'eqeqeq': [ 'error', 'smart' ], - 'quotes': [ 'warn', 'single', { - avoidEscape: true, - allowTemplateLiterals: true, - }], - 'func-names': 0, - 'no-mixed-spaces-and-tabs': 2, - 'camelcase': 1, - 'curly': [ 'warn', 'all' ], - 'space-before-function-paren': [ 'error', 'never' ], - 'no-eq-null': 0, - 'no-param-reassign': 1, - 'no-fallthrough': [ 'error', { - commentPattern: "fall.*through|pass", - }], - 'no-use-before-define': [ 'error', { - functions: false, - classes: true, - }], - 'padded-blocks': [ 'error', 'never' ], -}; - - module.exports = { root: true, installedESLint: true, @@ -93,10 +15,80 @@ module.exports = { }, }, - plugins: plugins, - extends: xtends, + plugins: [], + extends: ['airbnb-es5'], - globals: globals, + globals: { + API: false, // local: miq_api.js + ManageIQ: false, // local: mig_global.js + Promise: false, // bower: es6-shim + _: false, // bower: lodash + __: false, // local: i18n.js + angular: false, // bower: angular + c3: false, // bower: c3 + d3: false, // bower: d3 + i18n: false, // gem: gettext_i18n_rails_js + moment: false, // bower: moment + numeral: false, // bower: numeral + sprintf: false, // bower: sprintf + }, - rules: rules, + rules: { + 'indent': [ 'error', 2, { + SwitchCase: 1, + VariableDeclarator: 1, + }], + 'consistent-return': 1, + 'default-case': 1, + 'vars-on-top': 0, + 'no-var': 0, + 'linebreak-style': [ 'error', 'unix' ], + 'semi-spacing': ['error', { + before: false, + after: true, + }], + 'semi': [ 'error', 'always' ], + 'comma-dangle': [ 'warn', 'always-multiline' ], + 'space-unary-ops': [ 'error', { + words: true, + nonwords: false, + overrides: { + '!': true, + }, + }], + 'no-unused-vars': [ 'error', { + args: 'all', + argsIgnorePattern: '^_', + vars: 'local', + caughtErrors: 'all', + caughtErrorsIgnorePattern: '^_', + }], + 'no-console': 1, + 'no-alert': 2, + 'no-debugger': 2, + 'no-else-return': 1, + 'no-undef': [ 'warn', { + typeof: true, + }], + 'eqeqeq': [ 'error', 'smart' ], + 'quotes': [ 'warn', 'single', { + avoidEscape: true, + allowTemplateLiterals: true, + }], + 'func-names': 0, + 'no-mixed-spaces-and-tabs': 2, + 'camelcase': 1, + 'curly': [ 'warn', 'all' ], + 'space-before-function-paren': [ 'error', 'never' ], + 'no-eq-null': 0, + 'no-param-reassign': 1, + 'no-fallthrough': [ 'error', { + commentPattern: "fall.*through|pass", + }], + 'no-use-before-define': [ 'error', { + functions: false, + classes: true, + }], + 'padded-blocks': [ 'error', 'never' ], + } }; From c2632e01e514da23371d9ecbd33629dc4f958f59 Mon Sep 17 00:00:00 2001 From: Martin Hradil Date: Tue, 2 Aug 2016 14:26:24 +0000 Subject: [PATCH 7/8] eslintrc - convert to JSON because we no longer need it to be .js --- .eslintrc.js | 94 -------------------------------------------------- .eslintrc.json | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 94 deletions(-) delete mode 100644 .eslintrc.js create mode 100644 .eslintrc.json diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index b931545d42c..00000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,94 +0,0 @@ -module.exports = { - root: true, - installedESLint: true, - env: { - browser: true, - jquery: true, - }, - parserOptions: { - ecmaVersion: 5, - sourceType: 'script', - ecmaFeatures: { - globalReturn: false, - impliedStrict: false, - jsx: false, - }, - }, - - plugins: [], - extends: ['airbnb-es5'], - - globals: { - API: false, // local: miq_api.js - ManageIQ: false, // local: mig_global.js - Promise: false, // bower: es6-shim - _: false, // bower: lodash - __: false, // local: i18n.js - angular: false, // bower: angular - c3: false, // bower: c3 - d3: false, // bower: d3 - i18n: false, // gem: gettext_i18n_rails_js - moment: false, // bower: moment - numeral: false, // bower: numeral - sprintf: false, // bower: sprintf - }, - - rules: { - 'indent': [ 'error', 2, { - SwitchCase: 1, - VariableDeclarator: 1, - }], - 'consistent-return': 1, - 'default-case': 1, - 'vars-on-top': 0, - 'no-var': 0, - 'linebreak-style': [ 'error', 'unix' ], - 'semi-spacing': ['error', { - before: false, - after: true, - }], - 'semi': [ 'error', 'always' ], - 'comma-dangle': [ 'warn', 'always-multiline' ], - 'space-unary-ops': [ 'error', { - words: true, - nonwords: false, - overrides: { - '!': true, - }, - }], - 'no-unused-vars': [ 'error', { - args: 'all', - argsIgnorePattern: '^_', - vars: 'local', - caughtErrors: 'all', - caughtErrorsIgnorePattern: '^_', - }], - 'no-console': 1, - 'no-alert': 2, - 'no-debugger': 2, - 'no-else-return': 1, - 'no-undef': [ 'warn', { - typeof: true, - }], - 'eqeqeq': [ 'error', 'smart' ], - 'quotes': [ 'warn', 'single', { - avoidEscape: true, - allowTemplateLiterals: true, - }], - 'func-names': 0, - 'no-mixed-spaces-and-tabs': 2, - 'camelcase': 1, - 'curly': [ 'warn', 'all' ], - 'space-before-function-paren': [ 'error', 'never' ], - 'no-eq-null': 0, - 'no-param-reassign': 1, - 'no-fallthrough': [ 'error', { - commentPattern: "fall.*through|pass", - }], - 'no-use-before-define': [ 'error', { - functions: false, - classes: true, - }], - 'padded-blocks': [ 'error', 'never' ], - } -}; diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000000..f446061b4b2 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,94 @@ +{ + "root": true, + "installedESLint": true, + "env": { + "browser": true, + "jquery": true + }, + "parserOptions": { + "ecmaVersion": 5, + "sourceType": "script", + "ecmaFeatures": { + "globalReturn": false, + "impliedStrict": false, + "jsx": false + } + }, + + "plugins": [], + "extends": ["airbnb-es5"], + + "globals": { + "API": false, // local: miq_api.js + "ManageIQ": false, // local: mig_global.js + "Promise": false, // bower: es6-shim + "_": false, // bower: lodash + "__": false, // local: i18n.js + "angular": false, // bower: angular + "c3": false, // bower: c3 + "d3": false, // bower: d3 + "i18n": false, // gem: gettext_i18n_rails_js + "moment": false, // bower: moment + "numeral": false, // bower: numeral + "sprintf": false // bower: sprintf + }, + + "rules": { + "indent": [ "error", 2, { + "SwitchCase": 1, + "VariableDeclarator": 1 + }], + "consistent-return": 1, + "default-case": 1, + "vars-on-top": 0, + "no-var": 0, + "linebreak-style": [ "error", "unix" ], + "semi-spacing": ["error", { + "before": false, + "after": true + }], + "semi": [ "error", "always" ], + "comma-dangle": [ "warn", "always-multiline" ], + "space-unary-ops": [ "error", { + "words": true, + "nonwords": false, + "overrides": { + "!": true + } + }], + "no-unused-vars": [ "error", { + "args": "all", + "argsIgnorePattern": "^_", + "vars": "local", + "caughtErrors": "all", + "caughtErrorsIgnorePattern": "^_" + }], + "no-console": 1, + "no-alert": 2, + "no-debugger": 2, + "no-else-return": 1, + "no-undef": [ "warn", { + "typeof": true + }], + "eqeqeq": [ "error", "smart" ], + "quotes": [ "warn", "single", { + "avoidEscape": true, + "allowTemplateLiterals": true + }], + "func-names": 0, + "no-mixed-spaces-and-tabs": 2, + "camelcase": 1, + "curly": [ "warn", "all" ], + "space-before-function-paren": [ "error", "never" ], + "no-eq-null": 0, + "no-param-reassign": 1, + "no-fallthrough": [ "error", { + "commentPattern": "fall.*through|pass" + }], + "no-use-before-define": [ "error", { + "functions": false, + "classes": true + }], + "padded-blocks": [ "error", "never" ] + } +} From 036d4f36b380188ff4228a0c64114cc8236a8894 Mon Sep 17 00:00:00 2001 From: Martin Hradil Date: Tue, 2 Aug 2016 15:43:51 +0000 Subject: [PATCH 8/8] eslintignore - ignore non-JS and not-our-JS directories to prevent eslint from crashing while trying to lint node_modules, self service bundles, etc --- .eslintignore | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.eslintignore b/.eslintignore index e35547d7fe1..5ec2837d6a6 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,3 +3,11 @@ app/assets/javascripts/locale/**/*.js # hopeless and should go anyway app/assets/javascripts/dynatree/jquery.dynatree.js + +# not ours or already processed or not javascript +node_modules/ +vendor/assets/bower_components/ +public/ +tmp/ +db/ +coverage/