def set_left(self, left): if left is None: self.left_version = None self.left_distro = None self.left_suite = None self.left_component = None self.left_pool_dir = None self.left_files = [] else: self.source_package = left.package.name self.left_distro = left.package.distro.name self.left_suite = left.package.dist self.left_component = left.package.component self.left_version = left.version self.left_pool_dir = left.package.poolPath self.left_files = [f[2] for f in files(left.getDscContents())] self.left_files.append(left.dscFilename) if isinstance(left.package.distro, OBSDistro): self.obs_project = left.package.distro.obsProject( left.package.dist, left.package.component) # this requires a just-in-time-populated cache of stuff from # OBS, so it isn't 100% reliable yet try: self.obs_package = left.package.obsName except Exception: logger.exception('ignoring error getting obsName for %s:', left.package)
def set_left(self, left): if left is None: self.left_version = None self.left_distro = None self.left_suite = None self.left_component = None self.left_pool_dir = None self.left_files = [] else: self.source_package = left.package.name self.left_distro = left.package.distro.name self.left_suite = left.package.dist self.left_component = left.package.component self.left_version = left.version self.left_pool_dir = left.package.poolDirectory().path self.left_files = [f[2] for f in files(left.getSources())] if isinstance(left.package.distro, OBSDistro): self.obs_project = left.package.distro.obsProject( left.package.dist, left.package.component) # this requires a just-in-time-populated cache of stuff from # OBS, so it isn't 100% reliable yet try: self.obs_package = left.package.obsName except Exception: logger.exception('ignoring error getting obsName for %s:', left.package)
def setUp(self): # Create a single package (not in any repo) and then set up json files # and directory structure in a way that matches snapshot.debian.org assert (update_sources.SNAPSHOT_BASE.startswith('file://')) self.debsnap_base = update_sources.SNAPSHOT_BASE[7:] filedir = os.path.join(self.debsnap_base, 'file') os.makedirs(os.path.join(filedir)) data = { '_comment': "foo", 'version': "1.2-1", 'fileinfo': {}, } foo = th.TestPackage(name='foo', version='1.2-1') foo.build() dsc_path = foo.dsc_path dsc_data = ControlFile(dsc_path, multi_para=False, signed=True).para with open(dsc_path, 'r') as fd: sha1 = hashlib.sha1(fd.read()).hexdigest() data['fileinfo'][sha1] = [{ 'name': os.path.basename(dsc_path), 'archive_name': 'debian', 'path': '/pool/main/f/foo', 'size': os.path.getsize(dsc_path), }] shutil.copyfile(dsc_path, os.path.join(filedir, sha1)) for dsc_hash, size, filename in files(dsc_data): path = os.path.join(foo.base_path, filename) with open(path, 'r') as fd: sha1 = hashlib.sha1(fd.read()).hexdigest() data['fileinfo'][sha1] = [{ 'name': filename, 'archive_name': 'debian', 'path': '/pool/main/f/foo', 'size': size, }] shutil.copyfile(path, os.path.join(filedir, sha1)) path = os.path.join(self.debsnap_base, 'mr/package/foo/1.2-1') os.makedirs(path) with open(os.path.join(path, 'srcfiles?fileinfo=1'), 'w') as fd: json.dump(data, fd) self.output_dir = mkdtemp(prefix='momtest.ustest.')
def set_right(self, right): if right is None: self.right_version = None self.right_distro = None self.right_suite = None self.right_component = None self.right_pool_dir = None self.right_files = [] else: self.source_package = right.package.name self.right_distro = right.package.distro.name self.right_suite = right.package.dist self.right_component = right.package.component self.right_version = right.version self.right_pool_dir = right.package.poolPath self.right_files = [f[2] for f in files(right.getDscContents())]
def set_base(self, base): if base is None: self.base_version = None self.base_distro = None self.base_suite = None self.base_component = None self.base_pool_dir = None self.base_files = [] else: self.source_package = base.package.name self.base_version = base.version self.base_distro = base.package.distro.name self.base_suite = base.package.dist self.base_component = base.package.component self.base_pool_dir = base.package.poolPath self.base_files = [f[2] for f in files(base.getDscContents())]
def set_right(self, right): if right is None: self.right_version = None self.right_distro = None self.right_suite = None self.right_component = None self.right_pool_dir = None self.right_files = [] else: self.source_package = right.package.name self.right_distro = right.package.distro.name self.right_suite = right.package.dist self.right_component = right.package.component self.right_version = right.version self.right_pool_dir = right.package.poolDirectory().path self.right_files = [f[2] for f in files(right.getSources())]
def set_base(self, base): if base is None: self.base_version = None self.base_distro = None self.base_suite = None self.base_component = None self.base_pool_dir = None self.base_files = [] else: self.source_package = base.package.name self.base_version = base.version self.base_distro = base.package.distro.name self.base_suite = base.package.dist self.base_component = base.package.component self.base_pool_dir = base.package.poolDirectory().path self.base_files = [f[2] for f in files(base.getSources())]
def write_text_report(left, left_patch, base, tried_bases, right, right_patch, merged_version, conflicts, src_file, patch_file, output_dir, merged_dir, merged_is_right, build_metadata_changed): """Write the merge report.""" package = left.package.name assert package == right.package.name, (package, right.package.name) assert isinstance(left, PackageVersion) left_distro = left.package.distro.name assert isinstance(right, PackageVersion) right_distro = right.package.distro.name filename = "%s/REPORT" % output_dir tree.ensure(filename) with open(filename, "w") as report: # Package and time print >> report, "%s" % package print >> report, "%s" % time.ctime() print >> report # General rambling print >> report, fill( "Below now follows the report of the automated " "merge of the %s changes to the %s source " "package against the new %s version." % (left_distro.title(), package, right_distro.title())) print >> report print >> report, fill( "This file is designed to be both human readable " "and machine-parseable. Any line beginning with " "four spaces is a file that should be downloaded " "for the complete merge set.") print >> report print >> report print >> report, fill( "Here are the particulars of the three versions " "of %s that were chosen for the merge. The base " "is the newest version that is a common ancestor " "of both the %s and %s packages. It may be of " "a different upstream version, but that's not " "usually a problem." % (package, left_distro.title(), right_distro.title())) print >> report print >> report, fill( "The files are the source package itself, and " "the patch from the common base to that version.") print >> report # Base version and files if tried_bases: # We print this even if base is not None: we want to # record the better base versions we tried and failed to find print >> report, "missing base version(s):" for v in tried_bases: print >> report, " %s" % v if base is not None: print >> report, "base: %s" % base.version for md5sum, size, name in files(base.getDscContents()): print >> report, " %s" % name print >> report # Left version and files print >> report, "our distro (%s): %s" % (left_distro, left.version) for md5sum, size, name in files(left.getDscContents()): print >> report, " %s" % name print >> report if left_patch is not None: print >> report, "base -> %s" % left_distro print >> report, " %s" % left_patch print >> report # Right version and files print >> report, "source distro (%s): %s" % (right_distro, right.version) for md5sum, size, name in files(right.getDscContents()): print >> report, " %s" % name print >> report if right_patch is not None: print >> report, "base -> %s" % right_distro print >> report, " %s" % right_patch print >> report # Generated section print >> report print >> report, "Generated Result" print >> report, "================" print >> report if base is None: print >> report, fill( "Failed to merge because the base version " "required for a 3-way diff is missing from " "%s pool. Uou will need to either merge " "manually; or add the missing base version " "sources to '%s/%s/*/%s/' and run " "update_sources.py." % (right_distro, config.get('ROOT'), right_distro, package)) print >> report elif merged_is_right: print >> report, fill("The %s version supercedes the %s version " "and can be added to %s with no changes." % (right_distro.title(), left_distro.title(), left_distro.title())) print >> report print >> report, "Merged without changes: YES" print >> report if build_metadata_changed: print >> report, "Build-time metadata changed: NO" print >> report else: if src_file.endswith(".dsc"): print >> report, fill( "No problems were encountered during the " "merge, so a source package has been " "produced along with a patch containing " "the differences from the %s version to " "the new version." % right_distro.title()) print >> report print >> report, fill( "You should compare the generated patch " "against the patch for the %s version " "given above and ensure that there are " "no unexpected changes. You should also " "sanity check the source package." % left_distro.title()) print >> report print >> report, "generated: %s" % merged_version # Files from the dsc dsc = ControlFile("%s/%s" % (output_dir, src_file), multi_para=False, signed=True).para print >> report, " %s" % src_file for md5sum, size, name in files(dsc): print >> report, " %s" % name print >> report if patch_file is not None: print >> report, "%s -> generated" % right_distro print >> report, " %s" % patch_file print >> report if build_metadata_changed: print >> report, "Build-time metadata changed: NO" print >> report else: print >> report, fill("Due to conflict or error, it was not " "possible to automatically create a " "source package. Instead the result of " "the mergehas been placed into the " "following tar file which you will need " "to turn into a source package once the " "problems have been resolved.") print >> report print >> report, " %s" % src_file print >> report if len(conflicts): print >> report print >> report, "Conflicts" print >> report, "=========" print >> report print >> report, fill( "In one or more cases, there were " "different changes made in both %s and " "%s to the same file; these are known as " "conflicts." % (left_distro.title(), right_distro.title())) print >> report print >> report, fill("It is not possible for these to be " "automatically resolved, so this source " "needs human attention.") print >> report print >> report, fill( "Those files marked with 'C ' contain " "diff3 conflict markers, which can be " "resolved using the text editor of your " "choice. Those marked with 'C*' could " "not be merged that way, so you will " "find .%s and .%s files instead and " "should chose one of them or a " "combination of both, moving it to the " "real filename and deleting the other." % (left_distro.upper(), right_distro.upper())) print >> report conflicts.sort() for name in conflicts: if os.path.isfile("%s/%s" % (merged_dir, name)): print >> report, " C %s" % name else: print >> report, " C* %s" % name print >> report if merged_version.revision is not None \ and left.version.upstream != merged_version.upstream: sa_arg = " -sa" else: sa_arg = "" print >> report print >> report, fill( "Once you have a source package you are " "happy to upload, you should make sure you " "include the orig.tar.gz if appropriate and " "information about all the versions included " "in the merge.") print >> report print >> report, fill("Use the following command to generate a " "correct .changes file:") print >> report print >> report, " $ dpkg-genchanges -S -v%s%s" % (left.version, sa_arg)
def write_text_report(left, left_patch, base, tried_bases, right, right_patch, merged_version, conflicts, src_file, patch_file, output_dir, merged_dir, merged_is_right, build_metadata_changed): """Write the merge report.""" package = left.package.name assert package == right.package.name, (package, right.package.name) assert isinstance(left, PackageVersion) left_source = left.getSources() left_distro = left.package.distro.name if base is None: base_source = None else: assert isinstance(base, PackageVersion) base_source = base.getSources() assert isinstance(right, PackageVersion) right_source = right.getSources() right_distro = right.package.distro.name filename = "%s/REPORT" % output_dir tree.ensure(filename) with open(filename, "w") as report: # Package and time print >>report, "%s" % package print >>report, "%s" % time.ctime() print >>report # General rambling print >>report, fill("Below now follows the report of the automated " "merge of the %s changes to the %s source " "package against the new %s version." % (left_distro.title(), package, right_distro.title())) print >>report print >>report, fill("This file is designed to be both human readable " "and machine-parseable. Any line beginning with " "four spaces is a file that should be downloaded " "for the complete merge set.") print >>report print >>report print >>report, fill("Here are the particulars of the three versions " "of %s that were chosen for the merge. The base " "is the newest version that is a common ancestor " "of both the %s and %s packages. It may be of " "a different upstream version, but that's not " "usually a problem." % (package, left_distro.title(), right_distro.title())) print >>report print >>report, fill("The files are the source package itself, and " "the patch from the common base to that version.") print >>report # Base version and files if tried_bases: # We print this even if base_source is not None: we want to # record the better base versions we tried and failed to find print >>report, "missing base version(s):" for v in tried_bases: print >>report, " %s" % v if base_source is not None: print >>report, "base: %s" % base_source["Version"] for md5sum, size, name in files(base_source): print >>report, " %s" % name print >>report # Left version and files print >>report, "our distro (%s): %s" % (left_distro, left_source["Version"]) for md5sum, size, name in files(left_source): print >>report, " %s" % name print >>report if left_patch is not None: print >>report, "base -> %s" % left_distro print >>report, " %s" % left_patch print >>report # Right version and files print >>report, "source distro (%s): %s" % (right_distro, right_source["Version"]) for md5sum, size, name in files(right_source): print >>report, " %s" % name print >>report if right_patch is not None: print >>report, "base -> %s" % right_distro print >>report, " %s" % right_patch print >>report # Generated section print >>report print >>report, "Generated Result" print >>report, "================" print >>report if base_source is None: print >>report, fill("Failed to merge because the base version " "required for a 3-way diff is missing from %s pool. " "You will need to either merge manually; or add the " "missing base version sources to '%s/%s/*/%s/' and run " "update_sources.py." % (right_distro, config.get('ROOT'), right_distro, package)) print >>report elif merged_is_right: print >>report, fill("The %s version supercedes the %s version " "and can be added to %s with no changes." % (right_distro.title(), left_distro.title(), left_distro.title())) print >>report print >>report, "Merged without changes: YES" print >>report if build_metadata_changed: print >>report, "Build-time metadata changed: NO" print >>report else: if src_file.endswith(".dsc"): print >>report, fill("No problems were encountered during the " "merge, so a source package has been " "produced along with a patch containing " "the differences from the %s version to the " "new version." % right_distro.title()) print >>report print >>report, fill("You should compare the generated patch " "against the patch for the %s version " "given above and ensure that there are no " "unexpected changes. You should also " "sanity check the source package." % left_distro.title()) print >>report print >>report, "generated: %s" % merged_version # Files from the dsc dsc = ControlFile("%s/%s" % (output_dir, src_file), multi_para=False, signed=True).para print >>report, " %s" % src_file for md5sum, size, name in files(dsc): print >>report, " %s" % name print >>report if patch_file is not None: print >>report, "%s -> generated" % right_distro print >>report, " %s" % patch_file print >>report if build_metadata_changed: print >>report, "Build-time metadata changed: NO" print >>report else: print >>report, fill("Due to conflict or error, it was not " "possible to automatically create a source " "package. Instead the result of the merge " "has been placed into the following tar file " "which you will need to turn into a source " "package once the problems have been " "resolved.") print >>report print >>report, " %s" % src_file print >>report if len(conflicts): print >>report print >>report, "Conflicts" print >>report, "=========" print >>report print >>report, fill("In one or more cases, there were different " "changes made in both %s and %s to the same " "file; these are known as conflicts." % (left_distro.title(), right_distro.title())) print >>report print >>report, fill("It is not possible for these to be " "automatically resolved, so this source " "needs human attention.") print >>report print >>report, fill("Those files marked with 'C ' contain diff3 " "conflict markers, which can be resolved " "using the text editor of your choice. " "Those marked with 'C*' could not be merged " "that way, so you will find .%s and .%s " "files instead and should chose one of them " "or a combination of both, moving it to the " "real filename and deleting the other." % (left_distro.upper(), right_distro.upper())) print >>report conflicts.sort() for name in conflicts: if os.path.isfile("%s/%s" % (merged_dir, name)): print >>report, " C %s" % name else: print >>report, " C* %s" % name print >>report if merged_version.revision is not None \ and Version(left_source["Version"]).upstream != merged_version.upstream: sa_arg = " -sa" else: sa_arg = "" print >>report print >>report, fill("Once you have a source package you are happy " "to upload, you should make sure you include " "the orig.tar.gz if appropriate and information " "about all the versions included in the merge.") print >>report print >>report, fill("Use the following command to generate a " "correct .changes file:") print >>report print >>report, " $ dpkg-genchanges -S -v%s%s" \ % (left_source["Version"], sa_arg)