From 1845f2e31adc6f9b1513b779f44e3bd347d6fd11 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Sun, 11 Sep 2016 14:49:59 +0200 Subject: Allow to set config with `.pronto_eslint_npm.yml` Make configuration dependent on instance instead of class, too. --- README.md | 23 ++++++++++++++++- lib/pronto/eslint_npm.rb | 44 ++++++++++++++++++++++++--------- pronto-eslint_npm.gemspec | 1 - spec/fixtures/test.git/custom_eslint.sh | 1 + spec/pronto/eslint_spec.rb | 36 ++++++++++++++++++++++++--- spec/spec_helper.rb | 10 +++++++- 6 files changed, 96 insertions(+), 19 deletions(-) create mode 100755 spec/fixtures/test.git/custom_eslint.sh diff --git a/README.md b/README.md index 4fb2cdc..9ee2e19 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,30 @@ You'll need to install [eslint by yourself with npm][eslint-install]. [eslint-install]: http://eslint.org/docs/user-guide/getting-started -## Configuration +## Configuration of ESLint Configuring ESLint via [.eslintrc and consorts][eslintrc] and excludes via [.eslintignore][eslintignore] will work just fine with pronto-eslint. [eslintrc]: http://eslint.org/docs/user-guide/configuring#configuration-file-formats + [eslintignore]: http://eslint.org/docs/user-guide/configuring#ignoring-files-and-directories + +## Configuration of ESLintNPM + +Pronto::ESLintNPM can be configured by placing a `.pronto_eslint_npm.yml` inside the directory +where pronto is run. + +Following options are available: + +| Option | Meaning | Default | +| ----------------- | --------------------------------------------------------------------------------- | ----------------------------------- | +| eslint_executable | ESLint executable to call | `eslint` (calls `eslint` in `PATH`) | +| files_to_lint | What files to lint. Absolute path of the file will be matched against this regexp | `(\.js|\.es6)$` | + +Example configuration to call custom eslint executable and only lint files ending with `.my_custom_extension`: + +```yaml +# .pronto_eslint_npm.yaml +eslint_executable: '/my/cusom/node/path/.bin/eslint' +files_to_lint: '\.my_custom_extension$' +``` diff --git a/lib/pronto/eslint_npm.rb b/lib/pronto/eslint_npm.rb index 6bbef09..9ff7df5 100644 --- a/lib/pronto/eslint_npm.rb +++ b/lib/pronto/eslint_npm.rb @@ -3,20 +3,38 @@ require 'shellwords' module Pronto class ESLintNpm < Runner - class << self - attr_writer :eslint_executable, :files_to_lint + CONFIG_FILE = '.pronto_eslint_npm.yml'.freeze + CONFIG_KEYS = %i(eslint_executable files_to_lint).freeze - def eslint_executable - @eslint_executable || 'eslint'.freeze - end + attr_writer :eslint_executable + + def eslint_executable + @eslint_executable || 'eslint'.freeze + end + + def files_to_lint + @files_to_lint || /(\.js|\.es6)$/ + end + + def files_to_lint=(regexp) + @files_to_lint = regexp.is_a?(Regexp) && regexp || Regexp.new(regexp) + end + + def read_config + config_file = File.join(repo_path, CONFIG_FILE) + return unless File.exist?(config_file) + config = YAML.load_file(config_file) - def files_to_lint - @files_to_lint || /(\.js|\.es6)$/ + CONFIG_KEYS.each do |config_key| + next unless config[config_key] + send("#{config_key}=", config[config_key]) end end def run - return [] unless @patches + return [] if !@patches || @patches.count.zero? + + read_config @patches .select { |patch| patch.additions > 0 } @@ -27,9 +45,11 @@ module Pronto private - def inspect(patch) + def repo_path @_repo_path ||= @patches.first.repo.path + end + def inspect(patch) offences = run_eslint(patch) clean_up_eslint_output(offences) .map do |offence| @@ -48,14 +68,14 @@ module Pronto end def js_file?(path) - self.class.files_to_lint =~ path.to_s + files_to_lint =~ path.to_s end def run_eslint(patch) - Dir.chdir(@_repo_path) do + Dir.chdir(repo_path) do escaped_file_path = Shellwords.escape(patch.new_file_full_path.to_s) JSON.parse( - `#{self.class.eslint_executable} #{escaped_file_path} -f json` + `#{eslint_executable} #{escaped_file_path} -f json` ) end end diff --git a/pronto-eslint_npm.gemspec b/pronto-eslint_npm.gemspec index f51cbbb..5b62845 100644 --- a/pronto-eslint_npm.gemspec +++ b/pronto-eslint_npm.gemspec @@ -27,5 +27,4 @@ Gem::Specification.new do |s| s.add_dependency('pronto', '~> 0.7.0') s.add_development_dependency('rake', '~> 11.0') s.add_development_dependency('rspec', '~> 3.4') - s.add_development_dependency('rspec-its', '~> 1.2') end diff --git a/spec/fixtures/test.git/custom_eslint.sh b/spec/fixtures/test.git/custom_eslint.sh new file mode 100755 index 0000000..54fafdc --- /dev/null +++ b/spec/fixtures/test.git/custom_eslint.sh @@ -0,0 +1 @@ +printf 'custom eslint called' diff --git a/spec/pronto/eslint_spec.rb b/spec/pronto/eslint_spec.rb index 7bbc77a..6358621 100644 --- a/spec/pronto/eslint_spec.rb +++ b/spec/pronto/eslint_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' module Pronto describe ESLintNpm do let(:eslint) { ESLintNpm.new(patches) } + let(:patches) { [] } describe '#run' do subject(:run) { eslint.run } @@ -35,6 +36,33 @@ module Pronto it 'has correct first message' do expect(run.first.msg).to eql("'foo' is not defined.") end + + context( + 'with files to lint config that never matches', + config: { files_to_lint: 'will never match' } + ) do + it 'returns zero errors' do + expect(run.count).to eql(0) + end + end + + context( + 'with files to lint config that matches only .js', + config: { files_to_lint: /\.js/ } + ) do + it 'returns correct amount of errors' do + expect(run.count).to eql(2) + end + end + + context( + 'with different eslint executable', + config: { eslint_executable: './custom_eslint.sh' } + ) do + it 'calls the custom eslint eslint_executable' do + expect { run }.to raise_error(JSON::ParserError, /custom eslint called/) + end + end end context 'repo with ignored and not ignored file, each with three warnings' do @@ -52,8 +80,8 @@ module Pronto end end - describe '.files_to_lint' do - subject(:files_to_lint) { ESLintNpm.files_to_lint } + describe '#files_to_lint' do + subject(:files_to_lint) { eslint.files_to_lint } it 'matches .js by default' do expect(files_to_lint).to match('my_js.js') @@ -64,8 +92,8 @@ module Pronto end end - describe '.eslint_executable' do - subject(:eslint_executable) { ESLintNpm.eslint_executable } + describe '#eslint_executable' do + subject(:eslint_executable) { eslint.eslint_executable } it 'is `eslint` by default' do expect(eslint_executable).to eql('eslint') diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 72a128b..da4fc00 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,5 @@ require 'fileutils' require 'rspec' -require 'rspec/its' require 'pronto/eslint_npm' %w(test eslintignore).each do |repo_name| @@ -13,3 +12,12 @@ require 'pronto/eslint_npm' after { FileUtils.mv(dot_git, git) } end end + +RSpec.shared_context 'with config', config: true do + requested_config = metadata[:config].to_yaml + + let(:config_path) { File.join(repo.path.to_s, Pronto::ESLintNpm::CONFIG_FILE) } + + before(:each) { File.write(config_path, requested_config) } + after(:each) { FileUtils.rm(config_path) } +end -- cgit v1.2.3