Class: Cane::DocCheck

Inherits:
Struct
  • Object
show all
Defined in:
lib/cane/doc_check.rb

Overview

Creates violations for class definitions that do not have an explantory comment immediately preceding.

Constant Summary collapse

DESCRIPTION =
"Class definitions require explanatory comments on preceding line"
MAGIC_COMMENT_REGEX =

Stolen from ERB source, amended to be slightly stricter to work around some known false positives.

%r"#(\s+-\*-)?\s+(en)?coding\s*[=:]\s*([[:alnum:]\-_]+)"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#optsObject

Returns the value of attribute opts

Returns:

  • (Object)

    the current value of opts



8
9
10
# File 'lib/cane/doc_check.rb', line 8

def opts
  @opts
end

Class Method Details

.keyObject



13
# File 'lib/cane/doc_check.rb', line 13

def self.key; :doc; end

.nameObject



14
# File 'lib/cane/doc_check.rb', line 14

def self.name; "documentation checking"; end

.optionsObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/cane/doc_check.rb', line 15

def self.options
  {
    doc_glob:    ['Glob to run doc checks over',
                    default:  '{app,lib}/**/*.rb',
                    variable: 'GLOB',
                    clobber:  :no_doc],
    doc_exclude: ['Exclude file or glob from documentation checking',
                    variable: 'GLOB',
                    type: Array,
                    default: [],
                    clobber: :no_doc],
    no_readme:   ['Disable readme checking', cast: ->(x) { !x }],
    no_doc:      ['Disable documentation checking', cast: ->(x) { !x }]
  }
end

Instance Method Details

#class_definition?(line) ⇒ Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/cane/doc_check.rb', line 79

def class_definition?(line)
  line =~ /^\s*class\s+/ and $'.index('<<') != 0
end

#comment?(line) ⇒ Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/cane/doc_check.rb', line 83

def comment?(line)
  line =~ /^\s*#/ && !(MAGIC_COMMENT_REGEX =~ line)
end

#excluded?(file) ⇒ Boolean

Returns:

  • (Boolean)


97
98
99
# File 'lib/cane/doc_check.rb', line 97

def excluded?(file)
  exclusions.include?(file)
end

#exclusionsObject



91
92
93
94
95
# File 'lib/cane/doc_check.rb', line 91

def exclusions
  @exclusions ||= opts.fetch(:doc_exclude, []).flatten.map do |i|
    Dir[i]
  end.flatten.to_set
end

#extract_class_name(line) ⇒ Object



87
88
89
# File 'lib/cane/doc_check.rb', line 87

def extract_class_name(line)
  line.match(/class\s+([^\s;]+)/)[1]
end

#file_namesObject



75
76
77
# File 'lib/cane/doc_check.rb', line 75

def file_names
  Dir[opts.fetch(:doc_glob)].reject { |file| excluded?(file) }
end

#find_violations(file_name) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/cane/doc_check.rb', line 44

def find_violations(file_name)
  last_line = ""
  Cane::File.iterator(file_name).map.with_index do |line, number|
    result = if class_definition?(line) && !comment?(last_line)
      {
        file:        file_name,
        line:        number + 1,
        label:       extract_class_name(line),
        description: DESCRIPTION
      }
    end
    last_line = line
    result
  end.compact
end

#missing_file_violationsObject



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/cane/doc_check.rb', line 60

def missing_file_violations
  result = []
  return result if opts[:no_readme]

  filenames = ['README', 'readme']
  extensions = ['', '.txt', '.md']
  combinations = filenames.product(extensions)

  if combinations.none? {|n, x| Cane::File.exists?(n + x) }
    result << { description: 'Missing documentation',
                label: 'No README found' }
  end
  result
end

#violationsObject



36
37
38
39
40
41
42
# File 'lib/cane/doc_check.rb', line 36

def violations
  return [] if opts[:no_doc]

  missing_file_violations + worker.map(file_names) {|file_name|
    find_violations(file_name)
  }.flatten
end

#workerObject



101
102
103
# File 'lib/cane/doc_check.rb', line 101

def worker
  Cane.task_runner(opts)
end