[ruby-lint](https://github.com/YorickPeterse/ruby-lint) is a static code analysis tool for Ruby.
After I saw some stupid bugs caused by misremembering method or attribute names I tried it. It found those bugs but buried them in tons of false positives.
During the Cloud and Systems Management Department workshop in June 2016 I set out to find if there is a way to configure ruby-lint so that it is usable.
Found some (1) bugs in YaST. Found some (10) bugs in ruby-lint. It is not usable yet but I want to fix it.
## Lint statistics
I ran ruby-lint on some of our projects: YaST (and some of its dependencies) and Crowbar. This spreadsheet summarizes the number of reports ruby-lint produced. Nearly all of them are false positives, caused by bugs in ruby-lint listed below.
## Bugs in YaST found by ruby-lint
- [`y2milestone` was used instead of `Builtins.y2milestone`][yastbug].
## Bugs in ruby-lint
### Important bugs, fixed
- If there was a warning reported by the ruby parser itself (such as ambiguous syntax), ruby-lint would silently stop processing and produce a partial report.
[Do not stop parsing all files on a syntax warning][stopwarn177].
### Important bugs, not fixed yet
- To find information for a new class FooBar, ruby-lint ignores the `require` statements in analyzed code, instead autoloading files using the Rails convention: foo_bar.rb. This fails to find nearly all YaST classes.
Submitted a PR: [Explicit mapping of constants to files][const179].
- [Top level constant lookup does not work: `::File`][file180].
- ruby-lint checks whether performed calls correspond to defined APIs. To learn about the APIs it can either parse their code, or, especially for APIs implemented in C, it can load so called [definitions][definitions]. The gem ships many definitions for the standard library and some gems such as nokogiri.
But it only works if the namespaces described by the definition files are disjoint. That is a problem since we need `Yast` for yast2-ruby-bindings and `Yast::UI` for yast2-ycp-ui-bindings.
[Definitions for overlapping namespaces are not merged][mergedefs181].
- [Methods defined within `class << self` do not see each other][classself145].
### Other bugs, fixed
- [Make argument_amount report the method name][argamount172]
- [Sort reports consistently][sort176]
### Other bugs, not fixed yet
- Crash when a method argument has a slightly unusual value: an empty Regex `//`, an empty heredoc, or `yield`. This can be worked around by changing the code so I consider it less important.
[Not enough argument definitions][crashyield173].
- [Crash when referencing the 10th regex captured value `$10`][dollarten175].
- It reports "break can only be used inside a loop/block" when it sees a `break` in an outer loop after an inner loop has ended.
[loop_keywords is fooled by nested loops][nestedloop178].
[definitions]: http://code.yorickpeterse.com/ruby-lint/latest/file.definitions.html [classself145]: https://github.com/YorickPeterse/ruby-lint/issues/145 [argamount172]: https://github.com/YorickPeterse/ruby-lint/pull/172 [crashyield173]: https://github.com/YorickPeterse/ruby-lint/issues/173 [dollarten175]: https://github.com/YorickPeterse/ruby-lint/issues/175 [sort176]: https://github.com/YorickPeterse/ruby-lint/pull/176 [stopwarn177]: https://github.com/YorickPeterse/ruby-lint/pull/177 [nestedloop178]: https://github.com/YorickPeterse/ruby-lint/issues/178 [const179]: https://github.com/YorickPeterse/ruby-lint/pull/179 [file180]: https://github.com/YorickPeterse/ruby-lint/issues/180 [mergedefs181]: https://github.com/YorickPeterse/ruby-lint/issues/181 [yastbug]: https://github.com/yast/yast-yast2/pull/475