1
- use std:: collections:: { BTreeSet , HashMap , HashSet } ;
1
+ use std:: collections:: { BTreeSet , HashMap } ;
2
2
use std:: fs:: { self , File } ;
3
3
use std:: io:: prelude:: * ;
4
4
use std:: io:: SeekFrom ;
@@ -15,7 +15,7 @@ use crate::core::{Feature, PackageIdSpecQuery, Shell, Verbosity, Workspace};
15
15
use crate :: core:: { Package , PackageId , PackageSet , Resolve , SourceId } ;
16
16
use crate :: ops:: registry:: { infer_registry, RegistryOrIndex } ;
17
17
use crate :: sources:: registry:: index:: { IndexPackage , RegistryDependency } ;
18
- use crate :: sources:: { PathSource , SourceConfigMap , CRATES_IO_REGISTRY } ;
18
+ use crate :: sources:: { PathSource , CRATES_IO_REGISTRY } ;
19
19
use crate :: util:: cache_lock:: CacheLockMode ;
20
20
use crate :: util:: context:: JobsConfig ;
21
21
use crate :: util:: errors:: CargoResult ;
@@ -196,19 +196,34 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Vec<Fi
196
196
// below, and will be validated during the verification step.
197
197
}
198
198
199
+ let deps = local_deps ( pkgs. iter ( ) . map ( |( p, f) | ( ( * p) . clone ( ) , f. clone ( ) ) ) ) ;
199
200
let just_pkgs: Vec < _ > = pkgs. iter ( ) . map ( |p| p. 0 ) . collect ( ) ;
200
- let publish_reg = get_registry ( ws. gctx ( ) , & just_pkgs, opts. reg_or_index . clone ( ) ) ?;
201
- debug ! ( "packaging for registry {publish_reg}" ) ;
201
+
202
+ let sid = match get_registry ( ws. gctx ( ) , & just_pkgs, opts. reg_or_index . clone ( ) ) {
203
+ Ok ( sid) => {
204
+ debug ! ( "packaging for registry {}" , sid) ;
205
+ Some ( sid)
206
+ }
207
+ Err ( e) => {
208
+ if deps. has_no_dependencies ( ) && opts. reg_or_index . is_none ( ) {
209
+ // The publish registry doesn't matter unless there are local dependencies,
210
+ // so ignore any errors if we don't need it. If they explicitly passed a registry
211
+ // on the CLI, we check it no matter what.
212
+ None
213
+ } else {
214
+ return Err ( e) ;
215
+ }
216
+ }
217
+ } ;
202
218
203
219
let mut local_reg = if ws. gctx ( ) . cli_unstable ( ) . package_workspace {
204
220
let reg_dir = ws. target_dir ( ) . join ( "package" ) . join ( "tmp-registry" ) ;
205
- Some ( TmpRegistry :: new ( ws. gctx ( ) , reg_dir, publish_reg) ?)
221
+ sid. map ( |sid| TmpRegistry :: new ( ws. gctx ( ) , reg_dir, sid) )
222
+ . transpose ( ) ?
206
223
} else {
207
224
None
208
225
} ;
209
226
210
- let deps = local_deps ( pkgs. iter ( ) . map ( |( p, f) | ( ( * p) . clone ( ) , f. clone ( ) ) ) ) ;
211
-
212
227
// Packages need to be created in dependency order, because dependencies must
213
228
// be added to our local overlay before we can create lockfiles that depend on them.
214
229
let sorted_pkgs = deps. sort ( ) ;
@@ -252,52 +267,35 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Vec<Fi
252
267
/// packages that we're packaging: if we're packaging foo-bin and foo-lib, and foo-bin
253
268
/// depends on foo-lib, then the foo-lib entry in foo-bin's lockfile will depend on the
254
269
/// registry that we're building packages for.
255
- pub ( crate ) fn get_registry (
270
+ fn get_registry (
256
271
gctx : & GlobalContext ,
257
272
pkgs : & [ & Package ] ,
258
273
reg_or_index : Option < RegistryOrIndex > ,
259
274
) -> CargoResult < SourceId > {
260
- let reg_or_index = match reg_or_index {
275
+ let reg_or_index = match reg_or_index. clone ( ) {
261
276
Some ( r) => Some ( r) ,
262
277
None => infer_registry ( pkgs) ?,
263
278
} ;
264
279
280
+ // Validate the registry against the packages' allow-lists.
265
281
let reg = reg_or_index
266
282
. clone ( )
267
283
. unwrap_or_else ( || RegistryOrIndex :: Registry ( CRATES_IO_REGISTRY . to_owned ( ) ) ) ;
268
-
269
- // Validate the registry against the packages' allow-lists. For backwards compatibility, we
270
- // skip this if only a single package is being published (because in that case the registry
271
- // doesn't affect the packaging step).
272
- if pkgs. len ( ) > 1 {
273
- if let RegistryOrIndex :: Registry ( reg_name) = & reg {
274
- for pkg in pkgs {
275
- if let Some ( allowed) = pkg. publish ( ) . as_ref ( ) {
276
- if !allowed. iter ( ) . any ( |a| a == reg_name) {
277
- bail ! (
284
+ if let RegistryOrIndex :: Registry ( reg_name) = reg {
285
+ for pkg in pkgs {
286
+ if let Some ( allowed) = pkg. publish ( ) . as_ref ( ) {
287
+ if !allowed. iter ( ) . any ( |a| a == & reg_name) {
288
+ bail ! (
278
289
"`{}` cannot be packaged.\n \
279
290
The registry `{}` is not listed in the `package.publish` value in Cargo.toml.",
280
291
pkg. name( ) ,
281
292
reg_name
282
293
) ;
283
- }
284
294
}
285
295
}
286
296
}
287
297
}
288
-
289
- let sid = match reg {
290
- RegistryOrIndex :: Index ( url) => SourceId :: for_registry ( & url) ?,
291
- RegistryOrIndex :: Registry ( reg) if reg == CRATES_IO_REGISTRY => SourceId :: crates_io ( gctx) ?,
292
- RegistryOrIndex :: Registry ( reg) => SourceId :: alt_registry ( gctx, & reg) ?,
293
- } ;
294
-
295
- // Load source replacements that are built-in to Cargo.
296
- let sid = SourceConfigMap :: empty ( gctx) ?
297
- . load ( sid, & HashSet :: new ( ) ) ?
298
- . replaced_source_id ( ) ;
299
-
300
- Ok ( sid)
298
+ Ok ( ops:: registry:: get_source_id ( gctx, reg_or_index. as_ref ( ) ) ?. replacement )
301
299
}
302
300
303
301
/// Just the part of the dependency graph that's between the packages we're packaging.
@@ -316,6 +314,12 @@ impl LocalDependencies {
316
314
. map ( |name| self . packages [ & name] . clone ( ) )
317
315
. collect ( )
318
316
}
317
+
318
+ pub fn has_no_dependencies ( & self ) -> bool {
319
+ self . graph
320
+ . iter ( )
321
+ . all ( |node| self . graph . edges ( node) . next ( ) . is_none ( ) )
322
+ }
319
323
}
320
324
321
325
/// Build just the part of the dependency graph that's between the given packages,
0 commit comments