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