lint_trap 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +97 -0
  3. data/Dockerfile +222 -0
  4. data/Gemfile +2 -0
  5. data/Rakefile +45 -0
  6. data/circle.yml +22 -0
  7. data/config/checkstyle/checkstyle_logger-all.jar +0 -0
  8. data/config/checkstyle/sun_checks.xml +177 -0
  9. data/config/coffeelint/lint_trap.coffee +12 -0
  10. data/config/jshint/formatter.js +22 -0
  11. data/config/rubocop/formatter.rb +22 -0
  12. data/config/scsslint/scsslint +34 -0
  13. data/lib/lint_trap/command.rb +39 -0
  14. data/lib/lint_trap/container/base.rb +30 -0
  15. data/lib/lint_trap/container/docker.rb +46 -0
  16. data/lib/lint_trap/container/fake.rb +28 -0
  17. data/lib/lint_trap/language/base.rb +18 -0
  18. data/lib/lint_trap/language/coffeescript.rb +13 -0
  19. data/lib/lint_trap/language/cpp.rb +17 -0
  20. data/lib/lint_trap/language/css.rb +13 -0
  21. data/lib/lint_trap/language/go.rb +13 -0
  22. data/lib/lint_trap/language/java.rb +13 -0
  23. data/lib/lint_trap/language/javascript.rb +13 -0
  24. data/lib/lint_trap/language/json.rb +13 -0
  25. data/lib/lint_trap/language/python.rb +13 -0
  26. data/lib/lint_trap/language/ruby.rb +13 -0
  27. data/lib/lint_trap/language/scss.rb +13 -0
  28. data/lib/lint_trap/language.rb +50 -0
  29. data/lib/lint_trap/linter/base.rb +58 -0
  30. data/lib/lint_trap/linter/checkstyle.rb +24 -0
  31. data/lib/lint_trap/linter/coffeelint.rb +21 -0
  32. data/lib/lint_trap/linter/cppcheck.rb +18 -0
  33. data/lib/lint_trap/linter/csslint.rb +23 -0
  34. data/lib/lint_trap/linter/golint.rb +19 -0
  35. data/lib/lint_trap/linter/jshint.rb +20 -0
  36. data/lib/lint_trap/linter/jsonlint.rb +18 -0
  37. data/lib/lint_trap/linter/pylint.rb +19 -0
  38. data/lib/lint_trap/linter/rubocop.rb +22 -0
  39. data/lib/lint_trap/linter/scsslint.rb +22 -0
  40. data/lib/lint_trap/linter.rb +42 -0
  41. data/lib/lint_trap/{parsers/base_parser.rb → parser/base.rb} +8 -9
  42. data/lib/lint_trap/{parsers/csslint_parser.rb → parser/csslint.rb} +4 -5
  43. data/lib/lint_trap/{parsers/line_parser.rb → parser/line.rb} +14 -5
  44. data/lib/lint_trap/parser/standard.rb +22 -0
  45. data/lib/lint_trap/parser/vim_quickfix.rb +19 -0
  46. data/lib/lint_trap/version.rb +1 -1
  47. data/lib/lint_trap.rb +5 -14
  48. data/lint_trap.gemspec +3 -0
  49. data/spec/command_spec.rb +38 -0
  50. data/spec/container/docker_spec.rb +34 -0
  51. data/spec/container/fake_spec.rb +29 -0
  52. data/spec/fixtures/Good.java +6 -0
  53. data/spec/fixtures/bad.coffee +1 -0
  54. data/spec/fixtures/bad.cpp +5 -0
  55. data/spec/fixtures/bad.css +4 -0
  56. data/spec/fixtures/bad.go +7 -0
  57. data/spec/fixtures/bad.java +3 -0
  58. data/spec/fixtures/bad.js +3 -0
  59. data/spec/fixtures/bad.json +4 -0
  60. data/spec/fixtures/bad.py +2 -0
  61. data/spec/fixtures/bad.rb +4 -0
  62. data/spec/fixtures/bad.scss +3 -0
  63. data/spec/fixtures/good.coffee +1 -0
  64. data/spec/fixtures/good.cpp +4 -0
  65. data/spec/fixtures/good.css +3 -0
  66. data/spec/fixtures/good.go +7 -0
  67. data/spec/fixtures/good.js +5 -0
  68. data/spec/fixtures/good.json +4 -0
  69. data/spec/fixtures/good.py +6 -0
  70. data/spec/fixtures/good.rb +5 -0
  71. data/spec/fixtures/good.scss +3 -0
  72. data/spec/fixtures/lint.txt +1 -0
  73. data/spec/integration/checkstyle_spec.rb +52 -0
  74. data/spec/integration/coffeelint_spec.rb +44 -0
  75. data/spec/integration/cppcheck_spec.rb +60 -0
  76. data/spec/integration/csslint_spec.rb +44 -0
  77. data/spec/integration/golint_spec.rb +44 -0
  78. data/spec/integration/jshint_spec.rb +70 -0
  79. data/spec/integration/jsonlint_spec.rb +60 -0
  80. data/spec/integration/pylint_spec.rb +51 -0
  81. data/spec/integration/rubocop_spec.rb +52 -0
  82. data/spec/integration/scsslint_spec.rb +44 -0
  83. data/spec/language/coffeescript_spec.rb +8 -0
  84. data/spec/language/cpp_spec.rb +8 -0
  85. data/spec/language/css_spec.rb +8 -0
  86. data/spec/language/go_spec.rb +8 -0
  87. data/spec/language/java_spec.rb +8 -0
  88. data/spec/language/javascript_spec.rb +8 -0
  89. data/spec/language/json_spec.rb +8 -0
  90. data/spec/language/python_spec.rb +8 -0
  91. data/spec/language/ruby_spec.rb +8 -0
  92. data/spec/language/scss_spec.rb +8 -0
  93. data/spec/language_spec.rb +143 -0
  94. data/spec/lint_trap_spec.rb +0 -16
  95. data/spec/linter/checkstyle_spec.rb +45 -0
  96. data/spec/linter/coffeelint_spec.rb +46 -0
  97. data/spec/linter/cppcheck_spec.rb +26 -0
  98. data/spec/linter/csslint_spec.rb +44 -0
  99. data/spec/linter/golint_spec.rb +22 -0
  100. data/spec/linter/jshint_spec.rb +44 -0
  101. data/spec/linter/jsonlint_spec.rb +22 -0
  102. data/spec/linter/pylint_spec.rb +46 -0
  103. data/spec/linter/rubocop_spec.rb +48 -0
  104. data/spec/linter/scsslint_spec.rb +44 -0
  105. data/spec/linter_spec.rb +67 -0
  106. data/spec/parser/csslint_spec.rb +25 -0
  107. data/spec/{parsers/standard_parser_spec.rb → parser/standard_spec.rb} +4 -3
  108. data/spec/{parsers/vim_quickfix_parser_spec.rb → parser/vim_quickfix_spec.rb} +5 -4
  109. data/spec/spec_helper.rb +8 -0
  110. data/spec/support/fixture_file_helper.rb +8 -0
  111. metadata +193 -18
  112. data/lib/lint_trap/parser_factory.rb +0 -32
  113. data/lib/lint_trap/parsers/null_parser.rb +0 -11
  114. data/lib/lint_trap/parsers/standard_parser.rb +0 -23
  115. data/lib/lint_trap/parsers/vim_quickfix_parser.rb +0 -20
  116. data/spec/parser_factory_spec.rb +0 -17
  117. data/spec/parsers/csslint_parser_spec.rb +0 -26
