@@ -20,7 +20,7 @@ use crate::core::{
20
20
} ;
21
21
use crate :: core:: { EitherManifest , Package , SourceId , VirtualManifest } ;
22
22
use crate :: ops;
23
- use crate :: sources:: { PathSource , CRATES_IO_INDEX , CRATES_IO_REGISTRY } ;
23
+ use crate :: sources:: { PathSource , SourceConfigMap , CRATES_IO_INDEX , CRATES_IO_REGISTRY } ;
24
24
use crate :: util:: edit_distance;
25
25
use crate :: util:: errors:: { CargoResult , ManifestError } ;
26
26
use crate :: util:: interning:: InternedString ;
@@ -109,6 +109,9 @@ pub struct Workspace<'gctx> {
109
109
110
110
/// Workspace-level custom metadata
111
111
custom_metadata : Option < toml:: Value > ,
112
+
113
+ /// Local overlay configuration. See [`crate::sources::overlay`].
114
+ local_overlays : HashMap < SourceId , PathBuf > ,
112
115
}
113
116
114
117
// Separate structure for tracking loaded packages (to avoid loading anything
@@ -237,6 +240,7 @@ impl<'gctx> Workspace<'gctx> {
237
240
resolve_behavior : ResolveBehavior :: V1 ,
238
241
resolve_honors_rust_version : false ,
239
242
custom_metadata : None ,
243
+ local_overlays : HashMap :: new ( ) ,
240
244
}
241
245
}
242
246
@@ -1674,6 +1678,44 @@ impl<'gctx> Workspace<'gctx> {
1674
1678
// Cargo to panic, see issue #10545.
1675
1679
self . is_member ( & unit. pkg ) && !( unit. target . for_host ( ) || unit. pkg . proc_macro ( ) )
1676
1680
}
1681
+
1682
+ /// Adds a local package registry overlaying a `SourceId`.
1683
+ ///
1684
+ /// See [`crate::sources::overlay::DependencyConfusionThreatOverlaySource`] for why you shouldn't use this.
1685
+ pub fn add_local_overlay ( & mut self , id : SourceId , registry_path : PathBuf ) {
1686
+ self . local_overlays . insert ( id, registry_path) ;
1687
+ }
1688
+
1689
+ /// Builds a package registry that reflects this workspace configuration.
1690
+ pub fn package_registry ( & self ) -> CargoResult < PackageRegistry < ' gctx > > {
1691
+ let source_config =
1692
+ SourceConfigMap :: new_with_overlays ( self . gctx ( ) , self . local_overlays ( ) ?) ?;
1693
+ PackageRegistry :: new_with_source_config ( self . gctx ( ) , source_config)
1694
+ }
1695
+
1696
+ /// Returns all the configured local overlays, including the ones from our secret environment variable.
1697
+ fn local_overlays ( & self ) -> CargoResult < impl Iterator < Item = ( SourceId , SourceId ) > > {
1698
+ let mut ret = self
1699
+ . local_overlays
1700
+ . iter ( )
1701
+ . map ( |( id, path) | Ok ( ( * id, SourceId :: for_local_registry ( path) ?) ) )
1702
+ . collect :: < CargoResult < Vec < _ > > > ( ) ?;
1703
+
1704
+ if let Ok ( overlay) = self
1705
+ . gctx
1706
+ . get_env ( "__CARGO_TEST_DEPENDENCY_CONFUSION_VULNERABILITY_DO_NOT_USE_THIS" )
1707
+ {
1708
+ let ( url, path) = overlay. split_once ( '=' ) . ok_or ( anyhow:: anyhow!(
1709
+ "invalid overlay format. I won't tell you why; you shouldn't be using it anyway"
1710
+ ) ) ?;
1711
+ ret. push ( (
1712
+ SourceId :: from_url ( url) ?,
1713
+ SourceId :: for_local_registry ( path. as_ref ( ) ) ?,
1714
+ ) ) ;
1715
+ }
1716
+
1717
+ Ok ( ret. into_iter ( ) )
1718
+ }
1677
1719
}
1678
1720
1679
1721
impl < ' gctx > Packages < ' gctx > {
0 commit comments