Skip to content

Commit e7073ea

Browse files
committed
Use the shared source building in package
This changes the registry validation slightly, adding in a check forbidding implicit source replacement. This affects the tests (which configure a dummy registry for source replacement), so we also weaken the checks by only erroring for registry issues when there are actually local dependencies.
1 parent b3860a4 commit e7073ea

File tree

3 files changed

+40
-35
lines changed

3 files changed

+40
-35
lines changed

src/cargo/ops/cargo_package.rs

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::{BTreeSet, HashMap, HashSet};
1+
use std::collections::{BTreeSet, HashMap};
22
use std::fs::{self, File};
33
use std::io::prelude::*;
44
use std::io::SeekFrom;
@@ -16,7 +16,7 @@ use crate::core::{Package, PackageId, PackageSet, Resolve, SourceId};
1616
use crate::ops::lockfile::LOCKFILE_NAME;
1717
use crate::ops::registry::{infer_registry, RegistryOrIndex};
1818
use crate::sources::registry::index::{IndexPackage, RegistryDependency};
19-
use crate::sources::{PathSource, SourceConfigMap, CRATES_IO_REGISTRY};
19+
use crate::sources::{PathSource, CRATES_IO_REGISTRY};
2020
use crate::util::cache_lock::CacheLockMode;
2121
use crate::util::context::JobsConfig;
2222
use crate::util::errors::CargoResult;
@@ -202,19 +202,34 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Vec<Fi
202202
// below, and will be validated during the verification step.
203203
}
204204

205+
let deps = local_deps(pkgs.iter().map(|(p, f)| ((*p).clone(), f.clone())));
205206
let just_pkgs: Vec<_> = pkgs.iter().map(|p| p.0).collect();
206-
let publish_reg = get_registry(ws.gctx(), &just_pkgs, opts.reg_or_index.clone())?;
207-
debug!("packaging for registry {publish_reg}");
207+
208+
let sid = match get_registry(ws.gctx(), &just_pkgs, opts.reg_or_index.clone()) {
209+
Ok(sid) => {
210+
debug!("packaging for registry {}", sid);
211+
Some(sid)
212+
}
213+
Err(e) => {
214+
if deps.has_no_dependencies() && opts.reg_or_index.is_none() {
215+
// The publish registry doesn't matter unless there are local dependencies,
216+
// so ignore any errors if we don't need it. If they explicitly passed a registry
217+
// on the CLI, we check it no matter what.
218+
None
219+
} else {
220+
return Err(e);
221+
}
222+
}
223+
};
208224

209225
let mut local_reg = if ws.gctx().cli_unstable().package_workspace {
210226
let reg_dir = ws.target_dir().join("package").join("tmp-registry");
211-
Some(TmpRegistry::new(ws.gctx(), reg_dir, publish_reg)?)
227+
sid.map(|sid| TmpRegistry::new(ws.gctx(), reg_dir, sid))
228+
.transpose()?
212229
} else {
213230
None
214231
};
215232

216-
let deps = local_deps(pkgs.iter().map(|(p, f)| ((*p).clone(), f.clone())));
217-
218233
// Packages need to be created in dependency order, because dependencies must
219234
// be added to our local overlay before we can create lockfiles that depend on them.
220235
let sorted_pkgs = deps.sort();
@@ -258,52 +273,35 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Vec<Fi
258273
/// packages that we're packaging: if we're packaging foo-bin and foo-lib, and foo-bin
259274
/// depends on foo-lib, then the foo-lib entry in foo-bin's lockfile will depend on the
260275
/// registry that we're building packages for.
261-
pub(crate) fn get_registry(
276+
fn get_registry(
262277
gctx: &GlobalContext,
263278
pkgs: &[&Package],
264279
reg_or_index: Option<RegistryOrIndex>,
265280
) -> CargoResult<SourceId> {
266-
let reg_or_index = match reg_or_index {
281+
let reg_or_index = match reg_or_index.clone() {
267282
Some(r) => Some(r),
268283
None => infer_registry(pkgs)?,
269284
};
270285

286+
// Validate the registry against the packages' allow-lists.
271287
let reg = reg_or_index
272288
.clone()
273289
.unwrap_or_else(|| RegistryOrIndex::Registry(CRATES_IO_REGISTRY.to_owned()));
274-
275-
// Validate the registry against the packages' allow-lists. For backwards compatibility, we
276-
// skip this if only a single package is being published (because in that case the registry
277-
// doesn't affect the packaging step).
278-
if pkgs.len() > 1 {
279-
if let RegistryOrIndex::Registry(reg_name) = &reg {
280-
for pkg in pkgs {
281-
if let Some(allowed) = pkg.publish().as_ref() {
282-
if !allowed.iter().any(|a| a == reg_name) {
283-
bail!(
290+
if let RegistryOrIndex::Registry(reg_name) = reg {
291+
for pkg in pkgs {
292+
if let Some(allowed) = pkg.publish().as_ref() {
293+
if !allowed.iter().any(|a| a == &reg_name) {
294+
bail!(
284295
"`{}` cannot be packaged.\n\
285296
The registry `{}` is not listed in the `package.publish` value in Cargo.toml.",
286297
pkg.name(),
287298
reg_name
288299
);
289-
}
290300
}
291301
}
292302
}
293303
}
294-
295-
let sid = match reg {
296-
RegistryOrIndex::Index(url) => SourceId::for_registry(&url)?,
297-
RegistryOrIndex::Registry(reg) if reg == CRATES_IO_REGISTRY => SourceId::crates_io(gctx)?,
298-
RegistryOrIndex::Registry(reg) => SourceId::alt_registry(gctx, &reg)?,
299-
};
300-
301-
// Load source replacements that are built-in to Cargo.
302-
let sid = SourceConfigMap::empty(gctx)?
303-
.load(sid, &HashSet::new())?
304-
.replaced_source_id();
305-
306-
Ok(sid)
304+
Ok(ops::registry::get_source_id(gctx, reg_or_index.as_ref())?.replacement)
307305
}
308306

309307
/// Just the part of the dependency graph that's between the packages we're packaging.
@@ -322,6 +320,12 @@ impl LocalDependencies {
322320
.map(|name| self.packages[&name].clone())
323321
.collect()
324322
}
323+
324+
pub fn has_no_dependencies(&self) -> bool {
325+
self.graph
326+
.iter()
327+
.all(|node| self.graph.edges(node).next().is_none())
328+
}
325329
}
326330

327331
/// Build just the part of the dependency graph that's between the given packages,

src/cargo/ops/registry/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ fn registry(
191191
///
192192
/// The return value is a pair of `SourceId`s: The first may be a built-in replacement of
193193
/// crates.io (such as index.crates.io), while the second is always the original source.
194-
fn get_source_id(
194+
pub(crate) fn get_source_id(
195195
gctx: &GlobalContext,
196196
reg_or_index: Option<&RegistryOrIndex>,
197197
) -> CargoResult<RegistrySourceIds> {

tests/testsuite/package.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5999,7 +5999,8 @@ fn registry_not_in_publish_list() {
59995999
.masquerade_as_nightly_cargo(&["package-workspace"])
60006000
.with_status(101)
60016001
.with_stderr_data(str![[r#"
6002-
[ERROR] registry index was not found in any configuration: `alternative`
6002+
[ERROR] `foo` cannot be packaged.
6003+
The registry `alternative` is not listed in the `package.publish` value in Cargo.toml.
60036004
60046005
"#]])
60056006
.run();

0 commit comments

Comments
 (0)