# rubocop:disable Metrics/AbcSize - ruby

I am really stuck in this part:
If i disable # rubocop:disable Metrics/AbcSize, then I am getting this error:
ruby -v : ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-darwin14]
rubocop -V
0.52.1 (using Parser 2.4.0.2, running on ruby 2.4.2 x86_64-darwin14)
$ rubocop .
Inspecting 7 files
.....W.
Offenses:
recipes/default.rb:13:1: W: Lint/MissingCopEnableDirective: Re-enable Metrics/AbcSize cop with # rubocop:enable after disabling it.
# rubocop:disable Metrics/AbcSize
^
7 files inspected, 1 offense detected
If I enable rubocop in the script then getting this:
rubocop .
Inspecting 7 files
.....C.
Offenses:
recipes/default.rb:31:1: C: Metrics/AbcSize: Assignment Branch Condition size for check_tropo_versions is too high. [33.02/20]
def check_tropo_versions ...
^^^^^^^^^^^^^^^^^^^^^^^^
7 files inspected, 1 offense detected
A few lines of my script:
# rubocop:enable Metrics/AbcSize
require 'nokogiri'
Chef.event_handler do
on :resource_updated do |resource, _action|
if resource.declared_type.to_s == 'remote_file' && resource.cookbook_name == 'tropo-patch' && resource.recipe_name == 'default'
puts "#{Time.now.strftime('%Y%m%d%H%M%S')},#{resource.path},#{resource.source[0]}"
File.open('/var/log/tropo-patch.log', 'a') { |f| f.write("#{Time.now.strftime('%Y%m%d%H%M%S')},#{resource.path},#{resource.source[0]}\n") }
end
end
end
I cannot disable rubocop from global config file, but if it can resolve I will try this as well:
Metrics/AbcSize:
Description: >-
A calculated magnitude based on number of assignments,
branches, and conditions.
Reference: 'http://c2.com/cgi/wiki?AbcMetric'
Enabled: true

What Rubocop is basically complaining about is that it asks you to enable the cop after the method is closed, so the cop can be in effect for other methods of the file. If you disable it on the first line of the file, it will be disable for all methods in that file. Disabling cops for whole files is not a good idea, since you should be explicit and conscious when disabling the cops.
The fix in your case is just simply disabling the cop before your method, and then enable it after.
For example:
# rubocop:disable Metrics/AbcSize
require 'nokogiri'
Chef.event_handler do
on :resource_updated do |resource, _action|
if resource.declared_type.to_s == 'remote_file' && resource.cookbook_name == 'tropo-patch' && resource.recipe_name == 'default'
puts "#{Time.now.strftime('%Y%m%d%H%M%S')},#{resource.path},#{resource.source[0]}"
File.open('/var/log/tropo-patch.log', 'a') { |f| f.write("#{Time.now.strftime('%Y%m%d%H%M%S')},#{resource.path},#{resource.source[0]}\n") }
end
end
end
# rubocop:enable Metrics/AbcSize
Also, if you need to disable multiple cops, you can enable all of them by using:
# rubocop:enable all
Hope that helps!
Edit: After looking at Tom Lord's comment on your question, I noticed that you haven't posted the actual method that is breaking the rule of the cop. Still, the solution I provided should work if your put the disable and enable statements at the correct places. In addition, I second what Tom stated, that if you show us the code we might improve the method and you will not need to disable the cop for the method.

You can disable a cop for this method only, instead of adding # rubocop:disable at the top of the file, just mark your offender like this
def check_tropo_versions # rubocop:disable Metrics/AbcSize
# ...

Use cookstyle in place of rubocop there. It’s got better defaults for linting cookbook code.

Related

Rubocop, how to Disable/Enable cops on blocks of code

