Bug#460101: python-debian: add update function to PackageFile which yields changed packages
Mike O'Connor
stew at vireo.org
Thu Jan 10 15:40:29 UTC 2008
Package: python-debian
Version: 0.1.8
Severity: wishlist
Tags: patch
*** Please type your report below this line *** When I update a
Packages using pdiffs with patchLines debian_support.updateFile, I
really would like to know exectly which Packages inside the Packages
file are affected.
Attached I a patch which adds:
def update( self, remote, verbose=None):
to PackageFile which will update the PackageFile, and iterate through
the list of Packages which have changed.
Please look it over and consider applying.
thanks,
stew
-- System Information:
Debian Release: lenny/sid
APT prefers testing
APT policy: (990, 'testing'), (500, 'unstable')
Architecture: amd64 (x86_64)
Kernel: Linux 2.6.22-3-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Versions of packages python-debian depends on:
ii python 2.4.4-6 An interactive high-level object-o
ii python-support 0.7.5 automated rebuilding support for p
python-debian recommends no packages.
-- no debconf information
-------------- next part --------------
--- /var/lib/python-support/python2.4/debian_bundle/debian_support.py 2007-12-28 13:46:42.000000000 -0500
+++ /tmp/debian_support.py 2008-01-10 09:37:35.000000000 -0500
@@ -102,40 +102,73 @@
self.file = fileObj
self.lineno = 0
- def __iter__(self):
- line = self.file.readline()
- self.lineno += 1
- pkg = []
- while line:
- if line == '\n':
- if len(pkg) == 0:
- self.raiseSyntaxError('expected package record')
- yield pkg
- pkg = []
- line = self.file.readline()
- self.lineno += 1
- continue
-
- match = self.re_field.match(line)
- if not match:
- self.raiseSyntaxError("expected package field")
- (name, contents) = match.groups()
- contents = contents or ''
-
- while True:
- line = self.file.readline()
- self.lineno += 1
- match = self.re_continuation.match(line)
- if match:
- (ncontents,) = match.groups()
- if ncontents is None:
- ncontents = ""
- contents = "%s\n%s" % (contents, ncontents)
+ def update( self, remote, verbose=None):
+ """
+ updates the local file from the given remote site, and
+ iterates through the packages which have changed
+ """
+ changed_lines = set()
+ lines = updateFile(remote, self.name, verbose, changed_lines)
+
+ self.file = file(self.name)
+ self.lineno = 0
+ return self.__iter__( sorted( changed_lines ) )
+
+ def __iter__(self, changed_lines=None):
+ """
+ iterate through packages which contain the given lines.
+ """
+ try:
+ line = self.file.readline()
+ self.lineno += 1
+ pkg = []
+ while line:
+ if line == '\n':
+ if len(pkg) == 0:
+ self.raiseSyntaxError('expected package record')
+ if changed_lines is not None:
+ if self.lineno >= changed_lines[0]:
+ while( changed_lines[ 0 ] < self.lineno ):
+ changed_lines.pop( 0 )
+ yield pkg
+ else:
+ yield pkg
+
+ pkg = []
+ line = self.file.readline()
+ self.lineno += 1
+ continue
+
+ match = self.re_field.match(line)
+ if not match:
+ self.raiseSyntaxError("expected package field. instead got:" + line)
+ (name, contents) = match.groups()
+ contents = contents or ''
+
+ while True:
+ line = self.file.readline()
+ self.lineno += 1
+ match = self.re_continuation.match(line)
+ if match:
+ (ncontents,) = match.groups()
+ if ncontents is None:
+ ncontents = ""
+ contents = "%s\n%s" % (contents, ncontents)
+ else:
+ break
+ pkg.append((name, contents))
+ if pkg:
+ if changed_lines is not None:
+ if self.lineno >= lines[0]:
+ while( lines[ 0 ] < self.lineno ):
+ lines.pop( 0 )
+ yield pkg
else:
- break
- pkg.append((name, contents))
- if pkg:
- yield pkg
+ yield pkg
+
+ except IndexError:
+ # we must be out of changed lines, so we are done
+ return
def raiseSyntaxError(self, msg, lineno=None):
if lineno is None:
@@ -229,13 +262,30 @@
lines.append(l)
yield (first, last, lines)
-def patchLines(lines, patches):
- """Applies patches to lines. Updates lines in place."""
+class adjust_changed_lines:
+ def __init__( self, after, delta ):
+ self.after, self.delta = after, delta
+
+ def __call__( self, line ):
+ if line >= self.after:
+ return line + self.delta
+ else:
+ return line
+
+def patchLines(lines, patches, changed=None):
+ """
+ Applies patches to lines. Updates lines in place.
+ if changed is a set, it is updated with a list of lines which are new
+ """
for (first, last, args) in patches:
lines[first:last] = args
+ if isinstance( changed, set ):
+ new_changed = set( map( adjust_changed_lines( first, len( args) + first - last ), changed ) )
+ changed.clear()
+ changed.update( new_changed )
+ changed.update( range( first, first+len( args ) ) )
def replaceFile(lines, local):
-
import os.path
local_new = local + '.new'
@@ -284,7 +334,7 @@
replaceFile(lines, local)
return lines
-def updateFile(remote, local, verbose=None):
+def updateFile(remote, local, verbose=None, changed_lines=None):
"""Updates the local file by downloading a remote patch.
Returns a list of lines in the local file.
@@ -369,7 +419,7 @@
+ '.gz')
if readLinesSHA1(patch_contents ) <> patch_hashes[patch_name]:
raise ValueError, "patch %s was garbled" % `patch_name`
- patchLines(lines, patchesFromEdScript(patch_contents))
+ patchLines(lines, patchesFromEdScript(patch_contents), changed_lines)
new_hash = readLinesSHA1(lines)
if new_hash <> remote_hash:
More information about the pkg-python-debian-maint
mailing list