Class: Rails::Hyperdrive::GemManifest

Inherits:
Object
  • Object
show all
Defined in:
lib/rails/hyperdrive/gem_manifest.rb

Overview

A companion gem's root manifest (hyperdrive.yml) declares artifact gating: top-level gem:/versions: defaults for the whole gem, per-skill entries keyed by the skill dir's relative path from its skills root, per-guideline entries keyed by filename. Fail-open at every level: malformed input warns and resolves to an ungated install — an artifact is never skipped because its gating could not be read, and nothing raises.

Defined Under Namespace

Classes: Gate

Constant Summary collapse

FILE_NAME =
"hyperdrive.yml"
METADATA_KEY =
"rails_hyperdrive_manifest"
UNGATED =
["*"].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(spec, warnings:) ⇒ GemManifest

Returns a new instance of GemManifest.



55
56
57
58
59
60
61
62
# File 'lib/rails/hyperdrive/gem_manifest.rb', line 55

def initialize(spec, warnings:)
  @spec = spec
  @warnings = warnings
  root = load_root
  @skills = section(root, "skills", "skill relpath")
  @guidelines = section(root, "guidelines", "guideline filename")
  @default_targets, @default_versions = defaults(root)
end

Class Method Details

.load(spec, warnings: []) ⇒ Object



20
21
22
# File 'lib/rails/hyperdrive/gem_manifest.rb', line 20

def load(spec, warnings: [])
  new(spec, warnings: warnings)
end

.malformed_requirements?(versions) ⇒ Boolean

versions: is optional everywhere; nil means unconstrained.

Returns:

  • (Boolean)


41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rails/hyperdrive/gem_manifest.rb', line 41

def malformed_requirements?(versions)
  requirements = versions.is_a?(Hash) ? versions.values : [versions]
  requirements.compact.any? do |req|
    parts = Array(req).flat_map { |s| s.is_a?(String) ? s.split(",").map(&:strip) : s }
    begin
      Gem::Requirement.new(*parts)
      false
    rescue ArgumentError
      true
    end
  end
end

.opt_in?(spec) ⇒ Boolean

The metadata key counts even when its value is unusable — declaring it at all signals companion intent.

Returns:

  • (Boolean)


26
27
28
29
30
31
32
# File 'lib/rails/hyperdrive/gem_manifest.rb', line 26

def opt_in?(spec)
  return true if File.file?(File.join(spec.full_gem_path, FILE_NAME))
  return false unless spec.respond_to?(:metadata)

  raw = spec. && spec.[METADATA_KEY]
  !raw.to_s.strip.empty?
end

.parse_targets(raw) ⇒ Object



34
35
36
37
38
# File 'lib/rails/hyperdrive/gem_manifest.rb', line 34

def parse_targets(raw)
  entries = raw.is_a?(Array) ? raw : [raw]
  return nil if entries.any? { |e| e.nil? || e.is_a?(Array) || e.is_a?(Hash) }
  entries.flat_map { |e| e.to_s.split(",") }.map(&:strip).reject(&:empty?)
end

Instance Method Details

#guideline_gate(filename) ⇒ Object



69
70
71
72
# File 'lib/rails/hyperdrive/gem_manifest.rb', line 69

def guideline_gate(filename)
  return default_gate unless @guidelines.key?(filename)
  entry_gate(@guidelines[filename], filename, with_conditional: false)
end

#guideline_keysObject



78
79
80
# File 'lib/rails/hyperdrive/gem_manifest.rb', line 78

def guideline_keys
  @guidelines.keys
end

#skill_gate(rel) ⇒ Object



64
65
66
67
# File 'lib/rails/hyperdrive/gem_manifest.rb', line 64

def skill_gate(rel)
  return default_gate unless @skills.key?(rel)
  entry_gate(@skills[rel], rel, with_conditional: true)
end

#skill_keysObject



74
75
76
# File 'lib/rails/hyperdrive/gem_manifest.rb', line 74

def skill_keys
  @skills.keys
end