Module: Igniter::Extensions::Contracts::Audit::Builder

Defined in:
lib/igniter/extensions/contracts/audit/builder.rb

Class Method Summary collapse

Class Method Details

.build(target) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/igniter/extensions/contracts/audit/builder.rb', line 10

def build(target)
  result = unwrap_result(target)
  compiled_graph = result.compiled_graph
  outputs = result.outputs.to_h
  state_values = result.state.to_h

  Snapshot.new(
    graph: graph_name(compiled_graph),
    profile_fingerprint: result.profile_fingerprint,
    events: build_events(compiled_graph, state_values: state_values, outputs: outputs),
    states: build_states(compiled_graph, state_values: state_values, outputs: outputs),
    children: build_children(state_values),
    output_names: compiled_graph.operations.select(&:output?).map(&:name)
  )
end

.build_children(state_values) ⇒ Object



67
68
69
70
71
72
73
74
75
76
# File 'lib/igniter/extensions/contracts/audit/builder.rb', line 67

def build_children(state_values)
  state_values.each_with_object([]) do |(name, value), memo|
    next unless nested_execution_result?(value)

    memo << {
      node_name: name,
      snapshot: build(value).to_h
    }
  end
end

.build_events(compiled_graph, state_values:, outputs:) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/igniter/extensions/contracts/audit/builder.rb', line 39

def build_events(compiled_graph, state_values:, outputs:)
  compiled_graph.operations.each_with_index.map do |operation, index|
    Event.new(
      event_id: "#{operation.kind}:#{operation.name}:#{index}",
      type: event_type_for(operation),
      node_name: operation.name,
      path: [operation.name],
      status: status_for(operation, state_values: state_values, outputs: outputs),
      payload: payload_for(operation, state_values: state_values, outputs: outputs)
    )
  end
end

.build_states(compiled_graph, state_values:, outputs:) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/igniter/extensions/contracts/audit/builder.rb', line 52

def build_states(compiled_graph, state_values:, outputs:)
  compiled_graph.operations.each_with_object({}) do |operation, memo|
    next if operation.output?

    value = operation.output? ? outputs[operation.name] : state_values[operation.name]
    memo[operation.name] = {
      path: [operation.name],
      kind: operation.kind,
      status: status_for(operation, state_values: state_values, outputs: outputs),
      value: serialize_value(value),
      dependencies: dependency_names_for(operation)
    }
  end
end

.dependency_names_for(operation) ⇒ Object



101
102
103
104
105
106
# File 'lib/igniter/extensions/contracts/audit/builder.rb', line 101

def dependency_names_for(operation)
  names = []
  names.concat(Array(operation.attributes[:depends_on])) if operation.attribute?(:depends_on)
  names << operation.attributes[:from] if operation.attribute?(:from)
  names.map(&:to_sym).uniq
end

.event_type_for(operation) ⇒ Object



78
79
80
81
82
# File 'lib/igniter/extensions/contracts/audit/builder.rb', line 78

def event_type_for(operation)
  return :output_observed if operation.output?

  :"#{operation.kind}_observed"
end

.graph_name(compiled_graph) ⇒ Object



32
33
34
35
36
37
# File 'lib/igniter/extensions/contracts/audit/builder.rb', line 32

def graph_name(compiled_graph)
  operation_names = compiled_graph.operations.reject(&:output?).map(&:name)
  return "contracts_graph" if operation_names.empty?

  "contracts_graph(#{operation_names.join(",")})"
end

.nested_execution_result?(value) ⇒ Boolean

Returns:

  • (Boolean)


125
126
127
# File 'lib/igniter/extensions/contracts/audit/builder.rb', line 125

def nested_execution_result?(value)
  value.is_a?(Igniter::Contracts::ExecutionResult)
end

.payload_for(operation, state_values:, outputs:) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
# File 'lib/igniter/extensions/contracts/audit/builder.rb', line 89

def payload_for(operation, state_values:, outputs:)
  value = operation.output? ? outputs[operation.name] : state_values[operation.name]
  payload = {
    kind: operation.kind,
    value: serialize_value(value)
  }

  dependencies = dependency_names_for(operation)
  payload[:dependencies] = dependencies if dependencies.any?
  payload
end

.serialize_value(value) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/igniter/extensions/contracts/audit/builder.rb', line 108

def serialize_value(value)
  case value
  when Igniter::Contracts::ExecutionResult
    {
      type: :execution_result,
      profile_fingerprint: value.profile_fingerprint,
      outputs: value.outputs.to_h
    }
  when Array
    value.map { |item| serialize_value(item) }
  when Hash
    value.transform_keys(&:to_sym).transform_values { |item| serialize_value(item) }
  else
    value
  end
end

.status_for(operation, state_values:, outputs:) ⇒ Object



84
85
86
87
# File 'lib/igniter/extensions/contracts/audit/builder.rb', line 84

def status_for(operation, state_values:, outputs:)
  collection = operation.output? ? outputs : state_values
  collection.key?(operation.name) ? :succeeded : :missing
end

.unwrap_result(target) ⇒ Object



26
27
28
29
30
# File 'lib/igniter/extensions/contracts/audit/builder.rb', line 26

def unwrap_result(target)
  return target.execution_result if target.respond_to?(:execution_result)

  target
end