Please, find attached the patches I mentioned on dev-ml
concerning minor revisions.
As mentioned there, the patch is not yet finished.

Besides my lack of time the main reason is that any attempts
to modify self._phases (or also any other flag) in
EbuildExecuter do not work
(e.g. if the commented line self._phases = () in the patch
is uncommented, python reports an error that a read-only
attribute is changed).

I do not have enough python knowledge to see the reason for
this error.

Let me summarize once more what still needs to be done:

1. Of course, the above problem must be fixed so that
the main "build" phases are skipped. I am unable to do this
in a reasonable time, but it should be easy for a python
expert.

2. The "merge" phase must be patched to not modify CONTENTS
when some corresponding flag in EbuildExecuter.py was set.

3. The setting of the variables P, PR, etc. needs to be
modified to *not* include the minor revision.

4. The setting of _rev in versions.py must be treated
similar as in e.g. _cp. Unfortunately, _rev is already
used in the setting of _cp so that it seems that the
whole meachanism to set these variables must be rewritten.
I suggest to postpone this until 1-3 are properly tested
and if it seems reasonable that the change can be done.

5. Finally, .tbz2 files should be updated.
This is probably not so easy, but IMHO also not so urgent:
In the worst case, the user has to recompile the package
manually to get the *.tbz2 file. (It means that those
users will not profit from minor revisions, but it will
not do much harm to them, either).

In any case, do not expect that I will have the time to
continue on this patch - my job needs currently all of my
time, and this will not change very soon.


--- portage.bak/pym/_emerge/EbuildExecuter.py
+++ portage.bak/pym/_emerge/EbuildExecuter.py
@@ -7,7 +7,9 @@
 import portage
 from portage import os
 from portage.eapi import eapi_has_src_prepare_and_src_configure, \
-       eapi_exports_replace_vars
+       eapi_exports_replace_vars, \
+       eapi_supports_minor_revision
+from portage.versions import pkgcmp, pkgsplit
 from portage.package.ebuild.doebuild import _prepare_fake_distdir
 
 class EbuildExecuter(CompositeTask):
@@ -35,6 +37,14 @@
                                        for match in vardb.match(pkg.slot_atom) 
+ \
                                        vardb.match('='+pkg.cpv)))
 
+               if eapi_supports_minor_revision(settings['EAPI']):
+                       vardb = pkg.root_config.trees['vartree'].dbapi
+                       for match in vardb.match(pkg.slot_atom):
+                               if(pkgcmp(pkgsplit(pkg.cpv), pkgsplit(match), 
True) == 1):
+                                       # This does not work, since attributes 
are readonly???
+                                       #self._phases = ()
+                                       break
+
                setup_phase = EbuildPhase(background=self.background,
                        phase="setup", scheduler=scheduler,
                        settings=settings)
--- portage.bak/pym/portage/eapi.py
+++ portage.bak/pym/portage/eapi.py
@@ -68,6 +68,9 @@
 def eapi_has_use_dep_defaults(eapi):
        return eapi not in ("0", "1", "2", "3")
 
+def eapi_supports_minor_revision(eapi):
+       return eapi not in ("0", "1", "2", "3", "4")
+
 def eapi_has_repo_deps(eapi):
        return eapi in ("4-python", "5-progress")
 
