Skip to content
This repository has been archived by the owner on Aug 6, 2021. It is now read-only.

Commit

Permalink
check for non-concurrent indexes
Browse files Browse the repository at this point in the history
  • Loading branch information
6 committed Jul 7, 2017
1 parent 72ee744 commit b52788e
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 7 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ TODO: Write usage instructions here

## Development

For running the spec files, this project depends on RuboCop's spec helpers. This means that in order to run the specs locally, you need a (shallow) clone of the RuboCop repository:

```
git clone --depth 1 git://github.com/bbatsov/rubocop.git vendor/rubocop
```

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
Expand Down
6 changes: 6 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
machine:
ruby:
version: 2.3.0
dependencies:
pre:
- git clone --depth 1 git://github.com/bbatsov/rubocop.git vendor/rubocop
1 change: 1 addition & 0 deletions egad.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "rspec-its"
spec.add_development_dependency "rspec-collection_matchers"
spec.add_development_dependency "rspec_junit_formatter", "~> 0.2"
spec.add_development_dependency "pry"
end
2 changes: 1 addition & 1 deletion lib/egad.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
require "rubocop"

require "rubocop/egad/version"
require "rubocop/cop/egad/add_index"
require "rubocop/cop/egad/add_index_non_concurrently"

module RuboCop
module Egad
Expand Down
6 changes: 0 additions & 6 deletions lib/rubocop/cop/egad/add_index.rb

This file was deleted.

36 changes: 36 additions & 0 deletions lib/rubocop/cop/egad/add_index_non_concurrently.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module RuboCop
module Cop
module Egad
class AddIndexNonConcurrently < Cop
MSG = 'Use `algorithm: :concurrently` to avoid locking database.'.freeze

def_node_matcher :add_index_or_add_reference?, <<-PATTERN
(send nil {:add_index :add_reference} ...)
PATTERN

def on_send(node)
if add_index_or_add_reference?(node)
options = options_hash(node)
if !options[:algorithm].present? || options[:algorithm] != "concurrently"
add_offense(node, :expression, MSG)
end
end
end

private

def options_hash(node)
options = {}
node.children.each do |c|
if c.is_a?(AST::Node) && c.type == :hash
c.each_pair do |key_node, value_node|
options[key_node.children.first.to_sym] = value_node.children.first.to_s
end
end
end
options
end
end
end
end
end
45 changes: 45 additions & 0 deletions spec/rubocop/cop/egad/add_index_non_concurrently_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
describe RuboCop::Cop::Egad::AddIndexNonConcurrently do
subject(:cop) { described_class.new }

before do
inspect_source(cop, source)
end

context "add_index" do
context "basic source, non-concurrent" do
let(:source) { "add_index :users, :some_column" }

it "registers an offense" do
expect(cop.offenses.size).to eq(1)
expect(cop.offenses.first.message).to eq("Use `algorithm: :concurrently` to avoid locking database.")
expect(cop.highlights).to eq([source])
end
end

context "complex source, non-concurrent" do
let(:source) { "add_index :users, [:some_column, :another], unique: true, algorithm: :btree, something: {nested: 1}" }

it "registers an offense" do
expect(cop.offenses.size).to eq(1)
expect(cop.offenses.first.message).to eq("Use `algorithm: :concurrently` to avoid locking database.")
expect(cop.highlights).to eq([source])
end
end

context "basic source, concurrent" do
let(:source) { "add_index :users, :some_column, algorithm: :concurrently" }

it "doesn't register an offense" do
expect(cop.offenses).to be_empty
end
end

context "complex source, concurrent" do
let(:source) { "add_index :users, [:some_column, :another], unique: true, algorithm: 'concurrently', something: {nested: 1}" }

it "doesn't register an offense" do
expect(cop.offenses).to be_empty
end
end
end
end
10 changes: 10 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
require "egad"
require "rspec/collection_matchers"
require "rspec/its"
require 'rubocop'
require 'pry' unless ENV["CI"]

rubocop_path = File.join(File.dirname(__FILE__), '../vendor/rubocop')
unless File.directory?(File.join(rubocop_path, '.git'))
raise("Can't run specs without a local RuboCop checkout. Look in the README.")
end
Dir["#{rubocop_path}/spec/support/**/*.rb"].each { |f| require f }
require 'rubocop/rspec/support'


RSpec.configure do |config|
# Enable flags like --only-failures and --next-failure
Expand Down

0 comments on commit b52788e

Please sign in to comment.