def test_control_field_parsing(self): """Test the parsing of control file fields.""" deb822_package = Deb822([ 'Package: python-py2deb', 'Depends: python-deb-pkg-tools, python-pip, python-pip-accel', 'Installed-Size: 42' ]) parsed_info = parse_control_fields(deb822_package) assert parsed_info == { 'Package': 'python-py2deb', 'Depends': RelationshipSet(Relationship(name=u'python-deb-pkg-tools'), Relationship(name=u'python-pip'), Relationship(name=u'python-pip-accel')), 'Installed-Size': 42 } # Test backwards compatibility with the old interface where `Depends' # like fields were represented as a list of strings (shallow parsed). parsed_info['Depends'] = [text_type(r) for r in parsed_info['Depends']] assert unparse_control_fields(parsed_info) == deb822_package # Test compatibility with fields like `Depends' containing a string. parsed_info['Depends'] = deb822_package['Depends'] assert unparse_control_fields(parsed_info) == deb822_package
def test_control_field_parsing(self): deb822_package = Deb822([ 'Package: python-py2deb', 'Depends: python-deb-pkg-tools, python-pip, python-pip-accel', 'Installed-Size: 42' ]) parsed_info = parse_control_fields(deb822_package) self.assertEqual( parsed_info, { 'Package': 'python-py2deb', 'Depends': RelationshipSet(Relationship(name=u'python-deb-pkg-tools'), Relationship(name=u'python-pip'), Relationship(name=u'python-pip-accel')), 'Installed-Size': 42 }) # Test backwards compatibility with the old interface where `Depends' # like fields were represented as a list of strings (shallow parsed). parsed_info['Depends'] = [unicode(r) for r in parsed_info['Depends']] self.assertEqual(unparse_control_fields(parsed_info), deb822_package) # Test compatibility with fields like `Depends' containing a string. parsed_info['Depends'] = deb822_package['Depends'] self.assertEqual(unparse_control_fields(parsed_info), deb822_package)
def test_relationship_parsing(self): """Test the parsing of Debian package relationship declarations.""" # Happy path (no parsing errors). relationship_set = parse_depends('foo, bar (>= 1) | baz') assert relationship_set.relationships[0].name == 'foo' assert relationship_set.relationships[1].relationships[0].name == 'bar' assert relationship_set.relationships[1].relationships[0].operator == '>=' assert relationship_set.relationships[1].relationships[0].version == '1' assert relationship_set.relationships[1].relationships[1].name == 'baz' assert parse_depends('foo (=1.0)') == RelationshipSet(VersionedRelationship( name='foo', operator='=', version='1.0', )) # Unhappy path (parsing errors). self.assertRaises(ValueError, parse_depends, 'foo (bar) (baz)') self.assertRaises(ValueError, parse_depends, 'foo (bar baz qux)')
def test_relationship_parsing(self): # Happy path (no parsing errors). relationship_set = parse_depends('foo, bar (>= 1) | baz') self.assertEqual(relationship_set.relationships[0].name, 'foo') self.assertEqual( relationship_set.relationships[1].relationships[0].name, 'bar') self.assertEqual( relationship_set.relationships[1].relationships[0].operator, '>=') self.assertEqual( relationship_set.relationships[1].relationships[0].version, '1') self.assertEqual( relationship_set.relationships[1].relationships[1].name, 'baz') self.assertEqual( parse_depends('foo (=1.0)'), RelationshipSet( VersionedRelationship(name='foo', operator='=', version='1.0'))) # Unhappy path (parsing errors). self.assertRaises(ValueError, parse_depends, 'foo (bar) (baz)') self.assertRaises(ValueError, parse_depends, 'foo (bar baz qux)')
def merge_control_fields(defaults, overrides): """ Merge the fields of two Debian control files. :param defaults: A dictionary with existing control field name/value pairs. :param overrides: A dictionary with fields that should override default name/value pairs. Values of the fields `Depends`, `Provides`, `Replaces` and `Conflicts` are merged while values of other fields are overwritten. :returns: A dictionary of the type :class:`.Deb822`. """ merged = Deb822() defaults = parse_control_fields(defaults) overrides = parse_control_fields(overrides) logger.debug( "Merging control files (%i default fields, %i override fields)", len(defaults), len(overrides)) # Merge the field names while preserving their order. field_names = list(defaults.keys()) for name in overrides.keys(): if name not in field_names: field_names.append(name) for name in field_names: if name in DEPENDS_LIKE_FIELDS: # Dependencies are merged instead of overridden. relationships = set() for source in [defaults, overrides]: if name in source: relationships.update(source[name].relationships) merged[name] = RelationshipSet(*sorted(relationships)) elif name not in overrides: merged[name] = defaults[name] elif name not in defaults: merged[name] = overrides[name] else: # Field present in both defaults and overrides; # in this case the override takes precedence. merged[name] = overrides[name] logger.debug("Merged control fields: %s", merged) return unparse_control_fields(merged)
def merge_control_fields(defaults, overrides): """ Merge the fields of two Debian control files. :param defaults: A dictionary with existing control field name/value pairs (may be an instance of :class:`debian.deb822.Deb822` but doesn't have to be). :param overrides: A dictionary with fields that should override default name/value pairs. Values of the fields `Depends`, `Provides`, `Replaces` and `Conflicts` are merged while values of other fields are overwritten. :returns: An instance of :class:`debian.deb822.Deb822` that contains the merged control field name/value pairs. """ defaults = parse_control_fields(defaults) overrides = parse_control_fields(overrides) logger.debug( "Merging control files (%i default fields, %i override fields)", len(defaults), len(overrides)) merged = {} for name in (set(defaults.keys()) | set(overrides.keys())): if name in DEPENDS_LIKE_FIELDS: # Dependencies are merged instead of overridden. relationships = set() for source in [defaults, overrides]: if name in source: relationships.update(source[name].relationships) merged[name] = RelationshipSet(*sorted(relationships)) elif name not in overrides: merged[name] = defaults[name] elif name not in defaults: merged[name] = overrides[name] else: # Field present in both defaults and overrides; # in this case the override takes precedence. merged[name] = overrides[name] logger.debug("Merged control fields: %s", merged) return unparse_control_fields(merged)