@@ -6,7 +6,6 @@ use std::path::{Path, PathBuf};
66use std:: sync:: Arc ;
77use std:: task:: Poll ;
88
9- use super :: RegistryOrIndex ;
109use crate :: core:: compiler:: { BuildConfig , CompileMode , DefaultExecutor , Executor } ;
1110use crate :: core:: dependency:: DepKind ;
1211use crate :: core:: manifest:: Target ;
@@ -15,6 +14,7 @@ use crate::core::resolver::HasDevUnits;
1514use crate :: core:: { Feature , PackageIdSpecQuery , Shell , Verbosity , Workspace } ;
1615use crate :: core:: { Package , PackageId , PackageSet , Resolve , SourceId } ;
1716use crate :: ops:: lockfile:: LOCKFILE_NAME ;
17+ use crate :: ops:: registry:: RegistryOrIndex ;
1818use crate :: sources:: registry:: index:: { IndexPackage , RegistryDependency } ;
1919use crate :: sources:: { PathSource , SourceConfigMap , CRATES_IO_REGISTRY } ;
2020use crate :: util:: cache_lock:: CacheLockMode ;
@@ -174,95 +174,43 @@ fn create_package(
174174 return Ok ( dst) ;
175175}
176176
177- /// Determine which registry the packages are for.
178- ///
179- /// The registry only affects the built packages if there are dependencies within the
180- /// packages that we're packaging: if we're packaging foo-bin and foo-lib, and foo-bin
181- /// depends on foo-lib, then the foo-lib entry in foo-bin's lockfile will depend on the
182- /// registry that we're building packages for.
183- fn infer_registry (
184- gctx : & GlobalContext ,
185- pkgs : & [ & Package ] ,
186- reg_or_index : Option < RegistryOrIndex > ,
187- ) -> CargoResult < SourceId > {
188- let reg_or_index = match reg_or_index {
189- Some ( r) => r,
190- None => {
191- if pkgs[ 1 ..] . iter ( ) . all ( |p| p. publish ( ) == pkgs[ 0 ] . publish ( ) ) {
192- // If all packages have the same publish settings, we take that as the default.
193- match pkgs[ 0 ] . publish ( ) . as_deref ( ) {
194- Some ( [ unique_pkg_reg] ) => RegistryOrIndex :: Registry ( unique_pkg_reg. to_owned ( ) ) ,
195- None | Some ( [ ] ) => RegistryOrIndex :: Registry ( CRATES_IO_REGISTRY . to_owned ( ) ) ,
196- Some ( [ reg, ..] ) if pkgs. len ( ) == 1 => {
197- // For backwards compatibility, avoid erroring if there's only one package.
198- // The registry doesn't affect packaging in this case.
199- RegistryOrIndex :: Registry ( reg. to_owned ( ) )
200- }
201- Some ( regs) => {
202- let mut regs: Vec < _ > = regs. iter ( ) . map ( |s| format ! ( "\" {}\" " , s) ) . collect ( ) ;
203- regs. sort ( ) ;
204- regs. dedup ( ) ;
205- // unwrap: the match block ensures that there's more than one reg.
206- let ( last_reg, regs) = regs. split_last ( ) . unwrap ( ) ;
207- bail ! (
208- "--registry is required to disambiguate between {} or {} registries" ,
209- regs. join( ", " ) ,
210- last_reg
211- )
212- }
213- }
214- } else {
215- let common_regs = pkgs
216- . iter ( )
217- // `None` means "all registries", so drop them instead of including them
218- // in the intersection.
219- . filter_map ( |p| p. publish ( ) . as_deref ( ) )
220- . map ( |p| p. iter ( ) . collect :: < HashSet < _ > > ( ) )
221- . reduce ( |xs, ys| xs. intersection ( & ys) . cloned ( ) . collect ( ) )
222- . unwrap_or_default ( ) ;
223- if common_regs. is_empty ( ) {
224- bail ! ( "conflicts between `package.publish` fields in the selected packages" ) ;
225- } else {
226- bail ! (
227- "--registry is required because not all `package.publish` settings agree" ,
228- ) ;
229- }
177+ /// If this set of packages has an unambiguous publish registry, find it.
178+ pub ( crate ) fn infer_registry ( pkgs : & [ & Package ] ) -> CargoResult < Option < RegistryOrIndex > > {
179+ if pkgs[ 1 ..] . iter ( ) . all ( |p| p. publish ( ) == pkgs[ 0 ] . publish ( ) ) {
180+ // If all packages have the same publish settings, we take that as the default.
181+ match pkgs[ 0 ] . publish ( ) . as_deref ( ) {
182+ Some ( [ unique_pkg_reg] ) => {
183+ Ok ( Some ( RegistryOrIndex :: Registry ( unique_pkg_reg. to_owned ( ) ) ) )
230184 }
231- }
232- } ;
233-
234- // Validate the registry against the packages' allow-lists. For backwards compatibility, we
235- // skip this if only a single package is being published (because in that case the registry
236- // doesn't affect the packaging step).
237- if pkgs. len ( ) > 1 {
238- if let RegistryOrIndex :: Registry ( reg_name) = & reg_or_index {
239- for pkg in pkgs {
240- if let Some ( allowed) = pkg. publish ( ) . as_ref ( ) {
241- if !allowed. iter ( ) . any ( |a| a == reg_name) {
242- bail ! (
243- "`{}` cannot be packaged.\n \
244- The registry `{}` is not listed in the `package.publish` value in Cargo.toml.",
245- pkg. name( ) ,
246- reg_name
247- ) ;
248- }
249- }
185+ None | Some ( [ ] ) => Ok ( None ) ,
186+ Some ( regs) => {
187+ let mut regs: Vec < _ > = regs. iter ( ) . map ( |s| format ! ( "\" {}\" " , s) ) . collect ( ) ;
188+ regs. sort ( ) ;
189+ regs. dedup ( ) ;
190+ // unwrap: the match block ensures that there's more than one reg.
191+ let ( last_reg, regs) = regs. split_last ( ) . unwrap ( ) ;
192+ bail ! (
193+ "--registry is required to disambiguate between {} or {} registries" ,
194+ regs. join( ", " ) ,
195+ last_reg
196+ )
250197 }
251198 }
199+ } else {
200+ let common_regs = pkgs
201+ . iter ( )
202+ // `None` means "all registries", so drop them instead of including them
203+ // in the intersection.
204+ . filter_map ( |p| p. publish ( ) . as_deref ( ) )
205+ . map ( |p| p. iter ( ) . collect :: < HashSet < _ > > ( ) )
206+ . reduce ( |xs, ys| xs. intersection ( & ys) . cloned ( ) . collect ( ) )
207+ . unwrap_or_default ( ) ;
208+ if common_regs. is_empty ( ) {
209+ bail ! ( "conflicts between `package.publish` fields in the selected packages" ) ;
210+ } else {
211+ bail ! ( "--registry is required because not all `package.publish` settings agree" , ) ;
212+ }
252213 }
253-
254- let sid = match reg_or_index {
255- RegistryOrIndex :: Index ( url) => SourceId :: for_registry ( & url) ?,
256- RegistryOrIndex :: Registry ( reg) if reg == CRATES_IO_REGISTRY => SourceId :: crates_io ( gctx) ?,
257- RegistryOrIndex :: Registry ( reg) => SourceId :: alt_registry ( gctx, & reg) ?,
258- } ;
259-
260- // Load source replacements that are built-in to Cargo.
261- let sid = SourceConfigMap :: empty ( gctx) ?
262- . load ( sid, & HashSet :: new ( ) ) ?
263- . replaced_source_id ( ) ;
264-
265- Ok ( sid)
266214}
267215
268216/// Packages an entire workspace.
@@ -294,7 +242,7 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Vec<Fi
294242 }
295243
296244 let just_pkgs: Vec < _ > = pkgs. iter ( ) . map ( |p| p. 0 ) . collect ( ) ;
297- let publish_reg = infer_registry ( ws. gctx ( ) , & just_pkgs, opts. reg_or_index . clone ( ) ) ?;
245+ let publish_reg = get_registry ( ws. gctx ( ) , & just_pkgs, opts. reg_or_index . clone ( ) ) ?;
298246 debug ! ( "packaging for registry {publish_reg}" ) ;
299247
300248 let mut local_reg = if ws. gctx ( ) . cli_unstable ( ) . package_workspace {
@@ -343,6 +291,60 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Vec<Fi
343291 Ok ( outputs. into_iter ( ) . map ( |x| x. 2 ) . collect ( ) )
344292}
345293
294+ /// Determine which registry the packages are for.
295+ ///
296+ /// The registry only affects the built packages if there are dependencies within the
297+ /// packages that we're packaging: if we're packaging foo-bin and foo-lib, and foo-bin
298+ /// depends on foo-lib, then the foo-lib entry in foo-bin's lockfile will depend on the
299+ /// registry that we're building packages for.
300+ pub ( crate ) fn get_registry (
301+ gctx : & GlobalContext ,
302+ pkgs : & [ & Package ] ,
303+ reg_or_index : Option < RegistryOrIndex > ,
304+ ) -> CargoResult < SourceId > {
305+ let reg_or_index = match reg_or_index {
306+ Some ( r) => Some ( r) ,
307+ None => infer_registry ( pkgs) ?,
308+ } ;
309+
310+ let reg = reg_or_index
311+ . clone ( )
312+ . unwrap_or_else ( || RegistryOrIndex :: Registry ( CRATES_IO_REGISTRY . to_owned ( ) ) ) ;
313+
314+ // Validate the registry against the packages' allow-lists. For backwards compatibility, we
315+ // skip this if only a single package is being published (because in that case the registry
316+ // doesn't affect the packaging step).
317+ if pkgs. len ( ) > 1 {
318+ if let RegistryOrIndex :: Registry ( reg_name) = & reg {
319+ for pkg in pkgs {
320+ if let Some ( allowed) = pkg. publish ( ) . as_ref ( ) {
321+ if !allowed. iter ( ) . any ( |a| a == reg_name) {
322+ bail ! (
323+ "`{}` cannot be packaged.\n \
324+ The registry `{}` is not listed in the `package.publish` value in Cargo.toml.",
325+ pkg. name( ) ,
326+ reg_name
327+ ) ;
328+ }
329+ }
330+ }
331+ }
332+ }
333+
334+ let sid = match reg {
335+ RegistryOrIndex :: Index ( url) => SourceId :: for_registry ( & url) ?,
336+ RegistryOrIndex :: Registry ( reg) if reg == CRATES_IO_REGISTRY => SourceId :: crates_io ( gctx) ?,
337+ RegistryOrIndex :: Registry ( reg) => SourceId :: alt_registry ( gctx, & reg) ?,
338+ } ;
339+
340+ // Load source replacements that are built-in to Cargo.
341+ let sid = SourceConfigMap :: empty ( gctx) ?
342+ . load ( sid, & HashSet :: new ( ) ) ?
343+ . replaced_source_id ( ) ;
344+
345+ Ok ( sid)
346+ }
347+
346348/// Just the part of the dependency graph that's between the packages we're packaging.
347349/// (Is the package name a good key? Does it uniquely identify packages?)
348350#[ derive( Clone , Debug , Default ) ]
0 commit comments