Class: Archimate::Lint::Linter
- Inherits:
-
Object
- Object
- Archimate::Lint::Linter
- Defined in:
- lib/archimate/lint/linter.rb
Overview
lint notes
- x
-
Unused element (not used in a view)
- x
-
Unused relation (not used in a view)
- x
-
Object in a Viewpoint (invalid object for viewpoint)
- x
-
Duplicate same name for type
- x
-
empty view
- ?
-
visual nesting without relationship
-
Warn about sketch model
- x
-
warn about names with (copy)
- x
-
blank element names
Instance Attribute Summary collapse
-
#model ⇒ Object
readonly
Returns the value of attribute model.
Instance Method Summary collapse
- #duplicate_elements ⇒ Object
- #duplicate_relationships ⇒ Object
- #duplicates(array, group_by_proc) ⇒ Object
- #empty_views ⇒ Object
- #entity_naming_rules ⇒ Object
- #format_issue(issue) ⇒ Object
-
#initialize(model) ⇒ Linter
constructor
A new instance of Linter.
- #invalid_for_viewpoint ⇒ Object
- #name_for_comparison(name) ⇒ Object
- #nesting_without_relation ⇒ Object
-
#report(output_io) ⇒ Object
TODO: consider a means to sort lint issues by entity instead of lint category this would point out the particularly problematic items that could be dealt with appropriately.
- #report_subsection(issues, output_io) ⇒ Object
- #unused_elements ⇒ Object
- #unused_relationships ⇒ Object
Constructor Details
#initialize(model) ⇒ Linter
Returns a new instance of Linter.
18 19 20 21 |
# File 'lib/archimate/lint/linter.rb', line 18 def initialize(model) @model = model @indent = "\n" + " " * 8 end |
Instance Attribute Details
#model ⇒ Object (readonly)
Returns the value of attribute model.
16 17 18 |
# File 'lib/archimate/lint/linter.rb', line 16 def model @model end |
Instance Method Details
#duplicate_elements ⇒ Object
69 70 71 |
# File 'lib/archimate/lint/linter.rb', line 69 def duplicate_elements duplicates(model.elements, ->(el) { [el.type, name_for_comparison(el.name)] }) end |
#duplicate_relationships ⇒ Object
73 74 75 |
# File 'lib/archimate/lint/linter.rb', line 73 def duplicate_relationships duplicates(model.relationships, ->(el) { [el.type, el.source, el.target, name_for_comparison(el.name)] }) end |
#duplicates(array, group_by_proc) ⇒ Object
81 82 83 84 85 86 87 |
# File 'lib/archimate/lint/linter.rb', line 81 def duplicates(array, group_by_proc) array .group_by { |el| group_by_proc.call(el) } .each_with_object([]) do |(_key, ary), dupes| dupes << ary.map(&:to_s) if ary.size > 1 end end |
#empty_views ⇒ Object
65 66 67 |
# File 'lib/archimate/lint/linter.rb', line 65 def empty_views model.diagrams.select { |diagram| diagram.nodes.empty? } end |
#entity_naming_rules ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/archimate/lint/linter.rb', line 128 def entity_naming_rules model.elements.each_with_object([]) do |entity, errors| if entity.name.nil? || entity.name.empty? errors << "#{entity} name is empty" elsif entity.name.size < 2 errors << "#{entity} name #{entity.name} is too short" elsif entity.name.include?("(copy)") errors << "#{entity} name #{entity.name} contains '(copy)'" end end end |
#format_issue(issue) ⇒ Object
42 43 44 45 46 |
# File 'lib/archimate/lint/linter.rb', line 42 def format_issue(issue) ary = Array(issue) return issue if ary.size == 1 "#{@indent}#{ary.join(@indent)}" end |
#invalid_for_viewpoint ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/archimate/lint/linter.rb', line 89 def invalid_for_viewpoint model.diagrams.each_with_object([]) do |diagram, errors| next if diagram.total_viewpoint? valid_entity_types = diagram.viewpoint&.allowed_element_types || DataModel::Elements.classes valid_relation_types = diagram.viewpoint&.allowed_relationship_types || DataModel::Relationships.classes invalid_elements = diagram.all_nodes.reject do |child| child.element.nil? || valid_entity_types.include?(child.element.class) end invalid_relations = diagram.connections.reject do |sc| sc.element.nil? || valid_relation_types.include?(sc.element.class) end next unless !invalid_elements.empty? || !invalid_relations.empty? errors << format( "%s viewpoint %s#{@indent}%s", diagram, diagram.viewpoint, (invalid_elements + invalid_relations).map(&:element).map(&:to_s).join(@indent) ) end end |
#name_for_comparison(name) ⇒ Object
77 78 79 |
# File 'lib/archimate/lint/linter.rb', line 77 def name_for_comparison(name) name&.strip&.downcase end |
#nesting_without_relation ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/archimate/lint/linter.rb', line 110 def nesting_without_relation model .diagrams .flat_map(&:all_nodes) # These are top level view nodes .reject { |view_node| !view_node.element || view_node.nodes.empty? } # reject the ones with no child view nodes .flat_map { |parent| parent .nodes .select(&:element) .map { |child| [parent, child] } } # map into parent-child pairs for children that are elements .select { |pair| model.relationships.none? { |rel| (rel.source.equal?(pair[0]) && rel.target.equal?(pair[1])) } } .map { |pair| "#{pair[1].element} should not nest in #{pair[0].element} without valid relationship"} end |
#report(output_io) ⇒ Object
TODO: consider a means to sort lint issues by entity instead of lint category
this would point out the particularly problematic items that could be
dealt with appropriately.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/archimate/lint/linter.rb', line 26 def report(output_io) [ [unused_elements, "Unused Element"], [duplicate_elements, "Duplicate Items"], [entity_naming_rules, "Naming Rules"], [unused_relationships, "Unused Relationship"], [duplicate_relationships, "Duplicate Relationships"], [empty_views, "Empty View"], [invalid_for_viewpoint, "Invalid Type for Viewpoint"], [nesting_without_relation, "Visual Nesting"] ] .map { |issues, title| issues.map { |issue| "#{title}: #{format_issue(issue)}" } } .tap { |issues| report_subsection(issues, output_io) } .tap { |issues| output_io.puts("Total Issues: #{issues.flatten.size}") } end |
#report_subsection(issues, output_io) ⇒ Object
48 49 50 51 52 53 |
# File 'lib/archimate/lint/linter.rb', line 48 def report_subsection(issues, output_io) issues.each do |sub_issues| output_io.puts(sub_issues) output_io.puts("Sub Total: #{sub_issues.size}") unless sub_issues.empty? end end |
#unused_elements ⇒ Object
55 56 57 58 |
# File 'lib/archimate/lint/linter.rb', line 55 def unused_elements referenced_elements = model.diagrams.inject([]) { |memo, dia| memo.concat(dia.elements) }.uniq model.elements.reject { |el| referenced_elements.include?(el) } end |
#unused_relationships ⇒ Object
60 61 62 63 |
# File 'lib/archimate/lint/linter.rb', line 60 def unused_relationships referenced_relationships = model.diagrams.inject([]) { |memo, dia| memo.concat(dia.relationships) }.uniq model.relationships.reject { |el| referenced_relationships.include?(el) } end |