Make configuration dependent on instance instead of class, too.
[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$'
+```
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 }
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|
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
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
--- /dev/null
+printf 'custom eslint called'
module Pronto
describe ESLintNpm do
let(:eslint) { ESLintNpm.new(patches) }
+ let(:patches) { [] }
describe '#run' do
subject(:run) { eslint.run }
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
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')
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')
require 'fileutils'
require 'rspec'
-require 'rspec/its'
require 'pronto/eslint_npm'
%w(test eslintignore).each do |repo_name|
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