[Pkg-bazaar-commits] r130 ./bzr-builddeb/people/jdw/merge_upstream: Improve the handling of strange .dsc files.

James Westby jw+debian at jameswestby.net
Tue Jun 26 18:45:53 UTC 2007


------------------------------------------------------------
revno: 130
committer: James Westby <jw+debian at jameswestby.net>
branch nick: merge_upstream
timestamp: Tue 2007-06-26 19:45:53 +0100
message:
  Improve the handling of strange .dsc files.
modified:
  errors.py
  import_dsc.py
  tests/test_import_dsc.py
-------------- next part --------------
=== modified file 'errors.py'
--- a/errors.py	2007-06-18 21:57:14 +0000
+++ b/errors.py	2007-06-26 18:45:53 +0000
@@ -70,3 +70,10 @@
     BzrError.__init__(self)
     self.changelog = changelog
 
+class ImportError(DebianError):
+  _fmt = """The files could not be imported: %(reason)s"""
+
+  def __init__(self, reason):
+    BzrError.__init__(self)
+    self.reason = reason
+

=== modified file 'import_dsc.py'
--- a/import_dsc.py	2007-06-26 17:33:10 +0000
+++ b/import_dsc.py	2007-06-26 18:45:53 +0000
@@ -36,27 +36,45 @@
                                                      common_directory,
                                                      )
 
+from errors import ImportError
 from merge_upstream import make_upstream_tag
 import patches
 
-def _dsc_sorter(dscname1, dscname2):
-  f1 = open(dscname1)
-  try:
-    dsc1 = deb822.Dsc(f1)
-  finally:
-    f1.close()
-  f2 = open(dscname2)
-  try:
-    dsc2 = deb822.Dsc(f2)
-  finally:
-    f2.close()
-  v1 = Version(dsc1['Version'])
-  v2 = Version(dsc2['Version'])
-  if v1 == v2:
-    return 0
-  if v1 > v2:
-    return 1
-  return -1
+# TODO: support native packages (should be easy).
+# TODO: Use a transport to retrieve the files, so that they can be got remotely
+
+class DscCache(object):
+
+  def __init__(self):
+    self.cache = {}
+
+  def get_dsc(self, name):
+    if name in self.cache:
+      dsc1 = self.cache[name]
+    else:
+      f1 = open(name)
+      try:
+        dsc1 = deb822.Dsc(f1)
+      finally:
+        f1.close()
+      self.cache[name] = dsc1
+    return dsc1
+
+class DscComp(object):
+
+  def __init__(self, cache):
+    self.cache = cache
+
+  def cmp(self, dscname1, dscname2):
+    dsc1 = self.cache.get_dsc(dscname1)
+    dsc2 = self.cache.get_dsc(dscname2)
+    v1 = Version(dsc1['Version'])
+    v2 = Version(dsc2['Version'])
+    if v1 == v2:
+      return 0
+    if v1 > v2:
+      return 1
+    return -1
 
 
 def import_orig(tree, origname, version, last_upstream=None):
@@ -157,6 +175,38 @@
 def import_dsc(target_dir, dsc_files):
   if os.path.exists(target_dir):
     raise FileExists(target_dir)
