Class: Igniter::Extensions::Contracts::Creator::Profile

Inherits:
Object
  • Object
show all
Defined in:
lib/igniter/extensions/contracts/creator/profile.rb

Constant Summary collapse

REGISTRY_CAPABILITIES =
{
  node: :nodes,
  dsl_keyword: :dsl_keywords,
  validator: :validators,
  runtime_handler: :runtime_handlers,
  diagnostic: :diagnostics_contributors,
  effect: :effects,
  executor: :executors,
  dependency_pack: :pack_manifests
}.freeze
PRESETS =
{
  feature_node: {
    kind: :feature,
    capabilities: %i[node dsl_keyword validator runtime_handler],
    dependency_hints: [],
    summary: "feature node pack with DSL, validation, and runtime"
  },
  diagnostic_bundle: {
    kind: :bundle,
    capabilities: %i[dependency_pack diagnostic],
    dependency_hints: %w[Igniter::Extensions::Contracts::ExecutionReportPack Igniter::Extensions::Contracts::ProvenancePack],
    summary: "developer-facing diagnostics bundle pack"
  },
  operational_adapter: {
    kind: :operational,
    capabilities: %i[effect executor],
    dependency_hints: [],
    summary: "effect/executor operational adapter pack"
  },
  bundle_pack: {
    kind: :bundle,
    capabilities: %i[dependency_pack],
    dependency_hints: [],
    summary: "bundle pack that installs or presets other packs"
  }
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name:, kind:, capabilities:, runtime_dependency_hints:, development_dependency_hints:, development_hints:, summary:) ⇒ Profile

Returns a new instance of Profile.



155
156
157
158
159
160
161
162
163
164
165
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 155

def initialize(name:, kind:, capabilities:, runtime_dependency_hints:, development_dependency_hints:,
               development_hints:, summary:)
  @name = name.to_sym
  @kind = kind.to_sym
  @capabilities = capabilities.map(&:to_sym).uniq.freeze
  @runtime_dependency_hints = runtime_dependency_hints.dup.freeze
  @development_dependency_hints = development_dependency_hints.dup.freeze
  @development_hints = development_hints.dup.freeze
  @summary = summary
  freeze
end

Instance Attribute Details

#capabilitiesObject (readonly)

Returns the value of attribute capabilities.



46
47
48
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 46

def capabilities
  @capabilities
end

#development_dependency_hintsObject (readonly)

Returns the value of attribute development_dependency_hints.



46
47
48
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 46

def development_dependency_hints
  @development_dependency_hints
end

#development_hintsObject (readonly)

Returns the value of attribute development_hints.



46
47
48
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 46

def development_hints
  @development_hints
end

#kindObject (readonly)

Returns the value of attribute kind.



46
47
48
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 46

def kind
  @kind
end

#nameObject (readonly)

Returns the value of attribute name.



46
47
48
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 46

def name
  @name
end

#runtime_dependency_hintsObject (readonly)

Returns the value of attribute runtime_dependency_hints.



46
47
48
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 46

def runtime_dependency_hints
  @runtime_dependency_hints
end

#summaryObject (readonly)

Returns the value of attribute summary.



46
47
48
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 46

def summary
  @summary
end

Class Method Details

.availableObject



54
55
56
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 54

def self.available
  PRESETS.keys
end

.build(profile: nil, kind: nil, capabilities: nil) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 58

def self.build(profile: nil, kind: nil, capabilities: nil)
  if profile
    preset = PRESETS.fetch(profile.to_sym) do
      raise ArgumentError, "unknown creator profile #{profile.inspect}"
    end
    effective_capabilities = Array(capabilities)
    effective_capabilities = preset.fetch(:capabilities) if capabilities.nil? || effective_capabilities.empty?

    runtime_hints = preset.fetch(:dependency_hints)
    development_pack_hints = development_dependency_hints_for(effective_capabilities, runtime_hints)

    return new(
      name: profile,
      kind: preset.fetch(:kind),
      capabilities: effective_capabilities,
      runtime_dependency_hints: runtime_hints,
      development_dependency_hints: development_pack_hints,
      development_hints: development_hints_for(effective_capabilities, runtime_hints, development_pack_hints),
      summary: preset.fetch(:summary)
    )
  end

  normalized_kind = (kind || infer_kind(Array(capabilities))).to_sym
  inferred_capabilities = Array(capabilities)
  inferred_capabilities = default_capabilities_for(normalized_kind) if inferred_capabilities.empty?
  runtime_hints = dependency_hints_for(inferred_capabilities)
  development_pack_hints = development_dependency_hints_for(inferred_capabilities, runtime_hints)

  new(
    name: :custom,
    kind: normalized_kind,
    capabilities: inferred_capabilities,
    runtime_dependency_hints: runtime_hints,
    development_dependency_hints: development_pack_hints,
    development_hints: development_hints_for(inferred_capabilities, runtime_hints, development_pack_hints),
    summary: "custom #{normalized_kind} authoring profile"
  )
