@@ -6,7 +6,6 @@ use std::borrow::Cow;
66use std:: cell:: RefCell ;
77use std:: collections:: { BTreeSet , HashMap , HashSet } ;
88use std:: ops:: Not ;
9- use std:: str:: FromStr ;
109use std:: sync:: Arc ;
1110
1211use itertools:: Itertools ;
@@ -38,7 +37,6 @@ use spk_schema::ident_build::{Build, EmbeddedSource, EmbeddedSourcePackage};
3837use spk_schema:: ident_component:: Component ;
3938use spk_schema:: name:: { OptNameBuf , PkgNameBuf } ;
4039use spk_schema:: prelude:: { HasVersion , Named } ;
41- use spk_schema:: version:: Version ;
4240use spk_schema:: version_range:: { DoubleEqualsVersion , Ranged , VersionFilter , parse_version_range} ;
4341use spk_schema:: {
4442 BuildIdent ,
@@ -1448,106 +1446,130 @@ impl DependencyProvider for SpkProvider {
14481446 if let Build :: Embedded ( EmbeddedSource :: Package ( parent) ) =
14491447 located_build_ident_with_component. ident . build ( )
14501448 {
1451- match actual_component {
1452- Component :: Run => {
1453- // The Run component is the default "home" of
1454- // embedded packages, no dependency needed in this
1455- // case.
1449+ let parent_ident: BuildIdent = match ( * * parent) . clone ( ) . try_into ( ) {
1450+ Ok ( ident) => ident,
1451+ Err ( err) => {
1452+ let msg = self . pool . intern_string ( format ! (
1453+ "failed to get valid parent ident for '{}': {err}" ,
1454+ located_build_ident_with_component. ident
1455+ ) ) ;
1456+ return Dependencies :: Unknown ( msg) ;
14561457 }
1457- component => ' invalid_parent: {
1458- // XXX: Do we not have a convenient way to read the
1459- // parent package from an embedded stub ident?
1460- let Ok ( pkg_name) = PkgNameBuf :: from_str ( & parent. ident . pkg_name ) else {
1461- break ' invalid_parent;
1462- } ;
1463- let Some ( version_str) = parent. ident . version_str . as_ref ( ) else {
1464- break ' invalid_parent;
1465- } ;
1466- let Ok ( version) = Version :: from_str ( version_str) else {
1467- break ' invalid_parent;
1468- } ;
1469- let Some ( build_str) = parent. ident . build_str . as_ref ( ) else {
1470- break ' invalid_parent;
1471- } ;
1472- let Ok ( build) = Build :: from_str ( build_str) else {
1473- break ' invalid_parent;
1474- } ;
1475- let ident = BuildIdent :: new (
1476- VersionIdent :: new ( pkg_name, version) ,
1477- build. clone ( ) ,
1478- ) ;
1479- let Ok ( parent) = repo. read_package ( & ident) . await else {
1480- break ' invalid_parent;
1481- } ;
1482- // Look through the components of the parent to see
1483- // if one (or more?) of them embeds this component.
1484- for parent_component in parent. components ( ) . iter ( ) {
1485- parent_component
1486- . embedded
1487- . iter ( )
1488- . filter ( |embedded_package| {
1489- embedded_package. pkg . name ( )
1490- == located_build_ident_with_component. ident . name ( )
1491- && embedded_package
1492- . pkg
1493- . target ( )
1494- . as_ref ( )
1495- . map ( |version| {
1496- version
1497- == located_build_ident_with_component
1458+ } ;
1459+ let parent = match repo. read_package ( & parent_ident) . await {
1460+ Ok ( spec) => spec,
1461+ Err ( err) => {
1462+ let msg = self . pool . intern_string ( format ! (
1463+ "failed to read parent package for '{}': {err}" ,
1464+ located_build_ident_with_component. ident
1465+ ) ) ;
1466+ return Dependencies :: Unknown ( msg) ;
1467+ }
1468+ } ;
1469+ // Look through the components of the parent to see
1470+ // if one (or more?) of them embeds this component.
1471+ let mut found = false ;
1472+ for parent_component in parent. components ( ) . iter ( ) {
1473+ parent_component
1474+ . embedded
1475+ . iter ( )
1476+ . filter ( |embedded_package| {
1477+ embedded_package. pkg . name ( )
1478+ == located_build_ident_with_component. ident . name ( )
1479+ && embedded_package
1480+ . pkg
1481+ . target ( )
1482+ . as_ref ( )
1483+ . map ( |version| {
1484+ version
1485+ == located_build_ident_with_component
1486+ . ident
1487+ . version ( )
1488+ } )
1489+ . unwrap_or ( true )
1490+ && embedded_package. components ( ) . contains ( actual_component)
1491+ } )
1492+ . for_each ( |_embedded_package| {
1493+ found = true ;
1494+ let dep_name = self . pool . intern_package_name (
1495+ ResolvoPackageName :: PkgNameBufWithComponent (
1496+ PkgNameBufWithComponent {
1497+ name : parent_ident. name ( ) . to_owned ( ) ,
1498+ component : SyntheticComponent :: Actual (
1499+ parent_component. name . clone ( ) ,
1500+ ) ,
1501+ } ,
1502+ ) ,
1503+ ) ;
1504+ known_deps. requirements . push (
1505+ self . pool
1506+ . intern_version_set (
1507+ dep_name,
1508+ RequestVS :: SpkRequest ( Request :: Pkg ( PkgRequest :: new (
1509+ RangeIdent {
1510+ repository_name : Some (
1511+ located_build_ident_with_component
14981512 . ident
1499- . version ( )
1500- } )
1501- . unwrap_or ( true )
1502- && embedded_package. components ( ) . contains ( component)
1503- } )
1504- . for_each ( |_embedded_package| {
1505- let dep_name = self . pool . intern_package_name (
1506- ResolvoPackageName :: PkgNameBufWithComponent (
1507- PkgNameBufWithComponent {
1508- name : ident. name ( ) . to_owned ( ) ,
1509- component : SyntheticComponent :: Actual (
1510- parent_component. name . clone ( ) ,
1513+ . repository_name ( )
1514+ . to_owned ( ) ,
15111515 ) ,
1512- } ,
1513- ) ,
1514- ) ;
1515- known_deps. requirements . push (
1516- self . pool . intern_version_set (
1517- dep_name,
1518- RequestVS :: SpkRequest ( Request :: Pkg (
1519- PkgRequest :: new (
1520- RangeIdent {
1521- repository_name : Some (
1522- located_build_ident_with_component
1523- . ident
1524- . repository_name ( )
1525- . to_owned ( ) ,
1526- ) ,
1527- name : ident. name ( ) . to_owned ( ) ,
1528- components : BTreeSet :: from_iter ( [
1529- parent_component. name . clone ( ) ,
1530- ] ) ,
1531- version : VersionFilter :: single (
1532- DoubleEqualsVersion :: version_range (
1533- ident. version ( ) . clone ( ) ,
1534- ) ,
1535- ) ,
1536- build : Some ( build. clone ( ) ) ,
1537- } ,
1538- RequestedBy :: Embedded (
1539- located_build_ident_with_component
1540- . ident
1541- . target ( )
1542- . clone ( ) ,
1516+ name : parent_ident. name ( ) . to_owned ( ) ,
1517+ components : BTreeSet :: from_iter ( [
1518+ parent_component. name . clone ( ) ,
1519+ ] ) ,
1520+ version : VersionFilter :: single (
1521+ DoubleEqualsVersion :: version_range (
1522+ parent_ident. version ( ) . clone ( ) ,
15431523 ) ,
15441524 ) ,
1545- ) )
1546- ) . into ( ) ,
1547- ) ;
1548- } ) ;
1549- }
1550- }
1525+ build : Some ( parent_ident. build ( ) . clone ( ) ) ,
1526+ } ,
1527+ RequestedBy :: Embedded (
1528+ located_build_ident_with_component
1529+ . ident
1530+ . target ( )
1531+ . clone ( ) ,
1532+ ) ,
1533+ ) ) ) ,
1534+ )
1535+ . into ( ) ,
1536+ ) ;
1537+ } ) ;
1538+ }
1539+ if !found {
1540+ // In the event that no owning component was found,
1541+ // this stub must still bring in at least one
1542+ // component from the parent. By convention, bring
1543+ // in the Run component of the parent.
1544+ let dep_name = self . pool . intern_package_name (
1545+ ResolvoPackageName :: PkgNameBufWithComponent ( PkgNameBufWithComponent {
1546+ name : parent_ident. name ( ) . to_owned ( ) ,
1547+ component : SyntheticComponent :: Actual ( Component :: Run ) ,
1548+ } ) ,
1549+ ) ;
1550+ let located_parent = LocatedBuildIdentWithComponent {
1551+ ident : parent_ident. clone ( ) . to_located (
1552+ located_build_ident_with_component
1553+ . ident
1554+ . repository_name ( )
1555+ . to_owned ( ) ,
1556+ ) ,
1557+ // as_request_with_components does not make use
1558+ // of the component field, assigning Base here
1559+ // does not imply anything.
1560+ component : SyntheticComponent :: Base ,
1561+ requires_build_from_source : false ,
1562+ } ;
1563+ known_deps. requirements . push (
1564+ self . pool
1565+ . intern_version_set (
1566+ dep_name,
1567+ RequestVS :: SpkRequest (
1568+ located_parent. as_request_with_components ( [ Component :: Run ] ) ,
1569+ ) ,
1570+ )
1571+ . into ( ) ,
1572+ ) ;
15511573 }
15521574 }
15531575 for option in package. get_build_options ( ) {
0 commit comments