diff mbox series

[2/2] devtool: upgrade: clean up changelog content for commit messages

Message ID 20260918120125.770604-2-daniel.turull@ericsson.com
State New
Headers show
Series [1/2] devtool: upgrade: write changelog metadata as JSON sidecar | expand

Commit Message

Daniel Turull Sept. 18, 2026, 12:01 p.m. UTC
From: Daniel Turull <daniel.turull@ericsson.com>

Strip noise that has no value in a commit message:
- GitHub PR references: trailing "(#NNN)" and full pull/issue URLs.
- Commit hash prefixes from "git log --oneline"-style content,
  including the git-log fallback used when no changelog file exists.
- GNU ChangeLog noise: "YYYY-MM-DD  Name  <email>" entry headers, and
  "* file (func):" / "+ commit <hash>" bullets plus their wrapped
  continuation lines, down to the next blank line, keeping only the
  human-readable summary of each entry. Remaining tabs are stripped.
- NEWS-style "Changes in X.Y.Z, DATE" release headers and their "==="
  underline (libportal/glib-family projects).

Lines exceeding 80 chars are wrapped, preserving existing indentation.

AI-Generated: Uses Kiro with Claude Sonnet 5
Signed-off-by: Daniel Turull <daniel.turull@ericsson.com>
---
 .../python3-guessing-game_git.bb.changelog    |  2 +-
 .../devtool-upgrade-test2_git.bb.changelog    |  2 +-
 .../devtool-upgrade-test5_git.bb.changelog    |  2 +-
 scripts/lib/devtool/upgrade.py                | 63 ++++++++++++++++++-
 4 files changed, 65 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/meta-selftest/recipes-devtools/python/python3-guessing-game_git.bb.changelog b/meta-selftest/recipes-devtools/python/python3-guessing-game_git.bb.changelog
index ef0052160b..6c7bf9f713 100644
--- a/meta-selftest/recipes-devtools/python/python3-guessing-game_git.bb.changelog
+++ b/meta-selftest/recipes-devtools/python/python3-guessing-game_git.bb.changelog
@@ -1 +1 @@ 
-40cf004 Sync with maturin tutorial source
+Sync with maturin tutorial source
diff --git a/meta-selftest/recipes-test/devtool/devtool-upgrade-test2_git.bb.changelog b/meta-selftest/recipes-test/devtool/devtool-upgrade-test2_git.bb.changelog
index ac133c483f..4699b1e89e 100644
--- a/meta-selftest/recipes-test/devtool/devtool-upgrade-test2_git.bb.changelog
+++ b/meta-selftest/recipes-test/devtool/devtool-upgrade-test2_git.bb.changelog
@@ -1 +1 @@ 
-6cc6077 dbus-wait.c: Fix typo
+dbus-wait.c: Fix typo
diff --git a/meta-selftest/recipes-test/devtool/devtool-upgrade-test5_git.bb.changelog b/meta-selftest/recipes-test/devtool/devtool-upgrade-test5_git.bb.changelog
index 8077da3e21..3196cc13bd 100644
--- a/meta-selftest/recipes-test/devtool/devtool-upgrade-test5_git.bb.changelog
+++ b/meta-selftest/recipes-test/devtool/devtool-upgrade-test5_git.bb.changelog
@@ -1 +1 @@ 
-0a60d6a Add dummy commit on tip for testing
+Add dummy commit on tip for testing
diff --git a/scripts/lib/devtool/upgrade.py b/scripts/lib/devtool/upgrade.py
index cdc85fe7ae..ba7348664f 100644
--- a/scripts/lib/devtool/upgrade.py
+++ b/scripts/lib/devtool/upgrade.py
@@ -14,6 +14,7 @@  import shlex
 import shutil
 import subprocess
 import tempfile
+import textwrap
 import logging
 import argparse
 import scriptutils
@@ -634,6 +635,66 @@  def _diff_git_log_changelog(old_content, new_content):
     return '\n'.join(subjects) if subjects else None
 
 