+  cache = DscCache()
+  dsc_files.sort(cmp=DscComp(cache).cmp)
+  safe_files = []
+  for dscname in dsc_files:
+    dsc = cache.get_dsc(dscname)
+    orig_file = None
+    diff_file = None
+    for file_details in dsc['files']:
+      name = file_details['name']
+      if name.endswith('.orig.tar.gz'):
+        if orig_file is not None:
+          raise ImportError("%s contains more than one .orig.tar.gz" % dscname)
+        orig_file = name
+      elif name.endswith('.diff.gz'):
+        if diff_file is not None:
+          raise ImportError("%s contains more than one .diff.gz" % dscname)
+        diff_file = name
+    if diff_file is None:
+      raise ImportError("%s contains only a .orig.tar.gz, it must contain a "
+                        ".diff.gz as well" % dscname)
+    version = Version(dsc['Version'])
+    if orig_file is not None:
+      safe_files.append((orig_file, version, 'orig'))
+    found = False
+    for safe_file in safe_files:
+      if safe_file[0].endswith("_%s.orig.tar.gz" % version.upstream_version):
+        found = True
+        break
+    if found == False:
+      raise ImportError("There is no upstream version corresponding to %s" % \
+                          diff_file)
+    safe_files.append((diff_file, version, 'diff'))
   os.mkdir(target_dir)
   format = bzrdir.format_registry.make_bzrdir('dirstate-tags')
   branch  = bzrdir.BzrDir.create_branch_convenience(target_dir,
@@ -164,34 +214,16 @@
   tree = branch.bzrdir.open_workingtree()
   tree.lock_write()
   try:
-    dsc_files.sort(cmp=_dsc_sorter)
     last_upstream = None
-    for dscname in dsc_files:
-      f = open(dscname)
-      try:
-        dsc = deb822.Dsc(f)
-      finally:
-        f.close()
-      orig_files = []
-      diff_files = []
-      for file_details in dsc['files']:
-        name = file_details['name']
-        if name.endswith('.orig.tar.gz'):
-          orig_files.append(name)
-        elif name.endswith('.diff.gz'):
-          diff_files.append(name)
-      assert len(orig_files) < 2, "I don't know how to import a source " \
-                                  "package with multiple .orig.tar.gz files."
-      assert len(diff_files) == 1, "I don't know how to import a source " \
-                                   "package which doesn't have a single " \
-                                   ".diff.gz file."
-      version = Version(dsc['Version'])
-      dangling_revid = None
-      if len(orig_files) == 1:
-        dangling_revid = import_orig(tree, orig_files[0], version,
+    dangling_revid = None
+    for (filename, version, type) in safe_files:
+      if type == 'orig':
+        dangling_revid = import_orig(tree, filename, version,
                                      last_upstream=last_upstream)
         last_upstream = version.upstream_version
-      import_diff(tree, diff_files[0], version, dangling_revid=dangling_revid)
+      elif type == 'diff':
+        import_diff(tree, filename, version, dangling_revid=dangling_revid)
+        dangling_revid = None
   finally:
     tree.unlock()
 

=== modified file 'tests/test_import_dsc.py'
--- a/tests/test_import_dsc.py	2007-06-26 17:33:10 +0000
+++ b/tests/test_import_dsc.py	2007-06-26 18:45:53 +0000
@@ -26,6 +26,7 @@
 from bzrlib.tests import TestCaseWithTransport
 from bzrlib.workingtree import WorkingTree
 
+from errors import ImportError
 from import_dsc import import_dsc
 
 def write_to_file(filename, contents):
@@ -121,7 +122,7 @@
     os.system('diff -Nru %s %s | gzip -9 - > %s' % (self.basedir, diffdir,
                                                    self.diff_2))
 
-  def make_dsc(self, filename, version, file1, file2=None):
+  def make_dsc(self, filename, version, file1, extra_files=[]):
     write_to_file(filename, """Format: 1.0
 Source: package
 Version: %s
@@ -133,14 +134,17 @@
 Files:
  8636a3e8ae81664bac70158503aaf53a 1328218 %s
 """ % (version, file1))
-    if file2 is not None:
+    i = 1
+    for extra_file in extra_files:
       append_to_file(filename,
-                     " 1acd97ad70445afd5f2a64858296f21c 20709 %s" % file2)
+                     " 1acd97ad70445afd5f2a64858296f21%d 20709 %s\n" % \
+                     (i, extra_file))
+      i += 1
 
   def make_dsc_1(self):
     self.make_orig_1()
     self.make_diff_1()
-    self.make_dsc(self.dsc_1, '0.1-1', self.orig_1, self.diff_1)
+    self.make_dsc(self.dsc_1, '0.1-1', self.orig_1, [self.diff_1])
 
   def make_dsc_1b(self):
     self.make_diff_1b()
@@ -153,7 +157,7 @@
   def make_dsc_2(self):
     self.make_orig_2()
     self.make_diff_2()
-    self.make_dsc(self.dsc_2, '0.2-1', self.orig_2, self.diff_2)
+    self.make_dsc(self.dsc_2, '0.2-1', self.orig_2, [self.diff_2])
 
   def import_dsc_1(self):
     self.make_dsc_1()
@@ -422,3 +426,14 @@
     self.assertEqual(changes.modified[0][0], 'debian/changelog')
     self.assertEqual(changes.modified[0][2], 'file')
 
+  def test_import_dsc_restrictions_on_dscs(self):
+    """Test that errors are raised for confusing sets of .dsc files."""
+    self.make_dsc(self.dsc_1, '0.1-1', self.diff_1)
+    self.assertRaises(ImportError, import_dsc, self.target, [self.dsc_1])
+    self.make_dsc(self.dsc_1, '0.1-1', self.orig_1)
+    self.assertRaises(ImportError, import_dsc, self.target, [self.dsc_1])
+    self.make_dsc(self.dsc_1, '0.1-1', self.orig_1, [self.diff_1, self.diff_1])
+    self.assertRaises(ImportError, import_dsc, self.target, [self.dsc_1])
+    self.make_dsc(self.dsc_1, '0.1-1', self.orig_1, [self.orig_1, self.diff_1])
+    self.assertRaises(ImportError, import_dsc, self.target, [self.dsc_1])
+



More information about the Pkg-bazaar-commits mailing list