commit:     2fab50edb1db47a0b12ebb7452b16ffbcde645e5
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Wed May 12 22:37:00 2021 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon May 24 05:05:32 2021 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=2fab50ed

Support selective fetch/mirror restriction for EAPI 8

Bug: https://bugs.gentoo.org/371413
Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>

 lib/portage/dep/__init__.py         |  8 +++++++-
 lib/portage/eapi.py                 |  8 +++++++-
 lib/portage/package/ebuild/fetch.py | 14 ++++++++++++--
 3 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/lib/portage/dep/__init__.py b/lib/portage/dep/__init__.py
index e32f01fc0..5dd7cb682 100644
--- a/lib/portage/dep/__init__.py
+++ b/lib/portage/dep/__init__.py
@@ -686,7 +686,13 @@ def _use_reduce_cached(depstr, uselist, masklist, 
matchall, excludeall, \
                                need_bracket = True
                        else:
                                need_simple_token = False
-                               if token_class and not is_src_uri:
+                               if is_src_uri:
+                                       if (not 
eapi_attrs.selective_src_uri_restriction and
+                                                       
token.startswith(("fetch+", "mirror+"))):
+                                               raise InvalidDependString(
+                                                       _("Selective 
fetch/mirror restriction not allowed "
+                                                       "in EAPI %s: token %s") 
% (eapi, pos+1))
+                               elif token_class:
                                        #Add a hack for SRC_URI here, to avoid 
conditional code at the consumer level
                                        try:
                                                token = token_class(token, 
eapi=eapi,

diff --git a/lib/portage/eapi.py b/lib/portage/eapi.py
index 796184644..6a655aca2 100644
--- a/lib/portage/eapi.py
+++ b/lib/portage/eapi.py
@@ -22,6 +22,10 @@ def eapi_has_slot_operator(eapi):
 def eapi_has_src_uri_arrows(eapi):
        return eapi not in ("0", "1")
 
+def eapi_has_selective_src_uri_restriction(eapi):
+       return eapi not in ("0", "1", "2", "3", "4", "4-python", "4-slot-abi",
+                       "5", "5-progress", "6", "7")
+
 def eapi_has_use_deps(eapi):
        return eapi not in ("0", "1")
 
@@ -143,7 +147,8 @@ _eapi_attrs = collections.namedtuple('_eapi_attrs',
        'iuse_defaults iuse_effective posixish_locale '
        'path_variables_end_with_trailing_slash '
        'prefix '
-       'repo_deps required_use required_use_at_most_one_of slot_operator 
slot_deps '
+       'repo_deps required_use required_use_at_most_one_of '
+       'selective_src_uri_restriction slot_operator slot_deps '
        'src_uri_arrows strong_blocks use_deps use_dep_defaults '
        'empty_groups_always_true sysroot')
 
@@ -228,6 +233,7 @@ def _get_eapi_attrs(eapi):
                repo_deps = (eapi is None or eapi_has_repo_deps.func(eapi)),
                required_use = (eapi is None or 
eapi_has_required_use.func(eapi)),
                required_use_at_most_one_of = (eapi is None or 
eapi_has_required_use_at_most_one_of.func(eapi)),
+               selective_src_uri_restriction = (eapi is None or 
eapi_has_selective_src_uri_restriction.func(eapi)),
                slot_deps = (eapi is None or eapi_has_slot_deps.func(eapi)),
                slot_operator = (eapi is None or 
eapi_has_slot_operator.func(eapi)),
                src_uri_arrows = (eapi is None or 
eapi_has_src_uri_arrows.func(eapi)),

diff --git a/lib/portage/package/ebuild/fetch.py 
b/lib/portage/package/ebuild/fetch.py
index 2f3111b65..f687a01a2 100644
--- a/lib/portage/package/ebuild/fetch.py
+++ b/lib/portage/package/ebuild/fetch.py
@@ -898,6 +898,11 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0,
        primaryuri_dict = {}
        thirdpartymirror_uris = {}
        for myfile, myuri in file_uri_tuples:
+               override_mirror = myuri.startswith("mirror+")
+               override_fetch = override_mirror or myuri.startswith("fetch+")
+               if override_fetch:
+                       myuri = myuri.partition("+")[2]
+
                if myfile not in filedict:
                        filedict[myfile]=[]
                        if distdir_writable:
@@ -906,12 +911,17 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0,
                        else:
                                mirror_cache = None
 
+                       # fetch restriction implies mirror restriction
+                       # but fetch unrestriction does not grant mirror 
permission
+                       file_restrict_mirror = ((restrict_fetch or 
restrict_mirror)
+                                       and not override_mirror)
+
                        # With fetch restriction, a normal uri may only be 
fetched from
                        # custom local mirrors (if available).  A mirror:// uri 
may also
                        # be fetched from specific mirrors (effectively 
overriding fetch
                        # restriction, but only for specific mirrors).
                        location_lists = [local_mirrors]
-                       if not restrict_fetch and not restrict_mirror:
+                       if not file_restrict_mirror:
                                location_lists.append(public_mirrors)
 
                        for l in itertools.chain(*location_lists):
@@ -946,7 +956,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0,
                                writemsg(_("Invalid mirror definition in 
SRC_URI:\n"), noiselevel=-1)
                                writemsg("  %s\n" % (myuri), noiselevel=-1)
                else:
-                       if restrict_fetch or force_mirror:
+                       if (restrict_fetch and not override_fetch) or 
force_mirror:
                                # Only fetch from specific mirrors is allowed.
                                continue
                        primaryuris = primaryuri_dict.get(myfile)

Reply via email to