rubocop-thread_safety 0.1.0 → 0.2.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 +4 -4
- data/.gitmodules +1 -1
- data/.rubocop.yml +40 -0
- data/.travis.yml +22 -1
- data/Gemfile +4 -0
- data/README.md +17 -7
- data/Rakefile +3 -3
- data/bin/console +6 -7
- data/lib/rubocop-thread_safety.rb +1 -0
- data/lib/rubocop/cop/thread_safety/class_and_module_attributes.rb +23 -2
- data/lib/rubocop/cop/thread_safety/instance_variable_in_class_method.rb +18 -2
- data/lib/rubocop/cop/thread_safety/new_thread.rb +28 -0
- data/lib/rubocop/thread_safety/version.rb +1 -1
- data/rubocop-thread_safety.gemspec +10 -9
- metadata +34 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49b1f83536d04b431792ef8744dd170d7d86684c
|
4
|
+
data.tar.gz: da575c79213854fb96cf7ef78914aa45dc5abc40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7019d692d78fd1f0ebb9e9631f9db852393cb2dfbf2c8bcbb29272b5ae82ed1ac26e4672c154978d7c24e4a02c8bbc1f0e27403abd14996ca801e2aed4a45bf3
|
7
|
+
data.tar.gz: 2cd34c5eb52e62c54dbb4a4516c7eb74f94815f2f297ca957c08b9d6db45d15a129c00a2c6ac95e3958c18d150c69211585e1087698acedae1445b53dfdf7999
|
data/.gitmodules
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
AllCops:
|
2
|
+
DisplayCopNames: true
|
3
|
+
Include:
|
4
|
+
- Gemfile
|
5
|
+
- Rakefile
|
6
|
+
Exclude:
|
7
|
+
- vendor/**/*
|
8
|
+
|
9
|
+
Style/FileName:
|
10
|
+
Exclude:
|
11
|
+
- lib/rubocop-thread_safety.rb
|
12
|
+
|
13
|
+
# Enable more cops that are disabled by default:
|
14
|
+
|
15
|
+
Style/AutoResourceCleanup:
|
16
|
+
Enabled: true
|
17
|
+
|
18
|
+
Style/CollectionMethods:
|
19
|
+
Enabled: true
|
20
|
+
|
21
|
+
Style/MethodCalledOnDoEndBlock:
|
22
|
+
Enabled: true
|
23
|
+
Exclude:
|
24
|
+
- spec/**/*
|
25
|
+
|
26
|
+
Style/MissingElse:
|
27
|
+
Enabled: true
|
28
|
+
EnforcedStyle: case
|
29
|
+
|
30
|
+
Style/OptionHash:
|
31
|
+
Enabled: true
|
32
|
+
|
33
|
+
Style/Send:
|
34
|
+
Enabled: true
|
35
|
+
|
36
|
+
Style/StringMethods:
|
37
|
+
Enabled: true
|
38
|
+
|
39
|
+
Style/SymbolArray:
|
40
|
+
Enabled: true
|
data/.travis.yml
CHANGED
@@ -1,4 +1,25 @@
|
|
1
|
+
sudo: false
|
2
|
+
cache: bundler
|
1
3
|
language: ruby
|
4
|
+
|
2
5
|
rvm:
|
6
|
+
- 1.9.3
|
3
7
|
- 2.0.0
|
4
|
-
|
8
|
+
- 2.1
|
9
|
+
- 2.2
|
10
|
+
- 2.3.0
|
11
|
+
- ruby-head
|
12
|
+
- jruby-19mode
|
13
|
+
- jruby-9.0.5.0
|
14
|
+
- rbx-3
|
15
|
+
|
16
|
+
matrix:
|
17
|
+
allow_failures:
|
18
|
+
- rvm: ruby-head
|
19
|
+
- rvm: rbx-3
|
20
|
+
fast_finish: true
|
21
|
+
|
22
|
+
before_install: gem install bundler
|
23
|
+
script:
|
24
|
+
- bundle exec rspec
|
25
|
+
- bundle exec rubocop
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# RuboCop::ThreadSafety
|
2
2
|
|
3
|
-
|
3
|
+
Thread-safety analysis for your projects, as an extension to
|
4
|
+
[RuboCop](https://github.com/bbatsov/rubocop).
|
4
5
|
|
5
|
-
|
6
|
+
## Installation and Usage
|
6
7
|
|
7
|
-
|
8
|
+
### Installation into an application
|
8
9
|
|
9
10
|
Add this line to your application's Gemfile:
|
10
11
|
|
@@ -12,17 +13,26 @@ Add this line to your application's Gemfile:
|
|
12
13
|
gem 'rubocop-thread_safety'
|
13
14
|
```
|
14
15
|
|
15
|
-
|
16
|
+
Install it with Bundler by invoking:
|
16
17
|
|
17
18
|
$ bundle
|
18
19
|
|
19
|
-
|
20
|
+
Add this line to your application's `.rubocop.yml`:
|
21
|
+
|
22
|
+
require: rubocop-thread_safety
|
23
|
+
|
24
|
+
Now you can run `rubocop` and it will automatically load the RuboCop
|
25
|
+
Thread-Safety cops together with the standard cops.
|
26
|
+
|
27
|
+
### Scanning an application without adding it to the Gemfile
|
28
|
+
|
29
|
+
Install the gem:
|
20
30
|
|
21
31
|
$ gem install rubocop-thread_safety
|
22
32
|
|
23
|
-
|
33
|
+
Scan the application for just thread-safety issues:
|
24
34
|
|
25
|
-
|
35
|
+
$ rubocop -r rubocop-thread_safety --only Threadsafety,Style/GlobalVars,Style/ClassVars,Style/MutableConstant
|
26
36
|
|
27
37
|
## Development
|
28
38
|
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'rubocop-thread_safety'
|
5
5
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
# Pry.start
|
9
|
+
require 'pry'
|
10
|
+
Pry.start
|
12
11
|
|
13
|
-
require "irb"
|
14
|
-
IRB.start
|
12
|
+
# require "irb"
|
13
|
+
# IRB.start
|
@@ -4,8 +4,17 @@
|
|
4
4
|
module RuboCop
|
5
5
|
module Cop
|
6
6
|
module ThreadSafety
|
7
|
+
# Avoid mutating class and module attributes.
|
8
|
+
#
|
9
|
+
# They are implemented by class variables, which are not thread-safe.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# class User
|
14
|
+
# cattr_accessor :current_user
|
15
|
+
# end
|
7
16
|
class ClassAndModuleAttributes < Cop
|
8
|
-
MSG = 'Avoid class and module attributes.'.freeze
|
17
|
+
MSG = 'Avoid mutating class and module attributes.'.freeze
|
9
18
|
|
10
19
|
def_node_matcher :mattr?, <<-END
|
11
20
|
(send nil
|
@@ -13,10 +22,22 @@ module RuboCop
|
|
13
22
|
...)
|
14
23
|
END
|
15
24
|
|
25
|
+
def_node_matcher :attr?, <<-END
|
26
|
+
(send nil
|
27
|
+
{:attr :attr_accessor :attr_writer}
|
28
|
+
...)
|
29
|
+
END
|
30
|
+
|
16
31
|
def on_send(node)
|
17
|
-
return unless mattr?(node)
|
32
|
+
return unless mattr?(node) || singleton_attr?(node)
|
18
33
|
add_offense(node, :expression, format(MSG, node.source))
|
19
34
|
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def singleton_attr?(node)
|
39
|
+
attr?(node) && node.ancestors.map(&:type).include?(:sclass)
|
40
|
+
end
|
20
41
|
end
|
21
42
|
end
|
22
43
|
end
|
@@ -4,18 +4,34 @@
|
|
4
4
|
module RuboCop
|
5
5
|
module Cop
|
6
6
|
module ThreadSafety
|
7
|
+
# Avoid instance variables in class methods.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# class User
|
12
|
+
# def self.notify(info)
|
13
|
+
# @info = validate(info)
|
14
|
+
# Notifier.new(@info).deliver
|
15
|
+
# end
|
16
|
+
# end
|
7
17
|
class InstanceVariableInClassMethod < Cop
|
8
18
|
MSG = 'Avoid instance variables in class methods.'.freeze
|
9
19
|
|
10
20
|
def on_ivar(node)
|
11
|
-
return unless
|
21
|
+
return unless class_method_definition?(node)
|
12
22
|
|
13
23
|
add_offense(node, :name, MSG)
|
14
24
|
end
|
15
|
-
|
25
|
+
alias on_ivasgn on_ivar
|
16
26
|
|
17
27
|
private
|
18
28
|
|
29
|
+
def class_method_definition?(node)
|
30
|
+
in_defs?(node) ||
|
31
|
+
in_def_sclass?(node) ||
|
32
|
+
singleton_method_definition?(node)
|
33
|
+
end
|
34
|
+
|
19
35
|
def in_defs?(node)
|
20
36
|
node.ancestors.any? do |ancestor|
|
21
37
|
ancestor.type == :defs
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RuboCop
|
5
|
+
module Cop
|
6
|
+
module ThreadSafety
|
7
|
+
# Avoid starting new threads.
|
8
|
+
#
|
9
|
+
# Let a framework like Sidekiq handle the threads.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# Thread.new { do_work }
|
14
|
+
class NewThread < Cop
|
15
|
+
MSG = 'Avoid starting new threads.'.freeze
|
16
|
+
|
17
|
+
def_node_matcher :new_thread?, <<-END
|
18
|
+
(send (const nil :Thread) :new)
|
19
|
+
END
|
20
|
+
|
21
|
+
def on_send(node)
|
22
|
+
return unless new_thread?(node)
|
23
|
+
add_offense(node, :expression, format(MSG, node.source))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -4,10 +4,10 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'rubocop/thread_safety/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'rubocop-thread_safety'
|
8
8
|
spec.version = RuboCop::ThreadSafety::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ['Michael Gee']
|
10
|
+
spec.email = ['michaelpgee@gmail.com']
|
11
11
|
|
12
12
|
spec.summary = 'Thread-safety checks via static analysis'
|
13
13
|
spec.description = <<-end_description
|
@@ -17,14 +17,15 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.homepage = 'https://github.com/covermymeds/rubocop-thread_safety'
|
18
18
|
|
19
19
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
|
-
spec.bindir =
|
20
|
+
spec.bindir = 'exe'
|
21
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
-
spec.require_paths = [
|
22
|
+
spec.require_paths = ['lib']
|
23
23
|
|
24
24
|
spec.add_runtime_dependency 'rubocop'
|
25
25
|
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
27
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
28
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
29
|
+
spec.add_development_dependency 'simplecov'
|
30
|
+
spec.add_development_dependency 'pry' unless ENV['CI']
|
30
31
|
end
|
metadata
CHANGED
@@ -1,83 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-thread_safety
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Gee
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04-
|
11
|
+
date: 2016-04-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.10'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.10'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '10.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '10.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '3.0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: pry
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
|
-
- -
|
87
|
+
- - '>='
|
74
88
|
- !ruby/object:Gem::Version
|
75
89
|
version: '0'
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
|
-
- -
|
94
|
+
- - '>='
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
83
97
|
description: |2
|
@@ -89,10 +103,11 @@ executables: []
|
|
89
103
|
extensions: []
|
90
104
|
extra_rdoc_files: []
|
91
105
|
files:
|
92
|
-
-
|
93
|
-
-
|
94
|
-
-
|
95
|
-
-
|
106
|
+
- .gitignore
|
107
|
+
- .gitmodules
|
108
|
+
- .rspec
|
109
|
+
- .rubocop.yml
|
110
|
+
- .travis.yml
|
96
111
|
- Gemfile
|
97
112
|
- README.md
|
98
113
|
- Rakefile
|
@@ -101,6 +116,7 @@ files:
|
|
101
116
|
- lib/rubocop-thread_safety.rb
|
102
117
|
- lib/rubocop/cop/thread_safety/class_and_module_attributes.rb
|
103
118
|
- lib/rubocop/cop/thread_safety/instance_variable_in_class_method.rb
|
119
|
+
- lib/rubocop/cop/thread_safety/new_thread.rb
|
104
120
|
- lib/rubocop/thread_safety/version.rb
|
105
121
|
- rubocop-thread_safety.gemspec
|
106
122
|
homepage: https://github.com/covermymeds/rubocop-thread_safety
|
@@ -112,12 +128,12 @@ require_paths:
|
|
112
128
|
- lib
|
113
129
|
required_ruby_version: !ruby/object:Gem::Requirement
|
114
130
|
requirements:
|
115
|
-
- -
|
131
|
+
- - '>='
|
116
132
|
- !ruby/object:Gem::Version
|
117
133
|
version: '0'
|
118
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
135
|
requirements:
|
120
|
-
- -
|
136
|
+
- - '>='
|
121
137
|
- !ruby/object:Gem::Version
|
122
138
|
version: '0'
|
123
139
|
requirements: []
|
@@ -127,4 +143,3 @@ signing_key:
|
|
127
143
|
specification_version: 4
|
128
144
|
summary: Thread-safety checks via static analysis
|
129
145
|
test_files: []
|
130
|
-
has_rdoc:
|