Git Product home page Git Product logo

rubocop's Introduction

RuboCop Logo


Ruby Style Guide Gem Version CircleCI Status Actions Status Test Coverage Maintainability Discord

Role models are important.
-- Officer Alex J. Murphy / RoboCop

RuboCop is a Ruby static code analyzer (a.k.a. linter) and code formatter. Out of the box it will enforce many of the guidelines outlined in the community Ruby Style Guide. Apart from reporting the problems discovered in your code, RuboCop can also automatically fix many of them for you.

RuboCop is extremely flexible and most aspects of its behavior can be tweaked via various configuration options.


Patreon OpenCollective OpenCollective Tidelift

Working on RuboCop is often fun, but it also requires a great deal of time and energy.

Please consider financially supporting its ongoing development.

Installation

RuboCop's installation is pretty standard:

$ gem install rubocop

If you'd rather install RuboCop using bundler, add a line for it in your Gemfile (but set the require option to false, as it is a standalone tool):

gem 'rubocop', require: false

RuboCop is stable between minor versions, both in terms of API and cop configuration. We aim to ease the maintenance of RuboCop extensions and the upgrades between RuboCop releases. All big changes are reserved for major releases. To prevent an unwanted RuboCop update you might want to use a conservative version lock in your Gemfile:

gem 'rubocop', '~> 1.63', require: false

See our versioning policy for further details.

Quickstart

Just type rubocop in a Ruby project's folder and watch the magic happen.

$ cd my/cool/ruby/project
$ rubocop

You can also use this magic in your favorite editor with RuboCop's built-in LSP server.

Documentation

You can read a lot more about RuboCop in its official docs.

Compatibility

RuboCop officially supports the following runtime Ruby implementations:

  • MRI 2.7+
  • JRuby 9.4+

Targets Ruby 2.0+ code analysis.

See the compatibility documentation for further details.

Readme Badge

If you use RuboCop in your project, you can include one of these badges in your readme to let people know that your code is written following the community Ruby Style Guide.

Ruby Style Guide

Ruby Style Guide

Here are the Markdown snippets for the two badges:

