new file mode 100644
@@ -0,0 +1,3 @@
+Changelog for python3-guessing-game: 0.1.0 -> 0.2.0
+
+40cf004 Sync with maturin tutorial source
new file mode 100644
@@ -0,0 +1,24 @@
+Changelog for devtool-upgrade-test1: 1.5.3 -> 1.6.0
+
+1.6.0 - 15 March 2015
+ - fix lstat64 support when unavailable - separate patches supplied by
+ Ganael Laplanche and Peter Korsgaard
+ - (#1506) new option "-D" / "--delay-start" to only show bar after N
+ seconds (Damon Harper)
+ - new option "--fineta" / "-I" to show ETA as time of day rather than time
+ remaining - patch supplied by Erkki Seppälä (r147)
+ - (#1509) change ETA (--eta / -e) so that days are given if the hours
+ remaining are 24 or more (Jacek Wielemborek)
+ - (#1499) repeat read and write attempts on partial buffer fill/empty to
+ work around post-signal transfer rate drop reported by Ralf Ramsauer
+ - (#1507) do not try to calculate total size in line mode, due to bug
+ reported by Jacek Wielemborek and Michiel Van Herwegen
+ - cleanup: removed defunct RATS comments and unnecessary copyright notices
+ - clean up displayed lines when using --watchfd PID, when PID exits
+ - output errors on a new line to avoid overwriting transfer bar
+
+1.5.7 - 26 August 2014
+ - show KiB instead of incorrect kiB (Debian bug #706175)
+ - (#1284) do not gzip man page, for non-Linux OSes (Bob Friesenhahn)
+ - work around "awk" bug in tests/016-numeric-timer in decimal "," locales
+ - fix "make rpm" and "make srpm", extend "make release" to sign releases
new file mode 100644
@@ -0,0 +1,3 @@
+Changelog for devtool-upgrade-test2: 0.1+git -> 0.1+git
+
+6cc6077 dbus-wait.c: Fix typo
new file mode 100644
@@ -0,0 +1,24 @@
+Changelog for devtool-upgrade-test3: 1.5.3 -> 1.6.0
+
+1.6.0 - 15 March 2015
+ - fix lstat64 support when unavailable - separate patches supplied by
+ Ganael Laplanche and Peter Korsgaard
+ - (#1506) new option "-D" / "--delay-start" to only show bar after N
+ seconds (Damon Harper)
+ - new option "--fineta" / "-I" to show ETA as time of day rather than time
+ remaining - patch supplied by Erkki Seppälä (r147)
+ - (#1509) change ETA (--eta / -e) so that days are given if the hours
+ remaining are 24 or more (Jacek Wielemborek)
+ - (#1499) repeat read and write attempts on partial buffer fill/empty to
+ work around post-signal transfer rate drop reported by Ralf Ramsauer
+ - (#1507) do not try to calculate total size in line mode, due to bug
+ reported by Jacek Wielemborek and Michiel Van Herwegen
+ - cleanup: removed defunct RATS comments and unnecessary copyright notices
+ - clean up displayed lines when using --watchfd PID, when PID exits
+ - output errors on a new line to avoid overwriting transfer bar
+
+1.5.7 - 26 August 2014
+ - show KiB instead of incorrect kiB (Debian bug #706175)
+ - (#1284) do not gzip man page, for non-Linux OSes (Bob Friesenhahn)
+ - work around "awk" bug in tests/016-numeric-timer in decimal "," locales
+ - fix "make rpm" and "make srpm", extend "make release" to sign releases
new file mode 100644
@@ -0,0 +1,24 @@
+Changelog for devtool-upgrade-test4: 1.5.3 -> 1.6.0
+
+1.6.0 - 15 March 2015
+ - fix lstat64 support when unavailable - separate patches supplied by
+ Ganael Laplanche and Peter Korsgaard
+ - (#1506) new option "-D" / "--delay-start" to only show bar after N
+ seconds (Damon Harper)
+ - new option "--fineta" / "-I" to show ETA as time of day rather than time
+ remaining - patch supplied by Erkki Seppälä (r147)
+ - (#1509) change ETA (--eta / -e) so that days are given if the hours
+ remaining are 24 or more (Jacek Wielemborek)
+ - (#1499) repeat read and write attempts on partial buffer fill/empty to
+ work around post-signal transfer rate drop reported by Ralf Ramsauer
+ - (#1507) do not try to calculate total size in line mode, due to bug
+ reported by Jacek Wielemborek and Michiel Van Herwegen
+ - cleanup: removed defunct RATS comments and unnecessary copyright notices
+ - clean up displayed lines when using --watchfd PID, when PID exits
+ - output errors on a new line to avoid overwriting transfer bar
+
+1.5.7 - 26 August 2014
+ - show KiB instead of incorrect kiB (Debian bug #706175)
+ - (#1284) do not gzip man page, for non-Linux OSes (Bob Friesenhahn)
+ - work around "awk" bug in tests/016-numeric-timer in decimal "," locales
+ - fix "make rpm" and "make srpm", extend "make release" to sign releases
new file mode 100644
@@ -0,0 +1,3 @@
+Changelog for devtool-upgrade-test5: 0.1+git -> 0.1+git
+
+0a60d6a Add dummy commit on tip for testing
@@ -1944,6 +1944,23 @@ class DevtoolUpgradeTests(DevtoolBase):
except:
self.skip("Git user.name and user.email must be set")
+ def _check_changelog(self, recipe, oldrecipefile):
+ """Compare extracted changelog against reference data if available."""
+ changelog_ref = oldrecipefile + '.changelog'
+ if not os.path.exists(changelog_ref):
+ return
+ changelog_file = os.path.join(self.workspacedir, 'changelogs', '%s.txt' % recipe)
+ with open(changelog_ref, 'r') as f:
+ expected = f.read()
+ if not expected:
+ self.assertNotExists(changelog_file,
+ 'Changelog file should not exist when reference is empty')
+ else:
+ self.assertExists(changelog_file, 'Changelog file should exist after upgrade')
+ with open(changelog_file, 'r') as f:
+ actual = f.read()
+ self.assertEqual(expected, actual)
+
def test_devtool_upgrade(self):
# Check preconditions
self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
@@ -1982,6 +1999,8 @@ class DevtoolUpgradeTests(DevtoolBase):
with open(newrecipefile, 'r') as f:
newlines = f.readlines()
self.assertEqual(desiredlines, newlines)
+ # Check changelog
+ self._check_changelog(recipe, oldrecipefile)
# Check devtool reset recipe
result = runCmd('devtool reset %s -n' % recipe)
result = runCmd('devtool status')
@@ -2016,11 +2035,14 @@ class DevtoolUpgradeTests(DevtoolBase):
with open(newrecipefile, 'r') as f:
newlines = f.readlines()
self.assertEqual(desiredlines, newlines)
+ # Check changelog
+ self._check_changelog(recipe, oldrecipefile)
# Check devtool reset recipe
result = runCmd('devtool reset %s -n' % recipe)
result = runCmd('devtool status')
self.assertNotIn(recipe, result.output)
self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipe), 'Recipe directory should not exist after resetting')
+ self.assertNotExists(os.path.join(self.workspacedir, 'changelogs', '%s.txt' % recipe), 'Changelog file should be removed after reset')
def test_devtool_upgrade_git(self):
self._test_devtool_upgrade_git_by_recipe('devtool-upgrade-test2', '6cc6077a36fe2648a5f993fe7c16c9632f946517')
@@ -2051,6 +2073,8 @@ class DevtoolUpgradeTests(DevtoolBase):
with open(newrecipefile, 'r') as f:
newlines = f.readlines()
self.assertEqual(desiredlines, newlines)
+ # Check changelog
+ self._check_changelog(recipe, oldrecipefile)
def test_devtool_upgrade_all_checksums(self):
# Check preconditions
@@ -2075,6 +2099,8 @@ class DevtoolUpgradeTests(DevtoolBase):
with open(newrecipefile, 'r') as f:
newlines = f.readlines()
self.assertEqual(desiredlines, newlines)
+ # Check changelog
+ self._check_changelog(recipe, oldrecipefile)
def test_devtool_upgrade_recipe_upgrade_extra_tasks(self):
# Check preconditions
@@ -2116,6 +2142,8 @@ class DevtoolUpgradeTests(DevtoolBase):
with open(newcratesincfile, 'r') as f:
newlines = f.readlines()
self.assertEqual(desiredlines, newlines)
+ # Check changelog
+ self._check_changelog(recipe, oldrecipefile)
# Check devtool reset recipe
result = runCmd('devtool reset %s -n' % recipe)
result = runCmd('devtool status')
@@ -2046,6 +2046,14 @@ def _reset(recipes, no_clean, remove_work, config, basepath, workspace):
clean_preferred_provider(pn, config.workspace_path)
+ # Clean up changelog if present
+ changelog_file = os.path.join(config.workspace_path, 'changelogs', '%s.txt' % pn)
+ if os.path.exists(changelog_file):
+ os.remove(changelog_file)
+ changelog_dir = os.path.dirname(changelog_file)
+ if not os.listdir(changelog_dir):
+ os.rmdir(changelog_dir)
+
def reset(args, config, basepath, workspace):
"""Entry point for the devtool 'reset' subcommand"""
@@ -9,6 +9,7 @@
import os
import sys
import re
+import shlex
import shutil
import tempfile
import logging
@@ -26,6 +27,31 @@ from devtool import exec_build_env_command, setup_tinfoil, DevtoolError, parse_r
logger = logging.getLogger('devtool')
+# Common changelog filenames found in upstream source trees (matched case-insensitively):
+# changelog - util-linux, coreutils, dbus, acpid, hdparm
+# changelog.md - libslirp, ttyrun, python3-maturin, libjpeg-turbo
+# changelog.rst - python3-pluggy, python3-packaging
+# changes - openssl, python3-babel, icu, tcl
+# changes.md - openssl
+# changes.rst - python3-babel, python3-pathspec
+# changes.txt - python3-lxml, icu
+# news - systemd, glib-2.0, libxml2, dbus
+# news.md - libxml2
+# news.rst - python3-sphinx
+# news.adoc - ccache
+# history.md - python3-requests, python3-hatch-vcs
+# history.rst - python3-idna, python3-docutils
+# releases.md - rust, cargo (includes CVEs)
+# whatsnew.txt - libsdl2
+_CHANGELOG_BASENAMES = {
+ 'changelog', 'changelog.md', 'changelog.rst', 'changelog.txt',
+ 'changes', 'changes.md', 'changes.rst', 'changes.txt',
+ 'news', 'news.md', 'news.rst', 'news.adoc',
+ 'history', 'history.md', 'history.rst',
+ 'releases.md',
+ 'whatsnew.txt',
+}
+
def _run(cmd, cwd=''):
logger.debug("Running command %s> %s" % (cwd,cmd))
return bb.process.run('%s' % cmd, cwd=cwd)
@@ -529,6 +555,63 @@ def _run_recipe_upgrade_extra_tasks(pn, rd, tinfoil):
if not res:
raise DevtoolError('Running extra recipe upgrade task %s for %s failed' % (task, pn))
+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
+
+ # Try to find a changelog file that changed between versions
+ try:
+ stdout, _ = _run('git diff --name-only %s %s' % (old_tag, new_tag), srctree)
+ for fname in stdout.splitlines():
+ fname = fname.strip() # strip whitespace/CR from git output
+ if not fname:
+ continue
+ basename = os.path.basename(fname).lower()
+ if basename in _CHANGELOG_BASENAMES:
+ diff_out, _ = _run('git diff %s %s -- %s' % (old_tag, new_tag, shlex.quote(fname)), srctree)
+ if diff_out.strip():
+ # Extract only the added lines from the diff
+ lines = [line[1:] for line in diff_out.splitlines()
+ if line.startswith('+') and not line.startswith('+++')]
+ if lines:
+ changelog_content = '\n'.join(lines)
+ break
+ # Per-version release notes (e.g., git RelNotes/2.53.0.adoc, mesa relnotes/26.0.3.rst)
+ elif re.search(r'(\d+[.\-])+\d+\.(txt|md|rst|adoc)$', basename):
+ file_content, _ = _run('git show %s' % shlex.quote('%s:%s' % (new_tag, fname)), srctree)
+ if file_content.strip():
+ changelog_content = file_content.strip()
+ break
+ except bb.process.ExecutionError as e:
+ logger.warning('Changelog file extraction failed: %s' % str(e))
+
+ # For git sources, fall back to git log if no changelog file was found
+ if not changelog_content and is_git_source:
+ try:
+ stdout, _ = _run('git log --oneline %s..%s' % (old_tag, new_tag), srctree)
+ if stdout.strip():
+ changelog_content = stdout.strip()
+ except bb.process.ExecutionError as e:
+ logger.warning('Changelog git log extraction failed: %s' % str(e))
+
+ if not changelog_content:
+ return None
+
+ # Clean up content for readability and commit message use
+ changelog_content = re.sub(r'\n{3,}', '\n\n', changelog_content).strip()
+ if not changelog_content:
+ return None
+
+ changelog_dir = os.path.join(workspace_path, 'changelogs')
+ bb.utils.mkdirhier(changelog_dir)
+ changelog_path = os.path.join(changelog_dir, '%s.txt' % pn)
+ with open(changelog_path, 'w') as f:
+ f.write('Changelog for %s: %s -> %s\n\n' % (pn, old_ver, new_ver))
+ f.write(changelog_content)
+ f.write('\n')
+
+ return changelog_path
+
def upgrade(args, config, basepath, workspace):
"""Entry point for the devtool 'upgrade' subcommand"""
@@ -610,6 +693,18 @@ def upgrade(args, config, basepath, workspace):
logger.info('Upgraded source extracted to %s' % srctree)
logger.info('New recipe is %s' % rf)
+
+ # Extract changelog between versions using the tags created by
+ # _extract_new_source(): devtool-base-new for git, devtool-base-<pv> for tarballs
+ is_git = old_srcrev is not None
+ newpv = args.version or rd.getVar('PV')
+ new_tag = 'devtool-base-new' if is_git else 'devtool-base-%s' % newpv
+ changelog_file = _extract_changelog(srctree, pn, old_ver, newpv,
+ 'devtool-base', new_tag,
+ config.workspace_path, is_git)
+ if changelog_file:
+ logger.info('Changelog extracted to %s' % changelog_file)
+
if license_diff:
logger.info('License checksums have been updated in the new recipe; please refer to it for the difference between the old and the new license texts.')
preferred_version = rd.getVar('PREFERRED_VERSION_%s' % rd.getVar('PN'))