Hello community,

here is the log from the commit of package spec-cleaner for openSUSE:Factory 
checked in at 2017-05-17 17:19:22
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/spec-cleaner (Old)
 and      /work/SRC/openSUSE:Factory/.spec-cleaner.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "spec-cleaner"

Wed May 17 17:19:22 2017 rev:41 rq:495599 version:0.9.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/spec-cleaner/spec-cleaner.changes        
2017-04-13 10:45:21.071042089 +0200
+++ /work/SRC/openSUSE:Factory/.spec-cleaner.new/spec-cleaner.changes   
2017-05-17 17:20:24.691666785 +0200
@@ -1,0 +2,8 @@
+Wed May 17 12:41:28 UTC 2017 - tchva...@suse.com
+
+- Version update to 0.9.5:
+  * More fixes for the dep_parser
+  * Convert pypy urls to new format
+  * Start of rpmpreamble cleanup
+
+-------------------------------------------------------------------

Old:
----
  spec-cleaner-0.9.4.tar.gz

New:
----
  spec-cleaner-0.9.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ spec-cleaner.spec ++++++
--- /var/tmp/diff_new_pack.n1soEK/_old  2017-05-17 17:20:25.435561871 +0200
+++ /var/tmp/diff_new_pack.n1soEK/_new  2017-05-17 17:20:25.439561308 +0200
@@ -20,7 +20,7 @@
 # This is used for Fedora, we need to sync this
 %{!?py3_ver: %define py3_ver %{python3_version}}
 Name:           spec-cleaner
-Version:        0.9.4
+Version:        0.9.5
 Release:        0
 Summary:        .spec file cleaner
 License:        BSD-3-Clause
@@ -95,9 +95,11 @@
 %{python3_sitelib}/spec_cleaner/rpmhelpers.py
 %{python3_sitelib}/spec_cleaner/rpminstall.py
 %{python3_sitelib}/spec_cleaner/rpmpreamble.py
+%{python3_sitelib}/spec_cleaner/rpmpreambleelements.py
 %{python3_sitelib}/spec_cleaner/rpmprep.py
 %{python3_sitelib}/spec_cleaner/rpmprune.py
 %{python3_sitelib}/spec_cleaner/rpmregexp.py
+%{python3_sitelib}/spec_cleaner/rpmrequirestoken.py
 %{python3_sitelib}/spec_cleaner/rpmpackage.py
 %{python3_sitelib}/spec_cleaner/rpmscriplets.py
 %{python3_sitelib}/spec_cleaner/rpmsection.py


++++++ spec-cleaner-0.9.4.tar.gz -> spec-cleaner-0.9.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec-cleaner-spec-cleaner-0.9.4/.landscape.yaml 
new/spec-cleaner-spec-cleaner-0.9.5/.landscape.yaml
--- old/spec-cleaner-spec-cleaner-0.9.4/.landscape.yaml 2017-04-08 
11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/.landscape.yaml 2017-05-17 
14:22:32.000000000 +0200
@@ -6,3 +6,5 @@
 python-targets:
     - 2
     - 3
+pep8:
+  full: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/__init__.py 
new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/__init__.py
--- old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/__init__.py        
2017-04-08 11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/__init__.py        
2017-05-17 14:22:32.000000000 +0200
@@ -12,7 +12,7 @@
 from .rpmcleaner import RpmSpecCleaner
 
 
-__version__ = '0.9.4'
+__version__ = '0.9.5'
 
 
 def process_args(argv):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/dependency_parser.py 
new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/dependency_parser.py
--- old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/dependency_parser.py       
2017-04-08 11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/dependency_parser.py       
2017-05-17 14:22:32.000000000 +0200
@@ -33,7 +33,7 @@
     r')'
 )
 
-re_name = re.compile(r'[-A-Za-z0-9_~():.+/*\[\]]+')
+re_name = re.compile(r'[-A-Za-z0-9_~():;.+/*\[\]]+')
 re_version = re.compile(r'[-A-Za-z0-9_~():.+]+')
 re_spaces = re.compile(r'\s+')
 re_macro_unbraced = re.compile('%[A-Za-z0-9_]{3,}')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmbuild.py 
new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmbuild.py
--- old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmbuild.py        
2017-04-08 11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmbuild.py        
2017-05-17 14:22:32.000000000 +0200
@@ -16,7 +16,6 @@
             return
 
         # if user uses cmake/configure directly just recommend him using the 
macros
-        # but check on the multiline entry and do not ammend that
         if not self.minimal:
             self._comment_macro_calls(line)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmcleaner.py 
new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmcleaner.py
--- old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmcleaner.py      
2017-04-08 11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmcleaner.py      
2017-05-17 14:22:32.000000000 +0200
@@ -92,7 +92,13 @@
         self._load_licenses()
         # Determine if we need to skip the spec
         self._find_skip_parser()
+        # set the filemode
+        self._select_mode()
 
+    def _select_mode(self):
+        """
+        Set up input and output based on the options
+        """
         if self.options['output']:
             self.fout = open(self.options['output'], 'w')
         elif self.options['inline']:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmhelpers.py 
new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmhelpers.py
--- old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmhelpers.py      
2017-04-08 11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmhelpers.py      
2017-05-17 14:22:32.000000000 +0200
@@ -4,6 +4,7 @@
 import os
 
 from .fileutils import FileUtils
+from .rpmexception import RpmException
 
 LICENSES_CHANGES = 'licenses_changes.txt'
 TEX_CONVERSIONS = 'tex_conversions.txt'
@@ -116,6 +117,31 @@
     files.close()
     return groups
 
+def fix_license(value, conversions):
+    # license ; should be replaced by ands so find it
+    re_license_semicolon = re.compile(r'\s*;\s*')
+    # split using 'or', 'and' and parenthesis, ignore empty strings
+    licenses = []
+    for a in re.split(r'(\(|\)| and | or (?!later))', value):
+        if a != '':
+            licenses.append(a)
+    if not licenses:
+        licenses.append(value)
+
+    for (index, my_license) in enumerate(licenses):
+        my_license = ' '.join(my_license.split())
+        my_license = my_license.replace('ORlater', 'or later')
+        my_license = my_license.replace('ORsim', 'or similar')
+        my_license = my_license.rstrip(';')
+        my_license = re_license_semicolon.sub(' and ', my_license)
+        if my_license in conversions:
+            my_license = conversions[my_license]
+        licenses[index] = my_license
+
+    # create back new string with replaced licenses
+    s = ' '.join(licenses).replace("( ", "(").replace(" )", ")")
+    return s
+
 
 def sort_uniq(seq):
     def _check_list(x):
@@ -161,3 +187,38 @@
         seen[marker] = 1
         result.append(item)
     return result