end

.default_capabilities_for(kind) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 133

def self.default_capabilities_for(kind)
  case kind.to_sym
  when :feature
    %i[node dsl_keyword validator runtime_handler]
  when :operational
    %i[effect executor]
  when :bundle
    %i[dependency_pack]
  else
    []
  end
end

.dependency_hints_for(capabilities) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 97

def self.dependency_hints_for(capabilities)
  caps = capabilities.map(&:to_sym)
  hints = []
  if caps.include?(:diagnostic)
    hints.concat([
                   "Igniter::Extensions::Contracts::ExecutionReportPack",
                   "Igniter::Extensions::Contracts::ProvenancePack"
                 ])
  end
  hints << "Igniter::Extensions::Contracts::DebugPack" if caps.include?(:dependency_pack) && caps.include?(:diagnostic)

  hints.uniq
end

.development_dependency_hints_for(capabilities, dependency_hints) ⇒ Object



111
112
113
114
115
116
117
118
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 111

def self.development_dependency_hints_for(capabilities, dependency_hints)
  caps = capabilities.map(&:to_sym)
  hints = []
  hints << "Igniter::Extensions::Contracts::DebugPack"
  hints << "Igniter::Extensions::Contracts::JournalPack" if (caps & %i[effect executor]).any?
  hints << "Igniter::Extensions::Contracts::DebugPack" if caps.include?(:dependency_pack) && caps.include?(:diagnostic)
  hints.reject { |hint| dependency_hints.include?(hint) }.uniq
end

.development_hints_for(capabilities, dependency_hints, development_dependency_hints) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 120

def self.development_hints_for(capabilities, dependency_hints, development_dependency_hints)
  caps = capabilities.map(&:to_sym)
  hints = []
  hints << "use Igniter::Extensions::Contracts::DebugPack while authoring and validating the pack"
  hints << "consider Igniter::Extensions::Contracts::JournalPack while developing effect/executor adapters" if (caps & %i[
    effect executor
  ]).any?
  hints << "bundle diagnostics contributors only when they are truly additive and non-semantic" if caps.include?(:diagnostic)
  hints << "review runtime dependency pack composition carefully: #{dependency_hints.join(", ")}" unless dependency_hints.empty?
  hints << "keep development-only helper packs out of the runtime bundle surface: #{development_dependency_hints.join(", ")}" unless development_dependency_hints.empty?
  hints.uniq
end

.infer_kind(capabilities) ⇒ Object



146
147
148
149
150
151
152
153
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 146

def self.infer_kind(capabilities)
  caps = capabilities.map(&:to_sym)
  return :operational if (caps & %i[effect executor]).any?
  return :bundle if caps.include?(:dependency_pack) && (caps & %i[node dsl_keyword runtime_handler effect
                                                                  executor]).empty?

  :feature
end

Instance Method Details

#capability?(name) ⇒ Boolean

Returns:

  • (Boolean)


175
176
177
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 175

def capability?(name)
  capabilities.include?(name.to_sym)
end

#dependency_hintsObject



167
168
169
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 167

def dependency_hints
  runtime_dependency_hints
end

#registry_capabilitiesObject



171
172
173
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 171

def registry_capabilities
  capabilities.filter_map { |capability| REGISTRY_CAPABILITIES[capability] }.uniq
end

#to_hObject



179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/igniter/extensions/contracts/creator/profile.rb', line 179

def to_h
  {
    name: name,
    kind: kind,
    capabilities: capabilities,
    registry_capabilities: registry_capabilities,
    dependency_hints: dependency_hints,
    runtime_dependency_hints: runtime_dependency_hints,
    development_dependency_hints: development_dependency_hints,
    development_hints: development_hints,
    summary: summary
  }
end