Foodcritic / foodcritic

Lint tool for Chef cookbooks.
http://foodcritic.io
MIT License
407 stars 153 forks source link

Crash with `'block_depth': undefined method `size' for nil:NilClass (NoMethodError)` #661

Open chilicheech opened 7 years ago

chilicheech commented 7 years ago

When I run foodcritic against my cookbook it crashes with the following:

$ foodcritic . --tags ~FC071 --tags ~opensource
Checking 145 files
..................................................................................................../opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/api.rb:449:in `block_depth': undefined method `size' for nil:NilClass (NoMethodError)
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/api.rb:520:in `block (2 levels) in normal_attributes'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/nokogiri-1.8.0/lib/nokogiri/xml/node_set.rb:190:in `block in each'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/nokogiri-1.8.0/lib/nokogiri/xml/node_set.rb:189:in `upto'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/nokogiri-1.8.0/lib/nokogiri/xml/node_set.rb:189:in `each'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/api.rb:520:in `any?'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/api.rb:520:in `block in normal_attributes'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/nokogiri-1.8.0/lib/nokogiri/xml/node_set.rb:190:in `block in each'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/nokogiri-1.8.0/lib/nokogiri/xml/node_set.rb:189:in `upto'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/nokogiri-1.8.0/lib/nokogiri/xml/node_set.rb:189:in `each'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/api.rb:518:in `normal_attributes'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/api.rb:274:in `resource_attributes'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/rules/fc038.rb:5:in `block (4 levels) in load'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/nokogiri-1.8.0/lib/nokogiri/xml/node_set.rb:190:in `block in each'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/nokogiri-1.8.0/lib/nokogiri/xml/node_set.rb:189:in `upto'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/nokogiri-1.8.0/lib/nokogiri/xml/node_set.rb:189:in `each'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/rules/fc038.rb:4:in `select'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/rules/fc038.rb:4:in `block (3 levels) in load'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/linter.rb:280:in `matches'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/linter.rb:131:in `cookbook_matches'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/linter.rb:102:in `block (2 levels) in check'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/linter.rb:92:in `each'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/linter.rb:92:in `block in check'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/linter.rb:83:in `each'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/linter.rb:83:in `check'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/linter.rb:28:in `run'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/lib/foodcritic/command_line.rb:6:in `main'
    from /opt/chefdk/embedded/lib/ruby/gems/2.4.0/gems/foodcritic-11.3.0/bin/foodcritic:3:in `<top (required)>'
    from /opt/chefdk/bin/foodcritic:263:in `load'
    from /opt/chefdk/bin/foodcritic:263:in `<main>'

Per those logs it would seem it's related to fc038 but I don't have any actions set to :none. Is there a way for me to increase verbosity so I can tell exactly where in the cookbook it's failing?

Here's what I'm running on:

$ chef --version
Chef Development Kit Version: 2.0.28
chef-client version: 13.2.20
delivery version: master (17c1b0fed9be4c70f69091a6d21a4cbf0df60a23)
berks version: 6.2.0
kitchen version: 1.16.0
inspec version: 1.31.1
$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.1 (Maipo)
coderanger commented 7 years ago

Please include the source file which triggers this.

chilicheech commented 7 years ago

How do I find out what source file is causing it? I'm running it against a whole cookbook with several files.

coderanger commented 7 years ago

Just start rm-ing files (checkpoint in source control first of course :) until it stops happening.

chilicheech commented 7 years ago

OK, I found where it's happening. There is a typo in the code:

service 'my_service' do
  action [:enable, :start])
end

execute 'first blah' do
  only_if { am_i_awesome? }
end

execute 'second blah' do
end

Notice the closing parens at the end of the action property of the service resource. That's a typo. However, if I remove any of the execute resources foodcritic works. Also, if I remove the only_if from the first execute resource it also works.

It would be really awesome if foodcritic would tell me what line of what file caused it to crash. I suppose we should run rubocop/cookstyle first before running foodcritic because it is able to report that there's an unexpected parenthesis.

coderanger commented 7 years ago

Thanky, will try to repro in a test. We mostly rely on ripper et al to tell us if syntax is bad, and it sounds like that part of the code is at least producing some kind of AST so the best we can probably do is make FC not completely explode and let Rubocop/Cookstyle tell you about the syntax issue.