Merge pull request #35 from dferber90/globals

feat(rule): Add rule: globals
This commit is contained in:
Dominik Ferber
2015-10-14 20:53:43 +02:00
7 changed files with 441 additions and 17 deletions

View File

@@ -1,5 +1,4 @@
ESLint-plugin-Meteor
===================
# ESLint-plugin-Meteor
[![Build Status][travis-image]][travis-url]
[![Coverage Status][coverage-image]][coverage-url]
@@ -53,12 +52,17 @@ Finally, enable all of the rules that you would like to use.
```json
{
"rules": {
// Core API
"meteor/globals": 2,
"meteor/core": 2,
"meteor/pubsub": 2,
// Best Practices
"meteor/audit-argument-checks": 2,
"meteor/no-session": 2,
"meteor/no-blaze-lifecycle-assignment": 2,
"meteor/no-zero-timeout": 2,
"meteor/audit-argument-checks": 2,
"meteor/core": 2,
"meteor/pubsub": 2
"meteor/no-zero-timeout": 2
}
}
```
@@ -67,12 +71,16 @@ For a more thorough introduction, read [setting up a Meteor project](docs/SETUP_
# List of supported rules
## Core API
* [globals](docs/rules/globals.md): Definitions for global Meteor variables based on environment
* [core](docs/rules/core.md): Meteor Core API
* [pubsub](docs/rules/pubsub.md): Prevent misusage of Publish and Subscribe
## Best Practices
* [audit-argument-checks](docs/rules/audit-argument-checks.md): Enforce check on all arguments passed to methods and publish functions
* [no-session](docs/rules/no-session.md): Prevent usage of Session
* [no-blaze-lifecycle-assignment](docs/rules/no-blaze-lifecycle-assignment.md): Prevent deprecated template lifecycle callback assignments
* [no-zero-timeout](docs/rules/no-zero-timeout.md): Prevent usage of Meteor.setTimeout with zero delay
* [audit-argument-checks](docs/rules/audit-argument-checks.md): Enforce check on all arguments passed to methods and publish functions
* [core](docs/rules/core.md): Meteor Core API
* [pubsub](docs/rules/pubsub.md): Prevent misusage of Publish and Subscribe
## To Do

34
docs/rules/globals.md Normal file
View File

@@ -0,0 +1,34 @@
# Definitions for global Meteor variables based on environment (globals)
This rule defines global variables based on the environment the file is executed in.
This rule never emits warnings on its own. It is meant to be used with ESLint's `no-undef`.
Do not use the Meteor environment.
## Rule Details
This rule is meant to be used with ESLint's `no-undef`. This rule marks Meteor's globals as defined. `no-undef` can then warn when undefined variables are used.
The availability of properties on the defined variables is checked in other rules.
Do not use the Meteor environment (`env: meteor` in `.eslintrc` or `$ eslint ./ --env meteor`) when using this rule. This rule exports globals based on file location, while the Meteor environment exports the globals regardless of location. This leads to ESLint thinking a global is defined when it is actually not defined (e.g. `Session` on files in `/server`).
## Usage
```js
{
'meteor/globals': 1,
'no-undef': 2
}
```
## Further Reading
- http://eslint.org/docs/1.0.0/rules/no-undef
- [list of defined globals](lib/util/data/globalsExportedByPackages.js)
## Possible Improvements
* Define only globals exported from default Meteor packages.
Add option to include other globals separately instead.

View File

@@ -13,19 +13,29 @@ function unpack (rule) {
module.exports = {
rules: {
// Core API
globals: unpack('./rules/globals'),
core: unpack('./rules/core'),
pubsub: unpack('./rules/pubsub'),
// Best Practices
'audit-argument-checks': unpack('./rules/audit-argument-checks'),
'no-session': unpack('./rules/no-session'),
'no-blaze-lifecycle-assignment': unpack('./rules/no-blaze-lifecycle-assignment'),
'no-zero-timeout': unpack('./rules/no-zero-timeout'),
'audit-argument-checks': unpack('./rules/audit-argument-checks'),
core: unpack('./rules/core'),
pubsub: unpack('./rules/pubsub')
'no-zero-timeout': unpack('./rules/no-zero-timeout')
},
rulesConfig: {
// Core API
globals: 0,
core: 0,
pubsub: 0,
// Best Practices
'audit-argument-checks': 0,
'no-session': 0,
'no-blaze-lifecycle-assignment': 0,
'no-zero-timeout': 0,
'audit-argument-checks': 0,
core: 0,
pubsub: 0
'no-zero-timeout': 0
}
}

57
lib/rules/globals.js Normal file
View File

@@ -0,0 +1,57 @@
/**
* @fileoverview Definitions for global Meteor variables based on environment
* @author Dominik Ferber
* @copyright 2015 Dominik Ferber. All rights reserved.
* See LICENSE file in root directory for full license.
*/
// -----------------------------------------------------------------------------
// Rule Definition
// -----------------------------------------------------------------------------
import {Variable} from 'escope'
import globalsExportedByPackages from '../util/data/globalsExportedByPackages'
module.exports = getMeta => context => {
const {isLintedEnv, env} = getMeta(context.getFilename())
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
function generateGlobalVariable (name, scope) {
const variable = new Variable(name, scope)
variable.eslintExplicitGlobal = false
variable.writeable = true
return variable
}
// ---------------------------------------------------------------------------
// Public
// ---------------------------------------------------------------------------
if (!isLintedEnv) {
return {}
}
return {
Program: function () {
const globalScope = context.getScope()
const variables = globalScope.variables
// add variables of environment to globals
Object.keys(globalsExportedByPackages).forEach(globalVar => {
const globalVarEnv = globalsExportedByPackages[globalVar]
if (globalVarEnv.indexOf(env) !== -1) {
variables.push(generateGlobalVariable(globalVar, globalScope))
}
})
}
}
}
module.exports.schema = []

View File

@@ -0,0 +1,282 @@
import {
CLIENT,
SERVER,
PACKAGE,
UNIVERSAL,
PACKAGE_CONFIG,
MOBILE_CONFIG,
COMPATIBILITY
} from '../environment'
const exportedToAllEnvs = [CLIENT, COMPATIBILITY, SERVER, UNIVERSAL]
const exportedToClientEnvs = [CLIENT, COMPATIBILITY, UNIVERSAL]
const exportedToWebEnvs = [CLIENT, COMPATIBILITY, UNIVERSAL]
const exportedToServerEnvs = [SERVER, UNIVERSAL]
export default {
// accounts-base
Accounts: exportedToAllEnvs,
AccountsClient: exportedToClientEnvs,
AccountsServer: exportedToServerEnvs,
// autoupdate
Autoupdate: exportedToAllEnvs,
// babel-compiler
Babel: exportedToServerEnvs,
BabelCompiler: exportedToServerEnvs,
// babel-runtime
babelHelpers: exportedToAllEnvs,
// binary-heap
MaxHeap: exportedToAllEnvs,
MinHeap: exportedToAllEnvs,
MinMaxHeap: exportedToAllEnvs,
// blaze
Blaze: exportedToAllEnvs,
UI: exportedToAllEnvs,
Handlebars: exportedToAllEnvs,
// boilerplate-generator
Boilerplate: exportedToServerEnvs,
// browser-policy-common
BrowserPolicy: exportedToServerEnvs,
// caching-compiler
CachingCompiler: exportedToServerEnvs,
MultiFileCachingCompiler: exportedToServerEnvs,
// caching-html-compiler
CachingHtmlCompiler: exportedToServerEnvs,
// check
check: exportedToAllEnvs,
Match: exportedToAllEnvs,
// constraint-solver
ConstraintSolver: exportedToAllEnvs,
// ddp-client
// ddp
DDP: exportedToAllEnvs,
// ddp-common
DDPCommon: exportedToAllEnvs,
// ddp-rate-limiter
DDPRateLimiter: exportedToAllEnvs,
// ddp-server
// ddp
DDPServer: exportedToAllEnvs,
// deps
Tracker: exportedToAllEnvs,
Deps: exportedToAllEnvs,
// diff-sequence
DiffSequence: exportedToAllEnvs,
// ecmascript-runtime
// disabled because the babel-eslint parser defines them anyways
// Symbol: exportedToAllEnvs,
// Map: exportedToAllEnvs,
// Set: exportedToAllEnvs,
// ecmascript
ECMAScript: exportedToAllEnvs,
// ejson
EJSON: exportedToAllEnvs,
// email
Email: exportedToServerEnvs,
EmailInternals: exportedToServerEnvs,
// es5-shim
// Date: exportedToAllEnvs,
// parseInt: exportedToAllEnvs
// facebook
Facebook: exportedToAllEnvs,
// fastclick
FastClick: exportedToWebEnvs,
// geojson-utils
GeoJSON: exportedToAllEnvs,
// github
Github: exportedToAllEnvs,
// google
Google: exportedToAllEnvs,
// html-tools
HTMLTools: exportedToAllEnvs,
// htmljs
HTML: exportedToAllEnvs,
// http
HTTP: exportedToAllEnvs,
// jquery
$: exportedToClientEnvs,
jQuery: exportedToClientEnvs,
// launch-screen
LaunchScreen: exportedToAllEnvs,
// logging
Log: exportedToAllEnvs,
// logic-solver
Logic: exportedToAllEnvs,
// markdown
Showdown: exportedToAllEnvs,
// meetup
Meetup: exportedToAllEnvs,
// meteor-developer
MeteorDeveloperAccounts: exportedToAllEnvs,
// meteor
Meteor: exportedToAllEnvs,
// minifiers
CssTools: exportedToAllEnvs,
UglifyJSMinify: exportedToAllEnvs,
UglifyJS: exportedToAllEnvs,
// minimongo
LocalCollection: exportedToAllEnvs,
Minimongo: exportedToAllEnvs,
// mongo-id
MongoID: exportedToAllEnvs,
// mongo
MongoInternals: exportedToServerEnvs,
Mongo: exportedToAllEnvs,
// npm-mongo
NpmModuleMongodb: exportedToServerEnvs,
NpmModuleMongodbVersion: exportedToServerEnvs,
// oauth-encryption
OAuthEncryption: exportedToServerEnvs,
// oauth
OAuth: exportedToAllEnvs,
Oauth: exportedToAllEnvs,
// oauth1
OAuth1Binding: exportedToServerEnvs,
// ordered-dict
OrderedDict: exportedToAllEnvs,
// package-version-parser
PackageVersion: exportedToAllEnvs,
// promise
Promise: exportedToAllEnvs,
// random
Random: exportedToAllEnvs,
// rate-limit
RateLimiter: exportedToAllEnvs,
// reactive-dict
ReactiveDict: exportedToAllEnvs,
// reactive-var
ReactiveVar: exportedToAllEnvs,
// reload
Reload: exportedToClientEnvs,
// route-policy
RoutePolicy: exportedToServerEnvs,
// service-configuration
ServiceConfiguration: exportedToAllEnvs,
// session
Session: exportedToClientEnvs,
// sha
SHA256: exportedToAllEnvs,
// spacebars-compiler
SpacebarsCompiler: exportedToAllEnvs,
// spacebars
Spacebars: exportedToAllEnvs,
// spiderable
Spiderable: exportedToAllEnvs,
// templating-tools
TemplatingTools: exportedToAllEnvs,
// templating
Template: exportedToClientEnvs,
// tinytest
Tinytest: exportedToAllEnvs,
// tracker
// Tracker: exportedToAllEnvs,
// Deps: exportedToAllEnvs,
// twitter
Twitter: exportedToAllEnvs,
// ui
// Blaze: exportedToAllEnvs,
// UI: exportedToAllEnvs,
// Handlebars: exportedToAllEnvs,
// underscore
_: exportedToAllEnvs,
// url
URL: exportedToAllEnvs,
// webapp-hashing
WebAppHashing: exportedToAllEnvs,
// webapp
WebApp: exportedToAllEnvs,
main: exportedToServerEnvs,
WebAppInternals: exportedToServerEnvs,
// weibo
Weibo: exportedToAllEnvs,
// xmlbuilder
XmlBuilder: exportedToServerEnvs,
// globals from npm package "gloabls"
// used by setting "env: meteor" in .eslintrc)
App: [MOBILE_CONFIG],
Assets: [SERVER, UNIVERSAL],
Cordova: [PACKAGE_CONFIG],
Npm: [PACKAGE_CONFIG, SERVER, UNIVERSAL],
Package: [...exportedToAllEnvs, PACKAGE_CONFIG],
Plugin: [PACKAGE],
process: [SERVER, UNIVERSAL]
// Router: false,
// share: false,
// Utils: false
}

View File

@@ -29,6 +29,7 @@
"homepage": "https://github.com/dferber90/eslint-plugin-meteor",
"bugs": "https://github.com/dferber90/eslint-plugin-meteor/issues",
"dependencies": {
"escope": "3.2.0",
"invariant": "2.1.1",
"lodash.find": "3.2.1",
"path-exists": "2.0.0"

View File

@@ -0,0 +1,32 @@
/**
* @fileoverview Definitions for global Meteor variables based on environment
* @author Dominik Ferber
* @copyright 2015 Dominik Ferber. All rights reserved.
* See LICENSE file in root directory for full license.
*/
// -----------------------------------------------------------------------------
// Requirements
// -----------------------------------------------------------------------------
import {SERVER} from '../../../dist/util/environment'
const rule = require('../../../dist/rules/globals')
const RuleTester = require('eslint').RuleTester
// -----------------------------------------------------------------------------
// Tests
// -----------------------------------------------------------------------------
const ruleTester = new RuleTester()
ruleTester.run('globals', rule(() => ({env: SERVER, isLintedEnv: true})), {
valid: ['Session.set("hi", true)'],
invalid: []
})
ruleTester.run('globals', rule(() => ({env: SERVER, isLintedEnv: false})), {
valid: ['Session.set("hi", true)'],
invalid: []
})