GithubHelp home page GithubHelp logo

excellent's Introduction

Excellent

Build Status

Excellent finds the nasty lines in your code. It implements a comprehensive set of checks for possibly buggy parts of your app that would otherwise make it into your repo and eventually to the production server.

See the API documentation at http://docs.github.com/simplabs/excellent and the Wiki at http://wiki.github.com/simplabs/excellent.

Installation

Simply install with Ruby Gems:

gem install excellent

Example

Assume you have the following class definition,

class ShoppingBasket < ActiveRecord::Base

  def initialize(items = [])
    self.items = items
  end

end

then Excellent will report the problems in this piece of code:

$ excellent shopping_basket.rb

  Excellent result:

  test.rb
    * Line   1: ShoppingBasket does not validate any attributes.
    * Line   1: ShoppingBasket defines initialize method.
    * Line   1: ShoppingBasket does not specify attr_accessible.

  Found 3 warnings.

To analyse all the models in your Rails application, just do

excellent app/models

in your RAILS_ROOT. You can also invoke analysation through the Simplabs::Excellent::Runner class. Excellent can also produce HTML output. To get a formatted HTML report, just specify html:<filename>:

excellent -o out.html app/models

You can also use Excellent in a Rake task:

require 'simplabs/excellent/rake'

Simplabs::Excellent::Rake::ExcellentTask.new(:excellent) do |t|
  t.html  = 'doc/excellent.html' # optional, if you don't specify html, output will be written to $stdout
  t.paths = %w(app lib)
end

Configuration

You can configure which checks to run and which thresholds etc. to use. Simply place a .excellent.yml in the root directory of you project (the directory that you will be starting excellent from). You can enable/disable by using the check name as hash key and specifying a truthy/falsy value:

AbcMetricMethodCheck: true
AssignmentInConditionalCheck: false

By default all checks are enabled so you would usually only switch off certain checks you're not interested in. Some checks also take cofngigurations like thresholds, patterns etc. You can configure those by simply defining nested hashes in the YAML:

ClassLineCountCheck:
  threshold: 500
MethodNameCheck:
  pattern: '^[a-z].*'

This would for example only report classes with more than 500 lines and require that all method names start with a lower case letter.

You can get a list of the enabled checks and their configurations by running:

excellent --checks

You can also place a .excellent.yml file in your home directory that contains default settings you always want to apply. Settings in project-specific configuration files will override these default settings.

Excellent now also supports ignore paths. Simple place a .excellentignore file in the root directory of your project and these directories will be ignored, e.g.:

vendor
some/specific/file.rb

Static analysis

A few words regarding static code analysis: Static code analysis tools like Excellent can never really understand the code. They just search for patterns that might inidicate problematic code. The word might really has to be stressed here since static analysis will usually return a reasonable number of false positives. For example, there might be pretty good reasons for empty +rescue+ blocks that suppress all errors (Excellent itself does it). So, don't try and code with the aim of passing Excellent with zero warnings. That will most likely make your code a mess. Instead use Excellent as a helper to find potentially problematic code early.

Author

