Class: Stellwerk::Rules::Layers

Inherits:
Object
  • Object
show all
Defined in:
lib/stellwerk/rules/layers.rb

Defined Under Namespace

Classes: InvalidLayersSpec

Instance Method Summary collapse

Constructor Details

#initialize(rule_spec) ⇒ Layers

Returns a new instance of Layers.



10
11
12
13
# File 'lib/stellwerk/rules/layers.rb', line 10

def initialize(rule_spec)
  @layers = rule_spec.map { |layer| Array(layer).map { |path_string| Pathname.new(path_string) } }
  validate_layers!
end

Instance Method Details

#all_componentsObject



34
35
36
# File 'lib/stellwerk/rules/layers.rb', line 34

def all_components
  @layers.flatten
end

#filter_graph(reference_graph) ⇒ Object



27
28
29
30
31
32
# File 'lib/stellwerk/rules/layers.rb', line 27

def filter_graph(reference_graph)
  reference_graph.select do |reference|
    all_components.any? { |component| path_in_component?(reference.relative_path, component) } &&
      all_components.any? { |component| path_in_component?(reference.constant.location, component) }
  end
end

#find_violations(reference_graph) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/stellwerk/rules/layers.rb', line 15

def find_violations(reference_graph)
  relevant_graph = filter_graph(reference_graph)

  relevant_graph.map do |reference|
    # TO DO: violations should include some rule specific violation context
    # e.g. from layer and to layer
    if layer_index(reference.relative_path) > layer_index(reference.constant.location)
      Violation.new(:layers, reference)
    end
  end.compact
end

#layer_index(file_path) ⇒ Object



45
46
47
48
49
# File 'lib/stellwerk/rules/layers.rb', line 45

def layer_index(file_path)
  @layers.index do |components|
    components.any? { |component| path_in_component?(file_path, component) }
  end
end

#path_in_component?(path, component) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
41
42
43
# File 'lib/stellwerk/rules/layers.rb', line 38

def path_in_component?(path, component)
  # TO DO: Find out whether we can use Pathname methods to determine whether one path contains another
  component_dirname = component.to_s
  component_dirname += "/" unless component.to_s.end_with?("/")
  path.to_s.start_with?(component_dirname)
end

#validate_layers!Object

Raises:



51
52
53
54
55
# File 'lib/stellwerk/rules/layers.rb', line 51

def validate_layers!
  raise InvalidLayersSpec, "Overlapping layers" if all_components.count != all_components.uniq.count
  raise InvalidLayersSpec, "No layers exist" if @layers.empty?
  raise InvalidLayersSpec, "Empty layers exist" if @layers.any?(&:empty?)
end