@@ -0,0 +1,39 @@
1
+ require_relative 'container/fake'
2
+ require 'open3'
3
+
4
+ module LintTrap
5
+ # Wraps the execution of linter commands
6
+ class Command
7
+ attr_reader :binary
8
+
9
+ def initialize(binary, flags, files)
10
+ @binary = binary
11
+ @flags = flags
12
+ @files = files
13
+ end
14
+
15
+ def run(container)
16
+ Bundler.with_clean_env do
17
+ puts command(container) if ENV['DEBUG_LINTING']
18
+ Open3.popen3(command(container)) do |_, stdout, _, thread|
19
+ yield stdout
20
+
21
+ thread.join
22
+ end
23
+ end
24
+ end
25
+
26
+ def command(container = LintTrap::Container::Fake.new)
27
+ container.wrap("#{binary} #{flags} #{files(container)} 2>&1")
28
+ end
29
+ alias_method :to_s, :command
30
+
31
+ def files(container = LintTrap::Container::Fake.new)
32
+ Shellwords.join(@files.map{|file| container.container_path(file)})
33
+ end
34
+
35
+ def flags
36
+ @flags.join(' ')
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,30 @@
1
+ require 'pathname'
2
+
3
+ module LintTrap
4
+ module Container
5
+ class Base
6
+ LOCAL_CONFIG_PATH = Pathname.new(File.expand_path('../../../../config', __FILE__))
7
+
8
+ def initialize(image, repo_path)
9
+ @image = image
10
+ @repo_path = Pathname.new(repo_path)
11
+ end
12
+
13
+ def wrap(_command)
14
+ raise NotImplementedError
15
+ end
16
+
17
+ def config_path(_path)
18
+ raise NotImplementedError
19
+ end
20
+
21
+ def file_path(_path)
22
+ raise NotImplementedError
23
+ end
24
+
25
+ protected
26
+
27
+ attr_reader :image, :repo_path
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,46 @@
1
+ require_relative 'base'
2
+ require 'pathname'
3
+
4
+ module LintTrap
5
+ module Container
6
+ # Acts like a container, without actually requiring a container.
7
+ class Docker < Base
8
+ CONFIG_PATH = Pathname.new('/opt/lint_trap/config')
9
+ CODE_PATH = Pathname.new('/home/spin_cycle')
10
+
11
+ def wrap(command)
12
+ "docker run #{flags} #{image} #{command}"
13
+ end
14
+
15
+ def config_path(path)
16
+ CONFIG_PATH.join(path).to_s
17
+ end
18
+
19
+ def local_path(path)
20
+ relative_path = Pathname.new(path).relative_path_from(CODE_PATH)
21
+
22
+ repo_path.join(relative_path).to_s
23
+ end
24
+
25
+ def container_path(path)
26
+ relative_path = Pathname.new(path).relative_path_from(repo_path)
27
+
28
+ CODE_PATH.join(relative_path).to_s
29
+ end
30
+
31
+ private
32
+
33
+ def flags
34
+ [
35
+ # '-m', '50m', # memory
36
+ # '-c', '1', # number of cpus
37
+ '--privileged=false',
38
+ '-v', "#{LOCAL_CONFIG_PATH}:#{CONFIG_PATH}",
39
+ '-v', "#{repo_path}:#{CODE_PATH}",
40
+ "--workdir=#{CODE_PATH}",
41
+ '--user=spin_cycle'
42
+ ].join(' ')
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,28 @@
1
+ require_relative 'base'
2
+
3
+ module LintTrap
4
+ module Container
5
+ # Acts like a container, without actually requiring a container.
6
+ class Fake < Base
7
+ def initialize
8
+ super('no/image', 'local')
9
+ end
10
+
11
+ def wrap(command)
12
+ command
13
+ end
14
+
15
+ def config_path(path)
16
+ LOCAL_CONFIG_PATH.join(path).to_s
17
+ end
18
+
19
+ def container_path(path)
20
+ path
21
+ end
22
+
23
+ def local_path(path)
24
+ path
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ module LintTrap
2
+ module Language
3
+ # Interface for languages
4
+ class Base
5
+ def self.canonical_name
6
+ name.split('::').last
7
+ end
8
+
9
+ def name
10
+ self.class.canonical_name
11
+ end
12
+
13
+ def linters
14
+ raise NotImplementedError, 'Must define what linters this language supports.'
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base'
2
+ require_relative '../linter/coffeelint'
3
+
4
+ module LintTrap
5
+ module Language
6
+ # CoffeeScript
7
+ class CoffeeScript < Base
8
+ def linters
9
+ [Linter::CoffeeLint]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'base'
2
+ require_relative '../linter/cppcheck'
3
+
4
+ module LintTrap
5
+ module Language
6
+ # C++
7
+ class CPP < Base
8
+ def self.canonical_name
9
+ 'C++'
10
+ end
11
+
12
+ def linters
13
+ [Linter::CPPCheck]
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base'
2
+ require_relative '../linter/csslint'
3
+
4
+ module LintTrap
5
+ module Language
6
+ # CSS
7
+ class CSS < Base
8
+ def linters
9
+ [Linter::CSSLint]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base'
2
+ require_relative '../linter/golint'
3
+
4
+ module LintTrap
5
+ module Language
6
+ # Go
7
+ class Go < Base
8
+ def linters
9
+ [Linter::GoLint]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base'
2
+ require_relative '../linter/checkstyle'
3
+
4
+ module LintTrap
5
+ module Language
6
+ # Java
7
+ class Java < Base
8
+ def linters
9
+ [Linter::CheckStyle]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base'
2
+ require_relative '../linter/jshint'
3
+
4
+ module LintTrap
5
+ module Language
6
+ # JavaScript
7
+ class JavaScript < Base
8
+ def linters
9
+ [Linter::JSHint]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base'
2
+ require_relative '../linter/jsonlint'
3
+
4
+ module LintTrap
5
+ module Language
6
+ # JSON
7
+ class JSON < Base
8
+ def linters
9
+ [Linter::JSONLint]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base'
2
+ require_relative '../linter/pylint'
3
+
4
+ module LintTrap
5
+ module Language
6
+ # Python
7
+ class Python < Base
8
+ def linters
9
+ [Linter::PyLint]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base'
2
+ require_relative '../linter/rubocop'
3
+
4
+ module LintTrap
5
+ module Language
6
+ # Ruby
7
+ class Ruby < Base
8
+ def linters
9
+ [Linter::RuboCop]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base'
2
+ require_relative '../linter/scsslint'
3
+
4
+ module LintTrap
5
+ module Language
6
+ # SCSS
7
+ class SCSS < Base
8
+ def linters
9
+ [Linter::SCSSLint]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,50 @@
1
+ require 'linguist'
2
+
3
+ require_relative 'language/coffeescript'
4
+ require_relative 'language/cpp'
5
+ require_relative 'language/css'
6
+ require_relative 'language/go'
7
+ require_relative 'language/java'
8
+ require_relative 'language/javascript'
9
+ require_relative 'language/json'
10
+ require_relative 'language/python'
11
+ require_relative 'language/ruby'
12
+ require_relative 'language/scss'
13
+
14
+ module LintTrap
15
+ # Language lookup
16
+ module Language
17
+ @languages = {}
18
+
19
+ class << self
20
+ def register(language)
21
+ languages[language.canonical_name] = language
22
+ end
23
+
24
+ def detect(file)
25
+ language = Linguist::FileBlob.new(file).language
26
+
27
+ find(language.name)
28
+ end
29
+
30
+ def find(name)
31
+ languages[name]
32
+ end
33
+
34
+ protected
35
+
36
+ attr_reader :languages
37
+ end
38
+
39
+ register CoffeeScript
40
+ register CPP
41
+ register CSS
42
+ register Go
43
+ register Java
44
+ register JavaScript
45
+ register JSON
46
+ register Python
47
+ register Ruby
48
+ register SCSS
49
+ end
50
+ end
@@ -0,0 +1,58 @@
1
+ require_relative '../parser/standard'
2
+ require_relative '../command'
3
+
4
+ module LintTrap
5
+ module Linter
6
+ # The base class for all linters. Provides a template for linter execution.
7
+ class Base
8
+ CONFIG_PATH = File.expand_path('../../../../config', __FILE__)
9
+
10
+ def self.canonical_name
11
+ name.split('::').last
12
+ end
13
+
14
+ def initialize(container:, **options)
15
+ @container = container
16
+ @options = options
17
+ end
18
+
19
+ def lint(files)
20
+ command(files).run(container) do |stdout|
21
+ parser(stdout).parse do |violation|
22
+ yield violation
23
+ end
24
+ end
25
+ end
26
+
27
+ def name
28
+ self.class.canonical_name
29
+ end
30
+
31
+ protected
32
+
33
+ attr_reader :container, :options
34
+
35
+ private
36
+
37
+ def command(files)
38
+ Command.new(command_name, flags, files)
39
+ end
40
+
41
+ def parser(stdout)
42
+ LintTrap::Parser::Standard.new(stdout, container)
43
+ end
44
+
45
+ def config_path(path)
46
+ container.config_path(path)
47
+ end
48
+
49
+ def flags
50
+ raise NotImplementedError, 'Method flags must be implemented.'
51
+ end
52
+
53
+ def command_name
54
+ name.downcase
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,24 @@
1
+ require_relative 'base'
2
+
3
+ module LintTrap
4
+ module Linter
5
+ # Encapsulates logic specific to checkstyle command line tool.
6
+ class CheckStyle < Base
7
+ JAR = 'checkstyle/checkstyle_logger-all.jar'
8
+ CHECKS_XML = 'checkstyle/sun_checks.xml'
9
+
10
+ private
11
+
12
+ def command_name
13
+ 'java'
14
+ end
15
+
16
+ def flags
17
+ [
18
+ '-jar', config_path(JAR),
19
+ '-c', options[:config] || config_path(CHECKS_XML)
20
+ ]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'base'
2
+
3
+ module LintTrap
4
+ module Linter
5
+ # Encapsulates logic specific to coffeelint command line tool.
6
+ class CoffeeLint < Base
7
+ REPORTER = 'coffeelint/lint_trap.coffee'
8
+
9
+ private
10
+
11
+ def flags
12
+ [
13
+ "--reporter=#{config_path(REPORTER)}",
14
+ '--nocolor'
15
+ ].tap do |flags|
16
+ flags.concat(["--file=#{options[:config]}"]) if options[:config]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'base'
2
+
3
+ module LintTrap
4
+ module Linter
5
+ # Encapsulates logic specific to cppcheck command line tool.
6
+ class CPPCheck < Base
7
+ private
8
+
9
+ def flags
10
+ [
11
+ '--enable=all',
12
+ '--error-exitcode=1',
13
+ '--template="{file}:{line}:::{id}:{severity}:{message}"'
14
+ ]
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'base'
2
+ require_relative '../parser/csslint'
3
+
4
+ module LintTrap
5
+ module Linter
6
+ # Encapsulates logic specific to csslint command line tool.
7
+ class CSSLint < Base
8
+ private
9
+
10
+ def flags
11
+ [
12
+ '--format=compact'
13
+ ].tap do |flags|
14
+ flags.concat(["--config=#{options[:config]}"]) if options[:config]
15
+ end
16
+ end
17
+
18
+ def parser(stdout)
19
+ LintTrap::Parser::CSSLint.new(stdout, container)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'base'
2
+ require_relative '../parser/vim_quickfix'
3
+
4
+ module LintTrap
5
+ module Linter
6
+ # Encapsulates logic specific to golint command line tool.
7
+ class GoLint < Base
8
+ private
9
+
10
+ def flags
11
+ []
12
+ end
13
+
14
+ def parser(stdout)
15
+ LintTrap::Parser::VimQuickfix.new(stdout, container)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'base'
2
+
3
+ module LintTrap
4
+ module Linter
5
+ # Encapsulates logic specific to jshint command line tool.
6
+ class JSHint < Base
7
+ FORMATTER = 'jshint/formatter.js'
8
+
9
+ private
10
+
11
+ def flags
12
+ [
13
+ '--reporter', config_path(FORMATTER)
14
+ ].tap do |flags|
15
+ flags.concat(['--config', options[:config]]) if options[:config]
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'base'
2
+
3
+ module LintTrap
4
+ module Linter
5
+ # Encapsulates logic specific to durable-json-lint command line tool.
6
+ class JSONLint < Base
7
+ private
8
+
9
+ def command_name
10
+ 'durable-json-lint'
11
+ end
12
+
13
+ def flags
14
+ ['--format', '{{file}}:{{line}}:{{column}}:::error:{{{description}}}']
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'base'
2
+
3
+ module LintTrap
4
+ module Linter
5
+ # Encapsulates logic specific to pylint command line tool.
6
+ class PyLint < Base
7
+ private
8
+
9
+ def flags
10
+ [
11
+ '-r', 'no',
12
+ '--msg-template', '"{abspath}:{line}:{column}::{symbol}:{category}:{msg}"'
13
+ ].tap do |flags|
14
+ flags.concat(['--rcfile', options[:config]]) if options[:config]
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ require_relative 'base'
2
+
3
+ module LintTrap
4
+ module Linter
5
+ # Encapsulates logic specific to rubocop command line tool.
6
+ class RuboCop < Base
7
+ FORMATTER = 'rubocop/formatter.rb'
8
+
9
+ private
10
+
11
+ def flags
12
+ [
13
+ '--require', config_path(FORMATTER),
14
+ '--format', 'LintTrap::Rubocop::Formatter',
15
+ '--no-color'
16
+ ].tap do |flags|
17
+ flags.concat(['--config', options[:config]]) if options[:config]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ require_relative 'base'
2
+
3
+ module LintTrap
4
+ module Linter
5
+ # Encapsulates logic specific to scsslint command line tool.
6
+ class SCSSLint < Base
7
+ COMMAND = 'scsslint/scsslint'
8
+
9
+ def command_name
10
+ config_path(COMMAND)
11
+ end
12
+
13
+ def flags
14
+ [
15
+ '--format=LintTrap'
16
+ ].tap do |flags|
17
+ flags.concat(['--config', options[:config]]) if options[:config]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,42 @@
1
+ require_relative 'linter/checkstyle'
2
+ require_relative 'linter/coffeelint'
3
+ require_relative 'linter/cppcheck'
4
+ require_relative 'linter/csslint'
5
+ require_relative 'linter/golint'
6
+ require_relative 'linter/jshint'
7
+ require_relative 'linter/jsonlint'
8
+ require_relative 'linter/pylint'
9
+ require_relative 'linter/rubocop'
10
+ require_relative 'linter/scsslint'
11
+
12
+ module LintTrap
13
+ # Linter lookup
14
+ module Linter
15
+ @linters = {}
16
+
17
+ class << self
18
+ def register(linter)
19
+ linters[linter.canonical_name] = linter
20
+ end
21
+
22
+ def find(name)
23
+ linters[name]
24
+ end
25
+
26
+ protected
27
+
28
+ attr_reader :linters
29
+ end
30
+
31
+ register CheckStyle
32
+ register CoffeeLint
33
+ register CPPCheck
34
+ register CSSLint
35
+ register GoLint
36
+ register JSHint
37
+ register JSONLint
38
+ register PyLint
39
+ register RuboCop
40
+ register SCSSLint
41
+ end
42
+ end