Copyright (c) 2009-2018 simplabs GmbH (http://simplabs.com) and contributors, released under the MIT license.

Excellent was inspired by roodi (https://github.com/martinjandrews/roodi), reek (https://github.com/troessner/reek) and flog (https://github.com/seattlerb/flog).

excellent's People

Contributors

geekygrappler avatar marcoow avatar trans 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

excellent's Issues

Allow subdirectory configuration to override project toplevel configuration

E.g., I was almost able to exclude src/ruboto/ from being scanned by excellent, by writing tons of false rules in src/ruboto/.excellent.yml. However, excellent does not seem to be loading this file as it prepares to scan src/ruboto/. Instead, it seems that excellent only loads the project toplevel .excellent.yml.

HTML Output is not working

I was attempting to run excellent on my whole app and capture the output in an HTML file. I tried the following:

  1. excellent -o excellent_out.html . - did not work
  2. excellent -o public/excellent_out.html . - did not work
  3. excellent -o public/excellent_out.html ./ - did not work

Then I cd'd up a level and tried:

  1. excellent -o excellent_out.html app_directory/ - did not work

Am I missing something? Any help would be greatly appreciated!

Rake task causes crashes

I have a set of Rake tasks on my project already.

I add Excellent; it works called directly as './bin/excellent'

I add lib/tasks/excellent.rake with the Rake task defined in the project README; it works.

However, when I try to run OTHER Rake tasks I now get this:

rake aborted!
undefined method `initializers' for #<Instance:0x937ca68 @delegate=:all>

Tasks: TOP => db:migrate => environment
(See full trace by running task with --trace)

The minimum task definition needed for excellent to cause other tasks to crash is this task:

  require 'simplabs/excellent/rake'

refactor warnings etc.

To be able to cleanly produce statistics besides the mere warnings, I think it would make sense to refactor the warnings so that FileInfo (or whatever they may be called) objects are returned by the runner, which have a list of warnings as well as a list of stats (line count etc.) These descriptors would then be passed to the formatters.

switch to sydparse?

It could make sense to switch to sydparse (http://gemcutter.org/search?query=sydparse&commit=Search).

sydparse is the parser used by rubinius. I assume that sydparse will or already does support Ruby 1.9 since Rubinius of coruse wants to support 1.9 syntax. It's (for the most part) implemented in C, so it will be significantly faster than ruby_parser. The big question is how much refactoring would be neccessary to make Excellent work with sydparse.

The Numbers

Looks like all output is threshold based. It would be nice if there were also a way to get a report of the actual numbers.

I was about to release my own basic loc (lines of code) project when I discovered Excellent. Rather the release yet another narrow ruby metrics gem, I'd much rather contribute my work to Excellent. I don't see any overall loc check in Excellent now. I could make it so the threshold would be reasonable ratios between lines of comments, lines of code and (where possible) lines of test code.

Also I'd love to add a charting capability to the html formatter. Bar graphs could be used for most metrics, and other figures, like sloc figures, make for great pie charts. Beyond that, maybe history graphs like metric_fu has which can graph changes over time, which is pretty cool.

So if you don't mind I would like to contribute to the project.

BTW, it's very nice to see such well written code.

warning when redefining `!` method name

If you redefine the ! (not) method you get a warning. I think in most cases redefining ! is proberbly a mistake and quoting the README "Instead use Excellent as a helper to find possibly problematic code early". So maybe this isn't an issue, but I wanted to flag it up in case you have a different feeling.

Here is where I redefine !, in a null object used in replacement of nil:

class NullObject <  BasicObject
  def !; true; end
end

crash when doing mass assignment for block parameter

When running excellent on the following code

{
  a: 1,
  b: 2,
  c: 3
}.inject(0) do |sum, (key, value)|
  sum += value
end

excellent crashes with the following error.

simplabs/excellent/parsing/code_processor.rb:96:in `process_masgn': undefined method `each' for "ey":String (NoMethodError)

The line 96 is in process_masgn

def process_masgn(exp)
  exp[1][1..-1].each { |parameter| @contexts.last.parameters << parameter[1] if parameter[1].is_a?(Symbol) } if @contexts.last.is_a?(BlockContext)
  process_default(exp)
end

I'm using Ruby 1.9. However, String is no more an Enumerable in 1.9 and then each cannot be called on it. I'm not sure if exp is always a String, but if it is, we can fix the bug by calling first bytes

exp[1][1..-1].bytes.each { ... }

Debug checks and parser

Some checks produce invalid output (e.g. reporting global vars that are actually methods or reporting bad module names for functions etc.)

~/.excellent.yml

Could excellent look for ~/.excellent.yml when ./.excellent.yml does not exist? This makes it easier to set a configuration for lots of projects at once.

Excellent should specify its deps properly

dbenamy@ubuntu:~$ gem install excellent
Fetching: sexp_processor-4.0.1.gem (100%)
Fetching: ruby_parser-2.3.1.gem (100%)
ERROR:  Error installing excellent:
        ruby_parser requires sexp_processor (~> 3.0, runtime)


dbenamy@ubuntu:~$ gem install sexp_processor -v '=3.0'
Fetching: sexp_processor-3.0.0.gem (100%)
Successfully installed sexp_processor-3.0.0
1 gem installed
Installing ri documentation for sexp_processor-3.0.0...
Installing RDoc documentation for sexp_processor-3.0.0...


dbenamy@ubuntu:~$ gem install excellent
Fetching: facets-2.9.3.gem (100%)
Fetching: excellent-1.5.4.gem (100%)
Successfully installed ruby_parser-2.3.1
Successfully installed facets-2.9.3
Successfully installed excellent-1.5.4
3 gems installed
Installing ri documentation for ruby_parser-2.3.1...
Installing ri documentation for facets-2.9.3...
Installing ri documentation for excellent-1.5.4...
Installing RDoc documentation for ruby_parser-2.3.1...
Installing RDoc documentation for facets-2.9.3...
Installing RDoc documentation for excellent-1.5.4...


dbenamy@ubuntu:~$ excellent lib/company_requestor.rb
/home/dbenamy/.rvm/gems/ree-1.8.7-2012.02/gems/ruby_parser-2.3.1/lib/ruby_parser_extras.rb:1026: undefined method `sexp_type' for class `Sexp' (NameError)
        from /home/dbenamy/.rvm/rubies/ree-1.8.7-2012.02/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `gem_original_require'
        from /home/dbenamy/.rvm/rubies/ree-1.8.7-2012.02/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `require'
        from /home/dbenamy/.rvm/gems/ree-1.8.7-2012.02/gems/ruby_parser-2.3.1/lib/ruby_parser.rb:12
        from /home/dbenamy/.rvm/rubies/ree-1.8.7-2012.02/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `gem_original_require'
        from /home/dbenamy/.rvm/rubies/ree-1.8.7-2012.02/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `require'
        from /home/dbenamy/.rvm/gems/ree-1.8.7-2012.02/gems/excellent-1.5.4/lib/simplabs/excellent/parsing/parser.rb:2
        from /home/dbenamy/.rvm/rubies/ree-1.8.7-2012.02/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `gem_original_require'
        from /home/dbenamy/.rvm/rubies/ree-1.8.7-2012.02/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `require'
        from /home/dbenamy/.rvm/gems/ree-1.8.7-2012.02/gems/excellent-1.5.4/lib/simplabs/excellent/runner.rb:3
        from /home/dbenamy/.rvm/rubies/ree-1.8.7-2012.02/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `gem_original_require'
        from /home/dbenamy/.rvm/rubies/ree-1.8.7-2012.02/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `require'
        from /home/dbenamy/.rvm/gems/ree-1.8.7-2012.02/gems/excellent-1.5.4/lib/simplabs/excellent.rb:4
        from /home/dbenamy/.rvm/rubies/ree-1.8.7-2012.02/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `gem_original_require'
        from /home/dbenamy/.rvm/rubies/ree-1.8.7-2012.02/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `require'
        from /home/dbenamy/.rvm/gems/ree-1.8.7-2012.02/gems/excellent-1.5.4/bin/excellent:5
        from /home/dbenamy/.rvm/gems/ree-1.8.7-2012.02/bin/excellent:19:in `load'
        from /home/dbenamy/.rvm/gems/ree-1.8.7-2012.02/bin/excellent:19

Let me know if I can provide any other info that would help.

"Global variable ! used"

When I run Excellent it complains about the following:
app/controllers/application_controller.rb
* Line 69: Global variable ! used.

But what does that mean? The lines around 69 in that files look like this:
around_filter :catch_response
#(....)
def catch_response
begin
yield
rescue Response::ResponseException=> ex
render_response(ex.resp)
end #LINE 69
end

Add configuration files

Configuration files should be added that let the user control which checks to apply for which elements. Maybe that should be similar to the way reek does it.

Look over which tests are executed by default

Maybe the complexity checks should not be executed by default since they produce tons of output that is usually of little help. Maybe other checks should be excluded from the list of default checks too

Make HTML output nicer

It would be really cool to see the offending code fore each warning. Highlighting that code would also be very cool.

add highlighted source to the HTML formatter

The HTML formatter should display highlighted source code for the warnings (maybe 5 lines before and 5 lines after the finding with the actual line that containts the finding highlighted in a special way); see a387715

Mark false positives

I think it would be great, if programmers mark specific lines of code to exclude from the check. So they can at e.g. "# excellent:ignore" to a method to skip flog test or to a model to skip validation check.
Of course, everybody has to check for himself, if he use this to "make the checker silent", but also it provides the possibility to reach zero warnings. For example checkstyle in the java world does this, too.

Warning.check no more filled

Since the support of config files, the check field is no more filled when adding a warning.

This was handy

  • to know which check you want to disable or modify the threshold/config
  • to "compare" evolution between two raw reports (eg flog score gets better)

Note that the template message doesn't help has it gets gsub! and message and message_template are than equal.

Error at /lib/simplabs/excellent/parsing/conditional_context.rb:15

After running:

excellent app/

I received the following error after analyzing most (all?) of the files successfully, I get the following error:

app/controllers/application_controller.rb
* Line 182: Global variable ! used.
/usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/conditional_context.rb:15:in contains_parameter?': undefined method[]' for nil:NilClass (NoMethodError)
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/case_context.rb:14:in initialize' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:113:innew'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:113:in process_case' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:218:inblock (2 levels) in process'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:275:in error_handler' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:217:inblock in process'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:340:in in_context' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:194:inprocess'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:39:in process' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:138:inblock in process_default'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:138:in each' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:138:inprocess_default'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:218:in block (2 levels) in process' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:275:inerror_handler'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:217:in block in process' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:340:inin_context'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:194:in process' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:39:inprocess'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:138:in block in process_default' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:138:ineach'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:138:in process_default' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:218:inblock (2 levels) in process'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:275:in error_handler' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:217:inblock in process'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:340:in in_context' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:194:inprocess'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:39:in process' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:138:inblock in process_default'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:138:in each' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:138:inprocess_default'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:51:in process_defn' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:218:inblock (2 levels) in process'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:275:in error_handler' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:217:inblock in process'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:340:in in_context' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:194:inprocess'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:39:in process' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:138:inblock in process_default'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:138:in each' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:138:inprocess_default'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:43:in process_class' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:218:inblock (2 levels) in process'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:275:in error_handler' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:217:inblock in process'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:340:in in_context' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/sexp_processor-4.2.1/lib/sexp_processor.rb:194:inprocess'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/parsing/code_processor.rb:39:in process' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/runner.rb:59:incheck'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/runner.rb:77:in check_file' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/runner.rb:89:inblock in check_paths'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/runner.rb:88:in each' from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/lib/simplabs/excellent/runner.rb:88:incheck_paths'
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/excellent-1.7.1/bin/excellent:50:in <top (required)>' from /usr/local/rvm/gems/ruby-1.9.3-p392/bin/excellent:19:inload'
from /usr/local/rvm/gems/ruby-1.9.3-p392/bin/excellent:19:in <main>' from /usr/local/rvm/gems/ruby-1.9.3-p392/bin/ruby_noexec_wrapper:14:ineval'
from /usr/local/rvm/gems/ruby-1.9.3-p392/bin/ruby_noexec_wrapper:14:in `

'

Let me know if I can provide any additional information. Thanks for the gem!

After upgrading to Excellent 1.7.0, Excellent stops reporting issues.

On a particular app we have, Excellent 1.6.0 spits out piles of issues, while Excellent 1.7.0 does nothing. This is on a Mac with Ruby 2.0.

$ gem list excellent

*** LOCAL GEMS ***

excellent (1.7.0, 1.6.0)
$ excellent .

  Excellent result:

  Found 0 warnings.

$ gem uninstall excellent -v 1.7.0
Successfully uninstalled excellent-1.7.0
$ excellent .

  Excellent result:

  ./app/controllers/projects_controller.rb
    * Line  20: Global variable ! used.
    * Line  27: Global variable ! used.
    * Line  39: Global variable ! used.
    * Line  53: Global variable ! used.

[etc...]

$ excellent . | wc
      96     368    3323
$ gem update excellent
Updating installed gems
Updating excellent
Fetching: excellent-1.7.0.gem (100%)
Successfully installed excellent-1.7.0
Parsing documentation for excellent-1.7.0
Installing ri documentation for excellent-1.7.0
Installing darkfish documentation for excellent-1.7.0
Done installing documentation for excellent after 2 seconds
Gems updated: excellent
$ excellent .

  Excellent result:

  Found 0 warnings.

$ ruby --version
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin12.3.0]

Rule Request: UnnecessaryShellCommand

As an engineer, I want to be warned early when my application code is trying to shell out for things that libraries already provide, such as:

  • curl/wget (Can probably use a URL request)
  • sed/awk/gawk/nawk (Can just use a regular expression)
  • jq (Can use a JSON marshaller)

This rule would encourage more performant applications, remove dependencies on unnecessary software components, reduce attack surfaces, and increase cross-platform support, by avoiding relying on platform-specific shell command syntax.

Example triggers:

  • Supplying a process object with a launch path ending with curl, wget, sed, awk, jq, jq.exe, etc.

Example non-triggers:

  • Supplying a process object with an argument of curl, wget, sed, awk, jq, jq.exe, etc. While there are plenty of cases where these would constitute unnecessary shell commands, such as /usr/bin/env curl... or exec wget..., the false positives for such commands are unfortunately more numerous than the true positives.

This rule should contain a limited number of common shell commands, such as those listed above. We can add more over time. Configuration for this rule should be able to customize which of these command patterns is relevant to the user's application needs.

As a security concern, this rule can reasonably become a default rule, as shelling out introduces additional security risks, including shell injections, compared to sticking to pure library code.

I would be happy to see this rule be included in excellent's available suite of checks, and if we find we're happy to apply it in a lot of places, then we can always turn it on by default later.

Add more formatters

more formatters should be added (HTML etc). There should also be a documented API for custom formatters.

Model checks complain about inherited `initialize` methods

Running Excellent over my Rails models yields the following results:

  app/models/source.rb
    * Line   1: Source defines initialize method.

  app/models/thing.rb
    * Line   1: Thing defines initialize method.

  app/models/tweet.rb
    * Line   1: Tweet defines initialize method.

These models are plain vanilla ActiveRecord::Base decendants. They don't have their own initialize methods.

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.