Skip to content

Commit 13df62b

Browse files
hsbtclaude
andcommitted
Clean up orphaned release-tag link refs in NEWS.md updater
When update-NEWS-gemlist.rb drops a bundled/default gem entry from NEWS.md (because it no longer differs from the previous-release snapshot), the matching `[gem-vX.Y.Z]: ...` link definitions were left behind by update-NEWS-github-release.rb. Detect refs that are no longer cited from the body and drop them alongside the ones we re-emit, while preserving defs still referenced by gems whose release range could not be refreshed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent cf91f20 commit 13df62b

1 file changed

Lines changed: 26 additions & 18 deletions

File tree

tool/update-NEWS-github-release.rb

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -275,36 +275,44 @@ def update_news_md(results)
275275
i += 1
276276
end
277277

278-
# Collect all new footnote links
279-
all_footnotes = []
278+
# All footnote definitions we can emit from this run, indexed by ref name
279+
available_footnotes = {}
280280
results.each do |r|
281281
r[:footnote_links].each do |fl|
282-
all_footnotes << "[#{fl[:ref]}]: #{fl[:url]}"
282+
available_footnotes[fl[:ref]] = "[#{fl[:ref]}]: #{fl[:url]}"
283283
end
284284
end
285285

286-
# Remove any existing footnote links that we are about to add (avoid duplicates)
287-
existing_refs = Set.new(all_footnotes.map { |f| f[/^\[([^\]]+)\]:/, 1] })
288-
new_lines = new_lines.reject do |line|
289-
if line =~ /^\[([^\]]+)\]:\s+https:\/\/github\.com\//
290-
existing_refs.include?($1)
291-
else
292-
false
286+
# Refs the regenerated body actually uses (e.g. `][gem-vX.Y.Z]`)
287+
used_refs = new_lines.join.scan(/\]\[([^\]]+)\]/).flatten.uniq
288+
used_set = used_refs.to_set
289+
290+
# Drop existing GitHub release-tag link defs that are either orphaned (no
291+
# body reference) or about to be re-emitted from this run's results. Defs
292+
# still referenced by gems we couldn't refresh are preserved in place.
293+
release_ref_pattern = %r{^\[([^\]]+)\]:\s+https://github\.com/[^/]+/[^/]+/releases/tag/}
294+
new_lines.reject! do |line|
295+
if (m = line.match(release_ref_pattern))
296+
ref = m[1]
297+
!used_set.include?(ref) || available_footnotes.key?(ref)
293298
end
294299
end
295300

296-
# Ensure the file ends with a newline before adding footnotes
297-
unless new_lines.last&.end_with?("\n")
298-
new_lines << "\n"
299-
end
301+
# Trim trailing blank lines so the appended footer block is clean
302+
new_lines.pop while new_lines.last == "\n"
303+
new_lines << "\n" unless new_lines.last&.end_with?("\n")
300304

301-
# Append footnote links at the end of the file
302-
all_footnotes.each do |footnote|
303-
new_lines << "#{footnote}\n"
305+
# Append footnote defs only for refs the body still references
306+
emitted = 0
307+
used_refs.each do |ref|
308+
if (footnote = available_footnotes[ref])
309+
new_lines << "#{footnote}\n"
310+
emitted += 1
311+
end
304312
end
305313

306314
File.write(news_path, new_lines.join)
307-
puts "Updated #{news_path} with #{results.length} gem update entries and #{all_footnotes.length} footnote links."
315+
puts "Updated #{news_path} with #{results.length} gem update entries and #{emitted} footnote links."
308316
end
309317

310318
# --- Main ---

0 commit comments

Comments
 (0)