@@ -96,7 +99,7 @@
        return eapi in ("5-hdepend",)
 
 _eapi_attrs = collections.namedtuple('_eapi_attrs',
-       'dots_in_PN dots_in_use_flags exports_EBUILD_PHASE_FUNC '
+       'minor_revision dots_in_PN dots_in_use_flags exports_EBUILD_PHASE_FUNC '
        'feature_flag_test feature_flag_targetroot '
        'hdepend iuse_defaults iuse_effective '
        'repo_deps required_use required_use_at_most_one_of slot_operator 
slot_deps '
@@ -121,6 +124,7 @@
                eapi = None
 
        eapi_attrs = _eapi_attrs(
+               minor_revision = (eapi is None or 
eapi_supports_minor_revision(eapi)),
                dots_in_PN = (eapi is None or eapi_allows_dots_in_PN(eapi)),
                dots_in_use_flags = (eapi is None or 
eapi_allows_dots_in_use_flags(eapi)),
                exports_EBUILD_PHASE_FUNC = (eapi is None or 
eapi_exports_EBUILD_PHASE_FUNC(eapi)),
--- portage.bak/pym/portage/versions.py
+++ portage.bak/pym/portage/versions.py
@@ -50,8 +50,10 @@
 }
 
 _v = r'(cvs\.)?(\d+)((\.\d+)*)([a-z]?)((_(pre|p|beta|alpha|rc)\d*)*)'
-_rev = r'\d+'
-_vr = _v + '(-r(' + _rev + '))?'
+
+_rev = r'(\d+)(\.(\d+))?'
+
+_vr = _v + '(-r' + _rev + ')?'
 
 _cp = {
        "dots_disallowed_in_PN": '(' + _cat + '/' + 
_pkg['dots_disallowed_in_PN'] + '(-' + _vr + ')?)',
@@ -115,7 +117,7 @@
                        print(_("!!! syntax error in version: %s") % myver)
                return False
 
-def vercmp(ver1, ver2, silent=1):
+def vercmp(ver1, ver2, minor=False, silent=1):
        """
        Compare two versions
        Example usage:
@@ -131,12 +133,16 @@
        @type pkg1: string (example: "2.1.2-r3")
        @param pkg2: version to compare againts (see ver_regexp in 
portage.versions.py)
        @type pkg2: string (example: "2.1.2_rc5")
+       @param minor: whether to take minor revision into account
+       @type minor: Boolean
        @rtype: None or float
        @return:
-       1. positive if ver1 is greater than ver2
-       2. negative if ver1 is less than ver2 
-       3. 0 if ver1 equals ver2
-       4. None if ver1 or ver2 are invalid (see ver_regexp in 
portage.versions.py)
+       1. 2 if ver1 is greater than ver2
+       2. -2 if ver1 is less than ver2
+       3. 1 if ver1 is greater than ver2 only in minor revision and minor=True
+       4. -1 if ver1 is greater than ver2 only in minor revision and minor=True
+       5. 0 if ver1 equals ver2 (up to minor revision if minor=False)
+       6. None if ver1 or ver2 are invalid (see ver_regexp in 
portage.versions.py)
        """
 
        if ver1 == ver2:
@@ -157,9 +163,9 @@
 
        # shortcut for cvs ebuilds (new style)
        if match1.group(1) and not match2.group(1):
-               return 1
+               return 2
        elif match2.group(1) and not match1.group(1):
-               return -1
+               return -2
        
        # building lists of the version parts before the suffix
        # first part is simple
@@ -212,13 +218,13 @@
 
        for i in range(0, max(len(list1), len(list2))):
                if len(list1) <= i:
-                       return -1
+                       return -2
                elif len(list2) <= i:
-                       return 1
+                       return 2
                elif list1[i] != list2[i]:
                        a = list1[i]
                        b = list2[i]
-                       rval = (a > b) - (a < b)
+                       rval = 2 * ((a > b) - (a < b))
                        return rval
 
        # main version is equal, so now compare the _suffix part
@@ -238,7 +244,7 @@
                if s1[0] != s2[0]:
                        a = suffix_value[s1[0]]
                        b = suffix_value[s2[0]]
-                       rval = (a > b) - (a < b)
+                       rval = 2 * ((a > b) - (a < b))
                        return rval
                if s1[1] != s2[1]:
                        # it's possible that the s(1|2)[1] == ''
@@ -251,7 +257,7 @@
                                r2 = int(s2[1])
                        except ValueError:
                                r2 = 0
-                       rval = (r1 > r2) - (r1 < r2)
+                       rval = 2 * ((r1 > r2) - (r1 < r2))
                        if rval:
                                return rval
 
@@ -264,10 +270,23 @@
                r2 = int(match2.group(10))
        else:
                r2 = 0
+       rval = 2 * ((r1 > r2) - (r1 < r2))
+       if not minor:
+               return rval
+
+
+       if match1.group(12):
+               r1 = int(match1.group(12))
+       else:
+               r1 = 0
+       if match2.group(12):
+               r2 = int(match2.group(12))
+       else:
+               r2 = 0
        rval = (r1 > r2) - (r1 < r2)
        return rval
-       
-def pkgcmp(pkg1, pkg2):
+
+def pkgcmp(pkg1, pkg2, minor=False):
        """
        Compare 2 package versions created in pkgsplit format.
 
@@ -285,13 +304,15 @@
        @rtype: None or integer
        @return: 
                1. None if package names are not the same
-               2. 1 if pkg1 is greater than pkg2
-               3. -1 if pkg1 is less than pkg2 
-               4. 0 if pkg1 equals pkg2
+               2. 2 if pkg1 is greater than pkg2
+               3. -2 if pkg1 is less than pkg2 
+               4. 1 if pkg1 is greater than pkg2 only in minor revision and 
minor=True
+               5. -1 if pkg1 is less than pkg2 only in minor revision and 
minor=True
+               6. 0 if pkg1 equals pkg2 (up to revision if minor=False)
        """
        if pkg1[0] != pkg2[0]:
                return None
-       return vercmp("-".join(pkg1[1:]), "-".join(pkg2[1:]))
+       return vercmp("-".join(pkg1[1:]), "-".join(pkg2[1:]), minor)
 
 def _pkgsplit(mypkg, eapi=None):
        """
@@ -557,7 +578,7 @@
                        v1 = x.version
                except AttributeError:
                        v1 = _pkg_str(x, eapi=eapi).version
-               if vercmp(v1, v2) > 0:
+               if vercmp(v1, v2, True) > 0:
                        bestmatch = x
                        v2 = v1
        return bestmatch


Reply via email to