+# GitHub PR references: trailing (#123) at end of line, or full URLs
+_GITHUB_PR_RE = re.compile(r'\s*\(#[0-9]+\)\s*$|\s*https?://github\.com/[^/]+/[^/]+/(pull|issues)/[0-9]+\s*')
+# Commit hash prefixes from git log --oneline: "abc1234 "
+_COMMIT_HASH_RE = re.compile(r'^[0-9a-f]{7,40}\s+')
+# A GNU ChangeLog entry: starts at either an entry header
+# ("2026-08-24  Werner Koch  <wk@gnupg.org>") or a technical bullet
+# ("* file.c (func): text" or "+ commit <hash>"), and extends through all
+# wrapped continuation lines up to (but not including) the next blank line.
+_GNU_CHANGELOG_ENTRY_RE = re.compile(
+    r'^(?:\d{4}-\d{2}-\d{2}\s+.+<.+@.+>|\s*(?:\*\s|\+ commit [0-9a-f]{7,40}).*)'
+    r'(?:\n(?!\s*$).*)*\n?',
+    re.MULTILINE)
+# NEWS-style release header + underline (glib/gtk family):
+# "Changes in 0.11.0, 2026-09-12\n===============================\n"
+_NEWS_RELEASE_HEADER_RE = re.compile(r'^Changes in .+,\s*\d{4}-\d{2}-\d{2}\s*\n=+\s*$', re.MULTILINE)
+
+def _join_single_line_paragraphs(text):
+    """Drop the blank line between two adjacent one-line paragraphs (each
+    surrounded by blank lines), so lines left behind by GNU ChangeLog entry
+    stripping read as one entry per line instead of double-spaced."""
+    paragraphs = text.split('\n\n')
+    out = [paragraphs[0]]
+    prev_is_single_line = '\n' not in paragraphs[0]
+    for para in paragraphs[1:]:
+        this_is_single_line = '\n' not in para
+        if prev_is_single_line and this_is_single_line:
+            out[-1] += '\n' + para
+        else:
+            out.append(para)
+        prev_is_single_line = this_is_single_line
+    return '\n\n'.join(out)
+
+
+def _cleanup_changelog(content):
+    """Strip GitHub PR refs, commit hashes, GNU ChangeLog entries (headers
+    and file/function bullets, plus their wrapped continuation lines) and
+    NEWS-style 'Changes in X.Y.Z, DATE' release headers with their
+    underline. Wrap lines over 80 chars, preserving indentation."""
+    content = _NEWS_RELEASE_HEADER_RE.sub('', content)
+    content = _GNU_CHANGELOG_ENTRY_RE.sub('', content)
+    out = []
+    for line in content.splitlines():
+        line = _GITHUB_PR_RE.sub(' ', line)
+        line = _COMMIT_HASH_RE.sub('', line)
+        line = line.replace('\t', '').rstrip()
+        stripped = line.lstrip()
+        indent = line[:len(line) - len(stripped)]
+        if len(line) > 80:
+            if stripped.startswith('- '):
+                indent += '  '
+            line = textwrap.fill(line, width=80, subsequent_indent=indent)
+        out.append(line)
+    text = '\n'.join(out)
+    # Entries removed above can leave 3+ blank newlines where a blank-line
+    # separator butted up against a removed entry's own blank line;
+    # collapse any such run down to a single blank line (2 newlines).
+    text = re.sub(r'\n{3,}', '\n\n', text).strip()
+    return _join_single_line_paragraphs(text)
+
+
 def _extract_changelog(srctree, pn, old_ver, new_ver, old_tag, new_tag, workspace_path, is_git_source):
     """Extract changelog between old and new version using devtool git tags."""
     changelog_content = None
@@ -723,7 +784,7 @@  def _extract_changelog(srctree, pn, old_ver, new_ver, old_tag, new_tag, workspac
         changelog_content = ''.join(filtered)
 
     # Clean up content for readability and commit message use
-    changelog_content = re.sub(r'\n{3,}', '\n\n', changelog_content).strip()
+    changelog_content = _cleanup_changelog(changelog_content)
     if not changelog_content:
         return None