Source code for libka.pkgedit.ka_changelog

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# pylint: disable=line-too-long
# kate: space-indent on; indent-width 4; replace-tabs on; indent-mode python; remove-trailing-space modified;
# vim: expandtab ts=4
# pylint: enable=line-too-long

############################################################################
#   Copyright © 2018-2024 José Manuel Santamaría Lema <panfaust@gmail.com> #
#                                                                          #
#   This program is free software; you can redistribute it and/or modify   #
#   it under the terms of the GNU General Public License as published by   #
#   the Free Software Foundation; either version 2 of the License, or      #
#   (at your option) any later version.                                    #
############################################################################

"""This module just provides the KAChangelog class"""

import codecs
import subprocess
import time
import re

from debian.changelog import Changelog
from debian.changelog import get_maintainer

from libka.ubuntu_info import ubuntu_dist_version_from_name, ubuntu_dist_name_from_version
from libka.ka_print import ka_print_good_stuff
from libka.ka_print import ka_print_plain

[docs] class KAChangelog(Changelog): """ This class is meant to represent a debian/changelog file. """ def __init__(self, file_path='debian/changelog'): Changelog.__init__(self) self._file_path = file_path # pylint: disable=arguments-differ
[docs] def parse_changelog(self): """Parses a changelog file.""" try: Changelog.parse_changelog(self, codecs.open(self._file_path, 'r', 'utf-8')) except Exception as exception: raise Exception(("Couldn't open %s\n" % self._file_path) + str(exception))
# pylint: disable=arguments-differ
[docs] def get_last_released_version(self): """ This function returns the last released version i.e. the version from the most recent changelog block ignoring 'UNRELEASED' changelog blocks. """ result = None for changelog_block in self: if str(changelog_block.distributions) != 'UNRELEASED': result = changelog_block.version break return result
[docs] def get_last_ubuntu_released_version(self): """ This function returns the last released version i.e. the version from the most recent changelog block ignoring 'UNRELEASED' changelog blocks. """ result = None ignored_blocks = ['UNRELEASED', 'experimental', 'unstable'] for changelog_block in self: if str(changelog_block.distributions) not in ignored_blocks: result = changelog_block.version break return result
[docs] def convert2sru(self, lp_bug_number=None, force=False): """ This method will edit the last changelog block to be fit for a SRU. If `force` is `True` it will perform the operation ignoring safety checks. """ #Convert the lp bug number to string, just in case lp_bug_number = str(lp_bug_number) #Set changelog distributionn ka_print_good_stuff("Changing changelog distribution:") old_dist = self.distributions new_dist = 'UNRELEASED' self.set_distributions(new_dist) ka_print_plain("%s -> %s" % (old_dist, new_dist)) #Set changelog version ka_print_good_stuff("Changing changelog version:") old_version = str(self.version) match = re.match('.*ubuntu1$', old_version) if (match is None) and not force: raise Exception("Changelog version does't end with 'ubuntu1', aborting SRU" "conversion.\n") new_version = re.sub('ubuntu1$', 'ubuntu0.1', old_version) self.set_version(new_version) ka_print_plain("%s -> %s" % (old_version, new_version)) #Add the LP bug number if lp_bug_number is not None: ka_print_good_stuff("Adding Launchpad bug number: ", end='') ka_print_plain(lp_bug_number) #Read info from the latest changelog block latest_changelog_block = next(iter(self)) orig_changelog_entries = latest_changelog_block.changes() #Prepare the new list of changelog entries final_changelog_entries = [] #Populate the new list of changelog entries, adding the LP bug to the #'New upstream release' line for changelog_entry in orig_changelog_entries: match = re.match('.*New upstream release.*', changelog_entry) if match is not None: changelog_entry = '%s (LP: #%s)' % (changelog_entry, lp_bug_number) final_changelog_entries.append(changelog_entry) #Set the final changelog entries #NOTE: Yes, it's true we shouldn't access objects 'private' variables, # however it seems there's no other way to do this with python-debian latest_changelog_block._changes = final_changelog_entries # pylint: disable=protected-access
[docs] def refresh_date(self): """ Executing this method will refresh the date in the last changelog block """ #Abort if the last changelog entry isn't 'UNRELEASED' if self.distributions != "UNRELEASED": raise Exception("Last changelog block distribution is not 'UNRELEASED'.") #Refresh changelog date self.set_date(time.strftime('%a, %d %b %Y %X %z'))
[docs] def new_upstream_release(self, new_upstream_version, stability=None): """ This method will prepare the changelog for a new upstream release. The `stability` parameter may be a string such as "beta" or "RC", if this parameter is different than `None` the changelog entry will say if the new release in question is a beta version, release candidate or whatever. """ #Convert the new upstream version to string, just in case new_upstream_version = str(new_upstream_version) #Create the text line to add to the changelog block if stability is None: new_upstream_release_text = 'New upstream release (%s)' % new_upstream_version else: new_upstream_release_text = ('New upstream (%s) release (%s)' % (stability, new_upstream_version)) #Find out the maintainer text for the changelog trailer maintainer_str = "%s <%s>" % get_maintainer() #Find out the new package version upstream_pkg_version = str(self.get_version().upstream_version) if upstream_pkg_version.endswith('+dfsg'): new_upstream_version += '+dfsg' epoch = self.get_version().epoch if epoch is not None: new_pkg_version_str = epoch + ":" + new_upstream_version else: new_pkg_version_str = new_upstream_version new_pkg_version_str += "-0ubuntu1" #Add the new changelog block or reuse the last one to get new_upstream_release_text in if self.distributions != "UNRELEASED": #If latest changelog entry is not 'UNRELEASED' we have to create a new changelog block self.new_block(package=self.get_package(), version=new_pkg_version_str, distributions="UNRELEASED", urgency='medium', author=maintainer_str, date=time.strftime('%a, %d %b %Y %X %z')) #Add the first changelog entry self.add_change('') self.add_change(' * ' + new_upstream_release_text) self.add_change('') else: #Set the new version self.set_version(new_pkg_version_str) #Add the "New upstream release" entry #Apparently we can't do this with python-debian right now self.dump() subprocess.call(["dch", "--urgency", "medium", "--multimaint-merge", new_upstream_release_text]) self.parse_changelog() #Update the maintainer trailer self.set_author(maintainer_str) self.set_date(time.strftime('%a, %d %b %Y %X %z'))
# pylint: disable=no-self-use
[docs] def get_ppa_suffix(self, dist, suffix_number): """ Returns a PPA suffix for the changelog. """ #Find out dist_version dist_version = ubuntu_dist_version_from_name(dist) #Create the suffix string suffix_string = "~ubuntu%s~ppa%s" % (dist_version, str(suffix_number)) #Return result return suffix_string
# pylint: enable=no-self-use
[docs] def add_ppa_suffix(self, dist, suffix_number): """ This method will append to the package version a suffix following this formula: ~ubuntu<dist_version>~ppa<suffix_number> It will also set the distribution name in the top changelog block. """ #Find out dist_version and dist_name dist_version = ubuntu_dist_version_from_name(dist) dist_name = ubuntu_dist_name_from_version(dist_version) #Create the suffix string suffix_string = self.get_ppa_suffix(dist, suffix_number) #Alter the changelog version, distribution and maint trailer version = str(self.get_version()) + suffix_string self.set_urgency("high") self.set_version(version) self.set_distributions(dist_name) maintainer_str = "%s <%s>" % get_maintainer() self.set_author(maintainer_str)
# pylint: disable=no-self-use
[docs] def get_qt_ppa_suffix(self, dist, end_number, begin_number=0): """ Returns a Qt PPA suffix for the changelog. """ #Find out dist_version dist_version = ubuntu_dist_version_from_name(dist) #Create the suffix string suffix_string = "~%s~ubuntu%s~ppa%s" % (str(begin_number), dist_version, str(end_number)) #Return result return suffix_string
# pylint: enable=no-self-use
[docs] def add_qt_ppa_suffix(self, dist, end_number, begin_number=0): """ This method will append to the package version a suffix following this formula: ~<begin_number>~ubuntu<dist_version>~ppa<end_number> It will also set the distribution name in the top changelog block. """ #Find out dist_version and dist_name dist_version = ubuntu_dist_version_from_name(dist) dist_name = ubuntu_dist_name_from_version(dist_version) #Create the suffix string suffix_string = self.get_qt_ppa_suffix(dist, end_number, begin_number) #Alter the changelog version, distribution and maint trailer version = str(self.get_version()) + suffix_string self.set_urgency("high") self.set_version(version) self.set_distributions(dist_name) maintainer_str = "%s <%s>" % get_maintainer() self.set_author(maintainer_str)
# pylint: disable=no-self-use, unused-argument
[docs] def get_tritemio_suffix(self, dist, suffix_number): """ Returns a string providing a tritemio suffix for the changelog """ # Get current version and find out if it's a debian version, see in the comment below why # we need this current_version = str(self.get_version()) is_ubuntu_version = re.search(r'ubuntu', current_version) is not None #If we have a debian version, we also need to append 'ubuntu0' to avoid situations like #this: # 1. package has a 1.0-1 version, synced with debian # 2. this package gets uploaded to tritemio with version '1.0-1+tritemio1' # 3. this package is uploaded again officially to ubuntu as '1.0-1ubuntu1' # 4. we try to rebuild this package again for tritemio, that would be with # version '1.0-1ubuntu1+tritemio1', however this version is lower than # the previous upload to tritemio, which was '1.0-1+tritemio1', and this # will make wannabuild unable to rebuild the package unless we edit # manually the wannabuild database if is_ubuntu_version: suffix_string = "+tritemio%s" % str(suffix_number) else: suffix_string = "ubuntu0+tritemio%s" % str(suffix_number) #Return result return suffix_string
# pylint: disable=no-self-use, unused-argument
[docs] def add_tritemio_suffix(self, dist, suffix_number): """ This method will append to the package version a suffix following this formula: +tritemio<suffix_number> It will also set the distribution name in the top changelog block. """ #Create the suffix string suffix_string = self.get_tritemio_suffix(dist, suffix_number) #Alter the changelog version, distribution and maint trailer version = str(self.get_version()) + suffix_string self.set_version(version) self.set_distributions(dist) maintainer_str = "%s <%s>" % get_maintainer() self.set_author(maintainer_str)
[docs] def make_ubuntu_release(self, dist): """ This method will prepare the changelog for an Ubuntu archive upload. """ #Abort if the last changelog entry isn't 'UNRELEASED' if self.distributions != "UNRELEASED": raise Exception("Last changelog block distribution is not 'UNRELEASED'.") #Edit last changelog entry - maint trailer. self.dump() subprocess.check_call(["dch", "-r", "-m", "-D", dist, "--multimaint-merge", ""]) self.parse_changelog()
[docs] def dump(self): """Dump to hard disk all the changes made so far""" self.write_to_open_file(codecs.open(self._file_path, 'w', 'utf-8'))