lint_trappings 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.md +21 -0
- data/lib/lint_trappings.rb +17 -0
- data/lib/lint_trappings/application.rb +138 -0
- data/lib/lint_trappings/arguments_parser.rb +145 -0
- data/lib/lint_trappings/cli.rb +61 -0
- data/lib/lint_trappings/command/base.rb +36 -0
- data/lib/lint_trappings/command/display_documentation.rb +65 -0
- data/lib/lint_trappings/command/display_formatters.rb +14 -0
- data/lib/lint_trappings/command/display_help.rb +8 -0
- data/lib/lint_trappings/command/display_linters.rb +24 -0
- data/lib/lint_trappings/command/display_version.rb +14 -0
- data/lib/lint_trappings/command/scan.rb +19 -0
- data/lib/lint_trappings/configuration.rb +94 -0
- data/lib/lint_trappings/configuration_loader.rb +98 -0
- data/lib/lint_trappings/configuration_resolver.rb +49 -0
- data/lib/lint_trappings/document.rb +45 -0
- data/lib/lint_trappings/errors.rb +127 -0
- data/lib/lint_trappings/executable.rb +26 -0
- data/lib/lint_trappings/file_finder.rb +171 -0
- data/lib/lint_trappings/formatter/base.rb +67 -0
- data/lib/lint_trappings/formatter/checkstyle.rb +34 -0
- data/lib/lint_trappings/formatter/default.rb +99 -0
- data/lib/lint_trappings/formatter/json.rb +62 -0
- data/lib/lint_trappings/formatter_forwarder.rb +23 -0
- data/lib/lint_trappings/formatter_loader.rb +45 -0
- data/lib/lint_trappings/lint.rb +37 -0
- data/lib/lint_trappings/linter.rb +182 -0
- data/lib/lint_trappings/linter_configuration_validator.rb +42 -0
- data/lib/lint_trappings/linter_loader.rb +44 -0
- data/lib/lint_trappings/linter_plugin.rb +35 -0
- data/lib/lint_trappings/linter_selector.rb +120 -0
- data/lib/lint_trappings/location.rb +39 -0
- data/lib/lint_trappings/output.rb +118 -0
- data/lib/lint_trappings/preprocessor.rb +41 -0
- data/lib/lint_trappings/rake_task.rb +145 -0
- data/lib/lint_trappings/report.rb +58 -0
- data/lib/lint_trappings/runner.rb +161 -0
- data/lib/lint_trappings/spec.rb +12 -0
- data/lib/lint_trappings/spec/directory_helpers.rb +22 -0
- data/lib/lint_trappings/spec/indentation_helpers.rb +7 -0
- data/lib/lint_trappings/spec/matchers/report_lint_matcher.rb +169 -0
- data/lib/lint_trappings/spec/shared_contexts/linter_shared_context.rb +35 -0
- data/lib/lint_trappings/utils.rb +123 -0
- data/lib/lint_trappings/version.rb +4 -0
- metadata +117 -0
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'lint_trappings'
|
2
|
+
|
3
|
+
# Stub declaration so nested modules can reference it
|
4
|
+
module LintTrappings::Spec; end
|
5
|
+
|
6
|
+
Dir[File.join(File.dirname(__FILE__), 'spec', '**', '*.rb')].each do |file|
|
7
|
+
require file
|
8
|
+
end
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.include LintTrappings::Matchers
|
12
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
|
3
|
+
# Helpers for creating temporary directories for testing.
|
4
|
+
module LintTrappings::Spec::DirectoryHelpers
|
5
|
+
module_function
|
6
|
+
|
7
|
+
# Creates a directory in a temporary directory which will automatically be
|
8
|
+
# destroyed at the end of the spec run. Any block passed to this will be
|
9
|
+
# executed with the created directory as the working directory.
|
10
|
+
#
|
11
|
+
# @return [String] The full path of the directory.
|
12
|
+
def directory(name = 'some-dir', &block)
|
13
|
+
tmpdir = Dir.mktmpdir.tap do |path|
|
14
|
+
Dir.chdir(path) do
|
15
|
+
Dir.mkdir(name)
|
16
|
+
Dir.chdir(name, &block) if block_given?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
File.join(tmpdir, name)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
module LintTrappings::Spec::IndentationHelpers
|
2
|
+
# Strips off excess leading indentation from each line so we can use Heredocs
|
3
|
+
# for writing code without having the leading indentation count.
|
4
|
+
def normalize_indent(code)
|
5
|
+
LintTrappings::Utils.normalize_indent(code)
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
# rubocop:disable Metrics/ClassLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/LineLength
|
2
|
+
|
3
|
+
module LintTrappings::Matchers
|
4
|
+
# RSpec matcher that returns whether or not a linter reported lints matching
|
5
|
+
# the specified criteria.
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
#
|
9
|
+
# it { should report_lint line: 2 }
|
10
|
+
class ReportLintMatcher
|
11
|
+
ALLOWED_KEYWORD_ARGUMENTS = %i[line message]
|
12
|
+
|
13
|
+
def initialize(*args, **kwargs)
|
14
|
+
@options = kwargs
|
15
|
+
|
16
|
+
if args.any?
|
17
|
+
raise ArgumentError,
|
18
|
+
'`report_lint` was given more than one argument!' if args.length > 1
|
19
|
+
|
20
|
+
if @options[:line]
|
21
|
+
raise ArgumentError,
|
22
|
+
'`line` keyword argument cannot be specified when Range is given'
|
23
|
+
end
|
24
|
+
|
25
|
+
@range = args.first
|
26
|
+
if @range.is_a?(Array)
|
27
|
+
if @range.length != 2 ||
|
28
|
+
!@range.first.is_a?(Integer) ||
|
29
|
+
!@range.last.is_a?(Integer)
|
30
|
+
raise ArgumentError,
|
31
|
+
'Location tuple must be an Array of two integers ' \
|
32
|
+
"representing line and column, but was #{@range.inspect}"
|
33
|
+
end
|
34
|
+
|
35
|
+
# Convert to an actual range by assuming it spans nothing
|
36
|
+
@range = @range..@range
|
37
|
+
elsif !@range.is_a?(Range)
|
38
|
+
raise ArgumentError, '`report_lint` must be given a Range e.g. [1, 2]..[3, 4]'
|
39
|
+
elsif !(@range.begin.is_a?(Array) && @range.end.is_a?(Array))
|
40
|
+
raise ArgumentError, 'Source range must have Array tuple endpoints'
|
41
|
+
end
|
42
|
+
else
|
43
|
+
# Otherwise no explicit range was specified, so verify the options
|
44
|
+
@options.keys.each do |key|
|
45
|
+
raise ArgumentError,
|
46
|
+
"Unknown keyword argument #{key}" unless ALLOWED_KEYWORD_ARGUMENTS.include?(key)
|
47
|
+
end
|
48
|
+
|
49
|
+
@line = @options[:line]
|
50
|
+
end
|
51
|
+
|
52
|
+
@message = @options[:message] if @options[:message]
|
53
|
+
end
|
54
|
+
|
55
|
+
def matches?(linter)
|
56
|
+
# We're cheating by accessing private values here, but it will allow us to
|
57
|
+
# present more-helpful error messages since we get access to so much more
|
58
|
+
# information by passing the linter instead of just a list of lints.
|
59
|
+
@linter = linter
|
60
|
+
@lints = linter.instance_variable_get(:@lints)
|
61
|
+
|
62
|
+
any_lint_matches?
|
63
|
+
end
|
64
|
+
|
65
|
+
def failure_message
|
66
|
+
output = 'expected that a lint would be reported'
|
67
|
+
|
68
|
+
if !any_range_matches?
|
69
|
+
output <<
|
70
|
+
if @line
|
71
|
+
" on line #{@line}"
|
72
|
+
elsif @range
|
73
|
+
" on #{range_to_str(@range)}"
|
74
|
+
end.to_s
|
75
|
+
|
76
|
+
output <<
|
77
|
+
case @lints.count
|
78
|
+
when 0
|
79
|
+
', but none were'
|
80
|
+
when 1
|
81
|
+
if @line
|
82
|
+
", but was reported on line #{@lints.first.source_range.begin.line}"
|
83
|
+
elsif @range
|
84
|
+
", but was reported on #{range_to_str(@lints.first.source_range)}"
|
85
|
+
end.to_s
|
86
|
+
else
|
87
|
+
if @line
|
88
|
+
", but lints were reported on the following lines instead:\n" +
|
89
|
+
@lints.map { |lint| lint.source_range.line }.sort.join(', ')
|
90
|
+
elsif @range
|
91
|
+
", but lints were reported on the following ranges instead:\n" +
|
92
|
+
@lints.map { |lint| range_to_str(lint.source_range) }.join("\n")
|
93
|
+
end.to_s
|
94
|
+
end
|
95
|
+
elsif @message
|
96
|
+
matching_lints = lints_matching_range
|
97
|
+
output <<
|
98
|
+
if @message.is_a?(Regexp)
|
99
|
+
" with message matching pattern #{@message.inspect} "
|
100
|
+
else
|
101
|
+
" with message #{@message.inspect} "
|
102
|
+
end
|
103
|
+
|
104
|
+
output << "but got:\n" << matching_lints.map(&:message).join("\n")
|
105
|
+
end
|
106
|
+
|
107
|
+
output
|
108
|
+
end
|
109
|
+
|
110
|
+
def failure_message_when_negated
|
111
|
+
'expected that a lint would NOT be reported'
|
112
|
+
end
|
113
|
+
|
114
|
+
def description
|
115
|
+
output = 'report a lint'
|
116
|
+
output <<
|
117
|
+
if @line
|
118
|
+
" on line #{@line}"
|
119
|
+
elsif @range
|
120
|
+
" on #{range_to_str(@range)}"
|
121
|
+
end.to_s
|
122
|
+
|
123
|
+
output
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def lints_matching_range
|
129
|
+
@lints.select { |lint| range_matches?(lint) }
|
130
|
+
end
|
131
|
+
|
132
|
+
def any_lint_matches?
|
133
|
+
return true if !@line && !@range && @lints.any?
|
134
|
+
lints_matching_range.any? { |lint| message_matches?(lint) }
|
135
|
+
end
|
136
|
+
|
137
|
+
def any_range_matches?
|
138
|
+
@lints.any? do |lint|
|
139
|
+
range_matches?(lint)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def range_matches?(lint)
|
144
|
+
if @line
|
145
|
+
lint.source_range.begin.line == @line
|
146
|
+
else
|
147
|
+
lint.source_range == @range
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def message_matches?(lint)
|
152
|
+
if @message.nil?
|
153
|
+
true
|
154
|
+
elsif @message.is_a?(Regexp)
|
155
|
+
lint.message =~ @message
|
156
|
+
elsif @message.is_a?(String)
|
157
|
+
lint.message == @message
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def range_to_str(range)
|
162
|
+
"(L#{range.begin.line},C#{range.begin.column})..(L#{range.end.line},C#{range.end.column})"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def report_lint(*args, **kwargs)
|
167
|
+
ReportLintMatcher.new(*args, **kwargs)
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Makes writing tests for linters a lot DRYer by taking any `src` variable
|
2
|
+
# defined via `let` and normalizing it (removing indentation that would be
|
3
|
+
# inserted by using Heredocs) and setting up the subject to be the lints
|
4
|
+
# returned by Linter#run.
|
5
|
+
#
|
6
|
+
# Thus a typical test will look like:
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# require 'spec_helper'
|
10
|
+
#
|
11
|
+
# RSpec.describe MyApp::Linter::MyLinter do
|
12
|
+
# include_context 'linter'
|
13
|
+
#
|
14
|
+
# context 'when source contains "foo"' do
|
15
|
+
# let(:src) { <<-SRC }
|
16
|
+
# This is some code
|
17
|
+
# with the word "foo" in it.
|
18
|
+
# SRC
|
19
|
+
#
|
20
|
+
# it { should report_lint line: 2 }
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
shared_context 'linter' do
|
24
|
+
let(:config) do
|
25
|
+
LINT_TRAP_APPLICATION_CLASS.base_configuration.for_linter(described_class)
|
26
|
+
end
|
27
|
+
|
28
|
+
subject do
|
29
|
+
linter = described_class.new(config)
|
30
|
+
document = LINT_TRAP_APPLICATION_CLASS.document_class
|
31
|
+
.new(normalize_indent(src), config)
|
32
|
+
linter.run(document)
|
33
|
+
linter
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module LintTrappings
|
2
|
+
# Miscellaneus collection of helper functions.
|
3
|
+
module Utils
|
4
|
+
module_function
|
5
|
+
|
6
|
+
# Returns whether a glob pattern (or any of a list of patterns) matches the
|
7
|
+
# specified file.
|
8
|
+
#
|
9
|
+
# This is defined here so our file globbing options are consistent
|
10
|
+
# everywhere we perform globbing.
|
11
|
+
#
|
12
|
+
# @param glob [String, Array]
|
13
|
+
# @param file [String]
|
14
|
+
# @return [Boolean]
|
15
|
+
def any_glob_matches?(globs_or_glob, file)
|
16
|
+
Array(globs_or_glob).any? do |glob|
|
17
|
+
::File.fnmatch?(glob, file,
|
18
|
+
::File::FNM_PATHNAME | # Wildcards don't match path separators
|
19
|
+
::File::FNM_DOTMATCH) # `*` wildcard matches dotfiles
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Find all consecutive items satisfying the given block of a minimum size,
|
24
|
+
# yielding each group of consecutive items to the provided block.
|
25
|
+
#
|
26
|
+
# @param items [Array]
|
27
|
+
# @param satisfies [Proc] function that takes an item and returns true/false
|
28
|
+
# @param min_consecutive [Fixnum] minimum number of consecutive items before
|
29
|
+
# yielding the group
|
30
|
+
# @yield Passes list of consecutive items all matching the criteria defined
|
31
|
+
# by the `satisfies` {Proc} to the provided block
|
32
|
+
# @yieldparam group [Array] List of consecutive items
|
33
|
+
# @yieldreturn [Boolean] block should return whether item matches criteria
|
34
|
+
# for inclusion
|
35
|
+
def for_consecutive_items(items, satisfies, min_consecutive = 2)
|
36
|
+
current_index = -1
|
37
|
+
|
38
|
+
while (current_index += 1) < items.count
|
39
|
+
next unless satisfies[items[current_index]]
|
40
|
+
|
41
|
+
count = count_consecutive(items, current_index, &satisfies)
|
42
|
+
next unless count >= min_consecutive
|
43
|
+
|
44
|
+
# Yield the chunk of consecutive items
|
45
|
+
yield items[current_index...(current_index + count)]
|
46
|
+
|
47
|
+
current_index += count # Skip this patch of consecutive items to find more
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Count the number of consecutive items satisfying the given {Proc}.
|
52
|
+
#
|
53
|
+
# @param items [Array]
|
54
|
+
# @param offset [Fixnum] index to start searching from
|
55
|
+
# @yield [item] Passes item to the provided block.
|
56
|
+
# @yieldparam item [Object] Item to evaluate as matching criteria for
|
57
|
+
# inclusion
|
58
|
+
# @yieldreturn [Boolean] whether to include the item
|
59
|
+
# @return [Integer]
|
60
|
+
def count_consecutive(items, offset = 0, &block)
|
61
|
+
count = 1
|
62
|
+
count += 1 while (offset + count < items.count) && block.call(items[offset + count])
|
63
|
+
count
|
64
|
+
end
|
65
|
+
|
66
|
+
# Convert a class name or CamelCase string into snake_case.
|
67
|
+
#
|
68
|
+
# @see stackoverflow.com/questions/1509915/converting-camel-case-to-underscore-case-in-ruby
|
69
|
+
#
|
70
|
+
# @param str [String]
|
71
|
+
#
|
72
|
+
# @return [String]
|
73
|
+
def snake_case(str)
|
74
|
+
str.gsub(/::/, '/')
|
75
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
76
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
77
|
+
.tr('-', '_')
|
78
|
+
.downcase
|
79
|
+
end
|
80
|
+
|
81
|
+
# Converts a string containing underscores/hyphens/spaces into CamelCase.
|
82
|
+
#
|
83
|
+
# @param str [String]
|
84
|
+
#
|
85
|
+
# @return [String]
|
86
|
+
def camel_case(str)
|
87
|
+
str.split(/_|-| /).map { |part| part.sub(/^\w/, &:upcase) }.join
|
88
|
+
end
|
89
|
+
|
90
|
+
# Returns the plural of the word if necessary based on the given count.
|
91
|
+
#
|
92
|
+
# @param word [String]
|
93
|
+
# @param count [Integer]
|
94
|
+
#
|
95
|
+
# @return [String]
|
96
|
+
def pluralize(word, count)
|
97
|
+
count == 1 ? word : "#{word}s"
|
98
|
+
end
|
99
|
+
|
100
|
+
# Strips off excess leading indentation from each line so we can use Heredocs
|
101
|
+
# for writing code without having the leading indentation count.
|
102
|
+
def normalize_indent(code)
|
103
|
+
leading_indent = code[/^(\s*)/, 1]
|
104
|
+
code.lstrip.gsub(/\n#{leading_indent}/, "\n")
|
105
|
+
end
|
106
|
+
|
107
|
+
# Calls a block of code with a modified set of environment variables,
|
108
|
+
# restoring them once the code has executed.
|
109
|
+
#
|
110
|
+
# @param env [Hash] environment variables to set
|
111
|
+
def with_environment(env)
|
112
|
+
old_env = {}
|
113
|
+
env.each do |var, value|
|
114
|
+
old_env[var] = ENV[var.to_s]
|
115
|
+
ENV[var.to_s] = value
|
116
|
+
end
|
117
|
+
|
118
|
+
yield
|
119
|
+
ensure
|
120
|
+
old_env.each { |var, value| ENV[var.to_s] = value }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lint_trappings
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Shane da Silva
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-02-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: parallel
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: terminal-table
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.4'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.4'
|
41
|
+
description: Framework for writing static analysis tools (a.k.a. linters)
|
42
|
+
email:
|
43
|
+
- shane@dasilva.io
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- LICENSE.md
|
49
|
+
- lib/lint_trappings.rb
|
50
|
+
- lib/lint_trappings/application.rb
|
51
|
+
- lib/lint_trappings/arguments_parser.rb
|
52
|
+
- lib/lint_trappings/cli.rb
|
53
|
+
- lib/lint_trappings/command/base.rb
|
54
|
+
- lib/lint_trappings/command/display_documentation.rb
|
55
|
+
- lib/lint_trappings/command/display_formatters.rb
|
56
|
+
- lib/lint_trappings/command/display_help.rb
|
57
|
+
- lib/lint_trappings/command/display_linters.rb
|
58
|
+
- lib/lint_trappings/command/display_version.rb
|
59
|
+
- lib/lint_trappings/command/scan.rb
|
60
|
+
- lib/lint_trappings/configuration.rb
|
61
|
+
- lib/lint_trappings/configuration_loader.rb
|
62
|
+
- lib/lint_trappings/configuration_resolver.rb
|
63
|
+
- lib/lint_trappings/document.rb
|
64
|
+
- lib/lint_trappings/errors.rb
|
65
|
+
- lib/lint_trappings/executable.rb
|
66
|
+
- lib/lint_trappings/file_finder.rb
|
67
|
+
- lib/lint_trappings/formatter/base.rb
|
68
|
+
- lib/lint_trappings/formatter/checkstyle.rb
|
69
|
+
- lib/lint_trappings/formatter/default.rb
|
70
|
+
- lib/lint_trappings/formatter/json.rb
|
71
|
+
- lib/lint_trappings/formatter_forwarder.rb
|
72
|
+
- lib/lint_trappings/formatter_loader.rb
|
73
|
+
- lib/lint_trappings/lint.rb
|
74
|
+
- lib/lint_trappings/linter.rb
|
75
|
+
- lib/lint_trappings/linter_configuration_validator.rb
|
76
|
+
- lib/lint_trappings/linter_loader.rb
|
77
|
+
- lib/lint_trappings/linter_plugin.rb
|
78
|
+
- lib/lint_trappings/linter_selector.rb
|
79
|
+
- lib/lint_trappings/location.rb
|
80
|
+
- lib/lint_trappings/output.rb
|
81
|
+
- lib/lint_trappings/preprocessor.rb
|
82
|
+
- lib/lint_trappings/rake_task.rb
|
83
|
+
- lib/lint_trappings/report.rb
|
84
|
+
- lib/lint_trappings/runner.rb
|
85
|
+
- lib/lint_trappings/spec.rb
|
86
|
+
- lib/lint_trappings/spec/directory_helpers.rb
|
87
|
+
- lib/lint_trappings/spec/indentation_helpers.rb
|
88
|
+
- lib/lint_trappings/spec/matchers/report_lint_matcher.rb
|
89
|
+
- lib/lint_trappings/spec/shared_contexts/linter_shared_context.rb
|
90
|
+
- lib/lint_trappings/utils.rb
|
91
|
+
- lib/lint_trappings/version.rb
|
92
|
+
homepage: https://github.com/sds/lint-trappings
|
93
|
+
licenses:
|
94
|
+
- MIT
|
95
|
+
metadata: {}
|
96
|
+
post_install_message:
|
97
|
+
rdoc_options: []
|
98
|
+
require_paths:
|
99
|
+
- lib
|
100
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '2'
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
requirements: []
|
111
|
+
rubyforge_project:
|
112
|
+
rubygems_version: 2.4.5.1
|
113
|
+
signing_key:
|
114
|
+
specification_version: 4
|
115
|
+
summary: Linter framework
|
116
|
+
test_files: []
|
117
|
+
has_rdoc:
|