Skip to content

Commit 04c963a

Browse files
committed
Add workspace support for source overlays
Adds workspace configuration options (not user-exposed) for overlaying sources.
1 parent 2a5633b commit 04c963a

File tree

7 files changed

+60
-16
lines changed

7 files changed

+60
-16
lines changed

crates/xtask-bump-check/src/xtask.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use std::fs;
1616
use std::task;
1717

1818
use cargo::core::dependency::Dependency;
19-
use cargo::core::registry::PackageRegistry;
2019
use cargo::core::Package;
2120
use cargo::core::Registry;
2221
use cargo::core::SourceId;
@@ -137,7 +136,7 @@ fn bump_check(args: &clap::ArgMatches, gctx: &cargo::util::GlobalContext) -> Car
137136

138137
let mut needs_bump = Vec::new();
139138

140-
check_crates_io(gctx, &changed_members, &mut needs_bump)?;
139+
check_crates_io(&ws, &changed_members, &mut needs_bump)?;
141140

142141
if let Some(referenced_commit) = referenced_commit.as_ref() {
143142
status(&format!("compare against `{}`", referenced_commit.id()))?;
@@ -385,12 +384,13 @@ fn symmetric_diff<'a>(
385384
///
386385
/// Assumption: We always release a version larger than all existing versions.
387386
fn check_crates_io<'a>(
388-
gctx: &GlobalContext,
387+
ws: &Workspace<'a>,
389388
changed_members: &HashMap<&'a str, &'a Package>,
390389
needs_bump: &mut Vec<&'a Package>,
391390
) -> CargoResult<()> {
391+
let gctx = ws.gctx();
392392
let source_id = SourceId::crates_io(gctx)?;
393-
let mut registry = PackageRegistry::new(gctx)?;
393+
let mut registry = ws.package_registry()?;
394394
let _lock = gctx.acquire_package_cache_lock(CacheLockMode::DownloadExclusive)?;
395395
registry.lock_patches();
396396
gctx.shell().status(

src/cargo/core/registry.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,10 @@ pub struct LockedPatchDependency {
194194
}
195195

196196
impl<'gctx> PackageRegistry<'gctx> {
197-
pub fn new(gctx: &'gctx GlobalContext) -> CargoResult<PackageRegistry<'gctx>> {
198-
let source_config = SourceConfigMap::new(gctx)?;
197+
pub fn new_with_source_config(
198+
gctx: &'gctx GlobalContext,
199+
source_config: SourceConfigMap<'gctx>,
200+
) -> CargoResult<PackageRegistry<'gctx>> {
199201
Ok(PackageRegistry {
200202
gctx,
201203
sources: SourceMap::new(),

src/cargo/core/workspace.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::core::{
2020
};
2121
use crate::core::{EitherManifest, Package, SourceId, VirtualManifest};
2222
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};
2424
use crate::util::edit_distance;
2525
use crate::util::errors::{CargoResult, ManifestError};
2626
use crate::util::interning::InternedString;
@@ -109,6 +109,9 @@ pub struct Workspace<'gctx> {
109109

110110
/// Workspace-level custom metadata
111111
custom_metadata: Option<toml::Value>,
112+
113+
/// Local overlay configuration. See [`crate::sources::overlay`].
114+
local_overlays: HashMap<SourceId, PathBuf>,
112115
}
113116

114117
// Separate structure for tracking loaded packages (to avoid loading anything
@@ -237,6 +240,7 @@ impl<'gctx> Workspace<'gctx> {
237240
resolve_behavior: ResolveBehavior::V1,
238241
resolve_honors_rust_version: false,
239242
custom_metadata: None,
243+
local_overlays: HashMap::new(),
240244
}
241245
}
242246

@@ -1674,6 +1678,44 @@ impl<'gctx> Workspace<'gctx> {
16741678
// Cargo to panic, see issue #10545.
16751679
self.is_member(&unit.pkg) && !(unit.target.for_host() || unit.pkg.proc_macro())
16761680
}
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+
}
16771719
}
16781720

16791721
impl<'gctx> Packages<'gctx> {

src/cargo/ops/cargo_add/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pub fn add(workspace: &Workspace<'_>, options: &AddOptions<'_>) -> CargoResult<(
7878
);
7979
}
8080

81-
let mut registry = PackageRegistry::new(options.gctx)?;
81+
let mut registry = workspace.package_registry()?;
8282

8383
let deps = {
8484
let _lock = options

src/cargo/ops/cargo_package.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::task::Poll;
99
use crate::core::compiler::{BuildConfig, CompileMode, DefaultExecutor, Executor};
1010
use crate::core::manifest::Target;
1111
use crate::core::resolver::CliFeatures;
12-
use crate::core::{registry::PackageRegistry, resolver::HasDevUnits};
12+
use crate::core::resolver::HasDevUnits;
1313
use crate::core::{Feature, PackageIdSpecQuery, Shell, Verbosity, Workspace};
1414
use crate::core::{Package, PackageId, PackageSet, Resolve, SourceId};
1515
use crate::sources::PathSource;
@@ -472,7 +472,7 @@ fn build_lock(ws: &Workspace<'_>, publish_pkg: &Package) -> CargoResult<String>
472472
let orig_resolve = ops::load_pkg_lockfile(ws)?;
473473

474474
let tmp_ws = Workspace::ephemeral(publish_pkg.clone(), ws.gctx(), None, true)?;
475-
let mut tmp_reg = PackageRegistry::new(ws.gctx())?;
475+
let mut tmp_reg = ws.package_registry()?;
476476
let mut new_resolve = ops::resolve_with_previous(
477477
&mut tmp_reg,
478478
&tmp_ws,

src/cargo/ops/cargo_update.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub struct UpdateOptions<'a> {
3232
}
3333

3434
pub fn generate_lockfile(ws: &Workspace<'_>) -> CargoResult<()> {
35-
let mut registry = PackageRegistry::new(ws.gctx())?;
35+
let mut registry = ws.package_registry()?;
3636
let previous_resolve = None;
3737
let mut resolve = ops::resolve_with_previous(
3838
&mut registry,
@@ -73,7 +73,7 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
7373
// Precise option specified, so calculate a previous_resolve required
7474
// by precise package update later.
7575
Some(_) => {
76-
let mut registry = PackageRegistry::new(opts.gctx)?;
76+
let mut registry = ws.package_registry()?;
7777
ops::resolve_with_previous(
7878
&mut registry,
7979
ws,
@@ -88,7 +88,7 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
8888
}
8989
}
9090
};
91-
let mut registry = PackageRegistry::new(opts.gctx)?;
91+
let mut registry = ws.package_registry()?;
9292
let mut to_avoid = HashSet::new();
9393

9494
if opts.to_update.is_empty() {
@@ -226,7 +226,7 @@ pub fn upgrade_manifests(
226226
// that we're synchronized against other Cargos.
227227
let _lock = gctx.acquire_package_cache_lock(CacheLockMode::DownloadExclusive)?;
228228

229-
let mut registry = PackageRegistry::new(gctx)?;
229+
let mut registry = ws.package_registry()?;
230230
registry.lock_patches();
231231

232232
for member in ws.members_mut().sorted() {

src/cargo/ops/resolve.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ version. This may also occur with an optional dependency that is not enabled.";
116116
/// This is a simple interface used by commands like `clean`, `fetch`, and
117117
/// `package`, which don't specify any options or features.
118118
pub fn resolve_ws<'a>(ws: &Workspace<'a>, dry_run: bool) -> CargoResult<(PackageSet<'a>, Resolve)> {
119-
let mut registry = PackageRegistry::new(ws.gctx())?;
119+
let mut registry = ws.package_registry()?;
120120
let resolve = resolve_with_registry(ws, &mut registry, dry_run)?;
121121
let packages = get_resolved_packages(&resolve, registry)?;
122122
Ok((packages, resolve))
@@ -142,7 +142,7 @@ pub fn resolve_ws_with_opts<'gctx>(
142142
force_all_targets: ForceAllTargets,
143143
dry_run: bool,
144144
) -> CargoResult<WorkspaceResolve<'gctx>> {
145-
let mut registry = PackageRegistry::new(ws.gctx())?;
145+
let mut registry = ws.package_registry()?;
146146
let (resolve, resolved_with_overrides) = if ws.ignore_lock() {
147147
let add_patches = true;
148148
let resolve = None;

0 commit comments

Comments
 (0)