+
+
+def add_group(group):
+    """
+    Flatten the lines of the group from sublits to one simple list
+    """
+    if isinstance(group, str):
+        return [group]
+    elif isinstance(group, list):
+        x = []
+        for subgroup in group:
+            x += add_group(subgroup)
+        return x
+    else:
+        raise RpmException('Unknown type of group in preamble: %s' % 
type(group))
+
+
+def find_pkgconfig_statement(elements):
+    """
+    Find pkgconfig() statement in the list and return true if matched
+    """
+    for i in elements:
+        if 'pkgconfig(' in i and not find_pkgconfig_declaration(elements):
+            return True
+    return False
+
+
+def find_pkgconfig_declaration(elements):
+    """
+    Find if there is direct pkgconfig dependency in the paragraph
+    """
+    for i in elements:
+        if 'pkgconfig ' in i or i.endswith('pkgconfig'):
+            return True
+    return False
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmpreamble.py 
new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmpreamble.py
--- old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmpreamble.py     
2017-04-08 11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmpreamble.py     
2017-05-17 14:22:32.000000000 +0200
@@ -1,11 +1,17 @@
 # vim: set ts=4 sw=4 et: coding=UTF-8
 
+import os.path
 import re
 
+try:
+    from urllib import parse as urlparse
+except ImportError:
+    import urlparse
+
 from .rpmsection import Section
-from .rpmexception import RpmException
-from .rpmhelpers import sort_uniq
+from .rpmpreambleelements import RpmPreambleElements
 from .dependency_parser import DependencyParser
+from .rpmhelpers import fix_license
 
 class RpmPreamble(Section):
 
@@ -30,89 +36,6 @@
         line, even if we reorder the lines.
     """
 
-    category_to_key = {
-        'name': 'Name',
-        'version': 'Version',
-        'release': 'Release',
-        'license': 'License',
-        'summary': 'Summary',
-        # The localized summary can contain various values, so it can't be here
-        'url': 'Url',
-        'group': 'Group',
-        'source': 'Source',
-        'nosource': 'NoSource',
-        'patch': 'Patch',
-        'buildrequires': 'BuildRequires',
-        'conflicts': 'Conflicts',
-        'prereq': 'PreReq',
-        'requires': 'Requires',
-        'requires_eq': '%requires_eq',
-        'recommends': 'Recommends',
-        'suggests': 'Suggests',
-        'enhances': 'Enhances',
-        'supplements': 'Supplements',
-        # Provides/Obsoletes cannot be part of this since we want to keep them
-        # mixed, so we'll have to specify the key when needed
-        'buildroot': 'BuildRoot',
-        'buildarch': 'BuildArch',
-        'exclusivearch': 'ExclusiveArch',
-        'excludearch': 'ExcludeArch',
-    }
-
-    categories_order = [
-        'define',
-        'bconds',
-        'bcond_conditions',
-        'name',
-        'version',
-        'release',
-        'summary',
-        'summary_localized',
-        'license',
-        'group',
-        'url',
-        'source',
-        'nosource',
-        'patch',
-        'buildrequires',
-        'requires',
-        'requires_eq',
-        'prereq',
-        'requires_phase',  # this is Requires(pre/post/...)
-        'recommends',
-        'suggests',
-        'enhances',
-        'supplements',
-        'conflicts',
-        'provides_obsoletes',
-        'buildroot',
-        'buildarch',
-        'exclusivearch',
-        'excludearch',
-        'misc',
-        'build_conditions',
-        'conditions',
-    ]
-
-    # categories that are sorted based on value in them
-    categories_with_sorted_package_tokens = [
-        'buildrequires',
-        'prereq',
-        'requires',
-        'requires_eq',
-        'recommends',
-        'suggests',
-        'enhances',
-        'supplements',
-        'conflicts',
-    ]
-
-    # categories that are sorted based on key value (eg Patch0 before Patch1)
-    categories_with_sorted_keyword_tokens = [
-        'source',
-        'patch',
-    ]
-
     def __init__(self, options):
         Section.__init__(self, options)
         # Old storage
@@ -125,6 +48,7 @@
         self._condition_define = False
         # Is the condition based probably on bcond evaluation
         self._condition_bcond = False
+        self.options = options
         # do we want pkgconfig and others?
         self.pkgconfig = options['pkgconfig']
         self.perl = options['perl']
@@ -142,17 +66,16 @@
         # list of allowed groups
         self.allowed_groups = options['allowed_groups']
         # start the object
-        self._start_paragraph()
+        self.paragraph = RpmPreambleElements(options)
         # initialize list of groups that need to pass over conversion fixer
-        self.categories_with_package_tokens = 
self.categories_with_sorted_package_tokens[:]
+        self.categories_with_package_tokens = 
self.paragraph.categories_with_sorted_package_tokens[:]
         # these packages actually need fixing after we sent the values to
         # reorder them
         self.categories_with_package_tokens.append('provides_obsoletes')
         # license handling
         self.subpkglicense = options['subpkglicense']
-        self.license = options['license']
-        # pkgconfig requirement detection
-        self.br_pkgconfig_required = False
+        # modname detection
+        self.modname = None
 
         # simple categories matching
         self.category_to_re = {
@@ -192,186 +115,100 @@
             'prefix': self.reg.re_preamble_prefix,
         }
 
-    def _start_paragraph(self):
-        self.paragraph = {}
-        for i in self.categories_order:
-            self.paragraph[i] = []
-        self.current_group = []
-
     def start_subparagraph(self):
-        # store the main content and clean up
+        # Backup the list and start a new one
         self._oldstore.append(self.paragraph)
-        self._start_paragraph()
+        self.paragraph = RpmPreambleElements(self.options)
 
-    def _add_group(self, group):
+    def _prune_ppc_condition(self):
         """
