jshint_on_rails 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,8 @@
1
+ Version 1.0.1 (04.04.2011)
2
+
3
+ * naming fix in lint.rb
4
+
5
+
6
+ Version 1.0.0 (30.03.2011)
7
+
8
+ * first gem release
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'rspec'
4
+ gem 'fakefs'
5
+ gem 'rake'
data/Gemfile.lock ADDED
@@ -0,0 +1,22 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ fakefs (0.2.1)
6
+ rake (0.8.7)
7
+ rspec (2.1.0)
8
+ rspec-core (~> 2.1.0)
9
+ rspec-expectations (~> 2.1.0)
10
+ rspec-mocks (~> 2.1.0)
11
+ rspec-core (2.1.0)
12
+ rspec-expectations (2.1.0)
13
+ diff-lcs (~> 1.1.2)
14
+ rspec-mocks (2.1.0)
15
+
16
+ PLATFORMS
17
+ ruby
18
+
19
+ DEPENDENCIES
20
+ fakefs
21
+ rake
22
+ rspec
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,70 @@
1
+ ##JSHint On Rails
2
+ JSHint on rails is a fork project from JSLint_on_rails, adapted to work with jshint.
3
+
4
+ **Installation Dependencies**
5
+ * Java 5 >
6
+ * Ruby 1.8 >
7
+ * Rails 2 >
8
+
9
+ ## Installation
10
+
11
+ **Rails 3**
12
+ * add `gem 'jshint_on_rails'` to you're projects Gemfile
13
+
14
+ The first time you run it, a file in config/jshint.yml will be created. It can be customized to fit your needs (well explained below).
15
+
16
+ As this project is a fork of psionides jslint_on_rails, the instructions are the same. [Click here](https://github.com/psionides/jslint_on_rails/blob/master/README.markdown) to follow his instructions.
17
+
18
+ ## Configuration
19
+
20
+ After the installation, observe that you'll probably will need to customize some settings, for example, the files you want to test and the ones you want to ignore (ex.: libraries such as jquery, mootools, underscore, etc).
21
+
22
+ The default config allows you to:
23
+ * write single line conditional statements
24
+ * ignore whitespaces (to support the option above and still being indented)
25
+
26
+ ## Running
27
+
28
+ To start checking your stuff run the following:
29
+
30
+ [bundle exec] rake jslint
31
+
32
+ Then you should see:
33
+
34
+ Running JSHint:
35
+
36
+ checking public/javascripts/scripts.js... OK
37
+ checking public/javascripts/models.js... OK
38
+ checking public/javascripts/presenters.js... OK
39
+
40
+ No JS errors found =)
41
+
42
+ If anything is wrong, you will get something like this instead:
43
+
44
+ Running JSHint:
45
+
46
+ checking public/javascripts/scripts.js... 2 errors:
47
+
48
+ Lint at line 24 character 15: Use '===' to compare with 'null'.
49
+ if (a == null && b == null) {
50
+
51
+ Lint at line 72 character 6: Extra comma.
52
+ },
53
+
54
+
55
+ Found 2 errors =(
56
+ rake aborted!
57
+ JSHint test failed.
58
+
59
+
60
+ If you want to test specific file or files (just once, without modifying the config), you can pass paths to include
61
+ and/or paths to exclude to the rake task:
62
+
63
+ rake jslint paths=public/javascripts/models/*.js,public/javascripts/lib/*.js exclude_paths=public/javascripts/lib/jquery.js
64
+
65
+
66
+ ## Credits
67
+
68
+ * JSLint on Rails was created by [Jakub Suder](http://psionides.jogger.pl), licensed under MIT License
69
+ * JSHint is a fork of JSLint and is maintained by the [JSHint Community](https://github.com/jshint/jshint)
70
+ * JSLint was created by [Douglas Crockford](http://jslint.com)
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ Bundler.setup
4
+
5
+ require 'rspec/core/rake_task'
6
+
7
+ desc 'Run the specs'
8
+ RSpec::Core::RakeTask.new do |t|
9
+ t.rspec_opts = ['--colour', '--format', 'documentation']
10
+ end
data/lib/jshint.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'jshint/errors'
2
+ require 'jshint/utils'
3
+ require 'jshint/lint'
4
+
5
+ if defined?(Rails) && Rails::VERSION::MAJOR == 3
6
+ require 'jshint/railtie'
7
+ end
@@ -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
@@ -0,0 +1,9 @@
1
+ module JSHint
2
+
3
+ class NoJavaException < StandardError
4
+ end
5
+
6
+ class LintCheckFailure < StandardError
7
+ end
8
+
9
+ end
@@ -0,0 +1,80 @@
1
+ require 'jshint/errors'
2
+ require 'jshint/utils'
3
+
4
+ module JSHint
5
+
6
+ PATH = File.dirname(__FILE__)
7
+
8
+ TEST_JAR_FILE = File.expand_path("#{PATH}/vendor/test.jar")
9
+ RHINO_JAR_FILE = File.expand_path("#{PATH}/vendor/rhino.jar")
10
+ TEST_JAR_CLASS = "Test"
11
+ RHINO_JAR_CLASS = "org.mozilla.javascript.tools.shell.Main"
12
+
13
+ JSHINT_FILE = File.expand_path("#{PATH}/vendor/jshint.js")
14
+
15
+ class Lint
16
+
17
+ # available options:
18
+ # :paths => [list of paths...]
19
+ # :exclude_paths => [list of exluded paths...]
20
+ # :config_path => path to custom config file (can be set via JSHint.config_path too)
21
+ def initialize(options = {})
22
+ default_config = Utils.load_config_file(DEFAULT_CONFIG_FILE)
23
+ custom_config = Utils.load_config_file(options[:config_path] || JSHint.config_path)
24
+ @config = default_config.merge(custom_config)
25
+
26
+ if @config['predef'].is_a?(Array)
27
+ @config['predef'] = @config['predef'].join(",")
28
+ end
29
+
30
+ included_files = files_matching_paths(options, :paths)
31
+ excluded_files = files_matching_paths(options, :exclude_paths)
32
+ @file_list = Utils.exclude_files(included_files, excluded_files)
33
+ @file_list.delete_if { |f| File.size(f) == 0 }
34
+
35
+ ['paths', 'exclude_paths'].each { |field| @config.delete(field) }
36
+ end
37
+
38
+ def run
39
+ check_java
40
+ Utils.xputs "Running JSHint...\n\n"
41
+ arguments = "#{JSHINT_FILE} #{option_string.inspect.gsub(/\$/, "\\$")} #{@file_list.join(' ')}"
42
+ success = call_java_with_status(RHINO_JAR_FILE, RHINO_JAR_CLASS, arguments)
43
+ raise LintCheckFailure, "JSHint test failed." unless success
44
+ end
45
+
46
+ private
47
+
48
+ def call_java_with_output(jar, mainClass, arguments = "")
49
+ %x(java -cp #{jar} #{mainClass} #{arguments})
50
+ end
51
+
52
+ def call_java_with_status(jar, mainClass, arguments = "")
53
+ system("java -cp #{jar} #{mainClass} #{arguments}")
54
+ end
55
+
56
+ def option_string
57
+ @config.map { |k, v| "#{k}=#{v.inspect}" }.join('&')
58
+ end
59
+
60
+ def check_java
61
+ unless @java_ok
62
+ java_test = call_java_with_output(TEST_JAR_FILE, TEST_JAR_CLASS)
63
+ if java_test.strip == "OK"
64
+ @java_ok = true
65
+ else
66
+ raise NoJavaException, "Please install Java before running JSHint."
67
+ end
68
+ end
69
+ end
70
+
71
+ def files_matching_paths(options, field)
72
+ path_list = options[field] || @config[field.to_s] || []
73
+ path_list = [path_list] unless path_list.is_a?(Array)
74
+ file_list = path_list.map { |p| Dir[p] }.flatten
75
+ Utils.unique_files(file_list)
76
+ end
77
+
78
+ end
79
+
80
+ end
@@ -0,0 +1,4 @@
1
+ require 'jshint/utils'
2
+
3
+ # for Rails, set config file path to config/jshint.yml in Rails root
4
+ JSHint.config_path = File.join(Rails.root, 'config', 'jshint.yml')
@@ -0,0 +1,21 @@
1
+ module JSHint
2
+ class Railtie < Rails::Railtie
3
+
4
+ rake_tasks do
5
+ require 'jshint/rails'
6
+ require 'jshint/tasks'
7
+ JSHint::Railtie.create_example_config
8
+ end
9
+
10
+ def self.create_example_config
11
+ unless File.exists?(JSHint.config_path)
12
+ begin
13
+ JSHint::Utils.copy_config_file
14
+ rescue StandardError => error
15
+ puts "Error: #{error.message}"
16
+ end
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ require 'jshint/lint'
2
+ require 'jshint/utils'
3
+
4
+ desc "Run JSHint check on selected Javascript files"
5
+ task :jshint do
6
+ include_paths = JSHint::Utils.paths_from_command_line('paths')
7
+ exclude_paths = JSHint::Utils.paths_from_command_line('exclude_paths')
8
+
9
+ if include_paths && exclude_paths.nil?
10
+ # if you pass paths= on command line but not exclude_paths=, and you have exclude_paths
11
+ # set in the config file, then the old exclude pattern will be used against the new
12
+ # include pattern, which may be very confusing...
13
+ exclude_paths = []
14
+ end
15
+
16
+ lint = JSHint::Lint.new :paths => include_paths, :exclude_paths => exclude_paths
17
+ lint.run
18
+ end
19
+
20
+ namespace :jshint do
21
+
22
+ desc "Create a copy of the default JSHint config file in your config directory"
23
+ task :copy_config do
24
+ JSHint::Utils.copy_config_file
25
+ end
26
+
27
+ end
@@ -0,0 +1,80 @@
1
+ require 'fileutils'
2
+ require 'yaml'
3
+
4
+ module JSHint
5
+
6
+ VERSION = "1.0.1"
7
+ DEFAULT_CONFIG_FILE = File.expand_path(File.dirname(__FILE__) + "/config/jshint.yml")
8
+
9
+ class << self
10
+ attr_accessor :config_path
11
+ end
12
+
13
+ module Utils
14
+ class << self
15
+
16
+ def xprint(txt)
17
+ print txt
18
+ end
19
+
20
+ def xputs(txt)
21
+ puts txt
22
+ end
23
+
24
+ def load_config_file(file_name)
25
+ if file_name && File.exists?(file_name) && File.file?(file_name) && File.readable?(file_name)
26
+ YAML.load_file(file_name)
27
+ else
28
+ {}
29
+ end
30
+ end
31
+
32
+ # workaround for a problem with case-insensitive file systems like HFS on Mac
33
+ def unique_files(list)
34
+ files = []
35
+ list.each do |entry|
36
+ files << entry unless files.any? { |f| File.identical?(f, entry) }
37
+ end
38
+ files
39
+ end
40
+
41
+ # workaround for a problem with case-insensitive file systems like HFS on Mac
42
+ def exclude_files(list, excluded)
43
+ list.reject { |entry| excluded.any? { |f| File.identical?(f, entry) }}
44
+ end
45
+
46
+ def paths_from_command_line(field)
47
+ argument = ENV[field] || ENV[field.upcase]
48
+ argument && argument.split(/,/)
49
+ end
50
+
51
+ def copy_config_file
52
+ raise ArgumentError, "Please set JSHint.config_path" if JSHint.config_path.nil?
53
+ xprint "Creating example JSHint config file in #{File.expand_path(JSHint.config_path)}... "
54
+ if File.exists?(JSHint.config_path)
55
+ xputs "\n\nWarning: config file exists, so it won't be overwritten. " +
56
+ "You can copy it manually from the jshint_on_rails directory if you want to reset it."
57
+ else
58
+ FileUtils.copy(JSHint::DEFAULT_CONFIG_FILE, JSHint.config_path)
59
+ xputs "done."
60
+ end
61
+ end
62
+
63
+ def remove_config_file
64
+ raise ArgumentError, "Please set JSHint.config_path" if JSHint.config_path.nil?
65
+ xprint "Removing config file... "
66
+ if File.exists?(JSHint.config_path) && File.file?(JSHint.config_path)
67
+ if File.read(JSHint.config_path) == File.read(JSHint::DEFAULT_CONFIG_FILE)
68
+ File.delete(JSHint.config_path)
69
+ xputs "OK."
70
+ else
71
+ xputs "File was modified, so it won't be deleted automatically."
72
+ end
73
+ else
74
+ xputs "OK (no config file found)."
75
+ end
76
+ end
77
+
78
+ end
79
+ end
80
+ end