Rake::DevEiate::

Checks

module
Extended With
Rake::DSL

Sanity and quality check tasks

Constants

MIXED_INDENT_RE

Regexp to match lines with mixed indentation

SADFACE

Emoji for style advisories

TAB_ARROW

Tab-arrow character

TRAILING_WHITESPACE_RE

Regexp to match trailing whitespace

Attributes

quality_check_whitelist[R]

The Rake::FileList containing files which should not be quality-checked.

Public Instance Methods

anchor
define_quality_checker_tasks()

Set up tasks that check for poor whitespace discipline

# File lib/rake/deveiate/checks.rb, line 57
def define_quality_checker_tasks

        namespace :quality_checks do

                task :all => [ :whitespace ]

                desc "Check source code for inconsistent whitespace"
                task :whitespace => [
                        :for_trailing_whitespace,
                        :for_mixed_indentation,
                ]

                desc "Check source code for trailing whitespace"
                task :for_trailing_whitespace do
                        lines = find_matching_source_lines do |line, _|
                                line =~ TRAILING_WHITESPACE_RE
                        end

                        unless lines.empty?
                                desc = "Found some trailing whitespace"
                                describe_lines_that_need_fixing( desc, lines, TRAILING_WHITESPACE_RE )
                                fail
                        end
                end

                desc "Check source code for mixed indentation"
                task :for_mixed_indentation do
                        lines = find_matching_source_lines do |line, _|
                                line =~ MIXED_INDENT_RE
                        end

                        unless lines.empty?
                                desc = "Found mixed indentation"
                                describe_lines_that_need_fixing( desc, lines, /[ ]\t/ )
                                fail
                        end
                end

        end

end
anchor
define_sanity_checker_tasks()

Set up some sanity-checks as dependencies of higher-level tasks

# File lib/rake/deveiate/checks.rb, line 101
def define_sanity_checker_tasks

        namespace :sanity_checks do

                desc "Check source code for common problems"
                task :all

        end

end
anchor
define_tasks()

Define check tasks

# File lib/rake/deveiate/checks.rb, line 39
def define_tasks
        super if defined?( super )

        self.define_quality_checker_tasks
        self.define_sanity_checker_tasks

        desc "Run several quality-checks on the code"
        task :quality_checks => [ 'quality_checks:all' ]

        desc "Run several sanity-checks on the code"
        task :sanity_checks => [ 'sanity_checks:all' ]

        task :check => [ :quality_checks, :sanity_checks ]

end
anchor
describe_lines_that_need_fixing( description, lines, re )

Output a listing of the specified lines with the given description, highlighting the characters matched by the specified re.

# File lib/rake/deveiate/checks.rb, line 140
def describe_lines_that_need_fixing( description, lines, re )
        self.prompt.say "\n"
        self.prompt.say SADFACE + "  "
        self.prompt.error( "Uh-oh! " + description )

        grouped_lines = group_line_matches( lines )

        grouped_lines.each do |filename, linegroups|
                linegroups.each do |group, lines|
                        if group.min == group.max
                                self.prompt.say( "%s:%d" % [ filename, group.min ], color: :bold )
                        else
                                self.prompt.say( "%s:%d-%d" % [ filename, group.min, group.max ], color: :bold )
                        end

                        lines.each_with_index do |line, i|
                                self.prompt.say "%s: %s" % [
                                        self.pastel.dark.white( group.to_a[i].to_s ),
                                        highlight_problems( line, re )
                                ]
                        end
                        self.prompt.say "\n"
                end
        end
end
anchor
find_matching_source_lines() { |line, previous_line| ... }

Return tuples of the form:

[ <filename>, <line number>, <line> ]

for every line in the Gemspec's source files for which the block returns true.

# File lib/rake/deveiate/checks.rb, line 119
def find_matching_source_lines
        matches = []

        source_files = self.project_files.grep( /\.(h|c|rb)$/ )
        source_files -= self.quality_check_whitelist

        source_files.each do |filename|
                previous_line = nil

                IO.foreach( filename ).with_index do |line, i|
                        matches << [filename, i + 1, line] if yield( line, previous_line )
                        previous_line = line
                end
        end

        return matches
end
anchor
group_line_matches( tuples )

Return a Hash, keyed by filename, whose values are tuples of Ranges and lines extracted from the given [filename, linenumber, line] tuples.

# File lib/rake/deveiate/checks.rb, line 169
def group_line_matches( tuples )
        by_file = tuples.group_by {|tuple| tuple.first }

        return by_file.each_with_object({}) do |(filename, lines), hash|
                last_linenum = 0
                linegroups = lines.slice_before do |filename, linenum|
                        gap = linenum > last_linenum + 1
                        last_linenum = linenum
                        gap
                end

                hash[ filename ] = linegroups.map do |group|
                        rng = group.first[1] .. group.last[1]
                        grouplines = group.transpose.last
                        [ rng, grouplines ]
                end
        end
end
anchor
highlight_problems( line, re )

Transform invisibles in the specified line into visible analogues.

# File lib/rake/deveiate/checks.rb, line 190
def highlight_problems( line, re )
        line.
                gsub( re )    { self.pastel.on_red( $& ) }.
                gsub( /\t+/ ) { self.pastel.dark.white( "#{TAB_ARROW}   " * $&.length ) }
end
anchor
setup( _name, **options )

Set up task defaults

# File lib/rake/deveiate/checks.rb, line 26
def setup( _name, **options )
        super if defined?( super )

        @quality_check_whitelist = Rake::FileList.new
end