alchemist: Introduce MaybePackageDetails
This patch follows the same pattern as MaybeEBuildMetadata: introduces
an enum that allows interleaving success/failure cases of package
loading and differentiating them statically at the same time.
While this new enum allows us cleaning up a few logic, this patch
focuses on introducing it with minimal changes.
This is a pure refactoring and not supposed to change any behavior.
BUG=b:303400631
TEST=bazel test //bazel/portage/bin/alchemist:all
Change-Id: Ie0d1396c7a068b697b3e404aa8dcd287465a0b3e
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/bazel/+/4982815
Reviewed-by: Maksim Ivanov <emaxx@chromium.org>
Tested-by: Shuhei Takahashi <nya@chromium.org>
Commit-Queue: Shuhei Takahashi <nya@chromium.org>
diff --git a/portage/bin/alchemist/src/analyze/restrict.rs b/portage/bin/alchemist/src/analyze/restrict.rs
index 344033f..47deb8e 100644
--- a/portage/bin/alchemist/src/analyze/restrict.rs
+++ b/portage/bin/alchemist/src/analyze/restrict.rs
@@ -32,11 +32,13 @@
use std::{
collections::{HashMap, HashSet},
path::PathBuf,
+ sync::Arc,
};
use crate::{
bash::vars::{BashValue, BashVars},
data::Slot,
+ ebuild::metadata::{EBuildBasicData, EBuildMetadata},
};
use super::*;
@@ -47,16 +49,22 @@
vars.insert("RESTRICT".to_owned(), value);
}
PackageDetails {
- repo_name: "baz".to_owned(),
- package_name: "foo/bar".to_owned(),
- version: "1.0".parse().unwrap(),
- vars: BashVars::new(vars),
+ metadata: Arc::new(EBuildMetadata {
+ basic_data: EBuildBasicData {
+ repo_name: "baz".to_owned(),
+ ebuild_path: PathBuf::from("/path/to/some.ebuild"),
+ package_name: "foo/bar".to_owned(),
+ short_package_name: "bar".to_owned(),
+ category_name: "foo".to_owned(),
+ version: "1.0".parse().unwrap(),
+ },
+ vars: BashVars::new(vars),
+ }),
slot: Slot::new("0"),
use_map,
accepted: true,
stable: true,
masked: false,
- ebuild_path: PathBuf::from("/path/to/some.ebuild"),
inherited: HashSet::new(),
inherit_paths: vec![],
direct_build_target: None,
diff --git a/portage/bin/alchemist/src/analyze/source.rs b/portage/bin/alchemist/src/analyze/source.rs
index cf7bdef..57c16c3 100644
--- a/portage/bin/alchemist/src/analyze/source.rs
+++ b/portage/bin/alchemist/src/analyze/source.rs
@@ -598,8 +598,10 @@
use crate::bash::vars::BashVars;
use crate::config::{ConfigNode, ConfigNodeValue, SimpleConfigSource};
use crate::data::{Slot, Vars};
+ use crate::ebuild::metadata::{EBuildBasicData, EBuildMetadata};
use crate::testutils::write_files;
use std::collections::HashSet;
+ use std::sync::Arc;
use tempfile::TempDir;
use version::Version;
@@ -621,21 +623,27 @@
)?;
let package = PackageDetails {
- repo_name: "baz".to_owned(),
- package_name: "sys-libs/foo".to_owned(),
- version: Version::try_new("0.1.0").unwrap(),
- vars: BashVars::new(HashMap::from([
- ("SRC_URI".to_owned(),
- BashValue::Scalar("https://example/f00-0.1.0.tar.gz -> foo-0.1.0.tar.gz extra? ( gs://chromeos-localmirror/foo-extra.tar.gz )".to_owned())),
- ("RESTRICT".to_owned(),
- BashValue::Scalar("extra? ( mirror )".to_owned())),
- ])),
+ metadata: Arc::new(EBuildMetadata {
+ basic_data: EBuildBasicData {
+ repo_name: "baz".to_owned(),
+ ebuild_path: tmp.path().join("foo-0.1.0.ebuild"),
+ package_name: "sys-libs/foo".to_owned(),
+ short_package_name: "foo".to_owned(),
+ category_name: "sys-libs".to_owned(),
+ version: Version::try_new("0.1.0").unwrap(),
+ },
+ vars: BashVars::new(HashMap::from([
+ ("SRC_URI".to_owned(),
+ BashValue::Scalar("https://example/f00-0.1.0.tar.gz -> foo-0.1.0.tar.gz extra? ( gs://chromeos-localmirror/foo-extra.tar.gz )".to_owned())),
+ ("RESTRICT".to_owned(),
+ BashValue::Scalar("extra? ( mirror )".to_owned())),
+ ])),
+ }),
slot: Slot::new("0"),
use_map,
accepted: true,
stable: true,
masked: false,
- ebuild_path: tmp.path().join("foo-0.1.0.ebuild"),
inherited: HashSet::new(),
inherit_paths: vec![],
direct_build_target: None,
@@ -736,60 +744,67 @@
#[test]
fn cros_workon_pinned_package_with_subtree() -> Result<()> {
let package = PackageDetails {
- repo_name: "baz".to_owned(),
- package_name: "sys-boot/libpayload".to_owned(),
- version: Version::try_new("0.1.0")?,
- vars: BashVars::new(HashMap::from([
- (
- "CROS_WORKON_PROJECT".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "chromiumos/third_party/coreboot".to_owned(),
- "chromiumos/platform/vboot_reference".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_LOCALNAME".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "coreboot".to_owned(),
- "../platform/vboot_reference".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_SUBTREE".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "payloads/libpayload src/commonlib util/kconfig util/xcompile".to_owned(),
- "Makefile firmware".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_COMMIT".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "e71dd376a369e2351265e79e19e926594f92e604".to_owned(),
- "49820c727819ca566c65efa0525a8022f07cc27e".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_TREE".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "6f11773570dfaaade362374b0d0392c28cf17206".to_owned(),
- "5e822365b04b4690729ca6ec32935a177db97ed2".to_owned(),
- "514603540da793957fa87fa22df81b288fb39d0f".to_owned(),
- "b2307ed1e70bf1a5718afaa81217ec9504854005".to_owned(),
- "bc55f0377f73029f50c4c74d5936e4d7bde877c6".to_owned(),
- "e70ebd7c76b9f9ad44b59e3002a5c57be5b9dc12".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_OPTIONAL_CHECKOUT".to_owned(),
- BashValue::IndexedArray(Vec::from(["".to_owned(), "".to_owned()])),
- ),
- ])),
+ metadata: Arc::new(EBuildMetadata {
+ basic_data: EBuildBasicData {
+ repo_name: "baz".to_owned(),
+ ebuild_path: PathBuf::from("/dev/null"),
+ package_name: "sys-boot/libpayload".to_owned(),
+ short_package_name: "libpayload".to_owned(),
+ category_name: "sys-boot".to_owned(),
+ version: Version::try_new("0.1.0").unwrap(),
+ },
+ vars: BashVars::new(HashMap::from([
+ (
+ "CROS_WORKON_PROJECT".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "chromiumos/third_party/coreboot".to_owned(),
+ "chromiumos/platform/vboot_reference".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_LOCALNAME".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "coreboot".to_owned(),
+ "../platform/vboot_reference".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_SUBTREE".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "payloads/libpayload src/commonlib util/kconfig util/xcompile"
+ .to_owned(),
+ "Makefile firmware".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_COMMIT".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "e71dd376a369e2351265e79e19e926594f92e604".to_owned(),
+ "49820c727819ca566c65efa0525a8022f07cc27e".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_TREE".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "6f11773570dfaaade362374b0d0392c28cf17206".to_owned(),
+ "5e822365b04b4690729ca6ec32935a177db97ed2".to_owned(),
+ "514603540da793957fa87fa22df81b288fb39d0f".to_owned(),
+ "b2307ed1e70bf1a5718afaa81217ec9504854005".to_owned(),
+ "bc55f0377f73029f50c4c74d5936e4d7bde877c6".to_owned(),
+ "e70ebd7c76b9f9ad44b59e3002a5c57be5b9dc12".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_OPTIONAL_CHECKOUT".to_owned(),
+ BashValue::IndexedArray(Vec::from(["".to_owned(), "".to_owned()])),
+ ),
+ ])),
+ }),
slot: Slot::new("0"),
use_map: UseMap::new(),
accepted: true,
stable: true,
masked: false,
- ebuild_path: PathBuf::from("/dev/null"),
inherited: HashSet::new(),
inherit_paths: vec![],
direct_build_target: None,
@@ -852,61 +867,67 @@
#[test]
fn cros_workon_pinned_package_without_subtree() -> Result<()> {
let package = PackageDetails {
- repo_name: "baz".to_owned(),
- package_name: "sys-boot/depthcharge".to_owned(),
- version: Version::try_new("0.1.0")?,
- vars: BashVars::new(HashMap::from([
- (
- "CROS_WORKON_PROJECT".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "chromiumos/platform/depthcharge".to_owned(),
- "chromiumos/platform/vboot_reference".to_owned(),
- "chromiumos/third_party/coreboot".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_LOCALNAME".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "../platform/depthcharge".to_owned(),
- "../platform/vboot_reference".to_owned(),
- "../third_party/coreboot".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_COMMIT".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "7e1e4037a9e46a9cbf502b2b20cdc9db1a84cf94".to_owned(),
- "52f28a4b68aa018fff3cc575610bc9c1c04a030f".to_owned(),
- "d5929971f3efe2e8a398c385309ca4aad110dc02".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_TREE".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "63534c063f7717bd89631830e076229c41829c17".to_owned(),
- "b7ba676717ca1fa2a26b1f3107afdce3be979a78".to_owned(),
- "5478a5900ed6376f77b84efb27677c105fc253d6".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_SUBTREE".to_owned(),
- BashValue::Scalar("".to_owned()),
- ),
- (
- "CROS_WORKON_OPTIONAL_CHECKOUT".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "".to_owned(),
- "".to_owned(),
- "".to_owned(),
- ])),
- ),
- ])),
+ metadata: Arc::new(EBuildMetadata {
+ basic_data: EBuildBasicData {
+ repo_name: "baz".to_owned(),
+ ebuild_path: PathBuf::from("/dev/null"),
+ package_name: "sys-boot/depthcharge".to_owned(),
+ short_package_name: "depthcharge".to_owned(),
+ category_name: "sys-boot".to_owned(),
+ version: Version::try_new("0.1.0").unwrap(),
+ },
+ vars: BashVars::new(HashMap::from([
+ (
+ "CROS_WORKON_PROJECT".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "chromiumos/platform/depthcharge".to_owned(),
+ "chromiumos/platform/vboot_reference".to_owned(),
+ "chromiumos/third_party/coreboot".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_LOCALNAME".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "../platform/depthcharge".to_owned(),
+ "../platform/vboot_reference".to_owned(),
+ "../third_party/coreboot".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_COMMIT".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "7e1e4037a9e46a9cbf502b2b20cdc9db1a84cf94".to_owned(),
+ "52f28a4b68aa018fff3cc575610bc9c1c04a030f".to_owned(),
+ "d5929971f3efe2e8a398c385309ca4aad110dc02".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_TREE".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "63534c063f7717bd89631830e076229c41829c17".to_owned(),
+ "b7ba676717ca1fa2a26b1f3107afdce3be979a78".to_owned(),
+ "5478a5900ed6376f77b84efb27677c105fc253d6".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_SUBTREE".to_owned(),
+ BashValue::Scalar("".to_owned()),
+ ),
+ (
+ "CROS_WORKON_OPTIONAL_CHECKOUT".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "".to_owned(),
+ "".to_owned(),
+ "".to_owned(),
+ ])),
+ ),
+ ])),
+ }),
slot: Slot::new("0"),
use_map: UseMap::new(),
accepted: true,
stable: true,
masked: false,
- ebuild_path: PathBuf::from("/dev/null"),
inherited: HashSet::new(),
inherit_paths: vec![],
direct_build_target: None,
@@ -949,59 +970,65 @@
#[test]
fn cros_workon_pinned_package_with_chromite_subtree() -> Result<()> {
let package = PackageDetails {
- repo_name: "baz".to_owned(),
- package_name: "chromeos-base/hwid_extractor".to_owned(),
- version: Version::try_new("0.1.0")?,
- vars: BashVars::new(HashMap::from([
- (
- "CROS_WORKON_PROJECT".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "chromiumos/platform/factory".to_owned(),
- "chromiumos/chromite".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_LOCALNAME".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "platform/factory".to_owned(),
- "../chromite".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_SUBTREE".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "py".to_owned(),
- "lib bin scripts PRESUBMIT.cfg".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_COMMIT".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "e71dd376a369e2351265e79e19e926594f92e604".to_owned(),
- "49820c727819ca566c65efa0525a8022f07cc27e".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_TREE".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "6f11773570dfaaade362374b0d0392c28cf17206".to_owned(),
- "5e822365b04b4690729ca6ec32935a177db97ed2".to_owned(),
- "514603540da793957fa87fa22df81b288fb39d0f".to_owned(),
- "b2307ed1e70bf1a5718afaa81217ec9504854005".to_owned(),
- "bc55f0377f73029f50c4c74d5936e4d7bde877c6".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_OPTIONAL_CHECKOUT".to_owned(),
- BashValue::IndexedArray(Vec::from(["".to_owned(), "".to_owned()])),
- ),
- ])),
+ metadata: Arc::new(EBuildMetadata {
+ basic_data: EBuildBasicData {
+ repo_name: "baz".to_owned(),
+ ebuild_path: PathBuf::from("/dev/null"),
+ package_name: "chromeos-base/hwid_extractor".to_owned(),
+ short_package_name: "hwid_extractor".to_owned(),
+ category_name: "chromeos-base".to_owned(),
+ version: Version::try_new("0.1.0").unwrap(),
+ },
+ vars: BashVars::new(HashMap::from([
+ (
+ "CROS_WORKON_PROJECT".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "chromiumos/platform/factory".to_owned(),
+ "chromiumos/chromite".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_LOCALNAME".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "platform/factory".to_owned(),
+ "../chromite".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_SUBTREE".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "py".to_owned(),
+ "lib bin scripts PRESUBMIT.cfg".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_COMMIT".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "e71dd376a369e2351265e79e19e926594f92e604".to_owned(),
+ "49820c727819ca566c65efa0525a8022f07cc27e".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_TREE".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "6f11773570dfaaade362374b0d0392c28cf17206".to_owned(),
+ "5e822365b04b4690729ca6ec32935a177db97ed2".to_owned(),
+ "514603540da793957fa87fa22df81b288fb39d0f".to_owned(),
+ "b2307ed1e70bf1a5718afaa81217ec9504854005".to_owned(),
+ "bc55f0377f73029f50c4c74d5936e4d7bde877c6".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_OPTIONAL_CHECKOUT".to_owned(),
+ BashValue::IndexedArray(Vec::from(["".to_owned(), "".to_owned()])),
+ ),
+ ])),
+ }),
slot: Slot::new("0"),
use_map: UseMap::new(),
accepted: true,
stable: true,
masked: false,
- ebuild_path: PathBuf::from("/dev/null"),
inherited: HashSet::new(),
inherit_paths: vec![],
direct_build_target: None,
@@ -1077,50 +1104,56 @@
)?;
let package = PackageDetails {
- repo_name: "baz".to_owned(),
- package_name: "chromeos-base/hwid_extractor".to_owned(),
- version: Version::try_new("0.1.0")?,
- vars: BashVars::new(HashMap::from([
- (
- "CROS_WORKON_PROJECT".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "chromiumos/platform/factory".to_owned(),
- "chromiumos/chromite".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_LOCALNAME".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "platform/factory".to_owned(),
- "../chromite".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_SUBTREE".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "py".to_owned(),
- "lib bin scripts PRESUBMIT.cfg".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_COMMIT".to_owned(),
- BashValue::Scalar("".to_owned()),
- ),
- (
- "CROS_WORKON_TREE".to_owned(),
- BashValue::Scalar("".to_owned()),
- ),
- (
- "CROS_WORKON_OPTIONAL_CHECKOUT".to_owned(),
- BashValue::IndexedArray(Vec::from(["".to_owned(), "".to_owned()])),
- ),
- ])),
+ metadata: Arc::new(EBuildMetadata {
+ basic_data: EBuildBasicData {
+ repo_name: "baz".to_owned(),
+ ebuild_path: PathBuf::from("/dev/null"),
+ package_name: "chromeos-base/hwid_extractor".to_owned(),
+ short_package_name: "hwid_extractor".to_owned(),
+ category_name: "chromeos-base".to_owned(),
+ version: Version::try_new("0.1.0").unwrap(),
+ },
+ vars: BashVars::new(HashMap::from([
+ (
+ "CROS_WORKON_PROJECT".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "chromiumos/platform/factory".to_owned(),
+ "chromiumos/chromite".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_LOCALNAME".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "platform/factory".to_owned(),
+ "../chromite".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_SUBTREE".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "py".to_owned(),
+ "lib bin scripts PRESUBMIT.cfg".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_COMMIT".to_owned(),
+ BashValue::Scalar("".to_owned()),
+ ),
+ (
+ "CROS_WORKON_TREE".to_owned(),
+ BashValue::Scalar("".to_owned()),
+ ),
+ (
+ "CROS_WORKON_OPTIONAL_CHECKOUT".to_owned(),
+ BashValue::IndexedArray(Vec::from(["".to_owned(), "".to_owned()])),
+ ),
+ ])),
+ }),
slot: Slot::new("0"),
use_map: UseMap::new(),
accepted: true,
stable: true,
masked: false,
- ebuild_path: PathBuf::from("/dev/null"),
inherited: HashSet::new(),
inherit_paths: vec![],
direct_build_target: None,
@@ -1158,49 +1191,55 @@
)?;
let package = PackageDetails {
- repo_name: "baz".to_owned(),
- package_name: "sys-boot/coreboot".to_owned(),
- version: Version::try_new("0.1.0")?,
- vars: BashVars::new(HashMap::from([
- (
- "CROS_WORKON_PROJECT".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "chromiumos/third_party/coreboot".to_owned(),
- "chromiumos/platform/vboot_reference".to_owned(),
- "chromiumos/chromite".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_LOCALNAME".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "coreboot".to_owned(),
- "../platform/vboot_reference".to_owned(),
- "../../chromite".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_SUBTREE".to_owned(),
- BashValue::Scalar("".to_owned()),
- ),
- (
- "CROS_WORKON_COMMIT".to_owned(),
- BashValue::Scalar("".to_owned()),
- ),
- (
- "CROS_WORKON_TREE".to_owned(),
- BashValue::Scalar("".to_owned()),
- ),
- (
- "CROS_WORKON_OPTIONAL_CHECKOUT".to_owned(),
- BashValue::Scalar("".to_owned()),
- ),
- ])),
+ metadata: Arc::new(EBuildMetadata {
+ basic_data: EBuildBasicData {
+ repo_name: "baz".to_owned(),
+ ebuild_path: PathBuf::from("/dev/null"),
+ package_name: "sys-boot/coreboot".to_owned(),
+ short_package_name: "coreboot".to_owned(),
+ category_name: "sys-boot".to_owned(),
+ version: Version::try_new("0.1.0").unwrap(),
+ },
+ vars: BashVars::new(HashMap::from([
+ (
+ "CROS_WORKON_PROJECT".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "chromiumos/third_party/coreboot".to_owned(),
+ "chromiumos/platform/vboot_reference".to_owned(),
+ "chromiumos/chromite".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_LOCALNAME".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "coreboot".to_owned(),
+ "../platform/vboot_reference".to_owned(),
+ "../../chromite".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_SUBTREE".to_owned(),
+ BashValue::Scalar("".to_owned()),
+ ),
+ (
+ "CROS_WORKON_COMMIT".to_owned(),
+ BashValue::Scalar("".to_owned()),
+ ),
+ (
+ "CROS_WORKON_TREE".to_owned(),
+ BashValue::Scalar("".to_owned()),
+ ),
+ (
+ "CROS_WORKON_OPTIONAL_CHECKOUT".to_owned(),
+ BashValue::Scalar("".to_owned()),
+ ),
+ ])),
+ }),
slot: Slot::new("0"),
use_map: UseMap::new(),
accepted: true,
stable: true,
masked: false,
- ebuild_path: PathBuf::from("/dev/null"),
inherited: HashSet::new(),
inherit_paths: vec![],
direct_build_target: None,
@@ -1223,60 +1262,70 @@
fn create_optional_subtree_package(use_map: UseMap) -> PackageDetails {
PackageDetails {
- repo_name: "baz".to_owned(),
- package_name: "sys-boot/libpayload".to_owned(),
- version: Version::try_new("0.1.0").unwrap(),
- vars: BashVars::new(HashMap::from([
- (
- "CROS_WORKON_PROJECT".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "chromiumos/third_party/coreboot".to_owned(),
- "chromiumos/platform/vboot_reference".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_LOCALNAME".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "coreboot".to_owned(),
- "../platform/vboot_reference".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_SUBTREE".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "payloads/libpayload src/commonlib util/kconfig util/xcompile".to_owned(),
- "Makefile firmware".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_COMMIT".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "e71dd376a369e2351265e79e19e926594f92e604".to_owned(),
- "49820c727819ca566c65efa0525a8022f07cc27e".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_TREE".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "6f11773570dfaaade362374b0d0392c28cf17206".to_owned(),
- "5e822365b04b4690729ca6ec32935a177db97ed2".to_owned(),
- "514603540da793957fa87fa22df81b288fb39d0f".to_owned(),
- "b2307ed1e70bf1a5718afaa81217ec9504854005".to_owned(),
- "bc55f0377f73029f50c4c74d5936e4d7bde877c6".to_owned(),
- "e70ebd7c76b9f9ad44b59e3002a5c57be5b9dc12".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_OPTIONAL_CHECKOUT".to_owned(),
- BashValue::IndexedArray(Vec::from(["use coreboot".to_owned(), "".to_owned()])),
- ),
- ])),
+ metadata: Arc::new(EBuildMetadata {
+ basic_data: EBuildBasicData {
+ repo_name: "baz".to_owned(),
+ ebuild_path: PathBuf::from("/dev/null"),
+ package_name: "sys-boot/libpayload".to_owned(),
+ short_package_name: "libpayload".to_owned(),
+ category_name: "sys-boot".to_owned(),
+ version: Version::try_new("0.1.0").unwrap(),
+ },
+ vars: BashVars::new(HashMap::from([
+ (
+ "CROS_WORKON_PROJECT".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "chromiumos/third_party/coreboot".to_owned(),
+ "chromiumos/platform/vboot_reference".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_LOCALNAME".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "coreboot".to_owned(),
+ "../platform/vboot_reference".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_SUBTREE".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "payloads/libpayload src/commonlib util/kconfig util/xcompile"
+ .to_owned(),
+ "Makefile firmware".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_COMMIT".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "e71dd376a369e2351265e79e19e926594f92e604".to_owned(),
+ "49820c727819ca566c65efa0525a8022f07cc27e".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_TREE".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "6f11773570dfaaade362374b0d0392c28cf17206".to_owned(),
+ "5e822365b04b4690729ca6ec32935a177db97ed2".to_owned(),
+ "514603540da793957fa87fa22df81b288fb39d0f".to_owned(),
+ "b2307ed1e70bf1a5718afaa81217ec9504854005".to_owned(),
+ "bc55f0377f73029f50c4c74d5936e4d7bde877c6".to_owned(),
+ "e70ebd7c76b9f9ad44b59e3002a5c57be5b9dc12".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_OPTIONAL_CHECKOUT".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "use coreboot".to_owned(),
+ "".to_owned(),
+ ])),
+ ),
+ ])),
+ }),
slot: Slot::new("0"),
use_map,
accepted: true,
stable: true,
masked: false,
- ebuild_path: PathBuf::from("/dev/null"),
inherited: HashSet::new(),
inherit_paths: vec![],
direct_build_target: None,
@@ -1390,53 +1439,59 @@
)?;
let package = PackageDetails {
- repo_name: "baz".to_owned(),
- package_name: "sys-boot/depthcharge".to_owned(),
- version: Version::try_new("9999")?,
- vars: BashVars::new(HashMap::from([
- (
- "CROS_WORKON_PROJECT".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "chromiumos/platform/depthcharge".to_owned(),
- "chromiumos/platform/vboot_reference".to_owned(),
- "chromiumos/third_party/coreboot".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_LOCALNAME".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "../platform/depthcharge".to_owned(),
- "../platform/vboot_reference".to_owned(),
- "../third_party/coreboot".to_owned(),
- ])),
- ),
- (
- "CROS_WORKON_COMMIT".to_owned(),
- BashValue::Scalar("".to_owned()),
- ),
- (
- "CROS_WORKON_TREE".to_owned(),
- BashValue::Scalar("".to_owned()),
- ),
- (
- "CROS_WORKON_SUBTREE".to_owned(),
- BashValue::Scalar("".to_owned()),
- ),
- (
- "CROS_WORKON_OPTIONAL_CHECKOUT".to_owned(),
- BashValue::IndexedArray(Vec::from([
- "".to_owned(),
- "".to_owned(),
- "".to_owned(),
- ])),
- ),
- ])),
+ metadata: Arc::new(EBuildMetadata {
+ basic_data: EBuildBasicData {
+ repo_name: "baz".to_owned(),
+ ebuild_path: PathBuf::from("/dev/null"),
+ package_name: "sys-boot/depthcharge".to_owned(),
+ short_package_name: "depthcharge".to_owned(),
+ category_name: "sys-boot".to_owned(),
+ version: Version::try_new("0.1.0").unwrap(),
+ },
+ vars: BashVars::new(HashMap::from([
+ (
+ "CROS_WORKON_PROJECT".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "chromiumos/platform/depthcharge".to_owned(),
+ "chromiumos/platform/vboot_reference".to_owned(),
+ "chromiumos/third_party/coreboot".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_LOCALNAME".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "../platform/depthcharge".to_owned(),
+ "../platform/vboot_reference".to_owned(),
+ "../third_party/coreboot".to_owned(),
+ ])),
+ ),
+ (
+ "CROS_WORKON_COMMIT".to_owned(),
+ BashValue::Scalar("".to_owned()),
+ ),
+ (
+ "CROS_WORKON_TREE".to_owned(),
+ BashValue::Scalar("".to_owned()),
+ ),
+ (
+ "CROS_WORKON_SUBTREE".to_owned(),
+ BashValue::Scalar("".to_owned()),
+ ),
+ (
+ "CROS_WORKON_OPTIONAL_CHECKOUT".to_owned(),
+ BashValue::IndexedArray(Vec::from([
+ "".to_owned(),
+ "".to_owned(),
+ "".to_owned(),
+ ])),
+ ),
+ ])),
+ }),
slot: Slot::new("0"),
use_map: UseMap::new(),
accepted: true,
stable: true,
masked: false,
- ebuild_path: PathBuf::from("/dev/null"),
inherited: HashSet::new(),
inherit_paths: vec![],
direct_build_target: None,
diff --git a/portage/bin/alchemist/src/bin/alchemist/generate_repo/common.rs b/portage/bin/alchemist/src/bin/alchemist/generate_repo/common.rs
index 74f90a7..9e6304e 100644
--- a/portage/bin/alchemist/src/bin/alchemist/generate_repo/common.rs
+++ b/portage/bin/alchemist/src/bin/alchemist/generate_repo/common.rs
@@ -9,7 +9,7 @@
dependency::PackageDependencies,
source::{PackageDistSource, PackageSources},
},
- ebuild::{PackageDetails, PackageMetadataError},
+ ebuild::{PackageDetails, PackageLoadError},
repository::RepositorySet,
};
use anyhow::Result;
@@ -155,7 +155,7 @@
#[derive(Clone, Debug)]
pub enum PackageError {
- PackageMetadataError(PackageMetadataError),
+ PackageMetadataError(PackageLoadError),
PackageAnalysisError(PackageAnalysisError),
}
@@ -174,7 +174,7 @@
}
pub fn ebuild(&self) -> &Path {
match self {
- Self::PackageMetadataError(p) => &p.ebuild,
+ Self::PackageMetadataError(p) => &p.ebuild_path,
Self::PackageAnalysisError(p) => &p.details.ebuild_path,
}
}
diff --git a/portage/bin/alchemist/src/bin/alchemist/generate_repo/deps.rs b/portage/bin/alchemist/src/bin/alchemist/generate_repo/deps.rs
index 31678f0..47ba4e0 100644
--- a/portage/bin/alchemist/src/bin/alchemist/generate_repo/deps.rs
+++ b/portage/bin/alchemist/src/bin/alchemist/generate_repo/deps.rs
@@ -125,7 +125,11 @@
#[cfg(test)]
mod tests {
- use std::collections::{HashMap, HashSet};
+ use std::{
+ collections::{HashMap, HashSet},
+ path::PathBuf,
+ sync::Arc,
+ };
use alchemist::{
analyze::{
@@ -134,7 +138,10 @@
},
bash::vars::BashVars,
data::{Slot, UseMap},
- ebuild::PackageDetails,
+ ebuild::{
+ metadata::{EBuildBasicData, EBuildMetadata},
+ PackageDetails,
+ },
};
use pretty_assertions::assert_eq;
use url::Url;
@@ -192,33 +199,33 @@
install_host_deps: vec![],
};
- let details_prototype = PackageDetails {
- repo_name: "baz".to_owned(),
- package_name: "prototype".to_owned(),
- version: Version::try_new("1.0").unwrap(),
- vars: BashVars::new(HashMap::new()),
+ let make_details = |short_package_name: &str| PackageDetails {
+ metadata: Arc::new(EBuildMetadata {
+ basic_data: EBuildBasicData {
+ repo_name: "baz".to_owned(),
+ ebuild_path: PathBuf::from(format!(
+ "/somewhere/sys-apps/{short_package_name}-1.0.ebuild"
+ )),
+ package_name: format!("sys-apps/{short_package_name}"),
+ short_package_name: short_package_name.to_owned(),
+ category_name: "sys-apps".to_owned(),
+ version: Version::try_new("1.0").unwrap(),
+ },
+ vars: BashVars::new(HashMap::new()),
+ }),
slot: Slot::new("0"),
use_map: UseMap::new(),
accepted: true,
stable: true,
masked: false,
- ebuild_path: "/somewhere/sys-apps/prototype-1.0.ebuild".into(),
inherited: HashSet::new(),
inherit_paths: vec![],
direct_build_target: None,
};
- let mut details1 = details_prototype.clone();
- details1.package_name = "sys-apps/p1".to_owned();
- details1.ebuild_path = "/somewhere/sys-apps/p1-1.0.ebuild".into();
-
- let mut details2 = details_prototype.clone();
- details2.package_name = "sys-apps/p2".to_owned();
- details2.ebuild_path = "/somewhere/sys-apps/p2-1.0.ebuild".into();
-
- let mut details3 = details_prototype.clone();
- details3.package_name = "sys-apps/p3".to_owned();
- details3.ebuild_path = "/somewhere/sys-apps/p3-1.0.ebuild".into();
+ let details1 = make_details("p1");
+ let details2 = make_details("p2");
+ let details3 = make_details("p3");
let packages = vec![
Package {
diff --git a/portage/bin/alchemist/src/bin/alchemist/generate_repo/mod.rs b/portage/bin/alchemist/src/bin/alchemist/generate_repo/mod.rs
index 2f9d3fd..65ffe35 100644
--- a/portage/bin/alchemist/src/bin/alchemist/generate_repo/mod.rs
+++ b/portage/bin/alchemist/src/bin/alchemist/generate_repo/mod.rs
@@ -23,7 +23,7 @@
},
config::{bundle::ConfigBundle, ProvidedPackage},
dependency::{package::PackageAtom, Predicate},
- ebuild::{CachedPackageLoader, PackageDetails, PackageMetadataError},
+ ebuild::{CachedPackageLoader, MaybePackageDetails, PackageDetails, PackageLoadError},
fakechroot::PathTranslator,
repository::RepositorySet,
resolver::PackageResolver,
@@ -56,7 +56,7 @@
fn evaluate_all_packages(
repos: &RepositorySet,
loader: &CachedPackageLoader,
-) -> Result<(Vec<Arc<PackageDetails>>, Vec<Arc<PackageMetadataError>>)> {
+) -> Result<(Vec<Arc<PackageDetails>>, Vec<Arc<PackageLoadError>>)> {
let ebuild_paths = repos.find_all_ebuilds()?;
// Evaluate packages in parallel.
@@ -67,8 +67,8 @@
eprintln!("Loaded {} ebuilds", results.len());
Ok(results.into_iter().partition_map(|eval| match eval {
- Ok(details) => Either::Left(details),
- Err(err) => Either::Right(err),
+ MaybePackageDetails::Ok(details) => Either::Left(details),
+ MaybePackageDetails::Err(err) => Either::Right(err),
}))
}
diff --git a/portage/bin/alchemist/src/ebuild/mod.rs b/portage/bin/alchemist/src/ebuild/mod.rs
index 6cf1a09..5a6cceb 100644
--- a/portage/bin/alchemist/src/ebuild/mod.rs
+++ b/portage/bin/alchemist/src/ebuild/mod.rs
@@ -8,6 +8,7 @@
use once_cell::sync::OnceCell;
use std::{
collections::{HashMap, HashSet},
+ ops::Deref,
path::{Path, PathBuf},
sync::{Arc, Mutex},
};
@@ -24,7 +25,7 @@
},
};
-use self::metadata::{CachedEBuildEvaluator, MaybeEBuildMetadata};
+use self::metadata::{CachedEBuildEvaluator, EBuildBasicData, EBuildMetadata, MaybeEBuildMetadata};
/// Parses IUSE defined by ebuild/eclasses and returns as an [IUseMap].
fn parse_iuse_map(vars: &BashVars) -> Result<IUseMap> {
@@ -44,30 +45,14 @@
.collect())
}
-type PackageResult = Result<PackageDetails, PackageMetadataError>;
-
-/// Holds the error that occurred when processing the ebuild.
-#[derive(Clone, Debug)]
-pub struct PackageMetadataError {
- pub repo_name: String,
- pub package_name: String,
- pub ebuild: PathBuf,
- pub version: Version,
- pub error: String,
-}
-
-#[derive(Clone, Debug)]
+#[derive(Debug)]
pub struct PackageDetails {
- pub repo_name: String,
- pub package_name: String,
- pub version: Version,
- pub vars: BashVars,
+ pub metadata: Arc<EBuildMetadata>,
pub slot: Slot,
pub use_map: UseMap,
pub accepted: bool,
pub stable: bool,
pub masked: bool,
- pub ebuild_path: PathBuf,
pub inherited: HashSet<String>,
pub inherit_paths: Vec<PathBuf>,
pub direct_build_target: Option<String>,
@@ -115,6 +100,53 @@
}
}
+impl Deref for PackageDetails {
+ type Target = EBuildMetadata;
+
+ fn deref(&self) -> &Self::Target {
+ &self.metadata
+ }
+}
+
+/// Represents an error that occurred when loading an ebuild.
+#[derive(Clone, Debug)]
+pub struct PackageLoadError {
+ pub metadata: MaybeEBuildMetadata,
+ pub error: String,
+}
+
+impl Deref for PackageLoadError {
+ type Target = MaybeEBuildMetadata;
+
+ fn deref(&self) -> &Self::Target {
+ &self.metadata
+ }
+}
+
+/// Represents a package, covering both successfully loaded ones and failed ones.
+///
+/// Since this enum is very lightweight (contains [`Arc`] only), you should not wrap it within
+/// reference-counting smart pointers like [`Arc`], but you can just clone it.
+///
+/// While this enum looks very similar to [`Result`], we don't make it a type alias of [`Result`]
+/// to implement a few convenient methods.
+#[derive(Clone, Debug)]
+pub enum MaybePackageDetails {
+ Ok(Arc<PackageDetails>),
+ Err(Arc<PackageLoadError>),
+}
+
+impl Deref for MaybePackageDetails {
+ type Target = EBuildBasicData;
+
+ fn deref(&self) -> &Self::Target {
+ match self {
+ MaybePackageDetails::Ok(details) => details,
+ MaybePackageDetails::Err(error) => error,
+ }
+ }
+}
+
#[derive(Debug)]
pub struct PackageLoader {
evaluator: Arc<CachedEBuildEvaluator>,
@@ -137,7 +169,7 @@
}
}
- pub fn load_package(&self, ebuild_path: &Path) -> Result<PackageResult> {
+ pub fn load_package(&self, ebuild_path: &Path) -> Result<MaybePackageDetails> {
// Drive the ebuild to read its metadata.
let metadata = self.evaluator.evaluate_metadata(ebuild_path)?;
@@ -147,13 +179,10 @@
let metadata = match metadata {
MaybeEBuildMetadata::Ok(metadata) => metadata,
MaybeEBuildMetadata::Err(error) => {
- return Ok(PackageResult::Err(PackageMetadataError {
- repo_name: error.repo_name.clone(),
- package_name,
- ebuild: ebuild_path.to_owned(),
- version: error.version.clone(),
+ return Ok(MaybePackageDetails::Err(Arc::new(PackageLoadError {
error: error.error.clone(),
- }))
+ metadata: MaybeEBuildMetadata::Err(error),
+ })))
}
};
@@ -220,11 +249,8 @@
}
});
- Ok(PackageResult::Ok(PackageDetails {
- repo_name: metadata.repo_name.clone(),
- package_name,
- version: metadata.version.clone(),
- vars: metadata.vars.clone(),
+ Ok(MaybePackageDetails::Ok(Arc::new(PackageDetails {
+ metadata,
slot,
use_map,
accepted,
@@ -232,19 +258,16 @@
masked,
inherited,
inherit_paths,
- ebuild_path: ebuild_path.to_owned(),
direct_build_target,
- }))
+ })))
}
}
-type CachedPackageResult = std::result::Result<Arc<PackageDetails>, Arc<PackageMetadataError>>;
-
/// Wraps PackageLoader to cache results.
#[derive(Debug)]
pub struct CachedPackageLoader {
loader: PackageLoader,
- cache: Mutex<HashMap<PathBuf, Arc<OnceCell<CachedPackageResult>>>>,
+ cache: Mutex<HashMap<PathBuf, Arc<OnceCell<MaybePackageDetails>>>>,
}
impl CachedPackageLoader {
@@ -255,7 +278,7 @@
}
}
- pub fn load_package(&self, ebuild_path: &Path) -> Result<CachedPackageResult> {
+ pub fn load_package(&self, ebuild_path: &Path) -> Result<MaybePackageDetails> {
let once_cell = {
let mut cache_guard = self.cache.lock().unwrap();
cache_guard
@@ -263,14 +286,7 @@
.or_default()
.clone()
};
- let details = once_cell.get_or_try_init(|| -> Result<CachedPackageResult> {
- match self.loader.load_package(ebuild_path)? {
- PackageResult::Ok(details) => {
- Result::Ok(CachedPackageResult::Ok(Arc::new(details)))
- }
- PackageResult::Err(err) => Result::Ok(CachedPackageResult::Err(Arc::new(err))),
- }
- })?;
+ let details = once_cell.get_or_try_init(|| self.loader.load_package(ebuild_path))?;
Ok(details.clone())
}
}
diff --git a/portage/bin/alchemist/src/resolver.rs b/portage/bin/alchemist/src/resolver.rs
index 30d9b22..7303a01 100644
--- a/portage/bin/alchemist/src/resolver.rs
+++ b/portage/bin/alchemist/src/resolver.rs
@@ -15,7 +15,7 @@
package::{PackageAtom, PackageDependencyAtom},
Predicate,
},
- ebuild::{CachedPackageLoader, PackageDetails},
+ ebuild::{CachedPackageLoader, MaybePackageDetails, PackageDetails},
repository::RepositorySet,
};
@@ -53,9 +53,9 @@
.map(|ebuild_path| self.loader.load_package(&ebuild_path))
.filter_map(|result| match result {
Ok(eval) => match eval {
- Ok(details) => Some(Ok(details)),
+ MaybePackageDetails::Ok(details) => Some(Ok(details)),
// We ignore packages that had metadata evaluation errors.
- Err(_) => None,
+ MaybePackageDetails::Err(_) => None,
},
Err(e) => Some(Err(e)),
})
@@ -99,9 +99,9 @@
let mut matches = Vec::with_capacity(packages.len());
for eval in packages {
let details = match eval {
- Ok(details) => details,
+ MaybePackageDetails::Ok(details) => details,
// We ignore packages that had metadata evaluation errors.
- Err(_) => continue,
+ MaybePackageDetails::Err(_) => continue,
};
match atom.package_matches(use_map, &details.as_package_ref()) {
Ok(result) => {