jshint 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/config/jshint.yml +20 -0
- data/jshint.gemspec +30 -0
- data/lib/jshint.rb +11 -0
- data/lib/jshint/configuration.rb +76 -0
- data/lib/jshint/lint.rb +95 -0
- data/lib/jshint/railtie.rb +10 -0
- data/lib/jshint/reporters.rb +3 -0
- data/lib/jshint/reporters/default.rb +61 -0
- data/lib/jshint/tasks/jshint.rake +23 -0
- data/lib/jshint/version.rb +3 -0
- data/spec/jshint_spec.rb +10 -0
- data/spec/lib/configuration_spec.rb +31 -0
- data/spec/lib/lint_spec.rb +74 -0
- data/spec/lib/reporters/default_spec.rb +91 -0
- data/spec/spec_helper.rb +17 -0
- data/vendor/assets/javascripts/jshint.js +11136 -0
- metadata +185 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YTFkMWQzYWVjZmExNDEzMDRjYzMwZmI1OTI5OTdiYTUyNWIwZjI2NA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YTc2MDljNzAwOTZiYjY5NTIyODEyNWEzNWM0ODk2MDY1ZTRkYjIyOA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZDI0ZDIxYzA0NmY2OGVlMzgxYzMwZTFjMTBiZjUxMTE5NGQ3NjI3OGRjODQy
|
10
|
+
MGQ2YzBkMzdjMGI1NDIxZGMyMjRlOTRhMjM3YzJmNTk2MWNhYWVjMGE5OGFm
|
11
|
+
MjllZGQxNzBkMTdiYTNkNTUzYTI5YjllMTM4YmU3NDUyNDA5OTY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MjlhZDE4NWM3M2Q5OTc2YmUzMzliMWZmNjBkM2RkMGZiMWQ2MDlkM2IzMzE2
|
14
|
+
YTg5ODY2NTU3Yjg1NzFlMDc2N2M3M2IxYTJlN2YyZjVlY2MzMDVjMzQ2MDc1
|
15
|
+
NWM2YTNmYTdkNGJjNGRiZGJjMWVmMzIzZjcyNjIyOGYwOWE1ODk=
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Damian Nicholson
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Jshint
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'jshint'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install jshint
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/config/jshint.yml
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
files: ["**/*.js"] # No need to put app/assets/ or vendor/assets here
|
2
|
+
options:
|
3
|
+
boss: true
|
4
|
+
browser: true
|
5
|
+
curly: true
|
6
|
+
eqeqeq: true
|
7
|
+
eqnull: true
|
8
|
+
expr: true
|
9
|
+
immed: true
|
10
|
+
indent: 2
|
11
|
+
latedef: true
|
12
|
+
newcap: true
|
13
|
+
noarg: true
|
14
|
+
sub: true
|
15
|
+
trailing: true
|
16
|
+
undef: true
|
17
|
+
unused: true
|
18
|
+
globals:
|
19
|
+
jQuery: true
|
20
|
+
"$": true
|
data/jshint.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'jshint/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "jshint"
|
8
|
+
spec.version = Jshint::VERSION
|
9
|
+
spec.authors = ["Damian Nicholson"]
|
10
|
+
spec.email = ["damian.nicholson21@gmail.com"]
|
11
|
+
spec.description = %q{It achieves this by linting your code through a library called JSHint which catches most code smells, and ensures code consistency}
|
12
|
+
spec.summary = %q{Ensures your JavaScript code adheres to best practices}
|
13
|
+
spec.homepage = "http://damiannicholson.com"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "therubyracer", "~> 0.10.2"
|
22
|
+
spec.add_dependency "execjs", "~> 1.4.0"
|
23
|
+
spec.add_dependency "railties", ">= 3.2.0"
|
24
|
+
spec.add_dependency 'multi_json', '~> 1.0'
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
27
|
+
spec.add_development_dependency "rake"
|
28
|
+
spec.add_development_dependency "rspec"
|
29
|
+
spec.add_development_dependency "yard"
|
30
|
+
end
|
data/lib/jshint.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Jshint
|
4
|
+
class Configuration
|
5
|
+
attr_reader :options
|
6
|
+
|
7
|
+
# @param path [String] The path to the config file
|
8
|
+
def initialize(path = nil)
|
9
|
+
@path = path || default_config_path
|
10
|
+
@options = parse_yaml_config
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns the value of the options Hash if one exists
|
14
|
+
#
|
15
|
+
# @param key [Symbol]
|
16
|
+
# @return The value of the of the options Hash at the passed in key
|
17
|
+
def [](key)
|
18
|
+
options[key.to_s]
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns a Hash of global variables if one exists
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# {
|
25
|
+
# "$" => true,
|
26
|
+
# jQuery => true,
|
27
|
+
# angular => true
|
28
|
+
# }
|
29
|
+
#
|
30
|
+
# @return [Hash, nil] The key value pairs or nil
|
31
|
+
def global_variables
|
32
|
+
options["options"]["globals"]
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns a Hash of options to be used by JSHint
|
36
|
+
#
|
37
|
+
# See http://jshint.com/docs/options/ for more config options
|
38
|
+
#
|
39
|
+
# @example
|
40
|
+
# {
|
41
|
+
# "eqeqeq" => true,
|
42
|
+
# "indent" => 2
|
43
|
+
# }
|
44
|
+
# @return [Hash, nil] The key value pairs of options or nil
|
45
|
+
def lint_options
|
46
|
+
options["options"].slice!("globals")
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns the list of files that JSHint should lint over relatives to the Application root
|
50
|
+
#
|
51
|
+
# @example
|
52
|
+
# [
|
53
|
+
# 'angular/controllers/*.js',
|
54
|
+
# 'angular/services/*.js'
|
55
|
+
# ]
|
56
|
+
#
|
57
|
+
# @return [Array<String>] An Array of String files paths
|
58
|
+
def files
|
59
|
+
options["files"]
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def read_config_file
|
65
|
+
@read_config_file ||= File.open(@path, 'r:UTF-8').read
|
66
|
+
end
|
67
|
+
|
68
|
+
def parse_yaml_config
|
69
|
+
YAML.load(read_config_file)
|
70
|
+
end
|
71
|
+
|
72
|
+
def default_config_path
|
73
|
+
File.join(Rails.root, 'config', 'jshint.yml')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/jshint/lint.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require "execjs"
|
2
|
+
require "multi_json"
|
3
|
+
require "jshint/configuration"
|
4
|
+
|
5
|
+
module Jshint
|
6
|
+
class Lint
|
7
|
+
attr_reader :errors, :config
|
8
|
+
|
9
|
+
RAILS_JS_ASSET_PATHS = [
|
10
|
+
'app/assets/javascripts',
|
11
|
+
'vendor/assets/javascripts',
|
12
|
+
'lib/assets/javascripts'
|
13
|
+
]
|
14
|
+
|
15
|
+
def initialize(config_path = nil)
|
16
|
+
@config = Configuration.new(config_path)
|
17
|
+
@errors = {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def lint
|
21
|
+
javascript_files.each do |file|
|
22
|
+
file_content = get_file_content_as_json(file)
|
23
|
+
code = %(
|
24
|
+
JSHINT(#{file_content}, #{jshint_options}, #{jshint_globals});
|
25
|
+
return JSHINT.errors;
|
26
|
+
)
|
27
|
+
errors[file] = context.exec(code)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_json(hash)
|
32
|
+
MultiJson.dump(hash)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def get_file_content(path)
|
38
|
+
File.open(path, "r:UTF-8").read
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_file_content_as_json(path)
|
42
|
+
content = get_file_content(path)
|
43
|
+
get_json(content)
|
44
|
+
end
|
45
|
+
|
46
|
+
def search_paths
|
47
|
+
paths = RAILS_JS_ASSET_PATHS.dup
|
48
|
+
if files.is_a? Array
|
49
|
+
files.each do |file|
|
50
|
+
paths = paths.map { |path| File.join(path, file) }
|
51
|
+
end
|
52
|
+
else
|
53
|
+
paths = paths.map { |path| File.join(path, files) }
|
54
|
+
end
|
55
|
+
|
56
|
+
paths
|
57
|
+
end
|
58
|
+
|
59
|
+
def files
|
60
|
+
@files ||= config.files
|
61
|
+
end
|
62
|
+
|
63
|
+
def jshint_globals
|
64
|
+
@jshint_globals ||= get_json(config.global_variables)
|
65
|
+
end
|
66
|
+
|
67
|
+
def jshint_options
|
68
|
+
@jshint_options ||= get_json(config.lint_options)
|
69
|
+
end
|
70
|
+
|
71
|
+
def jshint_path
|
72
|
+
File.join(Jshint.root, 'vendor', 'assets', 'javascripts', 'jshint.js')
|
73
|
+
end
|
74
|
+
|
75
|
+
def jshint
|
76
|
+
@jshint ||= get_file_content(jshint_path)
|
77
|
+
end
|
78
|
+
|
79
|
+
def context
|
80
|
+
@context ||= ExecJS.compile("var window = {};\n" + jshint)
|
81
|
+
end
|
82
|
+
|
83
|
+
def javascript_files
|
84
|
+
js_asset_files = []
|
85
|
+
search_paths.each do |path|
|
86
|
+
Dir.glob(path) do |file|
|
87
|
+
js_asset_files << file
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
js_asset_files
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Jshint::Reporters
|
2
|
+
class Default
|
3
|
+
attr_reader :output
|
4
|
+
|
5
|
+
# Sets up the output string for the final report
|
6
|
+
#
|
7
|
+
# @param results [Hash] Key value pairs containing the filename and associated errors
|
8
|
+
def initialize(results = {})
|
9
|
+
@results = results
|
10
|
+
@output = ''
|
11
|
+
end
|
12
|
+
|
13
|
+
# Loops through all the errors and generates the report
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# foo/bar/baz.js: line 4, col 46, Bad operand.
|
17
|
+
# foo/bar/baz.js: line 39, col 7, Missing semicolon.
|
18
|
+
#
|
19
|
+
# 2 errors
|
20
|
+
#
|
21
|
+
# @return [String] The default report
|
22
|
+
def report
|
23
|
+
len = 0
|
24
|
+
@results.each do |file, errors|
|
25
|
+
len += errors.length
|
26
|
+
print_errors_for_file(file, errors)
|
27
|
+
end
|
28
|
+
if output
|
29
|
+
print_footer(len)
|
30
|
+
output
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Appends new error strings to the Report output
|
35
|
+
#
|
36
|
+
# @example
|
37
|
+
# foo/bar/baz.js: line 4, col 46, Bad operand.
|
38
|
+
# foo/bar/baz.js: line 39, col 7, Missing semicolon.
|
39
|
+
#
|
40
|
+
# @param file [String] The filename containing the errors
|
41
|
+
# @param errors [Array] The errors for the file
|
42
|
+
# @return [void]
|
43
|
+
def print_errors_for_file(file, errors)
|
44
|
+
errors.map do |error|
|
45
|
+
output << "#{file}: line #{error['line']}, col #{error['character']}, #{error['reason']}\n" unless error.nil?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Appends a footer summary to the Report output
|
50
|
+
#
|
51
|
+
# @example
|
52
|
+
# 1 error
|
53
|
+
# 3 errors
|
54
|
+
#
|
55
|
+
# @param len [Fixnum] The number of errors in this Report
|
56
|
+
# @return [void]
|
57
|
+
def print_footer(len)
|
58
|
+
output << "\n#{len} error#{len === 1 ? nil : 's'}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'jshint'
|
2
|
+
require 'jshint/reporters'
|
3
|
+
|
4
|
+
namespace :jshint do
|
5
|
+
desc "Runs JSHint, the JavaScript lint tool over this projects JavaScript assets"
|
6
|
+
task :lint => :environment do
|
7
|
+
linter = Jshint::Lint.new
|
8
|
+
linter.lint
|
9
|
+
reporter = Jshint::Reporters::Default.new(linter.errors)
|
10
|
+
puts reporter.report
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Copies the default JSHint options to your Rails application"
|
14
|
+
task :install_config => :environment do
|
15
|
+
source_file = File.join(Jshint.root, 'config', 'jshint.yml')
|
16
|
+
source_dest = File.join(Rails.root, 'config', '')
|
17
|
+
FileUtils.cp(source_file, source_dest)
|
18
|
+
end
|
19
|
+
task :all => [:lint]
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Runs JSHint, the JavaScript lint tool over this projects JavaScript assets"
|
23
|
+
task :jshint => ["jshint:all"]
|