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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2b4eed435834382bb3694ea772ecd66ea9eaebbb
4
- data.tar.gz: 430cc7dd678b3a0305d8cab1f8b2fd6ac910f286
3
+ metadata.gz: 49b1f83536d04b431792ef8744dd170d7d86684c
4
+ data.tar.gz: da575c79213854fb96cf7ef78914aa45dc5abc40
5
5
  SHA512:
6
- metadata.gz: 630c1225098911d9e2f210ad95065d13f68430cd3957a1bcb58f37dd4bd7392574f2e63957af6b7861e0d217e95414775a2ef0ccb99c8b0e05896a65fbd50f08
7
- data.tar.gz: 38c09a805700ae2fb7fdb21fa496149704905259200b10c35df8e1c724a3a15097c0a28df15951cacf7a5efbc71075f70ba17207fa27fed76c7799ee0c00e702
6
+ metadata.gz: 7019d692d78fd1f0ebb9e9631f9db852393cb2dfbf2c8bcbb29272b5ae82ed1ac26e4672c154978d7c24e4a02c8bbc1f0e27403abd14996ca801e2aed4a45bf3
7
+ data.tar.gz: 2cd34c5eb52e62c54dbb4a4516c7eb74f94815f2f297ca957c08b9d6db45d15a129c00a2c6ac95e3958c18d150c69211585e1087698acedae1445b53dfdf7999
data/.gitmodules CHANGED
@@ -1,3 +1,3 @@
1
1
  [submodule "vendor/rubocop"]
2
2
  path = vendor/rubocop
3
- url = git@github.com:bbatsov/rubocop
3
+ url = https://github.com/bbatsov/rubocop
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
- before_install: gem install bundler -v 1.11.2
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
@@ -2,3 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in rubocop-thread_safety.gemspec
4
4
  gemspec
5
+
6
+ group :test do
7
+ gem 'codeclimate-test-reporter', require: false
8
+ end
data/README.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # RuboCop::ThreadSafety
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/rubocop/thread_safety`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Thread-safety analysis for your projects, as an extension to
4
+ [RuboCop](https://github.com/bbatsov/rubocop).
4
5
 
5
- TODO: Delete this and the text above, and describe your gem
6
+ ## Installation and Usage
6
7
 
7
- ## Installation
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
- And then execute:
16
+ Install it with Bundler by invoking:
16
17
 
17
18
  $ bundle
18
19
 
19
- Or install it yourself as:
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
- ## Usage
33
+ Scan the application for just thread-safety issues:
24
34
 
25
- TODO: Write usage instructions here
35
+ $ rubocop -r rubocop-thread_safety --only Threadsafety,Style/GlobalVars,Style/ClassVars,Style/MutableConstant
26
36
 
27
37
  ## Development
28
38
 
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task default: :spec
data/bin/console CHANGED
@@ -1,14 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "rubocop-thread_safety"
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
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
9
+ require 'pry'
10
+ Pry.start
12
11
 
13
- require "irb"
14
- IRB.start
12
+ # require "irb"
13
+ # IRB.start
@@ -4,3 +4,4 @@ require 'rubocop/thread_safety/version'
4
4
 
5
5
  require 'rubocop/cop/thread_safety/instance_variable_in_class_method'
6
6
  require 'rubocop/cop/thread_safety/class_and_module_attributes'
7
+ require 'rubocop/cop/thread_safety/new_thread'
@@ -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 in_defs?(node) || in_def_sclass?(node) || singleton_method_definition?(node)
21
+ return unless class_method_definition?(node)
12
22
 
13
23
  add_offense(node, :name, MSG)
14
24
  end
15
- alias_method :on_ivasgn, :on_ivar
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
@@ -1,5 +1,5 @@
1
1
  module RuboCop
2
2
  module ThreadSafety
3
- VERSION = "0.1.0"
3
+ VERSION = '0.2.0'.freeze
4
4
  end
5
5
  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 = "rubocop-thread_safety"
7
+ spec.name = 'rubocop-thread_safety'
8
8
  spec.version = RuboCop::ThreadSafety::VERSION
9
- spec.authors = ["Michael Gee"]
10
- spec.email = ["michaelpgee@gmail.com"]
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 = "exe"
20
+ spec.bindir = 'exe'
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
- spec.require_paths = ["lib"]
22
+ spec.require_paths = ['lib']
23
23
 
24
24
  spec.add_runtime_dependency 'rubocop'
25
25
 
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 "pry"
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.1.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-24 00:00:00.000000000 Z
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
- - ".gitignore"
93
- - ".gitmodules"
94
- - ".rspec"
95
- - ".travis.yml"
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: