Module: ArchUnit::Common::Projection

Defined in:
lib/archunit/common/projection/project_edges.rb,
lib/archunit/common/projection/mapped_edge.rb,
lib/archunit/common/projection/project_cycles.rb,
lib/archunit/common/projection/projected_edge.rb,
lib/archunit/common/projection/projected_node.rb,
lib/archunit/common/projection/edge_projections.rb,
lib/archunit/common/projection/project_to_nodes.rb,
lib/archunit/common/projection/cycles/tarjan_scc.rb,
lib/archunit/common/projection/cycles/johnson_cycles.rb

Overview

Pure functions and immutable values for relabeling dependency graphs.

Defined Under Namespace

Modules: Cycles Classes: MappedEdge, ProjectedEdge, ProjectedNode

Class Method Summary collapse

Class Method Details

.cycles_from_paths(paths, edges_by_ids) ⇒ Object



26
27
28
29
30
31
32
33
34
# File 'lib/archunit/common/projection/project_cycles.rb', line 26

def cycles_from_paths(paths, edges_by_ids)
  paths.map do |path|
    path.each_index.map do |index|
      source = path.fetch(index)
      target = path.fetch((index + 1) % path.length)
      edges_by_ids.fetch([source, target])
    end.freeze
  end.freeze
end

.identityObject

Maps an edge without filtering, including source-file self-edges.



40
41
42
# File 'lib/archunit/common/projection/edge_projections.rb', line 40

def identity
  ->(edge) { map_identity(edge) }
end

.per_edgeObject

Maps every non-self edge without changing its labels.



12
13
14
15
16
17
18
# File 'lib/archunit/common/projection/edge_projections.rb', line 12

def per_edge
  lambda do |edge|
    next if edge.source == edge.target

    map_identity(edge)
  end
end

.per_external_edgeObject

Maps non-self edges whose targets are outside the extracted project.



30
31
32
33
34
35
36
37
# File 'lib/archunit/common/projection/edge_projections.rb', line 30

def per_external_edge
  lambda do |edge|
    next unless edge.external
    next if edge.source == edge.target

    map_identity(edge)
  end
end

.per_internal_edgeObject

Maps non-self edges whose targets are part of the extracted project.



21
22
23
24
25
26
27
# File 'lib/archunit/common/projection/edge_projections.rb', line 21

def per_internal_edge
  lambda do |edge|
    next if edge.external || edge.source == edge.target

    map_identity(edge)
  end
end

.project_cycles(edges) ⇒ Object



18
19
20
21
22
23
24
# File 'lib/archunit/common/projection/project_cycles.rb', line 18

def project_cycles(edges)
  projected_edges = normalize_projected_edges(edges)
  label_ids = label_ids_for(projected_edges)
  edges_by_ids = index_edges(projected_edges, label_ids)
  paths = Cycles::JohnsonCycles.call(adjacency_for(edges_by_ids))
  cycles_from_paths(paths, edges_by_ids)
end

.project_edges(graph, mapper = nil, &block) ⇒ Object

Applies a callable Edge -> MappedEdge/nil hook and cumulates equal labels.



14
15
16
17
18
19
# File 'lib/archunit/common/projection/project_edges.rb', line 14

def project_edges(graph, mapper = nil, &block)
  map_function = resolve_map_function(mapper, block)
  projection_groups(graph, map_function).map do |(source_label, target_label), edges|
    ProjectedEdge.new(source_label:, target_label:, cumulated_edges: edges)
  end.freeze
end

.project_internal_cycles(graph) ⇒ Object



14
15
16
# File 'lib/archunit/common/projection/project_cycles.rb', line 14

def project_internal_cycles(graph)
  project_cycles(project_edges(graph, per_internal_edge))
end

.project_to_nodes(graph, include_externals: false) ⇒ Object



13
14
15
16
17
18
19
20
# File 'lib/archunit/common/projection/project_to_nodes.rb', line 13

def project_to_nodes(graph, include_externals: false)
  validate_include_externals(include_externals)
  labels, incoming, outgoing = collect_node_edges(graph, include_externals)

  labels.keys.sort.map do |label|
    ProjectedNode.new(label:, incoming: incoming[label], outgoing: outgoing[label])
  end.freeze
end