-        Actually store the lines from groups to resulting output
+        Check if we have ppc64 obsolete and delete it
         """
-        t = type(group)
-        if t == str:
-            return [group]
-        elif t == list:
-            x = []
-            for subgroup in group:
-                x += self._add_group(subgroup)
-            return x
-        else:
-            raise RpmException('Unknown type of group in preamble: %s' % t)
+        if not self.minimal and \
+             isinstance(self.paragraph.items['conditions'][0], list) and \
+             len(self.paragraph.items['conditions']) == 3 and \
+             self.paragraph.items['conditions'][0][0] == '# bug437293' and \
+             self.paragraph.items['conditions'][1].endswith('64bit'):
+            self.paragraph.items['conditions'] = []
 
-    def _sort_helper_key(self, a):
-        t = type(a)
-        if t == str:
-            key = a
-        elif t == list:
-            # if this is a list then all items except last are comment or 
whitespace
-            key = a[-1]
-        else:
-            raise RpmException('Unknown type during sort: %s' % t)
+    PYPI_SOURCE_HOSTS = ("pypi.io", "files.pythonhosted.org", 
"pypi.python.org")
 
-        # Special case is the category grouping where we have to get the 
number in
-        # after the value
-        if self.reg.re_patch.match(key):
-            match = self.reg.re_patch.match(key)
-            key = int(match.group(2))
-        elif self.reg.re_source.match(key):
-            match = self.reg.re_source.match(key)
-            value = match.group(1)
-            if not value:
-                value = '0'
-            key = int(value)
-        # Put brackety ()-style deps at the end of the list, after all other
-        elif self.reg.re_brackety_requires.search(key):
-            key = '1' + key
-        else:
-            key = '0' + key
-        return key
+    def _fix_pypi_source(self, url):
+        """
+        Check if the source is URL that points to PyPI and if it is, return
+        the canonical version.
+
+        This function is almost completely self-contained and only processes
+        the URL structure itself. On PyPI, the structure is predictable.
+        The only bad thing that can happen is the packager choosing to use
+        a macro instead of an explicit name of the file.
+        (which doesn't really make much sense, given that the url contains
+        the first letter of the name, so that is going to be explicit anyway)
+        """
+        parsed = urlparse.urlparse(url)
+        if not parsed.scheme: # not a URL
+            return url
+
+        if parsed.netloc not in self.PYPI_SOURCE_HOSTS: # not pypi
+            return url
+
+        filename = os.path.basename(parsed.path)
+        modname = filename[:filename.rfind("-")]
+
+        # TODO the following condition checks if the filename starts with a 
macro,
+        # and expects that if it does, the macro is called "modname". This is 
not
+        # always the case. It would be better to detect the name of the macro 
and
+        # browse local definitions to find its value.
+        if modname[0] == "%":
+            if (modname == "%modname" or modname == "%{modname}") \
+                    and self.modname:
+                modname = self.modname
+            else:
+                # don't know what to do
+                return url
+
+        return urlparse.urlunparse(('https', 'files.pythonhosted.org',
+                '/packages/source/{}/{}/{}'.format(modname[0], modname, 
filename),
+                '', '', ''))
 
     def end_subparagraph(self, endif=False):
-        lines = self._end_paragraph()
-        if len(self.paragraph['define']) > 0 or \
-           len(self.paragraph['bconds']) > 0:
+        if not self._oldstore:
+            nested = False
+        else:
+            nested = True
+        lines = self.paragraph.flatten_output(False, nested)
+        if len(self.paragraph.items['define']) > 0 or \
+           len(self.paragraph.items['bconds']) > 0:
             self._condition_define = True
         self.paragraph = self._oldstore.pop(-1)
-        self.paragraph['conditions'] += lines
+        self.paragraph.items['conditions'] += lines
 
         # If we are on endif we check the condition content
         # and if we find the defines we put it on top.
         if endif or not self.condition:
-            # check if we are doing the ppc64 migration and delete it
-            if not self.minimal and \
-                 isinstance(self.paragraph['conditions'][0], list) and \
-                 len(self.paragraph['conditions']) == 3 and \
-                 self.paragraph['conditions'][0][0] == '# bug437293' and \
-                 self.paragraph['conditions'][1].endswith('64bit'):
-                self.paragraph['conditions'] = []
+            self._prune_ppc_condition()
             if self._condition_define:
                 # If we have define conditions and possible bcond start
                 # we need to put it bellow bcond definitions as otherwise
                 # the switches do not have any effect
                 if self._condition_bcond:
-                    self.paragraph['bcond_conditions'] += 
self.paragraph['conditions']
-                elif len(self.paragraph['define']) == 0:
-                    self.paragraph['bconds'] += self.paragraph['conditions']
+                    self.paragraph.items['bcond_conditions'] += 
self.paragraph.items['conditions']
+                elif len(self.paragraph.items['define']) == 0:
+                    self.paragraph.items['bconds'] += 
self.paragraph.items['conditions']
                 else:
-                    self.paragraph['define'] += self.paragraph['conditions']
+                    self.paragraph.items['define'] += 
self.paragraph.items['conditions']
                 # in case the nested condition contains define we consider all 
parents
                 # to require to be on top too;
                 if len(self._oldstore) == 0:
                     self._condition_define = False
             else:
-                self.paragraph['build_conditions'] += 
self.paragraph['conditions']
+                self.paragraph.items['build_conditions'] += 
self.paragraph.items['conditions']
 
             # bcond must be reseted when on top and can be set even outside of 
the
             # define scope. So reset it here always
             if len(self._oldstore) == 0:
                 self._condition_bcond = False
-            self.paragraph['conditions'] = []
-
-    def _find_pkgconfig_statements(self, listname):
-        for i in self.paragraph[listname]:
-            if isinstance(i, str):
-                if 'pkgconfig(' in i and not 
self._find_pkgconfig_declarations(listname):
-                    return True
-            elif isinstance(i, list):
-                for j in i:
-                    if 'pkgconfig(' in j and not 
self._find_pkgconfig_declarations(listname):
-                        return True
-        return False
-
-    def _find_pkgconfig_declarations(self, listname):
-        for i in self.paragraph[listname]:
-            if isinstance(i, str):
-                if 'pkgconfig ' in i or i.endswith('pkgconfig'):
-                    return True
-            elif isinstance(i, list):
-                for j in i:
-                    if 'pkgconfig ' in j or j.endswith('pkgconfig'):
-                        return True
-        return False
-
-    def _end_paragraph(self, needs_license=False):
-        lines = []
-
-        # add license to the package if missing and needed
-        if needs_license:
-            if not self.paragraph['license']:
-                self.license = self._fix_license(self.license)
-                self._add_line_value_to('license', self.license)
-
-        # Check if we need the pkgconfig
-        if not self.br_pkgconfig_required and \
-           self._find_pkgconfig_statements('buildrequires'):
-            self.br_pkgconfig_required = True
-        # only in case we are in main scope
-        if not self._oldstore:
-            if self.br_pkgconfig_required and not 
self._find_pkgconfig_declarations('buildrequires'):
-                self._add_line_value_to('buildrequires', 'pkgconfig')
-
-        # sort based on category order
-        for i in self.categories_order:
-            sorted_list = []
-            # sort-out within the ordered groups based on the key
-            if i in self.categories_with_sorted_package_tokens:
-                self.paragraph[i].sort(key=self._sort_helper_key)
-                self.paragraph[i] = sort_uniq(self.paragraph[i])
-            # sort-out within the ordered groups based on the keyword
-            if i in self.categories_with_sorted_keyword_tokens:
-                self.paragraph[i].sort(key=self._sort_helper_key)
-            for group in self.paragraph[i]:
-                sorted_list += self._add_group(group)
-            # now check if we need to add comment for the prereq
-            if i == 'prereq' and not self.minimal:
-                sorted_list = self._verify_prereq_message(sorted_list)
-            lines += sorted_list
-        if self.current_group:
-            # the current group was not added to any category. It's just some
-            # random stuff that should be at the end anyway.
-            lines += self._add_group(self.current_group)
-            self.current_group = []
-        return lines
-
-    def _fix_license(self, value):
-        # split using 'or', 'and' and parenthesis, ignore empty strings
-        licenses = []
-        for a in re.split(r'(\(|\)| and | or (?!later))', value):
-            if a != '':
-                licenses.append(a)
-        if not licenses:
-            licenses.append(value)
-
-        for (index, my_license) in enumerate(licenses):
-            my_license = self.strip_useless_spaces(my_license)
-            my_license = my_license.replace('ORlater', 'or later')
-            my_license = my_license.replace('ORsim', 'or similar')
-            my_license = my_license.rstrip(';')
-            my_license = self.reg.re_license_semicolon.sub(' and ', my_license)
-            if my_license in self.license_conversions:
-                my_license = self.license_conversions[my_license]
-            licenses[index] = my_license
-
-        # create back new string with replaced licenses
-        s = ' '.join(licenses).replace("( ", "(").replace(" )", ")")
-        return s
+            self.paragraph.items['conditions'] = []
 
     def _split_name_and_version(self, value):
         # split the name and version from the requires element
@@ -393,32 +230,14 @@
         else:
             return value
 
-    def _pkgname_to_pkgconfig(self, value):
-        # we just want the pkgname if we have version string there
-        # and for the pkgconfig deps we need to put the version into
-        # the braces
-        pkgname, version = self._split_name_and_version(value)
-        pkgconfig = []
-        if pkgname == 'pkgconfig':
-            return [value]
-        if pkgname not in self.pkgconfig_conversions:
-            # first check if the package is in the replacements
-            return [value]
-        else:
-            # first split the pkgconfig data
-            pkgconf_list = self.pkgconfig_conversions[pkgname].split()
-            # then add each pkgconfig to the list
-            # print pkgconf_list
-            for j in pkgconf_list:
-                pkgconfig.append('pkgconfig({0}){1}'.format(j, version))
-        return pkgconfig
-
     def _pkgname_to_brackety(self, value, name, conversions):
         # we just want the pkgname if we have version string there
         # and for the pkgconfig deps we need to put the version into
         # the braces
         pkgname, version = self._split_name_and_version(value)
         converted = []
+        if pkgname == 'pkgconfig':
+            return [value]
         if pkgname not in conversions:
             # first check if the package is in the replacements
             return [value]
@@ -435,8 +254,8 @@
         # we do fix the package list only if there is no rpm call there on line
         # otherwise print there warning about nicer content and skip
         if self.reg.re_rpm_command.search(value):
-            if not self.previous_line.startswith('#') and not self.minimal:
-                self.current_group.append('# FIXME: Use %requires_eq macro 
instead')
+            if category == 'requires' and not 
self.previous_line.startswith('#') and not self.minimal:
+                self.paragraph.current_group.append('# FIXME: Use %requires_eq 
macro instead')
             return [value]
         tokens = DependencyParser(value).flat_out()
         # loop over all and do formatting as we can get more deps for one
@@ -459,19 +278,19 @@
             # replace pkgconfig name first
             token = self._fix_pkgconfig_name(token)
             # in scriptlets we most probably do not want the converted deps
-            if category != 'prereq':
+            if category != 'prereq' and category != 'requires_phase':
                 # here we go with descending priority to find match and replace
                 # the strings by some optimistic value of brackety dep
                 # priority is based on the first come first serve
                 if self.pkgconfig:
-                    token = self._pkgname_to_pkgconfig(token)
+                    token = self._pkgname_to_brackety(token, 'pkgconfig', 
self.pkgconfig_conversions)
                 # checking if it is not list is simple avoidance of running
                 # over already converted values
-                if type(token) is not list and self.perl:
+                if not isinstance(token, list) and self.perl:
                     token = self._pkgname_to_brackety(token, 'perl', 
self.perl_conversions)
-                if type(token) is not list and self.tex:
+                if not isinstance(token, list) and self.tex:
                     token = self._pkgname_to_brackety(token, 'tex', 
self.tex_conversions)
-                if type(token) is not list and self.cmake:
+                if not isinstance(token, list) and self.cmake:
                     token = self._pkgname_to_brackety(token, 'cmake', 
self.cmake_conversions)
             if isinstance(token, str):
                 expanded.append(token)
@@ -481,52 +300,14 @@
         expanded.sort()
         return expanded
 
-    def _verify_prereq_message(self, elements):
-        """
-            Verify if the prereq is present in the Requires(*) and add the 
fixme
-            comment if needed
-        """
-        message = '# FIXME: use proper Requires(pre/post/preun/...)'
-
-        # Check first if we have prereq values included
-        if not any("PreReq" in s for s in elements):
-            return elements
-
-        # Verify the message is not already present
-        if any(message in s for s in elements):
-            return elements
-
-        # add the message on the first position after any whitespace
-        location = next(i for i, j in enumerate(elements) if j)
-        elements.insert(location, message)
-
-        return elements
-
     def _add_line_value_to(self, category, value, key=None):
         """
