rubocop-aha 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +42 -0
- data/Rakefile +1 -0
- data/lib/config.yml +149 -0
- data/lib/rubocop-aha/cops/empty_gsub_replacement.rb +169 -0
- data/lib/rubocop-aha/version.rb +5 -0
- data/lib/rubocop-aha.rb +1 -0
- data/rubocop-aha.gemspec +27 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8793b3d95494dcf76bfc09519c0167bfa0a4b709
|
4
|
+
data.tar.gz: 51ee300e73e2f12f6eae259b9dc8bf052ea977f6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: efd209fa9820c789a3e28e03f08ac639d7f0eb53162667721897eda710ad02f3f6e490d5700b6d957da21c7f6dd46903ec72463754eaff55214f7fbcae1ee899
|
7
|
+
data.tar.gz: eba7fa55b47f8a345b0897594e4349e05b87cd2ad2ed01a8d553ec83d669cd359b44c2b45ddac4f8805d7edc61c6e988724b178d675783be00d7c01094a1756c
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Aha! Labs Inc
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/rubocop-aha.svg)](https://badge.fury.io/rb/rubocop-aha)
|
2
|
+
|
3
|
+
# rubocop
|
4
|
+
|
5
|
+
Common rubocop configuration for [Aha!](https://www.aha.io) projects.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'rubocop-aha'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
```bash
|
18
|
+
$ bundle
|
19
|
+
```
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
```bash
|
24
|
+
$ gem install rubocop-aha
|
25
|
+
```
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
Add the following to your project's `.rubocop.yml`:
|
30
|
+
|
31
|
+
```
|
32
|
+
inherit_gem:
|
33
|
+
rubocop-aha: lib/config.yml
|
34
|
+
```
|
35
|
+
|
36
|
+
## Contributing
|
37
|
+
|
38
|
+
We are unlikely to accept external contributions to change configuration rules. You are welcome to fork or extend for your own purposes if you like the baseline but disagree with some of our settings. :)
|
39
|
+
|
40
|
+
## License
|
41
|
+
|
42
|
+
MIT
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/lib/config.yml
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
require:
|
2
|
+
- ./rubocop-aha/cops/empty_gsub_replacement.rb
|
3
|
+
- rubocop/rspec/focused
|
4
|
+
- rubocop-rspec
|
5
|
+
|
6
|
+
AllCops:
|
7
|
+
Exclude:
|
8
|
+
- bin/**/*
|
9
|
+
- node_modules/**/*
|
10
|
+
- db/**/*
|
11
|
+
- tmp/**/*
|
12
|
+
- vendor/**/*
|
13
|
+
TargetRubyVersion: 2.3
|
14
|
+
DisplayCopNames: true
|
15
|
+
|
16
|
+
Rails:
|
17
|
+
Enabled: true
|
18
|
+
|
19
|
+
Bundler/OrderedGems:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Layout/CaseIndentation:
|
23
|
+
EnforcedStyle: end
|
24
|
+
|
25
|
+
Layout/ElseAlignment:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
Layout/EmptyLinesAroundBlockBody:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
Layout/EmptyLinesAroundExceptionHandlingKeywords:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
Layout/IndentHash:
|
35
|
+
EnforcedStyle: consistent
|
36
|
+
|
37
|
+
Layout/MultilineOperationIndentation:
|
38
|
+
EnforcedStyle: indented
|
39
|
+
|
40
|
+
Lint/BlockAlignment:
|
41
|
+
EnforcedStyleAlignWith: start_of_block
|
42
|
+
|
43
|
+
Lint/DefEndAlignment:
|
44
|
+
EnforcedStyleAlignWith: start_of_line
|
45
|
+
|
46
|
+
Lint/EndAlignment:
|
47
|
+
EnforcedStyleAlignWith: variable
|
48
|
+
|
49
|
+
Lint/InheritException:
|
50
|
+
EnforcedStyle: standard_error
|
51
|
+
|
52
|
+
Lint/UnusedBlockArgument:
|
53
|
+
Enabled: false
|
54
|
+
|
55
|
+
Lint/UnusedMethodArgument:
|
56
|
+
Enabled: false
|
57
|
+
|
58
|
+
Metrics/AbcSize:
|
59
|
+
Enabled: false
|
60
|
+
|
61
|
+
Metrics/BlockLength:
|
62
|
+
Enabled: false
|
63
|
+
|
64
|
+
Metrics/ClassLength:
|
65
|
+
Enabled: false
|
66
|
+
|
67
|
+
Metrics/CyclomaticComplexity:
|
68
|
+
Enabled: false
|
69
|
+
|
70
|
+
Metrics/LineLength:
|
71
|
+
Enabled: false
|
72
|
+
|
73
|
+
Metrics/MethodLength:
|
74
|
+
Enabled: false
|
75
|
+
|
76
|
+
Metrics/ModuleLength:
|
77
|
+
Enabled: false
|
78
|
+
|
79
|
+
Metrics/PerceivedComplexity:
|
80
|
+
Enabled: false
|
81
|
+
|
82
|
+
Performance/EmptyGsubReplacement:
|
83
|
+
Enabled: true
|
84
|
+
|
85
|
+
Performance/StringReplacement:
|
86
|
+
Enabled: false
|
87
|
+
|
88
|
+
Performance/TimesMap:
|
89
|
+
Enabled: false
|
90
|
+
|
91
|
+
Rails/HttpPositionalArguments:
|
92
|
+
Enabled: false
|
93
|
+
|
94
|
+
Rails/RequestReferer:
|
95
|
+
EnforcedStyle: referrer
|
96
|
+
|
97
|
+
Rails/SkipsModelValidations:
|
98
|
+
Enabled: false
|
99
|
+
|
100
|
+
RSpec/BeEql:
|
101
|
+
Enabled: false
|
102
|
+
|
103
|
+
RSpec/EmptyLineAfterSubject:
|
104
|
+
Enabled: false
|
105
|
+
|
106
|
+
RSpec/ExampleLength:
|
107
|
+
Enabled: false
|
108
|
+
|
109
|
+
RSpec/Focused:
|
110
|
+
Enabled: true
|
111
|
+
|
112
|
+
RSpec/MessageSpies:
|
113
|
+
Enabled: false
|
114
|
+
|
115
|
+
RSpec/MultipleExpectations:
|
116
|
+
Enabled: false
|
117
|
+
|
118
|
+
RSpec/NotToNot:
|
119
|
+
EnforcedStyle: to_not
|
120
|
+
|
121
|
+
RSpec/ScatteredSetup:
|
122
|
+
Enabled: false
|
123
|
+
|
124
|
+
RSpec/VerifiedDoubles:
|
125
|
+
Enabled: false
|
126
|
+
|
127
|
+
Style/ClassCheck:
|
128
|
+
Enabled: false
|
129
|
+
|
130
|
+
Style/Lambda:
|
131
|
+
EnforcedStyle: literal
|
132
|
+
|
133
|
+
Style/MultilineBlockChain:
|
134
|
+
Enabled: false
|
135
|
+
|
136
|
+
Style/NumericPredicate:
|
137
|
+
Enabled: false
|
138
|
+
|
139
|
+
Style/StringLiterals:
|
140
|
+
Enabled: false
|
141
|
+
|
142
|
+
Style/TernaryParentheses:
|
143
|
+
Enabled: false
|
144
|
+
|
145
|
+
Style/TrailingCommaInArguments:
|
146
|
+
EnforcedStyleForMultiline: comma
|
147
|
+
|
148
|
+
Style/WordArray:
|
149
|
+
Enabled: false
|
@@ -0,0 +1,169 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copied from https://raw.githubusercontent.com/bbatsov/rubocop/master/lib/rubocop/cop/performance/string_replacement.rb
|
3
|
+
# Becker: Removed tr replacement
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module Cop
|
7
|
+
module Performance
|
8
|
+
# This cop identifies places where `gsub` can be replaced by
|
9
|
+
# `delete`.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# @bad
|
13
|
+
# 'abc'.gsub('b', 'd')
|
14
|
+
# 'abc'.gsub('a', '')
|
15
|
+
# 'abc'.gsub(/a/, 'd')
|
16
|
+
# 'abc'.gsub!('a', 'd')
|
17
|
+
#
|
18
|
+
# @good
|
19
|
+
# 'abc'.gsub(/.*/, 'a')
|
20
|
+
# 'abc'.gsub(/a+/, 'd')
|
21
|
+
# 'a b c'.delete(' ')
|
22
|
+
class EmptyGsubReplacement < Cop
|
23
|
+
MSG = 'Use `%s` instead of `%s`.'.freeze
|
24
|
+
DETERMINISTIC_REGEX = /\A(?:#{LITERAL_REGEX})+\Z/
|
25
|
+
DELETE = 'delete'.freeze
|
26
|
+
BANG = '!'.freeze
|
27
|
+
SINGLE_QUOTE = "'".freeze
|
28
|
+
|
29
|
+
def_node_matcher :string_replacement?, <<-PATTERN
|
30
|
+
(send _ {:gsub :gsub!}
|
31
|
+
${regexp str (send (const nil :Regexp) {:new :compile} _)}
|
32
|
+
$str)
|
33
|
+
PATTERN
|
34
|
+
|
35
|
+
def on_send(node)
|
36
|
+
string_replacement?(node) do |first_param, second_param|
|
37
|
+
return if accept_second_param?(second_param)
|
38
|
+
return if accept_first_param?(first_param)
|
39
|
+
|
40
|
+
offense(node, first_param, second_param)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def autocorrect(node)
|
45
|
+
_string, _method, first_param, second_param = *node
|
46
|
+
first_source, = first_source(first_param)
|
47
|
+
second_source, = *second_param
|
48
|
+
|
49
|
+
unless first_param.str_type?
|
50
|
+
first_source = interpret_string_escapes(first_source)
|
51
|
+
end
|
52
|
+
|
53
|
+
replacement_method =
|
54
|
+
replacement_method(node, first_source, second_source)
|
55
|
+
|
56
|
+
replace_method(node, first_source, second_source, first_param,
|
57
|
+
replacement_method)
|
58
|
+
end
|
59
|
+
|
60
|
+
def replace_method(node, first, second, first_param, replacement)
|
61
|
+
lambda do |corrector|
|
62
|
+
corrector.replace(node.loc.selector, replacement)
|
63
|
+
unless first_param.str_type?
|
64
|
+
corrector.replace(first_param.source_range,
|
65
|
+
to_string_literal(first))
|
66
|
+
end
|
67
|
+
|
68
|
+
if second.empty? && first.length == 1
|
69
|
+
remove_second_param(corrector, node, first_param)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def accept_second_param?(second_param)
|
77
|
+
second_source, = *second_param
|
78
|
+
second_source.length >= 1
|
79
|
+
end
|
80
|
+
|
81
|
+
def accept_first_param?(first_param)
|
82
|
+
first_source, options = first_source(first_param)
|
83
|
+
return true if first_source.nil?
|
84
|
+
|
85
|
+
unless first_param.str_type?
|
86
|
+
return true if options
|
87
|
+
return true unless first_source =~ DETERMINISTIC_REGEX
|
88
|
+
# This must be done after checking DETERMINISTIC_REGEX
|
89
|
+
# Otherwise things like \s will trip us up
|
90
|
+
first_source = interpret_string_escapes(first_source)
|
91
|
+
end
|
92
|
+
|
93
|
+
first_source.length != 1
|
94
|
+
end
|
95
|
+
|
96
|
+
def offense(node, first_param, second_param)
|
97
|
+
first_source, = first_source(first_param)
|
98
|
+
unless first_param.str_type?
|
99
|
+
first_source = interpret_string_escapes(first_source)
|
100
|
+
end
|
101
|
+
second_source, = *second_param
|
102
|
+
message = message(node, first_source, second_source)
|
103
|
+
|
104
|
+
add_offense(node, range(node), message)
|
105
|
+
end
|
106
|
+
|
107
|
+
def first_source(first_param)
|
108
|
+
case first_param.type
|
109
|
+
when :regexp
|
110
|
+
source_from_regex_literal(first_param)
|
111
|
+
when :send
|
112
|
+
source_from_regex_constructor(first_param)
|
113
|
+
when :str
|
114
|
+
first_param.children.first
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def source_from_regex_literal(node)
|
119
|
+
regex, options = *node
|
120
|
+
source, = *regex
|
121
|
+
options, = *options
|
122
|
+
[source, options]
|
123
|
+
end
|
124
|
+
|
125
|
+
def source_from_regex_constructor(node)
|
126
|
+
_const, _init, regex = *node
|
127
|
+
case regex.type
|
128
|
+
when :regexp
|
129
|
+
source_from_regex_literal(regex)
|
130
|
+
when :str
|
131
|
+
source, = *regex
|
132
|
+
source
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def range(node)
|
137
|
+
range_between(node.loc.selector.begin_pos, node.source_range.end_pos)
|
138
|
+
end
|
139
|
+
|
140
|
+
def replacement_method(node, first_source, second_source)
|
141
|
+
replacement = if second_source.empty? && first_source.length == 1
|
142
|
+
DELETE
|
143
|
+
end
|
144
|
+
|
145
|
+
add_bang = node.method_name.to_s.end_with?('!')
|
146
|
+
"#{replacement}#{BANG if add_bang}"
|
147
|
+
end
|
148
|
+
|
149
|
+
def message(node, first_source, second_source)
|
150
|
+
replacement_method =
|
151
|
+
replacement_method(node, first_source, second_source)
|
152
|
+
|
153
|
+
format(MSG, replacement_method, node.method_name)
|
154
|
+
end
|
155
|
+
|
156
|
+
def method_suffix(node)
|
157
|
+
node.loc.end ? node.loc.end.source : ''
|
158
|
+
end
|
159
|
+
|
160
|
+
def remove_second_param(corrector, node, first_param)
|
161
|
+
end_range = range_between(first_param.source_range.end_pos,
|
162
|
+
node.source_range.end_pos)
|
163
|
+
|
164
|
+
corrector.replace(end_range, method_suffix(node))
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
data/lib/rubocop-aha.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'rubocop-aha/version'
|
data/rubocop-aha.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'rubocop-aha/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'rubocop-aha'
|
9
|
+
spec.version = RuboCop::Aha::VERSION
|
10
|
+
spec.authors = ['Zach Schneider']
|
11
|
+
spec.email = ['zach@aha.io']
|
12
|
+
|
13
|
+
spec.summary = 'Aha! rubocop config'
|
14
|
+
spec.description = 'Aha! rubocop config'
|
15
|
+
spec.homepage = 'https://github.com/aha-app/rubocop-aha'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0")
|
19
|
+
spec.bindir = 'exe'
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
spec.add_runtime_dependency 'rubocop', '>= 0.49.0'
|
24
|
+
|
25
|
+
spec.add_dependency 'rubocop-rspec', '~> 1.15'
|
26
|
+
spec.add_dependency 'rubocop-rspec-focused', '~> 0.1'
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubocop-aha
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Zach Schneider
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-07-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rubocop
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.49.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.49.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rubocop-rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.15'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.15'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubocop-rspec-focused
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.1'
|
55
|
+
description: Aha! rubocop config
|
56
|
+
email:
|
57
|
+
- zach@aha.io
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- lib/config.yml
|
68
|
+
- lib/rubocop-aha.rb
|
69
|
+
- lib/rubocop-aha/cops/empty_gsub_replacement.rb
|
70
|
+
- lib/rubocop-aha/version.rb
|
71
|
+
- rubocop-aha.gemspec
|
72
|
+
homepage: https://github.com/aha-app/rubocop-aha
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata: {}
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 2.6.12
|
93
|
+
signing_key:
|
94
|
+
specification_version: 4
|
95
|
+
summary: Aha! rubocop config
|
96
|
+
test_files: []
|