]> git.immae.eu Git - github/fretlink/pronto-hlint.git/commitdiff
Allow to set config with `.pronto_eslint_npm.yml`
authorMarkus Doits <markus.doits@stellenticket.de>
Sun, 11 Sep 2016 12:49:59 +0000 (14:49 +0200)
committerMarkus Doits <markus.doits@stellenticket.de>
Sun, 11 Sep 2016 13:13:42 +0000 (15:13 +0200)
Make configuration dependent on instance instead of class, too.

README.md
lib/pronto/eslint_npm.rb
pronto-eslint_npm.gemspec
spec/fixtures/test.git/custom_eslint.sh [new file with mode: 0755]
spec/pronto/eslint_spec.rb
spec/spec_helper.rb

index 4fb2cdcc1643d7a55b007b5e370f11aba4a1d29a..9ee2e1943eb38f2799b02abfd442e478d86470f0 100644 (file)
--- 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$'
+```
index 6bbef0959dedaf8ebda2989c2b14b5f7bf46fd4b..9ff7df57a8218bfc697236f6c960964c4efaa1b6 100644 (file)
@@ -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
index f51cbbb2b53e36074261a51e81fe19716e2aad2c..5b6284547fb9a6d0e71e69b0be19b51ffecc8a85 100644 (file)
@@ -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 (executable)
index 0000000..54fafdc
--- /dev/null
@@ -0,0 +1 @@
+printf 'custom eslint called'
index 7bbc77a80ec2c1369610224aad664a7ac17db860..6358621d2d0da390f639ae7d04a028353f9a66d2 100644 (file)
@@ -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')
index 72a128b117866f826aa0d78b08fefe48d29889dd..da4fc003e7e4702e3333ec54b78849724605c6ce 100644 (file)
@@ -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