I will like to disable a cop for a specific block or method.
I know it is possible to disable a cop for the whole project using .rubocop.yml but I just want to deactivate the cop temporarily for a specific portion of the code
I answer my question because it is always very difficult for me to find the reference to this solution:
# rubocop:disable Metrics/MethodLength
def my_code
..
end
# rubocop:enable Metrics/MethodLength
Same for multiple cops:
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
def my_code
..
end
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
Documentation: https://docs.rubocop.org/rubocop/configuration.html#disabling-cops-within-source-code
If you want to disable the cop for a particular line, you can just use something like this
before_action :authenticate_user!, except: [:index, :show] # rubocop:disable Style/SymbolArray
No need to enable it again. If there is a block of code and you want to enable or disable the cop, then as suggested above, you can follow that approach.

How can I validate a date string without rescuing the exception to keep the Rubocop HandleExceptions linter happy?

I have a string which might or might not be a valid date.
I want a clean and simple way to validate whilst keeping Rubocop happy.
# TODO: Welcome suggestions for a better way to deal with this...
# rubocop:disable HandleExceptions
def self.valid_date?(date)
Date.parse(date)
rescue ArgumentError
end
# rubocop:enable HandleExceptions
I actually feel like this is a clean way to achieve what I need, but is there a way to resolve whilst still keeping rubocop happy?
Add a explicit nil:
# TODO: Welcome suggestions for a better way to deal with this...
# rubocop:disable HandleExceptions
def self.valid_date?(date)
Date.parse(date)
rescue ArgumentError
nil
end
Otherwise, enable inline rescue in .rubocop.yml for a shorter method:
Style/RescueModifier:
Enabled: false
Then:
# TODO: Welcome suggestions for a better way to deal with this...
# rubocop:disable HandleExceptions
def self.valid_date?(date)
Date.parse(date) rescue nil
end
Remember, how readable is your code does not deppend on what a machine says, but what other people (i.e. a community) feel about it. Rubocop is just a tool for a quick way to review code without reading line by line manually.
# rubocop:disable Style/RescueModifier
def self.valid_date?(date)
Date.parse(date) rescue nil
end
# rubocop:enable Style/RescueModifier

How to make rubocop output nothing when there are no warnings or offenses?

I'd like rubocop but have it create no output if there are no offenses. I've played with the documented command line options, and taken a quick peek a the config option and source code without seeing anything promising.
The closest I've come is rubocop -f o, but even that produces a summary line:
$ rubocop -f o
--
0 Total
Any ideas on how to suppress output on a clean, successful run?
I believe there's no predefined option to do what you ask. The best option I think is to implement a custom formatter with the desired behaviour and use that to run RuboCop. As a super simple example consider the following, inspired by RuboCop's SimpleTextFormatter:
# my_rubocop_formatter.rb
class MyRuboCopFormatter < RuboCop::Formatter::BaseFormatter
def started(target_files)
#total_offenses = 0
end
def file_finished(file, offenses)
unless offenses.empty?
output.puts(offenses)
#total_offenses += offenses.count
end
end
def finished(inspected_files)
puts #total_offenses unless #total_offenses.zero?
end
end
You can run RuboCop using it with the following command:
rubocop -r '/path/to/my_rubocop_formatter.rb' \
-f MyRuboCopFormatter file_to_check.rb

Do any source code analysis tools detect unused parameters in Ruby?

How can I detect unused parameters in Ruby?
Options I'm aware of include
Being rigorous with TDD.
Heckle (currently works only with Ruby 1.8 due to ParseTree issues)
Using an IDE such as RubyMine to detect unused parameters or automate the refactoring.
But do any source code analysis tools or warning options allow you to detect unused parameters?
Background: I was doing some refactoring. I changed from (code slightly simplified):
# Not within the Foo class (therefore can't be as easily accessed by unit testing)
# and in addition, the name of the configuration file is hard-wired
def parse_configuration
raw_configuration = YAML.load_file("configuration.yml")
# Do stuff with raw_configuration to produce configuration_options_for_foo
return configuration_options_for_foo
end
if __FILE__ == $0
configuration_options_for_foo = parse_configuration
foo = Foo.new(configuration_options_for_foo)
end
to
class Foo
# Now unit tests can call Foo.new_using_yaml("configuration.yml")
# or use "test_configuration.yml"
def self.new_using_yaml(yaml_filename)
# Where I went wrong, forgetting to replace "configuration.yml" with yaml_filename
raw_configuration = YAML.load_file("configuration.yml")
# Do stuff with raw_configuration to produce configuration_options_for_foo
new(configuration_options_for_foo)
end
end
if __FILE__ == $0
foo = Foo.new_using_yaml("configuration.yml")
end
I think Laser does this.
It's pretty alpha-y, but seems to do what you want.
http://github.com/michaeledgar/laser
Reek can detect unused parameters.
Ruby-lint can detect an unused parameter.
RuboCop has just added (April 2014) detection of unused parameters with the cop "UnusedMethodArgument".

