Class: Kettle::Changelog::KeyedEntryUpserter
- Inherits:
-
Object
- Object
- Kettle::Changelog::KeyedEntryUpserter
- Defined in:
- lib/kettle/changelog/keyed_entry_upserter.rb
Constant Summary collapse
- SECTIONS =
%w[Added Changed Deprecated Removed Fixed Security].freeze
- KEY_PREFIX =
"[kc]"- PROJECT_FILE_UPDATE_FIRST_LINE =
/\A[-*]\s+\[kc\]\s+([^\s:]+):\s+updated\s+\d+\s+project\s+files?:\s*\z/- PROJECT_FILE_UPDATE_CATEGORY_LINE =
/\A\s{2,}[-*]\s+(.+?)\s+\((\d+)\)\s*\z/
Class Method Summary collapse
-
.collapse_project_file_updates(source) ⇒ Object
Consolidates repeated maintenance summaries after a prepared release is updated in place.
Instance Method Summary collapse
-
#initialize(section:, key:, entry:, legacy_prefixes: [], root: Kettle::Dev::CIHelpers.project_root) ⇒ KeyedEntryUpserter
constructor
A new instance of KeyedEntryUpserter.
- #run ⇒ Object
Constructor Details
#initialize(section:, key:, entry:, legacy_prefixes: [], root: Kettle::Dev::CIHelpers.project_root) ⇒ KeyedEntryUpserter
Returns a new instance of KeyedEntryUpserter.
70 71 72 73 74 75 76 77 |
# File 'lib/kettle/changelog/keyed_entry_upserter.rb', line 70 def initialize(section:, key:, entry:, legacy_prefixes: [], root: Kettle::Dev::CIHelpers.project_root) @root = root @section = section.to_s @key = key.to_s.strip @entry = entry @legacy_prefixes = Array(legacy_prefixes).map { |prefix| prefix.to_s.strip }.reject(&:empty?) @changelog_path = ENV.fetch("K_CHANGELOG_PATH", File.join(@root, "CHANGELOG.md")) end |
Class Method Details
.collapse_project_file_updates(source) ⇒ Object
Consolidates repeated maintenance summaries after a prepared release is updated in place. The AST supplies list-item boundaries; the two regular expressions only parse the stable text payload inside those already-classified Markdown items.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/kettle/changelog/keyed_entry_upserter.rb', line 16 def collapse_project_file_updates(source) require "ast/crispr/markdown/markly" context = Ast::Crispr::Markdown::Markly.document_context(content: source.to_s, source_label: "CHANGELOG.md") updates = context.structural_owners(owner_scope: :list_items) .select { |item| item.depth == 1 } .filter_map { |item| project_file_update_record(item) } duplicate_groups = updates.group_by { |update| update.fetch(:key) }.values.select { |group| group.length > 1 } return source.to_s if duplicate_groups.empty? lines = source.to_s.lines duplicate_groups.flatten.sort_by { |update| update.fetch(:start_line) }.reverse_each do |update| group = duplicate_groups.find { |candidate| candidate.include?(update) } first = group.min_by { |candidate| candidate.fetch(:start_line) } replacement = (update == first) ? project_file_update_entry(group).lines : [] lines[(update.fetch(:start_line) - 1)...update.fetch(:end_line)] = replacement end lines.join end |
Instance Method Details
#run ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/kettle/changelog/keyed_entry_upserter.rb', line 79 def run validate! source = read_source! matches = find_matches(source) if matches.count { |match| match.fetch(:kind) == :keyed } > 1 raise Error, "expected at most one #{key_label} entry in CHANGELOG.md" end if matches.any? { |match| match.fetch(:kind) == :keyed } && matches.any? { |match| match.fetch(:kind) == :legacy } raise Error, "found both keyed and legacy entries for #{key_label} in CHANGELOG.md" end body = @entry.respond_to?(:call) ? @entry.call(matches) : @entry rendered = render_entry(body) changed = matches.empty? || matches.any? { |match| normalize_source(match.fetch(:source)) != normalize_source(rendered) } || matches.length > 1 write_updated_source(source, rendered, matches) if changed matched = if matches.empty? "inserted" elsif matches.first.fetch(:kind) == :legacy "legacy" else "keyed" end { changed: changed, key: @key, section: @section, entry: rendered, matched: matched } end |