Fix ordering of eclass paths in Alchemy
Eclass search paths should be the inverse of the overlay's "masters"
order, to respect the intended semantics:
"The masters list is in reverse priority order: later entries take
precedence."
This commit fixes the divergence of the Alchemy's eclass inheritance
simulation from the real Portage's one. Note that it only makes
difference for same-named eclasses located in different places, which in
practice only means the fix is relevant for "toolchain-funcs.eclass"
(for the correct selection between its portage-stable and
chromiumos-overlay implementations).
BUG=b:293522502
TEST=add debug logging about inherited eclasses paths, build chromeos-base/chromeos-config-bsp, verify "chromiumos-overlay/eclass/toolchain-funcs.eclass" is used (and not "portage-stable/eclass/toolchain-funcs.eclass")
Change-Id: I6b33030fc1c3d66d592f51bff4c4155ecf790f47
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/bazel/+/4729041
Tested-by: Maksim Ivanov <emaxx@chromium.org>
Commit-Queue: Maksim Ivanov <emaxx@chromium.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
diff --git a/portage/bin/alchemist/src/ebuild/ebuild_prelude.sh b/portage/bin/alchemist/src/ebuild/ebuild_prelude.sh
index 3ba11f9..2f7137c 100644
--- a/portage/bin/alchemist/src/ebuild/ebuild_prelude.sh
+++ b/portage/bin/alchemist/src/ebuild/ebuild_prelude.sh
@@ -171,15 +171,17 @@
__xbuild_find_eclass() {
local name="$1"
- local eclass_dir path
+ local eclass_dir path result
+ # In case of multiple matches, proceed with the latest one as the eclass dirs
+ # are in the order from the least-preferred to the most-preferred ones.
for eclass_dir in "${__xbuild_eclass_dirs[@]}"; do
path="${eclass_dir}/${name}.eclass"
if [[ -f "${path}" ]]; then
- echo -n "${path}"
- return
+ result="${path}"
fi
done
- die "${name}.eclass not found"
+ [[ -z "${result}" ]] && die "${name}.eclass not found"
+ echo -n "${result}"
}
__xbuild_source_eclass() {
diff --git a/portage/bin/alchemist/src/repository.rs b/portage/bin/alchemist/src/repository.rs
index e552436..b719358 100644
--- a/portage/bin/alchemist/src/repository.rs
+++ b/portage/bin/alchemist/src/repository.rs
@@ -123,6 +123,8 @@
pub struct Repository {
name: String,
location: RepositoryLocation,
+ /// The list of parent repository locations (aka "masters"), in the order
+ /// from the least to the most preferred one.
parents: Vec<RepositoryLocation>,
}
@@ -158,12 +160,17 @@
&self.location.base_dir
}
+ /// Returns directories to be used for searching eclass files.
+ ///
+ /// Returned paths are sorted so that a lower-priority eclass directory
+ /// comes before a higher-priority one.
pub fn eclass_dirs(&self) -> impl Iterator<Item = &Path> {
- iter::once(self.location.eclass_dir.borrow()).chain(
- self.parents
- .iter()
- .map(|location| location.eclass_dir.borrow()),
- )
+ // Note the "parents" field ("masters" in the overlay layout) is already
+ // ordered in the "later entries take precedence" order.
+ self.parents
+ .iter()
+ .map(|location| location.eclass_dir.borrow())
+ .chain(iter::once(self.location.eclass_dir.borrow()))
}
pub fn profiles_dir(&self) -> &Path {