[![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop)

[![Ruby Style Guide](https://img.shields.io/badge/code_style-community-brightgreen.svg)](https://rubystyle.guide)

Team

Here's a list of RuboCop's core developers:

See the team page for more details.

Logo

RuboCop's logo was created by Dimiter Petrov. You can find the logo in various formats here.

The logo is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.

Contributors

Here's a list of all the people who have contributed to the development of RuboCop.

I'm extremely grateful to each and every one of them!

If you'd like to contribute to RuboCop, please take the time to go through our short contribution guidelines.

Converting more of the Ruby Style Guide into RuboCop cops is our top priority right now. Writing a new cop is a great way to dive into RuboCop!

Of course, bug reports and suggestions for improvements are always welcome. GitHub pull requests are even better! :-)

Funding

While RuboCop is free software and will always be, the project would benefit immensely from some funding. Raising a monthly budget of a couple of thousand dollars would make it possible to pay people to work on certain complex features, fund other development related stuff (e.g. hardware, conference trips) and so on. Raising a monthly budget of over $5000 would open the possibility of someone working full-time on the project which would speed up the pace of development significantly.

We welcome both individual and corporate sponsors! We also offer a wide array of funding channels to account for your preferences (although currently Open Collective is our preferred funding platform).

If you're working in a company that's making significant use of RuboCop we'd appreciate it if you suggest to your company to become a RuboCop sponsor.

You can support the development of RuboCop via GitHub Sponsors, Patreon, PayPal, Open Collective and Tidelift .

Note: If doing a sponsorship in the form of donation is problematic for your company from an accounting standpoint, we'd recommend the use of Tidelift, where you can get a support-like subscription instead.

Open Collective Backers

Support us with a monthly donation and help us continue our activities. [Become a backer]

Open Collective Sponsors

Become a sponsor and get your logo on our README on GitHub with a link to your site. [Become a sponsor]

Changelog

RuboCop's changelog is available here.

Copyright

Copyright (c) 2012-2024 Bozhidar Batsov. See LICENSE.txt for further details.

rubocop's People

Contributors

alexdowad avatar backus avatar bbatsov avatar biinari avatar bquorning avatar buehmann avatar darhazer avatar deivid-rodriguez avatar drenmi avatar dvandersluis avatar earlopain avatar edzhelyov avatar fatkodima avatar garettarrowood avatar gsamokovarov avatar hoshinotsuyoshi avatar jonas054 avatar koic avatar lumeet avatar marcandre avatar nobuyo avatar owst avatar pocke avatar r7kamura avatar rrosenblum avatar scottmatthewman avatar tamird avatar tejasbubane avatar ydah avatar yujinakayama avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rubocop's Issues

Landing page.

Screenshot from 2013-04-12 18:20:02
I've been working on a simple landing page for this project and just finished it. It's a little rough but I think it'll do. I'm not able to make a Pull Request because I've created a new branch (gh-pages) with only the site source code in it. So you'd have to create a new blank branch (called gh-pages) so I can make a Pull Request. Of course, if you want to and like the page.

The site is live on my fork of this project. You can have a look at it here. Nothing super, just a simple landing page with some text, built with Bootstrap and based on Intro.js's site. The site is also responsive and as far as I'm concerned IE7 compatible.

As you can see, the site includes some information about what Rubocop is, what it supports, how to install it, and finally how to use it. All of this content is taken from this project's README and in some parts slightly modified.

Crash "missing brace not found"

Minimal Repro

require 'logger'

logger = Logger.new(STDOUT)
logger.debug { "foo #{logger}" }

Fails on line 4 column 13 with the message "missing brace not found". Curiously, column 13 is the space character before the first brace on that line, not the brace itself. Could there also be an off-by-one error in calculating the column for exceptions?

Integration with flycheck

Integration with flycheck will make rubocop much more appealing to Emacs users. Integration with other editors would be a good idea as well.

ripper lib not supported on jruby

JRuby 1.7.2, Found this testing out flycheck:

Checker ruby-rubocop returned non-zero exit code 1, but no errors from output: the `ripper' lib is not supported on JRuby
LoadError: no such file to load -- ripper
  require at org/jruby/RubyKernel.java:1027
  require at /home/sme/.rbenv/versions/jruby-1.7.2/lib/ruby/shared/rubygems/custom_require.rb:36
   (root) at /home/sme/.rbenv/versions/jruby-1.7.2/lib/ruby/1.9/ripper/core.rb:11
  require at org/jruby/RubyKernel.java:1027
   (root) at /home/sme/.rbenv/versions/jruby-1.7.2/lib/ruby/shared/rubygems/custom_require.rb:1
  require at /home/sme/.rbenv/versions/jruby-1.7.2/lib/ruby/shared/rubygems/custom_require.rb:36
  require at org/jruby/RubyKernel.java:1027
   (root) at /home/sme/.rbenv/versions/jruby-1.7.2/lib/ruby/1.9/ripper.rb:3
   (root) at /home/sme/.rbenv/versions/jruby-1.7.2/lib/ruby/shared/rubygems/custom_require.rb:1
  require at org/jruby/RubyKernel.java:1027
  require at /home/sme/.rbenv/versions/jruby-1.7.2/lib/ruby/shared/rubygems/custom_require.rb:36
   (root) at /home/sme/.rbenv/versions/jruby-1.7.2/lib/ruby/gems/shared/gems/rubocop-0.6.1/bin/../lib/rubocop.rb:3
     load at org/jruby/RubyKernel.java:1046
   (root) at /home/sme/.rbenv/versions/jruby-1.7.2/lib/ruby/shared/rubygems/custom_require.rb:1

Checker definition probably flawed.

1.9 mode is the default, so I wouldn't expect ripper to even be needed. Likely just a jruby issue, but reporting for tracking anyway.

Feature: Custom Cops

Hey Guys,

I wanted to brainstorm about adding the ability for users to create custom cops. I think this would be a great feature. If the project/organization is concerned with style consistency, they likely have some differing opinions on what/how things should be checked.

Thinking about my own projects, I personally would like to create cops to check rspec method usage (expect instead of should, etc).

The way I can see this working is allowing users to create files (exactly the same as within the rubocop/cops source code) and place them in, for example, in a .rubocop folder within their project.

If you guys are onboard with this idea, I'd like to code it up and create a gist covering the basics of implementing a Cop.

Suggests to convert symbols :==, :<=> and the like to snake_case

~ $ cat bug.rb 
p :==, :<=>, :>, :<, :>=, :<=
~ $ rubocop bug.rb 
== bug.rb ==
C:  1: Use snake_case for symbols.
C:  1: Use snake_case for symbols.
C:  1: Use snake_case for symbols.
C:  1: Use snake_case for symbols.
C:  1: Use snake_case for symbols.
C:  1: Use snake_case for symbols.

1 files inspected, 6 offences detected
~ $ ruby --version; rubocop --version
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux]
0.5.0

Support for line numbers?

This is an awesome tool. We want to include it as a git pre-commit hook.
But we only wanted it to scan the lines that were changed in the git commit.

Rubocop currently scans the whole file. If rubocop could take a line numbers argument we could probably feed the output of git diff to rubocop.

Thanks!

method parameters ending with comma crash rubocop

Something like: foo(3,4,) or foo(a: 3, b: 4,) crashes.

gems/rubocop-0.4.2/lib/rubocop/cop/align_parameters.rb:46:in `get_args':  (RuntimeError)
app/helpers/categories_helper.rb: [:method_add_arg, [:fcall, [:@ident, "link_to", #<struct Rubocop::Cop::Position lineno=23, column=4>]], [:arg_paren, [[:method_add_arg, [:fcall, [:@ident, "t", #<struct Rubocop::Cop::Position lineno=24, column=6>]], [:arg_paren, [:args_add_block, [[:string_literal, [:string_content, [:@tstring_content, "shared.categories.reset-link", #<struct Rubocop::Cop::Position lineno=24, column=9>]]], [:bare_assoc_hash, [[:assoc_new, [:@label, "default:", #<struct Rubocop::Cop::Position lineno=24, column=40>], [:string_literal, [:string_content, [:@tstring_content, "Reset Filters", #<struct Rubocop::Cop::Position lineno=24, column=50>]]]]]]], false]]], [:vcall, [:@ident, "collection_path", #<struct Rubocop::Cop::Position lineno=25, column=6>]], [:bare_assoc_hash, [[:assoc_new, [:@label, "class:", #<struct Rubocop::Cop::Position lineno=26, column=6>], [:string_literal, [:string_content, [:@tstring_content, "reset disabled", #<struct Rubocop::Cop::Position lineno=26, column=14>]]]], [:assoc_new, [:@label, "title:", #<struct Rubocop::Cop::Position lineno=27, column=6>], [:method_add_arg, [:fcall, [:@ident, "t", #<struct Rubocop::Cop::Position lineno=27, column=13>]], [:arg_paren, [:args_add_block, [[:string_literal, [:string_content, [:@tstring_content, "tooltips.filtering.reset", #<struct Rubocop::Cop::Position lineno=27, column=16>]]], [:bare_assoc_hash, [[:assoc_new, [:@label, "default:", #<struct Rubocop::Cop::Position lineno=27, column=43>], [:string_literal, [:string_content, [:@tstring_content, "Return filters to the default view", #<struct Rubocop::Cop::Position lineno=27, column=53>]]]]]]], false]]]]]]]]]
        from gems/rubocop-0.4.2/lib/rubocop/cop/align_parameters.rb:16:in `block in inspect'

Semicolon rule should be mitigated

This pattern is extremely common:

class MyError < StandardError; end

It should probably find its way into the style guide, and rubocop should handle the following new cases:

  • completely empty class should have its end on the same line
  • semicolon rule should be relaxed in the above case

barfs on `def <=>`

Scanning this:

class Foo
  def <=> other
    name <=> other.name
  end
end

produces undefined method '[]' for nil:NilClass this exception:

/Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/op_method.rb:11:in `block in inspect': undefined method `[]' for nil:NilClass (NoMethodError)
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:82:in `each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cop/op_method.rb:9:in `inspect'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cli.rb:74:in `block (2 levels) in run'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cli.rb:66:in `each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cli.rb:66:in `block in run'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cli.rb:44:in `each'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/lib/rubocop/cli.rb:44:in `run'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/bin/rubocop:13:in `block in <top (required)>'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/2.0.0/benchmark.rb:296:in `realtime'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.6.0/bin/rubocop:12:in `<top (required)>'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/bin/rubocop:23:in `load'
    from /Users/lloeki/.rbenv/versions/2.0.0-p0/bin/rubocop:23:in `<main>'

Update tests to create directories in temporary directory

Currently the absence of a .ruboconf.yml file isn't tested because all tests create directories in the rubocop dir itself, which contains a .ruboconf.yml file.
I think it is better to move all those tests into a temporary directory using tmpdir so none of the tests are influenced by the supplied .ruboconf.yml file

Hash literal braces check

Currently we're not checking the style of hash literals. As mentioned in the guide there are two acceptable styles:

# with spaces
{ one: 1, two: 2 }

# without spaces
{one: 1, two: 2}

I think we need to introduce a cop named HashLiteralBraces (or something similar) and it should have a config option RequireOpeningAndClosingSpace (or something similar) set to true by default (since it's the more popular of the two styles). @jonas054, how does that sound?

[NoMethodError] rubocop /path/to/file

test case

rubocop lib/rubocop.rb

Registering cop Rubocop::Cop::LineLength
Registering cop Rubocop::Cop::Tab
Registering cop Rubocop::Cop::TrailingWhitespace
/Users/zhaocai/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rubocop-0.0.1/lib/rubocop/cli.rb:25:in `run': undefined method `each' for nil:NilClass (NoMethodError)
    from /Users/zhaocai/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rubocop-0.0.1/bin/rubocop:11:in `block in <top (required)>'
    from /Users/zhaocai/.rbenv/versions/1.9.3-p194/lib/ruby/1.9.1/benchmark.rb:295:in `realtime'
    from /Users/zhaocai/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rubocop-0.0.1/bin/rubocop:10:in `<top (required)>'
    from /Users/zhaocai/.rbenv/versions/1.9.3-p194/bin/rubocop:23:in `load'
    from /Users/zhaocai/.rbenv/versions/1.9.3-p194/bin/rubocop:23:in `<main>'

Strange behavior for inline blocks

Just an example:

Code:

[1,2,3].map { |r| "s-#{r}" }.join(',')

Exception:

/usr/local/var/lib/rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.4.0/lib/rubocop/cop/blocks.rb:32:in `check':  (RuntimeError)
1.rb:1:9: Matching brace not found
    from /usr/local/var/lib/rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.4.0/lib/rubocop/cop/blocks.rb:17:in `block in inspect'
    from /usr/local/var/lib/rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.4.0/lib/rubocop/cop/blocks.rb:17:in `each_index'
    from /usr/local/var/lib/rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.4.0/lib/rubocop/cop/blocks.rb:17:in `inspect'
    from /usr/local/var/lib/rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.4.0/lib/rubocop/cli.rb:62:in `block (2 levels) in run'
    from /usr/local/var/lib/rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.4.0/lib/rubocop/cli.rb:57:in `each'
    from /usr/local/var/lib/rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.4.0/lib/rubocop/cli.rb:57:in `block in run'
    from /usr/local/var/lib/rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.4.0/lib/rubocop/cli.rb:48:in `each'
    from /usr/local/var/lib/rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.4.0/lib/rubocop/cli.rb:48:in `run'
    from /usr/local/opt/rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.4.0/bin/rubocop:12:in `block in <top (required)>'
    from /usr/local/opt/rbenv/versions/2.0.0-p0/lib/ruby/2.0.0/benchmark.rb:296:in `realtime'
    from /usr/local/opt/rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.4.0/bin/rubocop:11:in `<top (required)>'
    from /usr/local/opt/rbenv/versions/2.0.0-p0/bin/rubocop:23:in `load'
    from /usr/local/opt/rbenv/versions/2.0.0-p0/bin/rubocop:23:in `<main>'

Seems like an bug for me.

By the way, if I add braces around the block (making this code invalid)

[1,2,3].map({ |r| "s-#{r}" }).join(',')

i get:

/usr/local/var/lib/rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.4.0/lib/rubocop/cop/syntax.rb:13:in `block in inspect': undefined method `captures' for nil:NilClass (NoMethodError)
    from /usr/local/var/lib/rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.4.0/lib/rubocop/cop/syntax.rb:12:in `each_line'
    from /usr/local/var/lib/rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.4.0/lib/rubocop/cop/syntax.rb:12:in `inspect'

Is this a correct behavior for invalid syntax?

Next one - reduce.

[1,2,3].reduce(0) { |memo, n| memo += n * n }

I get:

C:  1: Space missing after comma.
C:  1: Space missing after comma.

Ehm? What comma? I've already had that comma here.

Hope that helps!

Global variable `$INPUT_RECORD_SEPARATOR' not initialized on ruby 2.0.0-p0

Using ruby 2.0.0-p0 via rbenv.

When i have '$/' in file i get cop 'Prefer $INPUT_RECORD_SEPARATOR over $/.'
However if replace $/ with $INPUT_RECORD_SEPARATOR
I get warning
W: 15: Global variable `$input_record_separator' not initialized
(wich is true as such variable seems not to exist, returning nil when queried in irb)

Offending file example

invalid byte sequence in UTF-8

Does rubocop work with Ruby 2.0.0? I'm getting the following error in a Rail project that's on Ruby-2.0.0

/Users/davidragone/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.5.0/lib/rubocop/cli.rb:182:in block in ruby_files': invalid byte sequence in UTF-8 (ArgumentError) from /Users/davidragone/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.5.0/lib/rubocop/cli.rb:180:inselect'
from /Users/davidragone/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.5.0/lib/rubocop/cli.rb:180:in ruby_files' from /Users/davidragone/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.5.0/lib/rubocop/cli.rb:151:intarget_files'
from /Users/davidragone/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.5.0/lib/rubocop/cli.rb:44:in run' from /Users/davidragone/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.5.0/bin/rubocop:13:inblock in <top (required)>'
from /Users/davidragone/.rbenv/versions/2.0.0-p0/lib/ruby/2.0.0/benchmark.rb:296:in realtime' from /Users/davidragone/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/rubocop-0.5.0/bin/rubocop:12:in<top (required)>'
from /Users/davidragone/.rbenv/versions/2.0.0-p0/bin/rubocop:23:in load' from /Users/davidragone/.rbenv/versions/2.0.0-p0/bin/rubocop:23:in

'

Build fails

Many specs from cli_spec.rb are failing currently. See Travis-CI. This started with the introduction of the Coveralls code coverage gem.

All the failing specs fail for the same reason. A colored text is uncolored, which doesn't work, and then compared to an expected string without ANSI escape sequences. The comparison fails.

First I thought that the reason was that Coveralls and RuboCop both use ANSI coloring, but that they use different gems to achieve this. I tried changing RuboCop to use colorize (used by Coveralls) instead of term-ansicolor. That didn't help one bit.

Since it's the calls to String#uncolored that don't work, we could remove them and colorize all the expected strings instead. This fails to address the root cause, but it works. Should I implement this solution, or can anybody else find a better, more thorough solution?

AsciiIdentifiersAndComments cop should be configurable

We are a french dev shop, and we need to write comments in french. Still, we want to enforce identifiers to be ascii only.

The current AsciiIdentifiersAndComments cop checks both identifiers and comments. It should be configurable to check only one of them, or both, or neither.

Version 0.5.0 fails to run

After upgrading to version 0.5.0, rubocop started to fail with the following error:

xxxx$ rubocop app
/Users/xxxx/.rvm/gems/ruby-2.0.0-p0/gems/rubocop-0.5.0/lib/rubocop/cli.rb:182:in `block in ruby_files': invalid byte sequence in UTF-8 (ArgumentError)
    from /Users/xxxx/.rvm/gems/ruby-2.0.0-p0/gems/rubocop-0.5.0/lib/rubocop/cli.rb:180:in `select'
    from /Users/xxxx/.rvm/gems/ruby-2.0.0-p0/gems/rubocop-0.5.0/lib/rubocop/cli.rb:180:in `ruby_files'
    from /Users/xxxx/.rvm/gems/ruby-2.0.0-p0/gems/rubocop-0.5.0/lib/rubocop/cli.rb:157:in `block in target_files'
    from /Users/xxxx/.rvm/gems/ruby-2.0.0-p0/gems/rubocop-0.5.0/lib/rubocop/cli.rb:155:in `each'
    from /Users/xxxx/.rvm/gems/ruby-2.0.0-p0/gems/rubocop-0.5.0/lib/rubocop/cli.rb:155:in `target_files'
    from /Users/xxxx/.rvm/gems/ruby-2.0.0-p0/gems/rubocop-0.5.0/lib/rubocop/cli.rb:44:in `run'
    from /Users/xxxx/.rvm/gems/ruby-2.0.0-p0/gems/rubocop-0.5.0/bin/rubocop:13:in `block in <top (required)>'
    from /Users/xxxx/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/benchmark.rb:296:in `realtime'
    from /Users/xxxx/.rvm/gems/ruby-2.0.0-p0/gems/rubocop-0.5.0/bin/rubocop:12:in `<top (required)>'
    from /Users/xxxx/.rvm/gems/ruby-2.0.0-p0/bin/rubocop:23:in `load'
    from /Users/xxxx/.rvm/gems/ruby-2.0.0-p0/bin/rubocop:23:in `<main>'
    from /Users/xxxx/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `eval'
    from /Users/xxxx/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `<main>'

Version 0.4.6 worked with no issues on the same set of source code.

One line methods

Should one line methods be discouraged?

def foo; 'bar' end

They require a semicolon after method name when parens are absent, and rubocop points that as an offense.

I'm not really advocating in favour of (or against) them, in fact I'm just pointing out it may have passed unnoticed.

Two cops crash when scanning code using super

This code:

class Base
  def func
    "Hello"
  end
end

class Derived < Base
  def func
    super.slice(1..2)
  end
end

puts Derived.new.func

gives this stack dump:

/home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.6.0/lib/rubocop/cop/hash_literal.rb:12:in `block in inspect': undefined method `[]' for nil:NilClass (NoMethodError)
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
[...]
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.6.0/lib/rubocop/cop/hash_literal.rb:9:in `inspect'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.6.0/lib/rubocop/cli.rb:74:in `block (2 levels) in run'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.6.0/lib/rubocop/cli.rb:66:in `each'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.6.0/lib/rubocop/cli.rb:66:in `block in run'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.6.0/lib/rubocop/cli.rb:44:in `each'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.6.0/lib/rubocop/cli.rb:44:in `run'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.6.0/bin/rubocop:13:in `block in <top (required)>'
    from /home/jonas/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/benchmark.rb:295:in `realtime'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.6.0/bin/rubocop:12:in `<top (required)>'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/bin/rubocop:19:in `load'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/bin/rubocop:19:in `<main>'

So HashLiteral crashes. The same goes for ArrayLiteral if HashLiteral is disabled. I have a fix for the problem.

Interpolated variables not enclosed in braces are not noticed

When you interpolate global, instance or class variables in strings you can omit the enclosing braces. But RuboCop does not notice variables not enclosed in braces and gives a misleading warnings of

Prefer single-quoted strings when you don't need string interpolation or special symbols.

as double-quotation is required for the strings in question.

For example, consider the following code:

# -*- coding: utf-8 -*-

class Klass
  def meth
    @bar = @@bar = $bar = 'baz'
    puts "foo#@bar"
    puts "foo#@@bar"
    puts "foo#$bar"
  end
end

When inspecting this rubocop says

C:  5: Replace class var @@bar with a class instance var.
C:  6: Prefer single-quoted strings when you don't need string interpolation or special symbols.
C:  7: Prefer single-quoted strings when you don't need string interpolation or special symbols.
C:  7: Replace class var @@bar with a class instance var.
C:  8: Prefer single-quoted strings when you don't need string interpolation or special symbols.

But replacing the strings with single-quoted ones will not allow for interpolation.

Configuration file problems

I think we need to handle configuration files in a better way. The problems with the current implementation are:

  • We're too soft on missing configuration. Every cop parameter, including Enabled, has a default value. This means that when users update the rubocop gem and get a number of new cops, their old .rubocop.yml files in the projects should be updated too, but they might forget and they won't see the need for filling in more configuration values because of the defaults.
  • There's no error or warning for unexpected configuration values. A misspelled or outdated cop name or configuration parameter will go unnoticed.
  • If you have many .rubocop.yml files, you have a lot of duplication.

I have an idea for a solution. We add a config directory to the rubocop root. Here we store default configuration files such as all_enabled.yml which will look like the .rubocop.yml in the root today. Then we add an include mechanism called based_on. E.g.:

# .rubocop.yml

based_on: RUBOCOP_HOME/config/all_enabled.yml

LineLength:
  Enabled: true
  Max: 100

So everything after based_on will override settings in the included yml file. If you override the settings for a cop, you must specify all parameters, i.e. you can't just set Max and expect to inherit Enabled.

And we remove the default handling. Everything must be specified.

Undefined method `captures' for nil:NilClass

Not all error lines in the output from ruby -wc contain the word warning, which leads to an exception being rasied in syntax.rb.

For example:

jonas@jonas-laptop:~/.rvm/gems$ ruby -wc ~/.rvm/gems/ruby-1.9.3-p194/gems/activeadmin-0.5.0/lib/generators/active_admin/resource/templates/admin.rb 
/home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/activeadmin-0.5.0/lib/generators/active_admin/resource/templates/admin.rb:1: unterminated string meets end of file
/home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/activeadmin-0.5.0/lib/generators/active_admin/resource/templates/admin.rb:1: warning: possibly useless use of < in void context

So I get this exception:

jonas@jonas-laptop:~/.rvm/gems$ rubocop ruby-1.9.3-p194/gems/activeadmin-0.5.0/lib/generators/active_admin/resource/templates/admin.rb 
/home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.4.1/lib/rubocop/cop/syntax.rb:13:in `block in inspect': undefined method `captures' for nil:NilClass (NoMethodError)
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.4.1/lib/rubocop/cop/syntax.rb:12:in `each_line'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.4.1/lib/rubocop/cop/syntax.rb:12:in `inspect'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.4.1/lib/rubocop/cli.rb:62:in `block (2 levels) in run'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.4.1/lib/rubocop/cli.rb:57:in `each'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.4.1/lib/rubocop/cli.rb:57:in `block in run'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.4.1/lib/rubocop/cli.rb:48:in `each'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.4.1/lib/rubocop/cli.rb:48:in `run'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.4.1/bin/rubocop:12:in `block in <top (required)>'
    from /home/jonas/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/benchmark.rb:295:in `realtime'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/gems/rubocop-0.4.1/bin/rubocop:11:in `<top (required)>'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/bin/rubocop:19:in `load'
    from /home/jonas/.rvm/gems/ruby-1.9.3-p194/bin/rubocop:19:in `<main>'

More cops(rules)

Hey guys,

Here's a list of the more important rules that we should implement in the future.

  • Use Kernel#loop with break rather than begin/end/until or begin/end/while for post-loop tests.
  • Avoid return where not required for flow of control.
  • Avoid self where not required. (It is only required when calling a self write accessor.)
  • Avoid line continuation (\) where not required. In practice, avoid using line continuations at all~~.
  • Use only ascii symbols in identifiers and comments
  • When using reduce with short blocks, name the arguments |a, e| (accumulator, element).
  • When defining binary operators, name the argument other. (like def +(other))
  • Comment annotation would be all upcase and at the beginning of the comment like (# TODO improve performance).
  • Favor the use of module_function over extend self when you want to turn a module's instance methods into class methods.
  • Use the attr family of functions to define trivial accessors or mutators.
  • Use def self.method to define singleton methods. This makes the code easier to refactor since the class name is not repeated.
  • Signal exceptions using the fail method. Use raise only when catching an exception and re-raising it (because here you're not failing, but explicitly and purposefully raising an exception).
  • Never return from an ensure block. If you explicitly return from a method inside an ensure block, the return will take precedence over any exception being raised, and the method will return as if no exception had been raised at all. In effect, the exception will be silently thrown away.
  • Use implicit begin blocks where possible.
  • Don't suppress exceptions.
  • Avoid rescuing the Exception class. This will trap signals and calls to exit, requiring you to kill -9 the process.
  • Prefer literal array and hash creation notation (unless you need to pass parameters to their constructors, that is).
  • Prefer %w to the literal array syntax when you need an array of strings.
  • Use %r only for regular expressions matching more than one '/' character.
  • Favor %r if you have more than 1 '/' characters in your regexp.
  • Avoid %q, %Q, %x, %s, and %W.
  • Prefer () as delimiters for all % literals.
  • Avoid methods longer than 10 LOC (lines of code). Ideally, most methods will be shorter than 5 LOC. Empty lines do not contribute to the relevant LOC. (this cop should have configurable max length)
  • Avoid alias when alias_method will do.
  • Avoid more than three levels of block nesting.
  • One space after if, unless, etc.
  • Use two spaces for indentation.
  • Add empty lines around private and protected.
  • Indent private and protected as much as method definitions.

Details and examples about most rules are available in the guide itself.

I'm opening this ticket mostly so we can discuss who would like to implement what, so that we don't end up with two people working on the same cop. When somebody(me included) starts to work on a cop he'd write a comment here; when he's done - we'd scratch the rule from the list.

So, who'd like to pick a task first? :-)

@jonas054, @vsakarov, @emou

TrivialAccessors Cop Error

I received this error:

An error occurred while TrivialAccessors cop was inspecting /Users/ryan/www/articles/app/models/user.rb.
To see the complete backtrace run rubocop -d.
undefined method `[]' for nil:NilClass
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/trivial_accessors.rb:36:in `is_trivial_reader'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/trivial_accessors.rb:23:in `find_trivial_accessors'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/trivial_accessors.rb:12:in `block in inspect'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:89:in `block (2 levels) in each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:89:in `block (2 levels) in each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:89:in `block (2 levels) in each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:89:in `block (2 levels) in each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:89:in `block (2 levels) in each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:87:in `each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:89:in `block in each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:88:in `each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:88:in `each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:89:in `block in each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:88:in `each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:88:in `each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:89:in `block in each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:88:in `each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:88:in `each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:89:in `block in each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:88:in `each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:88:in `each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:89:in `block in each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:88:in `each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:88:in `each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/trivial_accessors.rb:11:in `inspect'
/Users/ryan/www/gems/rubocop/lib/rubocop/cli.rb:89:in `block in inspect_file'
/Users/ryan/www/gems/rubocop/lib/rubocop/cli.rb:80:in `each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cli.rb:80:in `inspect_file'
/Users/ryan/www/gems/rubocop/lib/rubocop/cli.rb:55:in `block in run'
/Users/ryan/www/gems/rubocop/lib/rubocop/cli.rb:37:in `each'
/Users/ryan/www/gems/rubocop/lib/rubocop/cli.rb:37:in `run'
../gems/rubocop/bin/rubocop:14:in `block in <main>'
/Users/ryan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/benchmark.rb:296:in `realtime'
../gems/rubocop/bin/rubocop:13:in `<main>'

While scanning this file:

class User < ActiveRecord::Base
  extend FriendlyId
  friendly_id :username, use: :slugged

  include ActiveModel::ForbiddenAttributesProtection

  devise :database_authenticatable, :registerable, :lockable, :timeoutable,
         :omniauthable, :recoverable, :rememberable, :trackable, :confirmable,
         :validatable

  belongs_to :avatar_image # Foreign key in users
  has_many :articles
  has_many :comments

  validates :username, presence: true, uniqueness: { case_sensitive: false },
                       format: { with: /^[\p{L}0-9]{3,15}$/iu }
  validates :facebook_page, url: true, length: { maximum: 240 }
  validates :website, url: true, length: { maximum: 240 }
  validates :blog, url: true, length: { maximum: 240 }

  alias_attribute :admin?, :admin
  alias_attribute :banned?, :banned

  def facebook_account?
    provider.present?
  end

  def picture?
    avatar_image.present?
  end

  def picture_url
    picture? ? avatar_image.url : 'placeholder.jpeg'
  end

  def total_views
    published_articles.joins('INNER JOIN views '\
                             'ON views.article_id = articles.id').count
  end

  def published_articles
    articles.published
  end

  def paginated_articles(page, per_page)
    published_articles.paginate(page: page, per_page: per_page)
  end

  # Require password to update account if email or password has changed
  def update_with_password(params, *options)
    password_or_email_changed = (email != params[:email] ||
                                 params[:password].present?)
    if password_or_email_changed && !facebook_account?
      super
    else
      params.delete(:current_password)
      update_without_password(params, *options)
    end
  end

  # Password isn't required if it's a facebook account
  def password_required?
    super && !facebook_account?
  end

  # Create or find a user record from Omniauth Hash
  def self.from_omniauth(auth)
    where(auth.slice(:provider, :uid)).first_or_initialize do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.username = auth.info.nickname.gsub('.', '') if auth.info
      user.email = auth.info.email if auth.info
    end
  end

  # create a user for registration based on devise-provided session
  def self.new_with_session(params, session)
    if session['devise.user_attributes']
      new(session['devise.user_attributes'],
          without_protection: true) do |user|
        user.attributes = params
        user.valid?
      end
    else
      super
    end
  end

protected
  # No confirmation if it's a facebook account
  def confirmation_required?
    facebook_account? ? false : super
  end
end

double alias problem

Maybe I've found a bug (?)... it seems that rubocop (version 0.5.0) doesn't like so much a snippet of code like this one:

alias has_foo? foo?
alias has_bar? bar?

I will do a PR...

Running cops in parallel

As we add more and more checks the performance naturally regresses a bit. Luckily the things we're doing are pretty parallelizable - we can simply split the cops into 3 groups, run them in 3 threads and just merge the results in the end. Even though Ruby's threading is not exactly its strong suite I still think we might be able to get some benefit out of this.

JRuby is inching closer to supporting Ripper(https://gist.github.com/enebo/4548938) and there the performance boost should be even bigger.

This issue is here mostly for discussion purposes. If anyone has the time to run a few simple experiments with basic parallelization and share the results that'd be great.

Feature Request: exclude certain folders

Eg. I don't want to have to worry about cops harassing autogenerated migrations and schemas for not using proper hash syntax. Would be good as a command line switch or something but might be nicer in the .yml! I'm new to ruby so you wouldn't want me near your codebase (hence me using the tool) but this would be a nice addition.

README improvements

We need to extend the README file a bit, since newcomers will likely miss out some of the things they can do with rubocop.

Add cop name to offence output

I ran into an issue today where some code was triggering a cop but upon reviewing the code I could find no preferable way to rewrite it, so I decided to disable that cop for just those few lines. (Thanks @jonas054 for this fabulous feature!) Unfortunately, I'm not as familiar with which cops do what ... so I had to go digging through the code to figure out which cop name to specify in the rubocop:disable comment. This process should be easier. I suggest that we change the output to something like the following:

C: 30: MethodLength: Method has too many lines. [12/10]
C: 86: ParameterLists: Avoid parameter lists longer than four parameters.

Issue with whitespace?': undefined method

/Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:99:in whitespace?': undefined methodtype' for nil:NilClass (NoMethodError)
from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/space_after_comma_etc.rb:11:in block in inspect' from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/space_after_comma_etc.rb:9:ineach_index'
from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/space_after_comma_etc.rb:9:in inspect' from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cli.rb:74:inblock (2 levels) in run'
from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cli.rb:66:in each' from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cli.rb:66:inblock in run'
from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cli.rb:44:in each' from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cli.rb:44:inrun'
from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/bin/rubocop:13:in block in <top (required)>' from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/benchmark.rb:295:inrealtime'
from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/bin/rubocop:12:in <top (required)>' from /Users/matt/.rbenv/versions/1.9.3-p327/bin/rubocop:23:inload'
from /Users/matt/.rbenv/versions/1.9.3-p327/bin/rubocop:23:in `

'

Takes a very long time if run with bundle exec

Running bundle exec rubocop is a magnitude slower than running rubocop for me.

I'm not sure where this might come from, but I do not experience it with other commands like cane, rails_best_practices or brakeman.

cane 0,34s user 0,01s system 93% cpu 0,378 total
bundle exec cane 1,25s user 0,04s system 99% cpu 1,295 total
rubocop 2,78s user 0,87s system 94% cpu 3,868 total
bundle exec rubocop 95,85s user 3,80s system 99% cpu 1:40,10 total

Is it just me or can you confirm this?

Comments shouldn't be part of the 80 characters rule

As comments aren't code, I don't think they should be part of the 80 characters rule which tells me that the Line is too long. I don't know about you?

In fact, let me rephrase. Do you think that comments should be part of the 80 characters per line rule as they're not code?

Received malformed format string ArgumentError from rubocop

/Users/michael.hogg/.rvm/gems/ruby-1.9.3-p392@fig/gems/rubocop-0.4.0/lib/rubocop/cop/offence.rb:17:in%': malformed format string - %[ (ArgumentError)
from /Users/michael.hogg/.rvm/gems/ruby-1.9.3-p392@fig/gems/rubocop-0.4.0/lib/rubocop/cop/offence.rb:17:in to_s' from /Users/michael.hogg/.rvm/gems/ruby-1.9.3-p392@fig/gems/rubocop-0.4.0/lib/rubocop/report/plain_text.rb:10:injoin'
from /Users/michael.hogg/.rvm/gems/ruby-1.9.3-p392@fig/gems/rubocop-0.4.0/lib/rubocop/report/plain_text.rb:10:in generate' from /Users/michael.hogg/.rvm/gems/ruby-1.9.3-p392@fig/gems/rubocop-0.4.0/lib/rubocop/report/plain_text.rb:14:indisplay'
from /Users/michael.hogg/.rvm/gems/ruby-1.9.3-p392@fig/gems/rubocop-0.4.0/lib/rubocop/cli.rb:67:in block in run' from /Users/michael.hogg/.rvm/gems/ruby-1.9.3-p392@fig/gems/rubocop-0.4.0/lib/rubocop/cli.rb:48:ineach'
from /Users/michael.hogg/.rvm/gems/ruby-1.9.3-p392@fig/gems/rubocop-0.4.0/lib/rubocop/cli.rb:48:in run' from /Users/michael.hogg/.rvm/gems/ruby-1.9.3-p392@fig/gems/rubocop-0.4.0/bin/rubocop:12:inblock in <top (required)>'
from /Users/michael.hogg/.rvm/rubies/ruby-1.9.3-p392/lib/ruby/1.9.1/benchmark.rb:295:in realtime' from /Users/michael.hogg/.rvm/gems/ruby-1.9.3-p392@fig/gems/rubocop-0.4.0/bin/rubocop:11:in<top (required)>'
from /Users/michael.hogg/.rvm/gems/ruby-1.9.3-p392@fig/bin/rubocop:19:in load' from /Users/michael.hogg/.rvm/gems/ruby-1.9.3-p392@fig/bin/rubocop:19:in

'
from /Users/michael.hogg/.rvm/gems/ruby-1.9.3-p392@fig/bin/ruby_noexec_wrapper:14:in eval' from /Users/michael.hogg/.rvm/gems/ruby-1.9.3-p392@fig/bin/ruby_noexec_wrapper:14:in'
`

Hash Literal breaks

/Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/array_literal.rb:12:in `block in inspect': undefined method `[]' for nil:NilClass (NoMethodError)
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:82:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:84:in `block in each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/cop.rb:83:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cop/array_literal.rb:9:in `inspect'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cli.rb:74:in `block (2 levels) in run'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cli.rb:66:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cli.rb:66:in `block in run'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cli.rb:44:in `each'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/lib/rubocop/cli.rb:44:in `run'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/bin/rubocop:13:in `block in <top (required)>'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/benchmark.rb:295:in `realtime'
  from /Users/matt/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rubocop-0.6.0/bin/rubocop:12:in `<top (required)>'
  from /Users/matt/.rbenv/versions/1.9.3-p327/bin/rubocop:23:in `load'
  from /Users/matt/.rbenv/versions/1.9.3-p327/bin/rubocop:23:in `<main>

Error - RescueException Cop

While scanning one of my projects, I came across the following RescueException Cop error:

Scanning /Users/ryan/www/articles/app/lib/url_validator.rb
/Users/ryan/www/gems/rubocop/lib/rubocop/cop/rescue_exception.rb:13:in `block in inspect': undefined method `lineno' for nil:NilClass (NoMethodError)
    from /Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
    from /Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
    from /Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
    from /Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
    from /Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
    from /Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
    from /Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:84:in `block (2 levels) in each'
    from /Users/ryan/www/gems/rubocop/lib/rubocop/cop/cop.rb:82:in `each'
...

Here is url_validator.rb:

class UrlValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless value.blank? || check_url_format(value)
      record.errors[attribute] << (options[:message] || I18n.t("activerecord.errors.models.user.correctly_enter_url"))
    end
  end

private
  def check_url_format(url)
    uri = URI.parse(url)
    uri.kind_of?(URI::HTTP)
  rescue URI::InvalidURIError
    false
  end
end

Error while running "code converter not found (UTF-8 to UTF-16)"

I use RVM with Ruby 1.9.2
I installed Rubocop 0.2.0
When I try to run it by command 'rubocop' in terminal i get that error

/home/user/.rvm/gems/ruby-1.9.2-p318/gems/rubocop-0.2.0/lib/rubocop/cli.rb:36:in encode!': code converter not found (UTF-8 to UTF-16) (Encoding::ConverterNotFoundError) from /home/user/.rvm/gems/ruby-1.9.2-p318/gems/rubocop-0.2.0/lib/rubocop/cli.rb:36:inblock (2 levels) in run'
from /home/user/.rvm/gems/ruby-1.9.2-p318/gems/rubocop-0.2.0/lib/rubocop/cli.rb:33:in map' from /home/user/.rvm/gems/ruby-1.9.2-p318/gems/rubocop-0.2.0/lib/rubocop/cli.rb:33:inblock in run'
from /home/user/.rvm/gems/ruby-1.9.2-p318/gems/rubocop-0.2.0/lib/rubocop/cli.rb:31:in each' from /home/user/.rvm/gems/ruby-1.9.2-p318/gems/rubocop-0.2.0/lib/rubocop/cli.rb:31:inrun'
from /home/user/.rvm/gems/ruby-1.9.2-p318/gems/rubocop-0.2.0/bin/rubocop:12:in block in <top (required)>' from /home/user/.rvm/rubies/ruby-1.9.2-p318/lib/ruby/1.9.1/benchmark.rb:310:inrealtime'
from /home/user/.rvm/gems/ruby-1.9.2-p318/gems/rubocop-0.2.0/bin/rubocop:11:in <top (required)>' from /home/user/.rvm/gems/ruby-1.9.2-p318/bin/rubocop:19:inload'
from /home/user/.rvm/gems/ruby-1.9.2-p318/bin/rubocop:19:in <main>' from /home/user/.rvm/gems/ruby-1.9.2-p318/bin/ruby_noexec_wrapper:14:ineval'
from /home/user/.rvm/gems/ruby-1.9.2-p318/bin/ruby_noexec_wrapper:14:in `

'*

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.