jshint 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jshint.gemspec
4
+ gemspec
5
+
6
+ gem 'pry'
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,11 @@
1
+ require "jshint/version"
2
+ require "jshint/railtie" if defined?(Rails)
3
+
4
+ module Jshint
5
+ autoload :Lint, 'jshint/lint'
6
+ autoload :Configuration, 'jshint/configuration'
7
+
8
+ def self.root
9
+ File.expand_path('../..', __FILE__)
10
+ end
11
+ end
@@ -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
@@ -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,10 @@
1
+ require 'jshint'
2
+ require 'rails'
3
+
4
+ module Jshint
5
+ class Railtie < Rails::Railtie
6
+ rake_tasks do
7
+ load "jshint/tasks/jshint.rake"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module Jshint::Reporters
2
+ autoload :Default, 'jshint/reporters/default'
3
+ 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"]