diff --git a/.gitignore b/.gitignore index 67a51760..98c45f77 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,5 @@ /repos /Gemfile.lock + +/node_modules diff --git a/Gemfile b/Gemfile index b0c31f9a..d35d3bed 100644 --- a/Gemfile +++ b/Gemfile @@ -40,10 +40,11 @@ gem 'travis', '~>1.7.6' gem 'awesome_spawn', '>= 1.4.1' gem 'default_value_for' -gem 'haml_lint', '= 0.16.1', :require => false -gem 'more_core_extensions', '~> 2.0.0', :require => 'more_core_extensions/all' -gem 'rubocop', '= 0.37.2', :require => false -gem 'rugged', :require => false +gem 'haml_lint', '= 0.16.1', :require => false +gem 'more_core_extensions', '~> 2.0.0', :require => 'more_core_extensions/all' +gem 'rubocop', '= 0.37.2', :require => false +gem 'rugged', :require => false +gem 'scss_lint', '~> 0.49.0', :require => false gem 'octokit', '~> 3.8.0' gem 'minigit', '~> 0.0.4' diff --git a/app/workers/commit_monitor_handlers/commit_range/rubocop_checker.rb b/app/workers/commit_monitor_handlers/commit_range/rubocop_checker.rb index 032e76ef..ff9aa5ca 100644 --- a/app/workers/commit_monitor_handlers/commit_range/rubocop_checker.rb +++ b/app/workers/commit_monitor_handlers/commit_range/rubocop_checker.rb @@ -24,7 +24,10 @@ def process_branch unmerged_results = [] unmerged_results << Linter::Rubocop.new(branch).run unmerged_results << Linter::Haml.new(branch).run + unmerged_results << Linter::ESLint.new(branch).run + unmerged_results << Linter::SCSS.new(branch).run unmerged_results.compact! + if unmerged_results.empty? @results = {"files" => []} else diff --git a/lib/linter/base.rb b/lib/linter/base.rb index 4c1eff7f..b0f358b5 100644 --- a/lib/linter/base.rb +++ b/lib/linter/base.rb @@ -27,13 +27,7 @@ def run end end - begin - offenses = JSON.parse(result.output.chomp) - rescue JSON::ParserError => error - logger.error("#{log_header} #{error.message}") - logger.error("#{log_header} Failed to parse JSON result #{result.output.inspect}") - return failed_linter_offenses("error parsing JSON result") - end + offenses = parse_output(result.output) logger.info("#{log_header} Completed run with offenses #{offenses.inspect}") offenses end @@ -69,6 +63,21 @@ def files_to_lint @files_to_lint ||= filtered_files(diff_service.new_files) end + def parse_output(str) + begin + convert_parsed(JSON.parse(str.chomp)) + rescue JSON::ParserError => error + logger.error("#{log_header} #{error.message}") + logger.error("#{log_header} Failed to parse JSON result #{result.output.inspect}") + return failed_linter_offenses("error parsing JSON result") + end + end + + # overriden in linters with different JSON format + def convert_parsed(hash_or_array) + hash_or_array + end + def run_linter(dir) logger.info("#{log_header} Executing linter...") require 'awesome_spawn' diff --git a/lib/linter/eslint.rb b/lib/linter/eslint.rb new file mode 100644 index 00000000..5f6ee183 --- /dev/null +++ b/lib/linter/eslint.rb @@ -0,0 +1,45 @@ +module Linter + class ESLint < Base + private + + def config_files + [".eslintrc.js", ".eslintrc.json"] + end + + def linter_executable + 'eslint .' + end + + def options + {:format => 'json'} + end + + def filtered_files(files) + files.select do |file| + file.end_with? '.js' + end + end + + def convert_parsed(array) + files = array.map { |f| convert_file(f) } + + {:files => files, + :summary => {:offense_count => files.reduce(0) { |memo, f| memo + f.offenses.count }, + :target_file_count => files.count}} + end + + def convert_file(file) + {:path => file[:filePath], + :offenses => file[:messages].map { |m| convert_offense(m) }} + end + + SEVERITY = ['off', 'warning', 'error'] + def convert_offense(offense) + {:severity => SEVERITY[offense[:severity]], + :message => offense[:message], + :location => {:line => offense[:line], + :column => offense[:column]}, + :cop_name => offense[:ruleId]} + end + end +end diff --git a/lib/linter/scss.rb b/lib/linter/scss.rb new file mode 100644 index 00000000..5afcda52 --- /dev/null +++ b/lib/linter/scss.rb @@ -0,0 +1,43 @@ +module Linter + class SCSS < Base + private + + def config_files + [".scss-lint.yml"] + end + + def linter_executable + 'scss-lint' + end + + def options + {:format => 'JSON'} + end + + def filtered_files(files) + files.select { |file| file.end_with?(".scss") } + end + + def convert_parsed(hash) + files = hash.map { |path, offenses| convert_file(path, offenses) } + + {:files => files, + :summary => {:offense_count => files.reduce(0) { |memo, f| memo + f.offenses.count }, + :target_file_count => files.count}} + end + + def convert_file(path, offenses) + {:path => path, + :offenses => offenses.map { |o| convert_offense(o) }} + end + + def convert_offense(offense) + {:severity => offense[:severity], + :message => offense[:reason], + :location => {:line => offense[:line], + :column => offense[:column]}, + :cop_name => offense[:linter]} + end + end + end +end diff --git a/package.json b/package.json new file mode 100644 index 00000000..9fc0c713 --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "eslint": "^3.13.1", + "eslint-cli": "^1.1.0" + } +}