Module: StillActive::CeilingReconciler
- Extended by:
- CeilingReconciler
- Included in:
- CeilingReconciler
- Defined in:
- lib/still_active/ceiling_reconciler.rb
Overview
Whole-tree correlation between the two capping signals, run once after the
fan-out (native or SBOM) has assembled every package's findings. A language
ceiling that says "upgrade
Instance Method Summary collapse
Instance Method Details
#reconcile_ceiling_with_poison(result_object) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/still_active/ceiling_reconciler.rb', line 14 def reconcile_ceiling_with_poison(result_object) # Qualify each capped dependency by the ecosystem that declares the cap. A # capped dep resolves in its parent's ecosystem, so a poison finding on a # `pypi` package caps a `pypi` dependency. A mixed SBOM has two flat- # resolution ecosystems (rubygems + pypi), so a bare-name match alone would # let a rubygems poison-cap on "foo" wrongly block a pypi "foo"'s ceiling. # Native results carry no :ecosystem (all rubygems) -> nil on both sides, # still consistent. capped = result_object.each_value .flat_map do |data| Array(data[:constraints]) .select { |constraint| constraint[:majors_behind].to_i.positive? } .map { |constraint| "#{data[:ecosystem]}/#{constraint[:dependency]}" } end .uniq result_object.each do |key, data| ceiling = data[:language_ceiling] next unless ceiling && ceiling[:fixed_by_upgrade] # Native results are keyed by the bare gem name; SBOM results are keyed by # "ecosystem/name@version" and carry the bare name in :name. package_name = data[:name] || key next unless capped.include?("#{data[:ecosystem]}/#{package_name}") ceiling[:fixed_by_upgrade] = false ceiling[:upgrade_blocked] = true end end |