The missing static analysis framework.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
bin
lib
spec
.gitignore
.rspec
.rubocop.yml
.travis.yml
CODE_OF_CONDUCT.md
Gemfile
Gemfile.lock
LICENSE.txt
README.md
Rakefile
spotless.gemspec

README.md

Spotless

Welcome! This is Spotless, the missing static analysis framework.

Installation

Add this line to your application's Gemfile:

gem 'spotless'

And then execute:

$ bundle

Or install it yourself as:

$ gem install spotless

Usage

There are three parts to a Spotless application: parsers, checks and linters. In this section we'll see how to use them to create a simple static analysis tool that ensures our JSON uses camelcase property names only.

Parsers

The parser is what deconstructs a file (or collection of files) into a tree the checks can understand. Parsers can use whatever approach they want: some of them might be very simple while others can get extremely complex (think about Rubocop or similar).

Let's try to build a simple JSON parser:

module JsonAnalyzer
  class Parser < Spotless::Parser
    def build_from_content(content)
      JSON.parse(content)
    end
  end
end

Checks

The checks take the tree created by the parser as input and analyze it for known problems, registering offenses when they encounter them.

We're only going to build one check for our sample app, which ensures all property names at the root level are camelcase:

module JsonAnalyzer
  module Checks
    class PropertyName < Spotless::Check
      ALLOWED_FORMAT = /\A([a-zA-Z0-9]+)\z/

      def run(tree)
        offenses = []

        tree.each_key do |key|
          offenses << "'#{key}' should be camelCase." unless key =~ ALLOWED_FORMAT
        end

        offenses
      end
    end
  end
end

Linters

Finally, the linter is configured with a parser class, a collection of checks and one or more glob patterns that the file paths to analyze must match.

The linter puts everything together and allows you to simply specify the file or directory to lint, taking care of the rest.

module JsonAnalyzer
  class Linter < Spotless::Linter
    self.parser = Parser

    self.checks = [
      Checks::PropertyName,
    ]
    
    self.patterns = ['*.json']
  end
end

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/aldesantis/spotless. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the Spotless project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

Todo

  • Message formatting for check offenses
  • File and line number in offenses
  • Command line interface
  • Load check configuration from YAML