Class: Kettle::Rb::GemFloors::Generator

Inherits:
Object
  • Object
show all
Defined in:
lib/kettle/rb/gem_floors/generator.rb

Overview

Regenerates lib/kettle/rb/gem_floors/data.rb for tracked gems from the rubygems.org versions API and ruby-advisory-db (through bundler-audit).

This is development tooling. It is loaded by the kettle:rb:gem_floors:generate rake task, never by require "kettle/rb".

For each minor series of a tracked gem the floor is the newest released patch that does not raise the series' original minimum Ruby. When that patch is affected by an advisory but an older compatible patch is not, the newest unaffected patch is used instead. Advisories that still affect the chosen floor are recorded as unpatched.

Constant Summary collapse

TRACKED =

Tracked gems and the oldest minor series to record for each.

[
  ["activemodel", "5.2"],
  ["activerecord", "5.2"],
  ["activesupport", "5.2"],
  ["sqlite3", "1.3"]
].freeze
DATA_PATH =
File.expand_path(File.join(File.dirname(__FILE__), "data.rb"))
VERSIONS_URL =
"https://rubygems.org/api/v1/versions/%s.json"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Generator

Returns a new instance of Generator.

Parameters:

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :tracked (Array<Array(String, String)>)

    gem names and oldest series

  • :versions_fetcher (#call)

    returns rubygems.org version hashes for a gem name

  • :advisories_fetcher (#call)

    returns advisories (+#id+, #vulnerable?) for a gem name

  • :advisory_db_commit (String, nil)

    ruby-advisory-db commit to record

  • :generated_on (String)

    date to record



47
48
49
50
51
52
53
# File 'lib/kettle/rb/gem_floors/generator.rb', line 47

def initialize(options = {})
  @tracked = options[:tracked] || TRACKED
  @versions_fetcher = options[:versions_fetcher] || method(:fetch_versions)
  @advisories_fetcher = options[:advisories_fetcher] || method(:fetch_advisories)
  @advisory_db_commit = options.key?(:advisory_db_commit) ? options[:advisory_db_commit] : database_commit
  @generated_on = options[:generated_on] || Time.now.utc.strftime("%Y-%m-%d")
end

Instance Attribute Details

#advisory_db_commitString? (readonly)

Returns ruby-advisory-db commit recorded in the data file.

Returns:

  • (String, nil)

    ruby-advisory-db commit recorded in the data file



36
37
38
# File 'lib/kettle/rb/gem_floors/generator.rb', line 36

def advisory_db_commit
  @advisory_db_commit
end

#generated_onString (readonly)

Returns generation date recorded in the data file.

Returns:

  • (String)

    generation date recorded in the data file



39
40
41
# File 'lib/kettle/rb/gem_floors/generator.rb', line 39

def generated_on
  @generated_on
end

#trackedArray<Array(String, String)> (readonly)

Returns tracked gem names and oldest series.

Returns:

  • (Array<Array(String, String)>)

    tracked gem names and oldest series



33
34
35
# File 'lib/kettle/rb/gem_floors/generator.rb', line 33

def tracked
  @tracked
end

Instance Method Details

#renderString

Returns Ruby source for data.rb.

Returns:

  • (String)

    Ruby source for data.rb



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/kettle/rb/gem_floors/generator.rb', line 65

def render
  lines = [
    "# frozen_string_literal: true",
    "",
    "# Generated by `rake kettle:rb:gem_floors:generate`; do not edit by hand.",
    "# Sources: rubygems.org versions API and ruby-advisory-db.",
    "",
    "module Kettle",
    "  module Rb",
    "    module GemFloors",
    "      GENERATED_ON = #{generated_on.inspect}",
    "      ADVISORY_DB_COMMIT = #{advisory_db_commit.inspect}",
    "      TRACKED_GEMS = #{tracked.map { |pair| pair.first }.inspect}.freeze",
    "      ROWS = ["
  ]
  lines << rows.map { |row| "        #{row.inspect}" }.join(",\n")
  lines.concat(["      ].freeze", "    end", "  end", "end", ""])
  lines.join("\n")
end

#rowsArray<Array>

Returns rows for GemFloors::ROWS.

Returns:

  • (Array<Array>)

    rows for GemFloors::ROWS



56
57
58
59
60
61
62
# File 'lib/kettle/rb/gem_floors/generator.rb', line 56

def rows
  result = []
  tracked.each do |gem_name, oldest_series|
    result.concat(rows_for(gem_name, Gem::Version.new(oldest_series)))
  end
  result
end

#write(path = DATA_PATH) ⇒ String

Writes the rendered data file.

Parameters:

  • path (String) (defaults to: DATA_PATH)

Returns:

  • (String)

    the written path



89
90
91
92
# File 'lib/kettle/rb/gem_floors/generator.rb', line 89

def write(path = DATA_PATH)
  File.open(path, "w") { |file| file.write(render) }
  path
end