jshint-rb 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Changelog.markdown +48 -0
- data/Gemfile +2 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +116 -0
- data/Rakefile +10 -0
- data/lib/jshint.rb +7 -0
- data/lib/jshint/config/jshint.yml +91 -0
- data/lib/jshint/errors.rb +7 -0
- data/lib/jshint/lint.rb +105 -0
- data/lib/jshint/rails.rb +4 -0
- data/lib/jshint/railtie.rb +19 -0
- data/lib/jshint/tasks.rb +31 -0
- data/lib/jshint/utils.rb +103 -0
- data/lib/jshint/vendor/jshint.js +60570 -0
- data/lib/jshint_on_rails.rb +1 -0
- data/spec/jslint_spec.rb +46 -0
- data/spec/lint_spec.rb +124 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/utils_spec.rb +191 -0
- metadata +134 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fca4b57a7fd55839fc3dfa5a48f46480a1cb0874
|
4
|
+
data.tar.gz: cce1f8ab14901bc48c92443af5fb179e70ca46ef
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b275be473f0971b6444cd5dcea2091bf4b340315befdba0ece7a4312ff9dc4a2cb8376105d01a49c388bae5b716997e14aad6f46459c00e52013284fc636e07e
|
7
|
+
data.tar.gz: 2a1255b5edc01f5821b0db2ea7578295d105c37ccbad101b2ee8ae7ee3a1f0835714780a184b5a7809298f5e29a63e7a93dc041362be41d4dcfe87cb96ac45ae
|
data/Changelog.markdown
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
Version 1.1.1 (16.04.2012)
|
2
|
+
|
3
|
+
* fixed issue with jslint:copy_config task
|
4
|
+
|
5
|
+
Version 1.1 (09.04.2012)
|
6
|
+
|
7
|
+
* removed support for installing as a Rails plugin
|
8
|
+
* doesn't auto-generate jslint.yml if it doesn't exist (create one explicitly using the rake task if you want)
|
9
|
+
* no need to set JSLint.config_path (if you aren't using the Railtie) if the file is in the default location
|
10
|
+
|
11
|
+
Version 1.0.7 (12.09.2011)
|
12
|
+
|
13
|
+
* fixed problem with local options from one file being applied to all subsequent files
|
14
|
+
|
15
|
+
Version 1.0.6 (19.02.2011)
|
16
|
+
|
17
|
+
* escape $ in predef line to prevent Bash for interpreting it
|
18
|
+
* predef can be passed as a YAML array
|
19
|
+
|
20
|
+
Version 1.0.5 (08.01.2011)
|
21
|
+
|
22
|
+
* options passed on the command line to JSLint are joined with "&" to fix the "predef" option
|
23
|
+
* load YAJL module explicitly (in some environments it may not be loaded automatically)
|
24
|
+
|
25
|
+
Version 1.0.4 (05.12.2010)
|
26
|
+
|
27
|
+
* bundler should be able to load the gem without :require
|
28
|
+
* added a Railtie to make things simpler in Rails 3
|
29
|
+
* don't print any warnings if tested JS file is empty
|
30
|
+
* lastsemic option will now not work if the missing semicolon is on a different line than the end bracket (so it only
|
31
|
+
makes sense for inline one-liner functions)
|
32
|
+
* updated JSLint to version from 2010-11-27 (adds some new warnings about comparing variables with empty string using
|
33
|
+
"==")
|
34
|
+
|
35
|
+
Version 1.0.3 (11.06.2010)
|
36
|
+
|
37
|
+
* Ruby 1.9 compatibility fixes
|
38
|
+
* 'es5' option is disabled by default
|
39
|
+
|
40
|
+
Version 1.0.2 (10.04.2010)
|
41
|
+
|
42
|
+
* Rails 3 compatibility fixes
|
43
|
+
* updated JSLint to version from 2010-04-06
|
44
|
+
* refactoring, added specs
|
45
|
+
|
46
|
+
Version 1.0.0 (18.12.2009)
|
47
|
+
|
48
|
+
* first gem release
|
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Bruno Gouveia
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
# JSHint.rb
|
2
|
+
|
3
|
+
[![Build Status](https://secure.travis-ci.org/josephholsten/jshint.rb.png)](http://travis-ci.org/josephholsten/jshint.rb)
|
4
|
+
|
5
|
+
**JSHint on Rails** is a Ruby library which lets you run
|
6
|
+
the [JSHint JavaScript code checker](http://jshint.com) on your Javascript code easily.
|
7
|
+
JSHint on rails is a fork project from [JSLint on Rails](https://github.com/jsuder/jslint_on_rails),
|
8
|
+
adapted to work with jshint.
|
9
|
+
|
10
|
+
## Requirements
|
11
|
+
|
12
|
+
* Ruby 1.8.7 or 1.9.2+
|
13
|
+
* Javascript engine compatible with [execjs](https://github.com/sstephenson/execjs) (on Mac and Windows it's provided by the OS)
|
14
|
+
* JSON engine compatible with [multi_json](https://github.com/intridea/multi_json) (included in Ruby 1.9, on 1.8 use e.g. [json gem](http://rubygems.org/gems/json))
|
15
|
+
* should work with (but doesn't require) Rails 2.x and 3.x
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
To use JSHint in Rails 3 you just need to do one thing:
|
20
|
+
|
21
|
+
* add `gem 'jshint-rb'` to bundler's Gemfile
|
22
|
+
|
23
|
+
In Rails 2 and other frameworks JSHint on Rails can't be loaded automatically using a Railtie, so you have to load it explicitly. The procedure in this case is:
|
24
|
+
|
25
|
+
* install the gem in your application using whatever technique is recommended for your framework (e.g. using bundler,
|
26
|
+
or by installing the gem manually with `gem install jshint-rb` and loading it with `require 'jshint'`)
|
27
|
+
* in your Rakefile, add a line to load the JSHint tasks:
|
28
|
+
|
29
|
+
require 'jshint/tasks'
|
30
|
+
|
31
|
+
## Configuration
|
32
|
+
|
33
|
+
It's strongly recommended that you create your own copy of the JSHint config file provided by the gem and tweak it to suit your preferences. To create a new config file from the template in your config directory, call this rake task:
|
34
|
+
|
35
|
+
[bundle exec] rake jshint:copy_config
|
36
|
+
|
37
|
+
This will create a config file at `config/jshint.yml` listing all available options. If for some reason you'd like to put the config file at a different location, set the `config_path` variable somewhere in your Rakefile:
|
38
|
+
|
39
|
+
JSHint.config_path = "config/lint.yml"
|
40
|
+
|
41
|
+
There are two things you can change in the config file:
|
42
|
+
|
43
|
+
* define which Javascript files are checked by default; you'll almost certainly want to change that, because the default
|
44
|
+
is `public/javascripts/**/*.js` which means all Javascript files, and you probably don't want JSHint to check entire
|
45
|
+
jQuery, Prototype or whatever other libraries you use - so change this so that only your scripts are checked (you can
|
46
|
+
put multiple entries under "paths:" and "exclude_paths:")
|
47
|
+
* enable or disable specific checks - I've set the defaults to what I believe is reasonable,
|
48
|
+
but what's reasonable for me may not be reasonable for you
|
49
|
+
|
50
|
+
## Running
|
51
|
+
|
52
|
+
To start the check, run the rake task:
|
53
|
+
|
54
|
+
[bundle exec] rake jshint
|
55
|
+
|
56
|
+
You will get a result like this (if everything goes well):
|
57
|
+
|
58
|
+
Running JSHint:
|
59
|
+
|
60
|
+
checking public/javascripts/Event.js... OK
|
61
|
+
checking public/javascripts/Map.js... OK
|
62
|
+
checking public/javascripts/Marker.js... OK
|
63
|
+
checking public/javascripts/Reports.js... OK
|
64
|
+
|
65
|
+
No JS errors found.
|
66
|
+
|
67
|
+
If anything is wrong, you will get something like this instead:
|
68
|
+
|
69
|
+
Running JSHint:
|
70
|
+
|
71
|
+
checking public/javascripts/Event.js... 2 errors:
|
72
|
+
|
73
|
+
Lint at line 24 character 15: Use '===' to compare with 'null'.
|
74
|
+
if (a == null && b == null) {
|
75
|
+
|
76
|
+
Lint at line 72 character 6: Extra comma.
|
77
|
+
},
|
78
|
+
|
79
|
+
checking public/javascripts/Marker.js... 1 error:
|
80
|
+
|
81
|
+
Lint at line 275 character 27: Missing radix parameter.
|
82
|
+
var x = parseInt(mapX);
|
83
|
+
|
84
|
+
|
85
|
+
Found 3 errors.
|
86
|
+
rake aborted!
|
87
|
+
JSHint test failed.
|
88
|
+
|
89
|
+
If you want to test specific file or files (just once, without modifying the config), you can pass paths to include
|
90
|
+
and/or paths to exclude to the rake task:
|
91
|
+
|
92
|
+
rake jshint paths=public/javascripts/models/*.js,public/javascripts/lib/*.js exclude_paths=public/javascripts/lib/jquery.js
|
93
|
+
|
94
|
+
For the best effect, you should include JSHint check in your Continuous Integration build - that way you'll get
|
95
|
+
immediate notification when you've committed JS code with errors.
|
96
|
+
|
97
|
+
## Running from your code
|
98
|
+
|
99
|
+
If you would prefer to write your own rake task to run JSHint, you can create and execute the JSHint object manually:
|
100
|
+
|
101
|
+
require 'jshint'
|
102
|
+
|
103
|
+
lint = JSHint::Lint.new(
|
104
|
+
:paths => ['public/javascripts/**/*.js'],
|
105
|
+
:exclude_paths => ['public/javascripts/vendor/**/*.js'],
|
106
|
+
:config_path => 'config/jslint.yml'
|
107
|
+
)
|
108
|
+
|
109
|
+
lint.run
|
110
|
+
|
111
|
+
## Credits
|
112
|
+
|
113
|
+
* JSLint on Rails was created by [Jakub Suder](http://psionides.eu), licensed under MIT License
|
114
|
+
* JSHint by [JSHint Community](https://github.com/jshint/jshint)
|
115
|
+
* JSHint is a fork of JSLint and is maintained by the [JSHint Community](https://github.com/jshint/jshint)
|
116
|
+
* JSLint was created by [Douglas Crockford](http://jslint.com)
|
data/Rakefile
ADDED
data/lib/jshint.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# ------------ rake task options ------------
|
2
|
+
|
3
|
+
# JS files to check by default, if no parameters are passed to rake jshint
|
4
|
+
# (you may want to limit this only to your own scripts and exclude any external scripts and frameworks)
|
5
|
+
|
6
|
+
# this can be overridden by adding 'paths' and 'exclude_paths' parameter to rake command:
|
7
|
+
# rake jshint paths=path1,path2,... exclude_paths=library1,library2,...
|
8
|
+
|
9
|
+
paths:
|
10
|
+
- public/javascripts/**/*.js
|
11
|
+
|
12
|
+
exclude_paths:
|
13
|
+
|
14
|
+
|
15
|
+
# ------------ jshint options ------------
|
16
|
+
# visit http://jshint.com/ for complete documentation
|
17
|
+
|
18
|
+
# "enforce" type options (true means potentially more warnings)
|
19
|
+
|
20
|
+
adsafe: false # true if ADsafe rules should be enforced. See http://www.ADsafe.org/
|
21
|
+
bitwise: true # true if bitwise operators should not be allowed
|
22
|
+
newcap: true # true if Initial Caps must be used with constructor functions
|
23
|
+
eqeqeq: false # true if === should be required (for ALL equality comparisons)
|
24
|
+
immed: false # true if immediate function invocations must be wrapped in parens
|
25
|
+
nomen: false # true if initial or trailing underscore in identifiers should be forbidden
|
26
|
+
onevar: false # true if only one var statement per function should be allowed
|
27
|
+
plusplus: false # true if ++ and -- should not be allowed
|
28
|
+
regexp: false # true if . and [^...] should not be allowed in RegExp literals
|
29
|
+
safe: false # true if the safe subset rules are enforced (used by ADsafe)
|
30
|
+
strict: false # true if the ES5 "use strict"; pragma is required
|
31
|
+
undef: true # true if variables must be declared before used
|
32
|
+
white: false # true if strict whitespace rules apply (see also 'indent' option)
|
33
|
+
|
34
|
+
# "allow" type options (false means potentially more warnings)
|
35
|
+
|
36
|
+
cap: false # true if upper case HTML should be allowed
|
37
|
+
css: false # true if CSS workarounds should be tolerated
|
38
|
+
debug: false # true if debugger statements should be allowed (set to false before going into production)
|
39
|
+
es5: false # true if ECMAScript 5 syntax should be allowed
|
40
|
+
evil: false # true if eval should be allowed
|
41
|
+
forin: false # true if unfiltered 'for in' statements should be allowed
|
42
|
+
fragment: false # true if HTML fragments should be allowed
|
43
|
+
laxbreak: false # true if statement breaks should not be checked
|
44
|
+
on: false # true if HTML event handlers (e.g. onclick="...") should be allowed
|
45
|
+
sub: false # true if subscript notation may be used for expressions better expressed in dot notation
|
46
|
+
|
47
|
+
# other options
|
48
|
+
|
49
|
+
maxlen: 160 # Maximum line length
|
50
|
+
indent: 2 # Number of spaces that should be used for indentation - used only if 'white' option is set
|
51
|
+
maxerr: 50 # The maximum number of warnings reported (per file)
|
52
|
+
passfail: false # true if the scan should stop on first error (per file)
|
53
|
+
# following are relevant only if undef = true
|
54
|
+
predef: '' # Names of predefined global variables - comma-separated string or a YAML array
|
55
|
+
browser: true # true if the standard browser globals should be predefined
|
56
|
+
rhino: false # true if the Rhino environment globals should be predefined
|
57
|
+
windows: false # true if Windows-specific globals should be predefined
|
58
|
+
widget: false # true if the Yahoo Widgets globals should be predefined
|
59
|
+
devel: false # true if functions like alert, confirm, console, prompt etc. are predefined
|
60
|
+
|
61
|
+
# jshint options
|
62
|
+
loopfunc: true # true if functions should be allowed to be defined within loops
|
63
|
+
asi: true # true if automatic semicolon insertion should be tolerated
|
64
|
+
boss: true # true if advanced usage of assignments and == should be allowed
|
65
|
+
couch: true # true if CouchDB globals should be predefined
|
66
|
+
curly: false # true if curly braces around blocks should be required (even in if/for/while)
|
67
|
+
noarg: true # true if arguments.caller and arguments.callee should be disallowed
|
68
|
+
node: true # true if the Node.js environment globals should be predefined
|
69
|
+
noempty: true # true if empty blocks should be disallowed
|
70
|
+
nonew: true # true if using `new` for side-effects should be disallowed
|
71
|
+
|
72
|
+
|
73
|
+
# ------------ jshint_on_rails custom lint options (switch to true to disable some annoying warnings) ------------
|
74
|
+
|
75
|
+
# ignores "missing semicolon" warning at the end of a function; this lets you write one-liners
|
76
|
+
# like: x.map(function(i) { return i + 1 }); without having to put a second semicolon inside the function
|
77
|
+
lastsemic: false
|
78
|
+
|
79
|
+
# allows you to use the 'new' expression as a statement (without assignment)
|
80
|
+
# so you can call e.g. new Ajax.Request(...), new Effect.Highlight(...) without assigning to a dummy variable
|
81
|
+
newstat: false
|
82
|
+
|
83
|
+
# ignores the "Expected an assignment or function call and instead saw an expression" warning,
|
84
|
+
# if the expression contains a proper statement and makes sense; this lets you write things like:
|
85
|
+
# element && element.show();
|
86
|
+
# valid || other || lastChance || alert('OMG!');
|
87
|
+
# selected ? show() : hide();
|
88
|
+
# although these will still cause a warning:
|
89
|
+
# element && link;
|
90
|
+
# selected ? 5 : 10;
|
91
|
+
statinexp: false
|
data/lib/jshint/lint.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'jshint/errors'
|
2
|
+
require 'jshint/utils'
|
3
|
+
require 'execjs'
|
4
|
+
require 'multi_json'
|
5
|
+
|
6
|
+
module JSHint
|
7
|
+
|
8
|
+
PATH = File.dirname(__FILE__)
|
9
|
+
|
10
|
+
JSHINT_FILE = File.expand_path("#{PATH}/vendor/jshint.js")
|
11
|
+
|
12
|
+
class Lint
|
13
|
+
|
14
|
+
# available options:
|
15
|
+
# :paths => [list of paths...]
|
16
|
+
# :exclude_paths => [list of exluded paths...]
|
17
|
+
# :config_path => path to custom config file (can be set via JSHint.config_path too)
|
18
|
+
def initialize(options = {})
|
19
|
+
default_config = Utils.load_config_file(DEFAULT_CONFIG_FILE)
|
20
|
+
custom_config = Utils.load_config_file(options[:config_path] || JSHint.config_path)
|
21
|
+
@config = default_config.merge(custom_config)
|
22
|
+
if @config['predef']
|
23
|
+
@config['predef'] = @config['predef'].split(",") unless @config['predef'].is_a?(Array)
|
24
|
+
end
|
25
|
+
|
26
|
+
included_files = files_matching_paths(options, :paths)
|
27
|
+
excluded_files = files_matching_paths(options, :exclude_paths)
|
28
|
+
@file_list = Utils.exclude_files(included_files, excluded_files)
|
29
|
+
@file_list.delete_if { |f| File.size(f) == 0 }
|
30
|
+
|
31
|
+
['paths', 'exclude_paths'].each { |field| @config.delete(field) }
|
32
|
+
end
|
33
|
+
|
34
|
+
def run
|
35
|
+
raise NoEngineException, "No JS engine available" unless js_engine
|
36
|
+
Utils.log "Running JSHint via #{js_engine.name}:\n\n"
|
37
|
+
|
38
|
+
errors = @file_list.map { |file| process_file(file) }.flatten
|
39
|
+
|
40
|
+
if errors.length == 0
|
41
|
+
Utils.log "\nNo JS errors found."
|
42
|
+
else
|
43
|
+
Utils.log "\nFound #{Utils.pluralize(errors.length, 'error')}."
|
44
|
+
raise LintCheckFailure, "JSHint test failed."
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def js_engine
|
51
|
+
ExecJS.runtime
|
52
|
+
end
|
53
|
+
|
54
|
+
def process_file(filename)
|
55
|
+
Utils.display "checking #{filename}... "
|
56
|
+
errors = []
|
57
|
+
|
58
|
+
if File.exist?(filename)
|
59
|
+
source = File.read(filename)
|
60
|
+
errors = run_lint(source)
|
61
|
+
|
62
|
+
if errors.length == 0
|
63
|
+
Utils.log "OK"
|
64
|
+
else
|
65
|
+
Utils.log print(Utils.pluralize(errors.length, "error") + ":\n");
|
66
|
+
|
67
|
+
errors.each do |error|
|
68
|
+
Utils.log "Lint at line #{error['line']} character #{error['character']}: #{error['reason']}"
|
69
|
+
|
70
|
+
if error['evidence']
|
71
|
+
evidence = error['evidence'].gsub(/^\s*(\S*(\s+\S+)*)\s*$/) { $1 }
|
72
|
+
Utils.log(evidence)
|
73
|
+
end
|
74
|
+
|
75
|
+
Utils.log ''
|
76
|
+
end
|
77
|
+
end
|
78
|
+
else
|
79
|
+
Utils.log "Error: couldn't open file."
|
80
|
+
end
|
81
|
+
|
82
|
+
errors
|
83
|
+
end
|
84
|
+
|
85
|
+
def run_lint(source)
|
86
|
+
code = %(
|
87
|
+
JSHINT(#{source.inspect}, #{MultiJson.dump(@config)});
|
88
|
+
return JSHINT.errors;
|
89
|
+
)
|
90
|
+
|
91
|
+
context.exec(code)
|
92
|
+
end
|
93
|
+
|
94
|
+
def context
|
95
|
+
@context ||= ExecJS.compile(File.read(JSHINT_FILE))
|
96
|
+
end
|
97
|
+
|
98
|
+
def files_matching_paths(options, field)
|
99
|
+
path_list = options[field] || @config[field.to_s] || []
|
100
|
+
path_list = [path_list] unless path_list.is_a?(Array)
|
101
|
+
file_list = path_list.map { |p| Dir[p] }.flatten
|
102
|
+
Utils.unique_files(file_list)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/lib/jshint/rails.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module JSHint
|
2
|
+
class Railtie < Rails::Railtie
|
3
|
+
rake_tasks do
|
4
|
+
require 'jshint/tasks'
|
5
|
+
JSHint::Railtie.create_example_config
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.create_example_config
|
9
|
+
unless File.exists?(JSHint.config_path)
|
10
|
+
begin
|
11
|
+
JSHint::Utils.copy_config_file
|
12
|
+
rescue StandardError => error
|
13
|
+
puts "Error: #{error.message}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|