Use python3-debian's Version class in merge-changelog, to support Python 3.

This commit is contained in:
Stefano Rivera 2019-09-04 19:01:41 -03:00
parent 66afe7c6fc
commit 3d345113cc
3 changed files with 11 additions and 177 deletions

1
debian/changelog vendored
View File

@ -4,6 +4,7 @@ ubuntu-dev-tools (0.173) UNRELEASED; urgency=medium
* pull-debian-debdiff: Don't unpack the older source package, it will often * pull-debian-debdiff: Don't unpack the older source package, it will often
use the same directory as the newer one, and break. use the same directory as the newer one, and break.
* Drop 404main, it's been totally broken for years. * Drop 404main, it's been totally broken for years.
* Use python3-debian's Version class in merge-changelog, to support Python 3.
[ Scott Kitterman ] [ Scott Kitterman ]
* Update requestsync to python3 (Closes: #927147) * Update requestsync to python3 (Closes: #927147)

View File

@ -1,4 +1,4 @@
#!/usr/bin/python #!/usr/bin/python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright © 2008 Canonical Ltd. # Copyright © 2008 Canonical Ltd.
# Author: Scott James Remnant <scott at ubuntu.com>. # Author: Scott James Remnant <scott at ubuntu.com>.
@ -21,15 +21,17 @@
import re import re
import sys import sys
from debian.debian_support import Version
def usage(exit_code=1): def usage(exit_code=1):
print '''Usage: merge-changelog <left changelog> <right changelog> print('''Usage: merge-changelog <left changelog> <right changelog>
merge-changelog takes two changelogs that once shared a common source, merge-changelog takes two changelogs that once shared a common source,
merges them back together, and prints the merged result to stdout. This merges them back together, and prints the merged result to stdout. This
is useful if you need to manually merge a ubuntu package with a new is useful if you need to manually merge a ubuntu package with a new
Debian release of the package. Debian release of the package.
''' ''')
sys.exit(exit_code) sys.exit(exit_code)
######################################################################## ########################################################################
@ -51,15 +53,15 @@ def merge_changelog(left_changelog, right_changelog):
for right_ver, right_text in right_cl: for right_ver, right_text in right_cl:
while len(left_cl) and left_cl[0][0] > right_ver: while len(left_cl) and left_cl[0][0] > right_ver:
(left_ver, left_text) = left_cl.pop(0) (left_ver, left_text) = left_cl.pop(0)
print left_text print(left_text)
while len(left_cl) and left_cl[0][0] == right_ver: while len(left_cl) and left_cl[0][0] == right_ver:
(left_ver, left_text) = left_cl.pop(0) (left_ver, left_text) = left_cl.pop(0)
print right_text print(right_text)
for _, left_text in left_cl: for _, left_text in left_cl:
print left_text print(left_text)
return False return False
@ -98,174 +100,6 @@ def read_changelog(filename):
return entries return entries
########################################################################
# Version parsing code
########################################################################
# Regular expressions make validating things easy
VALID_EPOCH = re.compile(r'^[0-9]+$')
VALID_UPSTREAM = re.compile(r'^[A-Za-z0-9+:.~-]*$')
VALID_REVISION = re.compile(r'^[A-Za-z0-9+.~]+$')
# Character comparison table for upstream and revision components
CMP_TABLE = "~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-.:"
class Version(object):
"""Debian version number.
This class is designed to be reasonably transparent and allow you
to write code like:
| s.version >= '1.100-1'
The comparison will be done according to Debian rules, so '1.2' will
compare lower.
Properties:
epoch Epoch
upstream Upstream version
revision Debian/local revision
"""
def __init__(self, ver):
"""Parse a string or number into the three components."""
self.epoch = 0
self.upstream = None
self.revision = None
ver = str(ver)
if not len(ver):
raise ValueError
# Epoch is component before first colon
idx = ver.find(":")
if idx != -1:
self.epoch = ver[:idx]
if not len(self.epoch):
raise ValueError
if not VALID_EPOCH.search(self.epoch):
raise ValueError
ver = ver[idx+1:]
# Revision is component after last hyphen
idx = ver.rfind("-")
if idx != -1:
self.revision = ver[idx+1:]
if not len(self.revision):
raise ValueError
if not VALID_REVISION.search(self.revision):
raise ValueError
ver = ver[:idx]
# Remaining component is upstream
self.upstream = ver
if not len(self.upstream):
raise ValueError
if not VALID_UPSTREAM.search(self.upstream):
raise ValueError
self.epoch = int(self.epoch)
def get_without_epoch(self):
"""Return the version without the epoch."""
string = self.upstream
if self.revision is not None:
string += "-%s" % (self.revision,)
return string
without_epoch = property(get_without_epoch)
def __str__(self):
"""Return the class as a string for printing."""
string = ""
if self.epoch > 0:
string += "%d:" % (self.epoch,)
string += self.upstream
if self.revision is not None:
string += "-%s" % (self.revision,)
return string
def __repr__(self):
"""Return a debugging representation of the object."""
return "<%s epoch: %d, upstream: %r, revision: %r>" \
% (self.__class__.__name__, self.epoch,
self.upstream, self.revision)
def __cmp__(self, other):
"""Compare two Version classes."""
other = Version(other)
result = cmp(self.epoch, other.epoch)
if result != 0:
return result
result = deb_cmp(self.upstream, other.upstream)
if result != 0:
return result
result = deb_cmp(self.revision or "", other.revision or "")
if result != 0:
return result
return 0
def strcut(string, idx, accept):
"""Cut characters from string that are entirely in accept."""
ret = ""
while idx < len(string) and string[idx] in accept:
ret += string[idx]
idx += 1
return (ret, idx)
def deb_order(string, idx):
"""Return the comparison order of two characters."""
if idx >= len(string):
return 0
elif string[idx] == "~":
return -1
else:
return CMP_TABLE.index(string[idx])
def deb_cmp_str(x, y):
"""Compare two strings in a deb version."""
idx = 0
while (idx < len(x)) or (idx < len(y)):
result = deb_order(x, idx) - deb_order(y, idx)
if result < 0:
return -1
elif result > 0:
return 1
idx += 1
return 0
def deb_cmp(x, y):
"""Implement the string comparison outlined by Debian policy."""
x_idx = y_idx = 0
while x_idx < len(x) or y_idx < len(y):
# Compare strings
(x_str, x_idx) = strcut(x, x_idx, CMP_TABLE)
(y_str, y_idx) = strcut(y, y_idx, CMP_TABLE)
result = deb_cmp_str(x_str, y_str)
if result != 0:
return result
# Compare numbers
(x_str, x_idx) = strcut(x, x_idx, "0123456789")
(y_str, y_idx) = strcut(y, y_idx, "0123456789")
result = cmp(int(x_str or "0"), int(y_str or "0"))
if result != 0:
return result
return 0
def main(): def main():
if len(sys.argv) > 1 and sys.argv[1] in ('-h', '--help'): if len(sys.argv) > 1 and sys.argv[1] in ('-h', '--help'):
usage(0) usage(0)

View File

@ -26,6 +26,7 @@ if sys.version_info[0] >= 3:
'grep-merges', 'grep-merges',
'hugdaylist', 'hugdaylist',
'import-bug-from-debian', 'import-bug-from-debian',
'merge-changelog',
'mk-sbuild', 'mk-sbuild',
'pbuilder-dist', 'pbuilder-dist',
'pbuilder-dist-simple', 'pbuilder-dist-simple',
@ -55,9 +56,7 @@ if sys.version_info[0] >= 3:
('share/ubuntu-dev-tools', ['enforced-editing-wrapper']), ('share/ubuntu-dev-tools', ['enforced-editing-wrapper']),
] ]
else: else:
scripts = [ scripts = []
'merge-changelog',
]
data_files = [] data_files = []
if __name__ == '__main__': if __name__ == '__main__':