mirror of
https://git.launchpad.net/ubuntu-dev-tools
synced 2025-05-05 05:51:29 +00:00
[ Ryan Kavanagh ]
* Added the merge-changelog script from https://lists.ubuntu.com/archives/ubuntu-x/2009-June/000586.html for those who need to manually merge packages. * Fixed typo in doc/grab-merge.1
This commit is contained in:
commit
0ee66adc16
10
debian/changelog
vendored
10
debian/changelog
vendored
@ -1,3 +1,13 @@
|
|||||||
|
ubuntu-dev-tools (0.98) UNRELEASED; urgency=low
|
||||||
|
|
||||||
|
[ Ryan Kavanagh ]
|
||||||
|
* Added the merge-changelog script from
|
||||||
|
https://lists.ubuntu.com/archives/ubuntu-x/2009-June/000586.html for those
|
||||||
|
who need to manually merge packages.
|
||||||
|
* Fixed typo in doc/grab-merge.1
|
||||||
|
|
||||||
|
-- Michael Bienia <geser@ubuntu.com> Thu, 08 Apr 2010 13:21:48 +0200
|
||||||
|
|
||||||
ubuntu-dev-tools (0.97) lucid; urgency=low
|
ubuntu-dev-tools (0.97) lucid; urgency=low
|
||||||
|
|
||||||
[ Michael Bienia ]
|
[ Michael Bienia ]
|
||||||
|
2
debian/control
vendored
2
debian/control
vendored
@ -45,6 +45,8 @@ Description: useful tools for Ubuntu developers
|
|||||||
- lp-set-dup - sets the "duplicate of" bug of a bug and its dups.
|
- lp-set-dup - sets the "duplicate of" bug of a bug and its dups.
|
||||||
- manage-credentials - manage Launchpad token credentials.
|
- manage-credentials - manage Launchpad token credentials.
|
||||||
- massfile - fill multiple bugs using a template.
|
- massfile - fill multiple bugs using a template.
|
||||||
|
- merge-changelog - manually merges two Debian changelogs with the same base
|
||||||
|
version.
|
||||||
- mk-sbuild - script to create LVM snapshot chroots via schroot and
|
- mk-sbuild - script to create LVM snapshot chroots via schroot and
|
||||||
sbuild.
|
sbuild.
|
||||||
- pbuilder-dist, cowbuilder-dist - wrapper script for managing several build
|
- pbuilder-dist, cowbuilder-dist - wrapper script for managing several build
|
||||||
|
11
debian/copyright
vendored
11
debian/copyright
vendored
@ -5,6 +5,7 @@ Upstream Authors:
|
|||||||
|
|
||||||
Albert Damen <albrt@gmx.net>
|
Albert Damen <albrt@gmx.net>
|
||||||
Albin Tonnerre <lut1n.tne@gmail.com>
|
Albin Tonnerre <lut1n.tne@gmail.com>
|
||||||
|
Bryce Harrington <bryce@ubuntu.com>
|
||||||
Daniel Hahler <ubuntu@thequod.de>
|
Daniel Hahler <ubuntu@thequod.de>
|
||||||
Daniel Holbach <daniel.holbach@ubuntu.com>
|
Daniel Holbach <daniel.holbach@ubuntu.com>
|
||||||
Emmet Hikory <persia@ubuntu.com>
|
Emmet Hikory <persia@ubuntu.com>
|
||||||
@ -45,7 +46,7 @@ Copyright:
|
|||||||
(C) 2008, 2009, Nathan Handler <nhandler@ubuntu.com>
|
(C) 2008, 2009, Nathan Handler <nhandler@ubuntu.com>
|
||||||
(C) Patrick Schoenfeld <schoenfeld@debian.org>
|
(C) Patrick Schoenfeld <schoenfeld@debian.org>
|
||||||
(C) 2006-2007, Pete Savage <petesavage@ubuntu.com>
|
(C) 2006-2007, Pete Savage <petesavage@ubuntu.com>
|
||||||
(C) 2009 Ryan Kavanagh <ryanakca@kubuntu.org>
|
(C) 2009-2010 Ryan Kavanagh <ryanakca@kubuntu.org>
|
||||||
(C) 2007-2009, Siegfried-A. Gevatter <rainct@ubuntu.com>
|
(C) 2007-2009, Siegfried-A. Gevatter <rainct@ubuntu.com>
|
||||||
(C) 2008, Stephan Hermann <sh@sourcecode.de>
|
(C) 2008, Stephan Hermann <sh@sourcecode.de>
|
||||||
(C) 2007 Steve Kowalik <stevenk@ubuntu.com>
|
(C) 2007 Steve Kowalik <stevenk@ubuntu.com>
|
||||||
@ -70,10 +71,10 @@ On Debian and Ubuntu systems, the complete text of the GNU General Public
|
|||||||
License v2 can be found in `/usr/share/common-licenses/GPL-2'.
|
License v2 can be found in `/usr/share/common-licenses/GPL-2'.
|
||||||
|
|
||||||
dch-repeat, get-branches, get-build-deps, grab-attachments, grab-merge,
|
dch-repeat, get-branches, get-build-deps, grab-attachments, grab-merge,
|
||||||
hugdaylist, manage-credentials, massfile, mk-sbuild, pbuilder-dist-simple,
|
hugdaylist, manage-credentials, massfile, merge-changelog, mk-sbuild,
|
||||||
pull-debian-debdiff, pull-debian-source, pull-lp-source, pull-revu-source,
|
pbuilder-dist-simple, pull-debian-debdiff, pull-debian-source, pull-lp-source,
|
||||||
setup-packaging-environment, suspicious-source, ubuntu-build and what-patch are
|
pull-revu-source, setup-packaging-environment, suspicious-source, ubuntu-build
|
||||||
licensed under the GNU General Public License, version 3:
|
and what-patch are licensed under the GNU General Public License, version 3:
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
.TH grab\-merge 1 "Marh 26, 2009" "ubuntu-dev-tools"
|
.TH grab\-merge 1 "March 26, 2009" "ubuntu-dev-tools"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
grab\-merge \- grab's a merge's files from merges.ubuntu.com.
|
grab\-merge \- grabs a merge's files from merges.ubuntu.com.
|
||||||
|
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
\fBgrab\-merge\fP <\fIpackage name\fP>
|
\fBgrab\-merge\fP <\fIpackage name\fP>
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
\fB404main\fP is a script that downloads a merge's packaging files and report
|
\fBgrab\-merge\fP is a script that downloads a merge's packaging files and report
|
||||||
from merges.ubuntu.com. Placing them in a new directory for working from.
|
from merges.ubuntu.com. Placing them in a new directory for working from.
|
||||||
|
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
|
20
doc/merge-changelog.1
Normal file
20
doc/merge-changelog.1
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
.TH merge-changelog 1 "February 15, 2010" "ubuntu-dev-tools"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
merge\-changelog \- merges two changelogs with a common base
|
||||||
|
|
||||||
|
.SH SYNOPSIS
|
||||||
|
\fBmerge\-changelog\fP <\fIleft changelog\fP> <\fIright changelog\fP>
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fBmerge\-changelog\fP takes two changelogs that once shared a common source,
|
||||||
|
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
|
||||||
|
Debian release of the package.
|
||||||
|
|
||||||
|
.SH AUTHORS
|
||||||
|
\fBmerge\-changelog\fP was written by Scott James Remnant <scott@ubuntu.com>
|
||||||
|
and Bryce Harrington <bryce@ubuntu.com>. This manpage was written by Ryan
|
||||||
|
Kavanagh <ryanakca@kubuntu.org>.
|
||||||
|
.PP
|
||||||
|
Both are released under the GNU General Public License, version 3.
|
266
merge-changelog
Executable file
266
merge-changelog
Executable file
@ -0,0 +1,266 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright © 2008 Canonical Ltd.
|
||||||
|
# Author: Scott James Remnant <scott at ubuntu.com>.
|
||||||
|
# Hacked up by: Bryce Harrington <bryce at ubuntu.com>
|
||||||
|
# Change merge_changelog to merge-changelog: Ryan Kavanagh
|
||||||
|
# <ryanakca@kubuntu.org>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of version 3 of the GNU General Public License as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import os, sys, re, time, logging
|
||||||
|
|
||||||
|
from stat import *
|
||||||
|
from textwrap import fill
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print '''Usage: merge-changelog <left changelog> <right changelog>
|
||||||
|
|
||||||
|
merge-changelog takes two changelogs that once shared a common source,
|
||||||
|
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
|
||||||
|
Debian release of the package.
|
||||||
|
'''
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# Changelog Management
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
# Regular expression for top of debian/changelog
|
||||||
|
CL_RE = re.compile(r'^(\w[-+0-9a-z.]*) \(([^\(\) \t]+)\)((\s+[-0-9a-z]+)+)\;',
|
||||||
|
re.IGNORECASE)
|
||||||
|
|
||||||
|
def merge_changelog(left_changelog, right_changelog):
|
||||||
|
"""Merge a changelog file."""
|
||||||
|
|
||||||
|
left_cl = read_changelog(left_changelog)
|
||||||
|
right_cl = read_changelog(right_changelog)
|
||||||
|
|
||||||
|
for right_ver, right_text in right_cl:
|
||||||
|
while len(left_cl) and left_cl[0][0] > right_ver:
|
||||||
|
(left_ver, left_text) = left_cl.pop(0)
|
||||||
|
print left_text
|
||||||
|
|
||||||
|
while len(left_cl) and left_cl[0][0] == right_ver:
|
||||||
|
(left_ver, left_text) = left_cl.pop(0)
|
||||||
|
|
||||||
|
print right_text
|
||||||
|
|
||||||
|
for left_ver, left_text in left_cl:
|
||||||
|
print left_text
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def read_changelog(filename):
|
||||||
|
"""Return a parsed changelog file."""
|
||||||
|
entries = []
|
||||||
|
|
||||||
|
cl = open(filename)
|
||||||
|
try:
|
||||||
|
(ver, text) = (None, "")
|
||||||
|
for line in cl:
|
||||||
|
match = CL_RE.search(line)
|
||||||
|
if match:
|
||||||
|
try:
|
||||||
|
ver = Version(match.group(2))
|
||||||
|
except ValueError:
|
||||||
|
ver = None
|
||||||
|
|
||||||
|
text += line
|
||||||
|
elif line.startswith(" -- "):
|
||||||
|
if ver is None:
|
||||||
|
ver = Version("0")
|
||||||
|
|
||||||
|
text += line
|
||||||
|
entries.append((ver, text))
|
||||||
|
(ver, text) = (None, "")
|
||||||
|
elif len(line.strip()) or ver is not None:
|
||||||
|
text += line
|
||||||
|
finally:
|
||||||
|
cl.close()
|
||||||
|
|
||||||
|
if len(text):
|
||||||
|
entries.append((ver, text))
|
||||||
|
|
||||||
|
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 getWithoutEpoch(self):
|
||||||
|
"""Return the version without the epoch."""
|
||||||
|
str = self.upstream
|
||||||
|
if self.revision is not None:
|
||||||
|
str += "-%s" % (self.revision,)
|
||||||
|
return str
|
||||||
|
|
||||||
|
without_epoch = property(getWithoutEpoch)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""Return the class as a string for printing."""
|
||||||
|
str = ""
|
||||||
|
if self.epoch > 0:
|
||||||
|
str += "%d:" % (self.epoch,)
|
||||||
|
str += self.upstream
|
||||||
|
if self.revision is not None:
|
||||||
|
str += "-%s" % (self.revision,)
|
||||||
|
return str
|
||||||
|
|
||||||
|
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(str, idx, accept):
|
||||||
|
"""Cut characters from str that are entirely in accept."""
|
||||||
|
ret = ""
|
||||||
|
while idx < len(str) and str[idx] in accept:
|
||||||
|
ret += str[idx]
|
||||||
|
idx += 1
|
||||||
|
|
||||||
|
return (ret, idx)
|
||||||
|
|
||||||
|
def deb_order(str, idx):
|
||||||
|
"""Return the comparison order of two characters."""
|
||||||
|
if idx >= len(str):
|
||||||
|
return 0
|
||||||
|
elif str[idx] == "~":
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
return cmp_table.index(str[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
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
if len(sys.argv) != 3:
|
||||||
|
usage()
|
||||||
|
|
||||||
|
left_changelog = sys.argv[1]
|
||||||
|
right_changelog = sys.argv[2]
|
||||||
|
|
||||||
|
merge_changelog(left_changelog, right_changelog)
|
||||||
|
sys.exit(0)
|
Loading…
x
Reference in New Issue
Block a user