irb history not working

in ~/.irbrc i have these lines:
require 'irb/ext/save-history'
#History configuration
IRB.conf[:SAVE_HISTORY] = 100
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-save-history"
and yet when i run irb and hit the up arrow nothing happens. also the irb history file specified is not getting created and nothing is logged to it.
irb history works in Debian Linux out of the box. There's no etc/irbrc, nor do I have a ~/.irbrc. So, hmmmm.
This person put a bit more in his irbrc than you did. Do you suppose the ARGV.concat could be the missing piece?
require 'irb/completion'
require 'irb/ext/save-history'
ARGV.concat [ "--readline", "--prompt-mode", "simple" ]
IRB.conf[:SAVE_HISTORY] = 100
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-save-history"
I don't have an answer for you why the above doesn't work, but I did find a file, /etc/irbrc on my system (OS X - Snow Leopard, Ruby 1.8.7) that does provide a working, persistent history for me. So two pieces of advice: i) check your /etc/irbrc (or equivalent) to make sure that there isn't anything in there that might interfere with your settings, and ii) try out the settings below to see if you can get history working that way.
# Some default enhancements/settings for IRB, based on
# http://wiki.rubygarden.org/Ruby/page/show/Irb/TipsAndTricks
unless defined? ETC_IRBRC_LOADED
# Require RubyGems by default.
require 'rubygems'
# Activate auto-completion.
require 'irb/completion'
# Use the simple prompt if possible.
IRB.conf[:PROMPT_MODE] = :SIMPLE if IRB.conf[:PROMPT_MODE] == :DEFAULT
# Setup permanent history.
HISTFILE = "~/.irb_history"
MAXHISTSIZE = 100
begin
histfile = File::expand_path(HISTFILE)
if File::exists?(histfile)
lines = IO::readlines(histfile).collect { |line| line.chomp }
puts "Read #{lines.nitems} saved history commands from '#{histfile}'." if $VERBOSE
Readline::HISTORY.push(*lines)
else
puts "History file '#{histfile}' was empty or non-existant." if $VERBOSE
end
Kernel::at_exit do
lines = Readline::HISTORY.to_a.reverse.uniq.reverse
lines = lines[-MAXHISTSIZE, MAXHISTSIZE] if lines.nitems > MAXHISTSIZE
puts "Saving #{lines.length} history lines to '#{histfile}'." if $VERBOSE
File::open(histfile, File::WRONLY|File::CREAT|File::TRUNC) { |io| io.puts lines.join("\n") }
end
rescue => e
puts "Error when configuring permanent history: #{e}" if $VERBOSE
end
ETC_IRBRC_LOADED=true
end
This is a known bug with a patch available. Easiest solution is to overwrite save-history.rb:
/usr/lib/ruby/1.8/irb/ext/save-history.rb
with a fixed version:
http://pastie.org/513500
or to do it in one go:
wget -O /usr/lib/ruby/1.8/irb/ext/save-history.rb http://pastie.org/pastes/513500/download
Check to make sure you built ruby with libreadline as irb history seems to not work without it.
This may also happen if you have extra irb config file, e.g. ~/.irbrc. If this is the case, copy the content from liwp's answer to the extra config and it should work.
I had the same problem on ubuntu 20.04 and fixed it by running:
gem install irb

Resources