Skip to content

Commit 6995e1d

Browse files
author
Jon Gjengset
committed
Extract config patch on use
1 parent 2c88a63 commit 6995e1d

File tree

6 files changed

+211
-71
lines changed

6 files changed

+211
-71
lines changed

src/cargo/core/resolver/encode.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ impl EncodableResolve {
154154
/// primary uses is to be used with `resolve_with_previous` to guide the
155155
/// resolver to create a complete Resolve.
156156
pub fn into_resolve(self, original: &str, ws: &Workspace<'_>) -> CargoResult<Resolve> {
157-
let path_deps = build_path_deps(ws);
157+
let path_deps = build_path_deps(ws)?;
158158
let mut checksums = HashMap::new();
159159

160160
let mut version = match self.version {
@@ -402,7 +402,7 @@ impl EncodableResolve {
402402
}
403403
}
404404

405-
fn build_path_deps(ws: &Workspace<'_>) -> HashMap<String, SourceId> {
405+
fn build_path_deps(ws: &Workspace<'_>) -> CargoResult<HashMap<String, SourceId>> {
406406
// If a crate is **not** a path source, then we're probably in a situation
407407
// such as `cargo install` with a lock file from a remote dependency. In
408408
// that case we don't need to fixup any path dependencies (as they're not
@@ -424,7 +424,7 @@ fn build_path_deps(ws: &Workspace<'_>) -> HashMap<String, SourceId> {
424424
for member in members.iter() {
425425
build_pkg(member, ws, &mut ret, &mut visited);
426426
}
427-
for deps in ws.root_patch().values() {
427+
for deps in ws.root_patch()?.values() {
428428
for dep in deps {
429429
build_dep(dep, ws, &mut ret, &mut visited);
430430
}
@@ -433,7 +433,7 @@ fn build_path_deps(ws: &Workspace<'_>) -> HashMap<String, SourceId> {
433433
build_dep(dep, ws, &mut ret, &mut visited);
434434
}
435435

436-
return ret;
436+
return Ok(ret);
437437

438438
fn build_pkg(
439439
pkg: &Package,

src/cargo/core/workspace.rs

Lines changed: 70 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ use crate::core::resolver::ResolveBehavior;
1616
use crate::core::{Dependency, Edition, PackageId, PackageIdSpec};
1717
use crate::core::{EitherManifest, Package, SourceId, VirtualManifest};
1818
use crate::ops;
19-
use crate::sources::PathSource;
19+
use crate::sources::{PathSource, CRATES_IO_INDEX, CRATES_IO_REGISTRY};
2020
use crate::util::errors::{CargoResult, CargoResultExt, ManifestError};
2121
use crate::util::interning::InternedString;
2222
use crate::util::paths;
23-
use crate::util::toml::{read_manifest, TomlProfiles};
24-
use crate::util::{Config, Filesystem};
23+
use crate::util::toml::{read_manifest, TomlDependency, TomlProfiles};
24+
use crate::util::{config::ConfigRelativePath, Config, Filesystem, IntoUrl};
2525

2626
/// The core abstraction in Cargo for working with a workspace of crates.
2727
///
@@ -362,31 +362,89 @@ impl<'cfg> Workspace<'cfg> {
362362
}
363363
}
364364

365+
fn config_patch(&self) -> CargoResult<HashMap<Url, Vec<Dependency>>> {
366+
let config_patch: Option<
367+
BTreeMap<String, BTreeMap<String, TomlDependency<ConfigRelativePath>>>,
368+
> = self.config.get("patch")?;
369+
370+
if config_patch.is_some() && !self.config.cli_unstable().patch_in_config {
371+
self.config.shell().warn("`[patch]` in cargo config was ignored, the -Zpatch-in-config command-line flag is required".to_owned())?;
372+
return Ok(HashMap::new());
373+
}
374+
375+
let source = SourceId::for_path(self.root())?;
376+
377+
let mut warnings = Vec::new();
378+
let mut nested_paths = Vec::new();
379+
380+
let mut patch = HashMap::new();
381+
for (url, deps) in config_patch.into_iter().flatten() {
382+
let url = match &url[..] {
383+
CRATES_IO_REGISTRY => CRATES_IO_INDEX.parse().unwrap(),
384+
url => self
385+
.config
386+
.get_registry_index(url)
387+
.or_else(|_| url.into_url())
388+
.chain_err(|| {
389+
format!("[patch] entry `{}` should be a URL or registry name", url)
390+
})?,
391+
};
392+
patch.insert(
393+
url,
394+
deps.iter()
395+
.map(|(name, dep)| {
396+
dep.to_dependency_split(
397+
name,
398+
/* pkg_id */ None,
399+
source,
400+
&mut nested_paths,
401+
self.config,
402+
&mut warnings,
403+
/* platform */ None,
404+
// NOTE: Since we use ConfigRelativePath, this root isn't used as
405+
// any relative paths are resolved before they'd be joined with root.
406+
self.root(),
407+
self.unstable_features(),
408+
None,
409+
)
410+
})
411+
.collect::<CargoResult<Vec<_>>>()?,
412+
);
413+
}
414+
415+
for message in warnings {
416+
self.config
417+
.shell()
418+
.warn(format!("[patch] in cargo config: {}", message))?
419+
}
420+
421+
let _ = nested_paths;
422+
423+
Ok(patch)
424+
}
425+
365426
/// Returns the root `[patch]` section of this workspace.
366427
///
367428
/// This may be from a virtual crate or an actual crate.
368-
pub fn root_patch(&self) -> HashMap<Url, Vec<Dependency>> {
429+
pub fn root_patch(&self) -> CargoResult<HashMap<Url, Vec<Dependency>>> {
369430
let from_manifest = match self.root_maybe() {
370431
MaybePackage::Package(p) => p.manifest().patch(),
371432
MaybePackage::Virtual(vm) => vm.patch(),
372433
};
373434

374-
let from_config = self
375-
.config
376-
.patch()
377-
.expect("config [patch] was never parsed");
435+
let from_config = self.config_patch()?;
378436
if from_config.is_empty() {
379-
return from_manifest.clone();
437+
return Ok(from_manifest.clone());
380438
}
381439
if from_manifest.is_empty() {
382-
return from_config.clone();
440+
return Ok(from_config.clone());
383441
}
384442

385443
// We could just chain from_manifest and from_config,
386444
// but that's not quite right as it won't deal with overlaps.
387445
let mut combined = from_manifest.clone();
388446
for (url, cdeps) in from_config {
389-
if let Some(deps) = combined.get_mut(url) {
447+
if let Some(deps) = combined.get_mut(&url) {
390448
// We want from_manifest to take precedence for each patched name.
391449
// NOTE: This is inefficient if the number of patches is large!
392450
let mut left = cdeps.clone();
@@ -404,7 +462,7 @@ impl<'cfg> Workspace<'cfg> {
404462
combined.insert(url.clone(), cdeps.clone());
405463
}
406464
}
407-
combined
465+
Ok(combined)
408466
}
409467

410468
/// Returns an iterator over all packages in this workspace

src/cargo/ops/resolve.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ pub fn resolve_with_previous<'cfg>(
240240
// locked.
241241
let mut avoid_patch_ids = HashSet::new();
242242
if register_patches {
243-
for (url, patches) in ws.root_patch().iter() {
243+
for (url, patches) in ws.root_patch()?.iter() {
244244
let previous = match previous {
245245
Some(r) => r,
246246
None => {

src/cargo/util/config/mod.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ use url::Url;
7474
use self::ConfigValue as CV;
7575
use crate::core::compiler::rustdoc::RustdocExternMap;
7676
use crate::core::shell::Verbosity;
77-
use crate::core::{features, CliUnstable, Dependency, Shell, SourceId, Workspace};
77+
use crate::core::{features, CliUnstable, Shell, SourceId, Workspace};
7878
use crate::ops;
7979
use crate::util::errors::{CargoResult, CargoResultExt};
8080
use crate::util::toml as cargo_toml;
@@ -176,8 +176,6 @@ pub struct Config {
176176
/// Lock, if held, of the global package cache along with the number of
177177
/// acquisitions so far.
178178
package_cache_lock: RefCell<Option<(Option<FileLock>, usize)>>,
179-
/// `[patch]` section parsed from configuration.
180-
patch: LazyCell<HashMap<Url, Vec<Dependency>>>,
181179
/// Cached configuration parsed by Cargo
182180
http_config: LazyCell<CargoHttpConfig>,
183181
net_config: LazyCell<CargoNetConfig>,
@@ -279,7 +277,6 @@ impl Config {
279277
upper_case_env,
280278
updated_sources: LazyCell::new(),
281279
package_cache_lock: RefCell::new(None),
282-
patch: LazyCell::new(),
283280
http_config: LazyCell::new(),
284281
net_config: LazyCell::new(),
285282
build_config: LazyCell::new(),
@@ -1327,17 +1324,6 @@ impl Config {
13271324
Ok(*(self.crates_io_source_id.try_borrow_with(f)?))
13281325
}
13291326

1330-
pub fn maybe_init_patch<F>(&self, f: F) -> CargoResult<&HashMap<Url, Vec<Dependency>>>
1331-
where
1332-
F: FnMut() -> CargoResult<HashMap<Url, Vec<Dependency>>>,
1333-
{
1334-
self.patch.try_borrow_with(f)
1335-
}
1336-
1337-
pub fn patch(&self) -> Option<&HashMap<Url, Vec<Dependency>>> {
1338-
self.patch.borrow()
1339-
}
1340-
13411327
pub fn creation_time(&self) -> Instant {
13421328
self.creation_time
13431329
}

0 commit comments

Comments
 (0)