-            Change a key-value line, to make sure we have the right spacing.
+        Change a key-value line, to make sure we have the right spacing.
 
-            Note: since we don't have a key <-> category matching, we need to
-            redo one. (Eg: Provides and Obsoletes are in the same category)
+        Note: since we don't have a key <-> category matching, we need to
+        redo one. (Eg: Provides and Obsoletes are in the same category)
         """
-        keylen = len('BuildRequires:  ')
-
-        if key:
-            pass
-        elif category in self.category_to_key:
-            key = self.category_to_key[category]
-        else:
-            raise RpmException('Unhandled category in preamble: %s' % category)
-
-        # append : only if the thing is not known macro
-        if not key.startswith('%'):
-            key += ':'
-        # if the key is already longer then just add one space
-        if len(key) >= keylen:
-            key += ' '
-        # fillup rest of the alignment if key is shorter than muster
-        while len(key) < keylen:
-            key += ' '
+        key = self.paragraph.compile_category_prefix(category, key)
 
         if category in self.categories_with_package_tokens:
             values = self._fix_list_of_packages(value, category)
@@ -538,12 +319,12 @@
             self._add_line_to(category, line)
 
     def _add_line_to(self, category, line):
-        if self.current_group:
-            self.current_group.append(line)
-            self.paragraph[category].append(self.current_group)
-            self.current_group = []
+        if self.paragraph.current_group:
+            self.paragraph.current_group.append(line)
+            self.paragraph.items[category].append(self.paragraph.current_group)
+            self.paragraph.current_group = []
         else:
-            self.paragraph[category].append(line)
+            self.paragraph.items[category].append(line)
 
         self.previous_line = line
 
@@ -599,13 +380,16 @@
 
         elif self.reg.re_comment.match(line):
             if line or self.previous_line:
-                self.current_group.append(line)
+                self.paragraph.current_group.append(line)
                 self.previous_line = line
             return
 
         elif self.reg.re_source.match(line):
             match = self.reg.re_source.match(line)
-            self._add_line_value_to('source', match.group(2), key='Source%s' % 
match.group(1))
+            source = match.group(2)
+            if not self.minimal:
+                source = self._fix_pypi_source(source)
+            self._add_line_value_to('source', source, key='Source%s' % 
match.group(1))
             return
 
         elif self.reg.re_patch.match(line):
@@ -631,6 +415,12 @@
                 self._add_line_to('misc', line)
             else:
                 self._add_line_to('define', line)
+
+            # catch "modname" for use in pypi url rewriting
+            define, name, value = line.split(None, 2)
+            if name == "modname":
+                self.modname = value
+
             return
 
         elif self.reg.re_requires_eq.match(line):
@@ -646,7 +436,7 @@
         elif self.reg.re_requires_phase.match(line):
             match = self.reg.re_requires_phase.match(line)
             # Put the requires content properly as key for formatting
-            self._add_line_value_to('prereq', match.group(2), 
key='Requires{0}'.format(match.group(1)))
+            self._add_line_value_to('requires_phase', match.group(2), 
key='Requires{0}'.format(match.group(1)))
             return
 
         elif self.reg.re_provides.match(line):
@@ -661,7 +451,7 @@
 
         elif self.reg.re_buildroot.match(line):
             # we only are fine with buildroot only once
-            if len(self.paragraph['buildroot']) == 0:
+            if len(self.paragraph.items['buildroot']) == 0:
                 self._add_line_value_to('buildroot', 
'%{_tmppath}/%{name}-%{version}-build')
             return
 
@@ -669,7 +459,7 @@
             # first convert the license string to proper format and then append
             match = self.reg.re_license.match(line)
             value = match.groups()[len(match.groups()) - 1]
-            value = self._fix_license(value)
+            value = fix_license(value, self.license_conversions)
             # only store subpkgs if they have different licenses
             if not (type(self).__name__ == 'RpmPackage' and not 
self.subpkglicense):
                 self._add_line_value_to('license', value)
@@ -698,7 +488,7 @@
             value = match.group(1)
             if not self.minimal:
                 if self.previous_line and not self.previous_line.startswith('# 
FIXME') and value not in self.allowed_groups:
-                    self.current_group.append('# FIXME: use correct group, see 
"https://en.opensuse.org/openSUSE:Package_group_guidelines";')
+                    self.paragraph.current_group.append('# FIXME: use correct 
group, see "https://en.opensuse.org/openSUSE:Package_group_guidelines";')
             self._add_line_value_to('group', value)
             return
 
@@ -724,6 +514,6 @@
             self._add_line_to('misc', line)
 
     def output(self, fout, newline=True, new_class=None):
-        lines = self._end_paragraph(self.subpkglicense)
+        lines = self.paragraph.flatten_output(self.subpkglicense)
         self.lines += lines
         Section.output(self, fout, newline, new_class)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmpreambleelements.py 
new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmpreambleelements.py
--- old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmpreambleelements.py     
1970-01-01 01:00:00.000000000 +0100
+++ new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmpreambleelements.py     
2017-05-17 14:22:32.000000000 +0200
@@ -0,0 +1,254 @@
+# vim: set ts=4 sw=4 et: coding=UTF-8
+
+from .rpmhelpers import sort_uniq, add_group, find_pkgconfig_statement, 
find_pkgconfig_declaration, fix_license
+from .rpmexception import RpmException
+
+class RpmPreambleElements(object):
+    """
+    Class containing structure used in rpmpreamble.
+    List of all the elements possible to be provided in dict and list forms.
+    """
+
+    category_to_key = {
+        'name': 'Name',
+        'version': 'Version',
+        'release': 'Release',
+        'license': 'License',
+        'summary': 'Summary',
+        # The localized summary can contain various values, so it can't be here
+        'url': 'Url',
+        'group': 'Group',
+        'source': 'Source',
+        'nosource': 'NoSource',
+        'patch': 'Patch',
+        'buildrequires': 'BuildRequires',
+        'conflicts': 'Conflicts',
+        'prereq': 'PreReq',
+        'requires': 'Requires',
+        'requires_eq': '%requires_eq',
+        'recommends': 'Recommends',
+        'suggests': 'Suggests',
+        'enhances': 'Enhances',
+        'supplements': 'Supplements',
+        # Provides/Obsoletes cannot be part of this since we want to keep them
+        # mixed, so we'll have to specify the key when needed
+        'buildroot': 'BuildRoot',
+        'buildarch': 'BuildArch',
+        'exclusivearch': 'ExclusiveArch',
+        'excludearch': 'ExcludeArch',
+    }
+
+    categories_order = [
+        'define',
+        'bconds',
+        'bcond_conditions',
+        'name',
+        'version',
+        'release',
+        'summary',
+        'summary_localized',
+        'license',
+        'group',
+        'url',
+        'source',
+        'nosource',
+        'patch',
+        'buildrequires',
+        'requires',
+        'requires_eq',
+        'prereq',
+        'requires_phase',  # this is Requires(pre/post/...)
+        'recommends',
+        'suggests',
+        'enhances',
+        'supplements',
+        'conflicts',
+        'provides_obsoletes',
+        'buildroot',
+        'buildarch',
+        'exclusivearch',
+        'excludearch',
+        'misc',
+        'build_conditions',
+        'conditions',
+    ]
+
+    # categories that are sorted based on value in them
+    categories_with_sorted_package_tokens = [
+        'buildrequires',
+        'prereq',
+        'requires',
+        'requires_eq',
+        'requires_phase',
+        'recommends',
+        'suggests',
+        'enhances',
+        'supplements',
+        'conflicts',
+    ]
+
+    # categories that are sorted based on key value (eg Patch0 before Patch1)
+    categories_with_sorted_keyword_tokens = [
+        'source',
+        'patch',
+    ]
+
+    def __init__(self, options):
+        self.items = {}
+        for i in self.categories_order:
+            self.items[i] = []
+        self.current_group = []
+        # minimal mode
+        self.minimal = options['minimal']
+        # regexp object
+        self.reg = options['reg']
+        # pkgconfig requirement detection
+        self.br_pkgconfig_required = False
+        # license string
+        self.license = options['license']
+        # dict of license replacement options
+        self.license_conversions = options['license_conversions']
+
+    def _sort_helper_key(self, a):
+        t = type(a)
+        if t == str:
+            key = a
+        elif t == list:
+            # if this is a list then all items except last are comment or 
whitespace
+            key = a[-1]
+        else:
+            raise RpmException('Unknown type during sort: %s' % t)
+
+        # Special case is the category grouping where we have to get the 
number in
+        # after the value
+        if self.reg.re_patch.match(key):
+            match = self.reg.re_patch.match(key)
+            key = int(match.group(2))
+        elif self.reg.re_source.match(key):
+            match = self.reg.re_source.match(key)
+            value = match.group(1)
+            if not value:
+                value = '0'
+            key = int(value)
+        # Put brackety ()-style deps at the end of the list, after all other
+        elif self.reg.re_brackety_requires.search(key):
+            key = '1' + key
+        else:
+            key = '0' + key
+        return key
+    
+    def _insert_value(self, category, value, key = None):
+        """
+        Add value to specified keystore
+        """
+        key = self.compile_category_prefix(category, key)
+        line = key + value
+        self.items[category].append(line)
+
+    def _add_pkgconfig_buildrequires(self, nested):
+        """
+        Check the content of buildrequires and add pkgconfig as an item
+        in case there are any pkgconfig() style dependencies present
+        
+        If we are in the top level object for preamble we append the BR,
+        otherwise we do just verify if there are nay dependencies
+        """
+        # first generate flat list from the BR
+        buildrequires = []
+        for group in self.items['buildrequires']:
+            buildrequires += add_group(group)
+        # Check if we need the pkgconfig
+        if not self.br_pkgconfig_required and \
+           find_pkgconfig_statement(buildrequires):
+            self.br_pkgconfig_required = True
+        # only in case we are in main scope
+        if not nested:
+            if self.br_pkgconfig_required and not 
find_pkgconfig_declaration(buildrequires):
+                self._insert_value('buildrequires', 'pkgconfig')
+
+    def _verify_prereq_message(self, elements):
+        """
+        Verify if the prereq is present in the Requires(*) and add the fixme
+        comment if needed
+        """
+        message = '# FIXME: use proper Requires(pre/post/preun/...)'
+
+        # Check first if we have prereq values included
+        if not any("PreReq" in s for s in elements):
+            return elements
+
+        # Verify the message is not already present
+        if any(message in s for s in elements):
+            return elements
+
+        # add the message on the first position after any whitespace
+        location = next(i for i, j in enumerate(elements) if j)
+        elements.insert(location, message)
+
+        return elements
+
+    def _run_global_list_operations(self, phase, elements):
+        """
+        Run all the checks that need to be run on the finalized sorted list
+        rather than on invidiual value
+        """
+        # check if we need to add comment for the prereq
+        if not self.minimal and phase == 'prereq':
+            elements = self._verify_prereq_message(elements)
+
+        return elements
+
+    def compile_category_prefix(self, category, key=None):
+        """
+        Simply compile the category key and provide enough whitespace for the
+        values to be alligned
+        """
+        keylen = len('BuildRequires:  ')
+
+        if key:
+            pass
+        elif category in self.category_to_key:
+            key = self.category_to_key[category]
+        else:
+            raise RpmException('Unhandled category in preamble: %s' % category)
+
+        # append : only if the thing is not known macro
+        if not key.startswith('%'):
+            key += ':'
+        # if the key is already longer then just add one space
+        if len(key) >= keylen:
+            key += ' '
+        # fillup rest of the alignment if key is shorter than muster
+        while len(key) < keylen:
+            key += ' '
+        return key
+
+    def flatten_output(self, needs_license=False, nested = False):
+        """
+        Do the finalized output for the itemlist.
+        """
+        lines = []
+
+        # add license to the package if missing and needed
+        if needs_license and not self.items['license']:
+            self.license = fix_license(self.license, self.license_conversions)
+            self._insert_value('license', self.license)
+        # add pkgconfig dep
+        self._add_pkgconfig_buildrequires(nested)
+        for i in self.categories_order:
+            sorted_list = []
+            # sort-out within the ordered groups based on the key
+            if i in self.categories_with_sorted_package_tokens + 
self.categories_with_sorted_keyword_tokens:
+                self.items[i].sort(key=self._sort_helper_key)
+                self.items[i] = sort_uniq(self.items[i])
+            # flatten the list from list of lists as no reordering is planned
+            for group in self.items[i]:
+                sorted_list += add_group(group)
+            # now do all sorts of operations where we needed sorted lists
+            lines += self._run_global_list_operations(i, sorted_list)
+        if self.current_group:
+            # the current group was not added to any category. It's just some
+            # random stuff that should be at the end anyway.
+            lines += add_group(self.current_group)
+            self.current_group = []
+        return lines
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmprep.py 
new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmprep.py
--- old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmprep.py 2017-04-08 
11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmprep.py 2017-05-17 
14:22:32.000000000 +0200
@@ -12,8 +12,8 @@
 
     def add(self, line):
         line = self._complete_cleanup(line)
+        line = self._cleanup_setup(line)
         if not self.minimal:
-            line = self._cleanup_setup(line)
             line = self._prepare_patch(line)
         Section.add(self, line)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmregexp.py 
new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmregexp.py
--- old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmregexp.py       
2017-04-08 11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmregexp.py       
2017-05-17 14:22:32.000000000 +0200
@@ -71,8 +71,6 @@
     re_rpm_command = re.compile(r'%\(.*\)')
     re_requires_eq = re.compile(r'^\s*%requires_eq\s*(.*)')
     re_onelinecond = re.compile(r'^\s*%{!?[^?]*\?[^:]+:[^}]+}')
-    # license ; should be replaced by ands so find it
-    re_license_semicolon = re.compile(r'\s*;\s*')
     # Special bracketed deps dection
     re_brackety_requires = re.compile(r'(pkgconfig|cmake|perl|tex|rubygem)\(')
     re_version_separator = re.compile(r'(\S+)((\s*[<>=\s]+)(\S+))*')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmrequirestoken.py 
new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmrequirestoken.py
--- old/spec-cleaner-spec-cleaner-0.9.4/spec_cleaner/rpmrequirestoken.py        
1970-01-01 01:00:00.000000000 +0100
+++ new/spec-cleaner-spec-cleaner-0.9.5/spec_cleaner/rpmrequirestoken.py        
2017-05-17 14:22:32.000000000 +0200
@@ -0,0 +1,39 @@
+from .rpmexception import RpmException
+
+class RpmRequiresToken(object):
+    """
+    Class containing informations about the dependency token
+    Can be used to specify all the values present on the line
+    Later on we use this to do various conversions
+    
+    prefix            name          comparator version
+    BuildRequires:    boringpackage >=         5.2.8
+    """
+    
+    name = None
+    comparator = None
+    version = None
+    prefix = None
+    
+    def __init__(self, name, comparator = None, version = None, prefix = None):
+        self.prefix = prefix
+        self.name = name
+        self.comparator = comparator
+        self.version = version
+        
+    def dump_token(self):
+        """
+        Output it all on nice pretty line
+        """
+
+        if not self.prefix:
+            raise RpmException('No defined prefix in RequiresToken')
+        if not self.name:
+            raise RpmException('No defined name in RequiresToken')
+        string = self.prefix + self.name
+        if self.version and not self.comparator:
+            raise RpmException('Have defined version and no comparator %s' % 
self.version)
+        if self.version:
+            string += ' ' + self.comparator + ' ' + self.version
+        
+        return string
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/acceptance-tests.py 
new/spec-cleaner-spec-cleaner-0.9.5/tests/acceptance-tests.py
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/acceptance-tests.py       
2017-04-08 11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/acceptance-tests.py       
2017-05-17 14:22:32.000000000 +0200
@@ -69,7 +69,7 @@
         testglob = os.path.join('tests', directory, '*.spec')
         return [os.path.basename(f) for f in glob.glob(testglob)]
 
-    def _run_individual_test(self, test, compare_dir, infile=None, 
outfile=None, options={}, **kwargs):
+    def _run_individual_test(self, test, compare_dir, infile=None, 
outfile=None, options=None, **kwargs):
         """
         Run the cleaner as specified and store the output for further 
