Class: RStyle

Inherits:
Object
  • Object
show all
Defined in:
lib/rstyle.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ RStyle

Returns a new instance of RStyle.



20
21
22
23
24
25
# File 'lib/rstyle.rb', line 20

def initialize(options)
  @options = parse_options(options)
  @errors = 0
  @warnings = 0
  @skip = nil
end

Instance Attribute Details

#errorsObject (readonly)

Returns the value of attribute errors.



18
19
20
# File 'lib/rstyle.rb', line 18

def errors
  @errors
end

#line_countObject (readonly)

Returns the value of attribute line_count.



18
19
20
# File 'lib/rstyle.rb', line 18

def line_count
  @line_count
end

#warningsObject (readonly)

Returns the value of attribute warnings.



18
19
20
# File 'lib/rstyle.rb', line 18

def warnings
  @warnings
end

Instance Method Details

#parse(lines) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/rstyle.rb', line 65

def parse(lines)
  @line_count = 0
  lines.each_with_index do |line, i|
    @oline = @line = line
    @line_count += 1

    # strip out text from strings
    # TODO include other forms of strings
    @line = @line.gsub(/"([^"]+)"/, "\"\"")

    # strip out text from regexps
    # TODO include other regexps
    @line = @line.gsub(/\/([^\/]+)\//, "//")

    max_len = @options[:line_length]
    begin
      if @oline.length > max_len
        error "line longer than #{max_len} characters (#{@oline.length})"
      end

      check :empty_line, "empty line contains whitespace", /^\s+$/

      check :tabs, "line contains tab(s)", /\t/

      check :ends_with_whitespace, "line ends with whitespace", /\S+\s+$/

      # skip all check below if in a comment
      next  if @line =~ /^\s*#/

      check :no_space_after_comma, "no space after ,", /,\S+/

      check :space_after, "space after ( and [ or before ) and ]",
            /[\(\[]\s+|\s+[\)\]]/

      check :two_spaces, "use two spaces before statement modifiers",
            /\S+( | {3,})(if|unless|until|rescue|while)/

      check(:snake_case, /\s*def (\S+)/) do |method|
        error "methods should be in snake_case"  if method =~ /[A-Z]/
      end

      check(:no_for, /^\s*for/) do
        warning "don't use for unless you know what you are doing"
      end
    ensure
      if @line =~ /^\s*#\s*RSTYLE:\s*(.+)$/
        @skip = $1.to_sym
      else
        @skip = nil
      end
    end

  end
end

#parse_options(options) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/rstyle.rb', line 27

def parse_options(options)
  Trollop::options(options) do
    opt :all, "enable all options"
    opt :empty_line, "empty lines"
    opt :tabs, "line contains tab(s)"
    opt :ends_with_whitespace, "line ends with whitespace"
    opt :no_space_after_comma, "no space after ','"
    opt :space_after, "space after ( and [ or before ) and ]"
    opt :two_spaces, "use two spaces before statement modifiers"
    opt :snake_case, "methods should be in snake_case"
    opt :no_for, "don't use for unless you know what you are doing"
    opt :line_length, "line length", :default => 80
  end
end

#read_file(file) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/rstyle.rb', line 52

def read_file(file)
  @file = file
  File.open(file) do |f|
    lines = []
    begin
      while lines << f.readline.chomp; end
    rescue EOFError
      # do nothing, it is expected
    end
    parse(lines)
  end
end

#source(files) ⇒ Object



42
43
44
45
46
47
48
49
50
# File 'lib/rstyle.rb', line 42

def source(files)
  files.each do |file|
    if File.directory?(file)
      source Dir.glob("#{file}/**/*.rb")
    elsif file =~ /\.rb/
      read_file(file)
    end
  end
end