comparison.
         """
@@ -86,7 +86,7 @@
             }
             full_options.update(self.option_presets)
             full_options.update(kwargs)
-            full_options.update(options)
+            full_options.update(options or {})
 
             cleaner = RpmSpecCleaner(full_options)
             cleaner.run()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/in/pypi-url-modname.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/in/pypi-url-modname.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/in/pypi-url-modname.spec  
1970-01-01 01:00:00.000000000 +0100
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/in/pypi-url-modname.spec  
2017-05-17 14:22:32.000000000 +0200
@@ -0,0 +1,3 @@
+%define     modname     idna
+Name:       python-%{modname}
+Source3: 
http://pypi.python.org/packages/source/i/%{modname}/%{modname}-%{version}.tar.bz2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/in/pypi-url.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/in/pypi-url.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/in/pypi-url.spec  1970-01-01 
01:00:00.000000000 +0100
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/in/pypi-url.spec  2017-05-17 
14:22:32.000000000 +0200
@@ -0,0 +1,4 @@
+Source0: http://pypi.python.org/packages/source/s/src/src-%{version}.tar.bz2
+Source1: http://github.com/release/src-%{version}.tar.bz2
+Source2: src-%{version}.tar.bz2
+Source3: 
http://pypi.python.org/packages/source/s/src/%{modname}-%{version}.tar.bz2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/in/requires.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/in/requires.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/in/requires.spec  2017-04-08 
11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/in/requires.spec  2017-05-17 
14:22:32.000000000 +0200
@@ -15,7 +15,7 @@
 BuildRequires:  %{rubygem rails >= 3.2}
 
 Requires: php5 => %{phpversion}
-
+Provides:       locale(ru;bg)
 Requires:       %{libname} >= %{version} libcurl-devel
 Provides:       %{name} = 0.3.0~gitbcaa
 Obsoletes:      %{name} = 0.3.0~gitbcaa
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec-cleaner-spec-cleaner-0.9.4/tests/in/rpmcmd.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/in/rpmcmd.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/in/rpmcmd.spec    2017-04-08 
11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/in/rpmcmd.spec    2017-05-17 
14:22:32.000000000 +0200
@@ -6,3 +6,4 @@
 Requires:       mozilla-nss-devel >= %(rpm -q --queryformat '%{VERSION}' 
mozilla-nss-devel)
 Requires:       ant = %(echo `rpm -q --queryformat '%{VERSION}' ant`)
 Requires:       akonadi-runtime >= %( echo `rpm -q --queryformat '%{VERSION}' 
akonadi-runtime`)
+Provides: NetworkManager-lang = %(rpm -q --queryformat '%{VERSION}' 
NetworkManager-lang)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/in/slowparse.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/in/slowparse.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/in/slowparse.spec 1970-01-01 
01:00:00.000000000 +0100
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/in/slowparse.spec 2017-05-17 
14:22:32.000000000 +0200
@@ -0,0 +1,12 @@
+Name:           bundle-lang-other
+BuildArch:      noarch
+Provides:       locale(aa;af;am;ang;as;az;be;bg;bn;bo;br;bs;byn)
+Provides:       locale(csb;cy;dv;dz;ee;eo;et;eu)
+Provides:       locale(fa;fo;fy;ga;gd;gez;gl;gn;gu;gv;haw;he;hi;hr)
+Provides:       locale(hy;ia;id;is;iu;ka;kk;kl;km)
+Provides:       
locale(kn;kok;ku;kw;ky;lg;li;lo;lt;lv;mg;mi;mk;ml;mn;mr;ms;mt;my;nds;ne)
+Provides:       locale(nn;nso;oc;om;or;pa;ps;rm;ro)
+Provides:       locale(rw;sa;se;si;sid;sk;sl;so;sp;sq;sr)
+Provides:       
locale(ss;st;sw;syr;ta;te;tg;th;ti;tig;tk;tl;tr;tt;ug;uk;ur;urd;uz)
+Provides:       locale(ve;ven;vi;wa;wal;wo;xh;yi;yo;zu)
+Source0:        README.other
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/out/pypi-url-modname.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/out/pypi-url-modname.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/out/pypi-url-modname.spec 
1970-01-01 01:00:00.000000000 +0100
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/out/pypi-url-modname.spec 
2017-05-17 14:22:32.000000000 +0200
@@ -0,0 +1,5 @@
+%define     modname     idna
+Name:           python-%{modname}
+Source3:        
https://files.pythonhosted.org/packages/source/i/idna/%{modname}-%{version}.tar.bz2
+
+%changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/out/pypi-url.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/out/pypi-url.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/out/pypi-url.spec 1970-01-01 
01:00:00.000000000 +0100
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/out/pypi-url.spec 2017-05-17 
14:22:32.000000000 +0200
@@ -0,0 +1,6 @@
+Source0:        
https://files.pythonhosted.org/packages/source/s/src/src-%{version}.tar.bz2
+Source1:        http://github.com/release/src-%{version}.tar.bz2
+Source2:        src-%{version}.tar.bz2
+Source3:        
http://pypi.python.org/packages/source/s/src/%{modname}-%{version}.tar.bz2
+
+%changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/out/requires.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/out/requires.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/out/requires.spec 2017-04-08 
11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/out/requires.spec 2017-05-17 
14:22:32.000000000 +0200
@@ -32,6 +32,7 @@
 PreReq:         kkk
 PreReq:         rrr >= %{version}
 PreReq:         zzz
+Provides:       locale(ru;bg)
 Provides:       %{name} = 0.3.0~gitbcaa
 Obsoletes:      %{name} = 0.3.0~gitbcaa
 Provides:       %{name} = 0.3.0+gitbcaa
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/out/rpmcmd.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/out/rpmcmd.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/out/rpmcmd.spec   2017-04-08 
11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/out/rpmcmd.spec   2017-05-17 
14:22:32.000000000 +0200
@@ -12,5 +12,6 @@
 # FIXME: Use %requires_eq macro instead
 Requires:       mozilla-nss-devel >= %(rpm -q --queryformat '%{VERSION}' 
mozilla-nss-devel)
 %requires_eq    vlc
+Provides:       NetworkManager-lang = %(rpm -q --queryformat '%{VERSION}' 
NetworkManager-lang)
 
 %changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/out/slowparse.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/out/slowparse.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/out/slowparse.spec        
1970-01-01 01:00:00.000000000 +0100
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/out/slowparse.spec        
2017-05-17 14:22:32.000000000 +0200
@@ -0,0 +1,14 @@
+Name:           bundle-lang-other
+Source0:        README.other
+Provides:       locale(aa;af;am;ang;as;az;be;bg;bn;bo;br;bs;byn)
+Provides:       locale(csb;cy;dv;dz;ee;eo;et;eu)
+Provides:       locale(fa;fo;fy;ga;gd;gez;gl;gn;gu;gv;haw;he;hi;hr)
+Provides:       locale(hy;ia;id;is;iu;ka;kk;kl;km)
+Provides:       
locale(kn;kok;ku;kw;ky;lg;li;lo;lt;lv;mg;mi;mk;ml;mn;mr;ms;mt;my;nds;ne)
+Provides:       locale(nn;nso;oc;om;or;pa;ps;rm;ro)
+Provides:       locale(rw;sa;se;si;sid;sk;sl;so;sp;sq;sr)
+Provides:       
locale(ss;st;sw;syr;ta;te;tg;th;ti;tig;tk;tl;tr;tt;ug;uk;ur;urd;uz)
+Provides:       locale(ve;ven;vi;wa;wal;wo;xh;yi;yo;zu)
+BuildArch:      noarch
+
+%changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/out-minimal/pypi-url-modname.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/out-minimal/pypi-url-modname.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/out-minimal/pypi-url-modname.spec 
1970-01-01 01:00:00.000000000 +0100
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/out-minimal/pypi-url-modname.spec 
2017-05-17 14:22:32.000000000 +0200
@@ -0,0 +1,5 @@
+%define     modname     idna
+Name:           python-%{modname}
+Source3:        
http://pypi.python.org/packages/source/i/%{modname}/%{modname}-%{version}.tar.bz2
+
+%changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/out-minimal/pypi-url.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/out-minimal/pypi-url.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/out-minimal/pypi-url.spec 
1970-01-01 01:00:00.000000000 +0100
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/out-minimal/pypi-url.spec 
2017-05-17 14:22:32.000000000 +0200
@@ -0,0 +1,6 @@
+Source0:        
http://pypi.python.org/packages/source/s/src/src-%{version}.tar.bz2
+Source1:        http://github.com/release/src-%{version}.tar.bz2
+Source2:        src-%{version}.tar.bz2
+Source3:        
http://pypi.python.org/packages/source/s/src/%{modname}-%{version}.tar.bz2
+
+%changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/out-minimal/requires.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/out-minimal/requires.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/out-minimal/requires.spec 
2017-04-08 11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/out-minimal/requires.spec 
2017-05-17 14:22:32.000000000 +0200
@@ -31,6 +31,7 @@
 PreReq:         kkk
 PreReq:         rrr >= %{version}
 PreReq:         zzz
+Provides:       locale(ru;bg)
 Provides:       %{name} = 0.3.0~gitbcaa
 Obsoletes:      %{name} = 0.3.0~gitbcaa
 Provides:       %{name} = 0.3.0+gitbcaa
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/out-minimal/rpmcmd.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/out-minimal/rpmcmd.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/out-minimal/rpmcmd.spec   
2017-04-08 11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/out-minimal/rpmcmd.spec   
2017-05-17 14:22:32.000000000 +0200
@@ -6,5 +6,6 @@
 Requires:       mozilla-nss >= %(rpm -q --queryformat '%{VERSION}' mozilla-nss)
 Requires:       mozilla-nss-devel >= %(rpm -q --queryformat '%{VERSION}' 
mozilla-nss-devel)
 %requires_eq    vlc
+Provides:       NetworkManager-lang = %(rpm -q --queryformat '%{VERSION}' 
NetworkManager-lang)
 
 %changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/out-minimal/slowparse.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/out-minimal/slowparse.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/out-minimal/slowparse.spec        
1970-01-01 01:00:00.000000000 +0100
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/out-minimal/slowparse.spec        
2017-05-17 14:22:32.000000000 +0200
@@ -0,0 +1,14 @@
+Name:           bundle-lang-other
+Source0:        README.other
+Provides:       locale(aa;af;am;ang;as;az;be;bg;bn;bo;br;bs;byn)
+Provides:       locale(csb;cy;dv;dz;ee;eo;et;eu)
+Provides:       locale(fa;fo;fy;ga;gd;gez;gl;gn;gu;gv;haw;he;hi;hr)
+Provides:       locale(hy;ia;id;is;iu;ka;kk;kl;km)
+Provides:       
locale(kn;kok;ku;kw;ky;lg;li;lo;lt;lv;mg;mi;mk;ml;mn;mr;ms;mt;my;nds;ne)
+Provides:       locale(nn;nso;oc;om;or;pa;ps;rm;ro)
+Provides:       locale(rw;sa;se;si;sid;sk;sl;so;sp;sq;sr)
+Provides:       
locale(ss;st;sw;syr;ta;te;tg;th;ti;tig;tk;tl;tr;tt;ug;uk;ur;urd;uz)
+Provides:       locale(ve;ven;vi;wa;wal;wo;xh;yi;yo;zu)
+BuildArch:      noarch
+
+%changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spec-cleaner-spec-cleaner-0.9.4/tests/out-minimal/sourcespatches.spec 
new/spec-cleaner-spec-cleaner-0.9.5/tests/out-minimal/sourcespatches.spec
--- old/spec-cleaner-spec-cleaner-0.9.4/tests/out-minimal/sourcespatches.spec   
2017-04-08 11:05:38.000000000 +0200
+++ new/spec-cleaner-spec-cleaner-0.9.5/tests/out-minimal/sourcespatches.spec   
2017-05-17 14:22:32.000000000 +0200
@@ -16,9 +16,9 @@
 Patch10:        test2
 
 %prep
-%setup -qn %name-%version
+%setup -q -n %name-%version
 %setup -q -n "%name-%version" -a1
-%setup -n "%name-%version" -q -b2
+%setup -q -n "%name-%version" -b2
 %setup -q -n %{name}-%{version}-src
 %patch10 -p4
 %patch -p1

++++++ spec-cleaner.dsc ++++++
--- /var/tmp/diff_new_pack.n1soEK/_old  2017-05-17 17:20:25.755516747 +0200
+++ /var/tmp/diff_new_pack.n1soEK/_new  2017-05-17 17:20:25.755516747 +0200
@@ -1,6 +1,6 @@
 Format: 3.0 (quilt)
 Source: spec-cleaner
-Version: 0.9.4-1
+Version: 0.9.5-1
 Binary: spec-cleaner
 Maintainer: Přemysl Janouch <pjano...@suse.com>
 Architecture: all


Reply via email to