@@ -7,7 +7,7 @@ use std::time::Duration;
77use std:: { cmp, env} ;
88
99use anyhow:: { bail, format_err} ;
10- use crates_io:: { NewCrate , NewCrateDependency , Registry } ;
10+ use crates_io:: { self , NewCrate , NewCrateDependency , Registry } ;
1111use curl:: easy:: { Easy , InfoType , SslOpt , SslVersion } ;
1212use log:: { log, Level } ;
1313use percent_encoding:: { percent_encode, NON_ALPHANUMERIC } ;
@@ -25,8 +25,13 @@ use crate::util::IntoUrl;
2525use crate :: util:: { paths, validate_package_name} ;
2626use crate :: version;
2727
28+ /// Registry settings loaded from config files.
29+ ///
30+ /// This is loaded based on the `--registry` flag and the config settings.
2831pub struct RegistryConfig {
32+ /// The index URL. If `None`, use crates.io.
2933 pub index : Option < String > ,
34+ /// The authentication token.
3035 pub token : Option < String > ,
3136}
3237
@@ -316,10 +321,15 @@ fn transmit(
316321 }
317322}
318323
324+ /// Returns the index and token from the config file for the given registry.
325+ ///
326+ /// `registry` is typically the registry specified on the command-line. If
327+ /// `None`, `index` is set to `None` to indicate it should use crates.io.
319328pub fn registry_configuration (
320329 config : & Config ,
321330 registry : Option < String > ,
322331) -> CargoResult < RegistryConfig > {
332+ // `registry.default` is handled in command-line parsing.
323333 let ( index, token) = match registry {
324334 Some ( registry) => {
325335 validate_package_name ( & registry, "registry name" , "" ) ?;
@@ -331,19 +341,26 @@ pub fn registry_configuration(
331341 )
332342 }
333343 None => {
334- // Checking for default index and token
335- (
336- config
337- . get_default_registry_index ( ) ?
338- . map ( |url| url. to_string ( ) ) ,
339- config. get_string ( "registry.token" ) ?. map ( |p| p. val ) ,
340- )
344+ // Use crates.io default.
345+ config. check_registry_index_not_set ( ) ?;
346+ ( None , config. get_string ( "registry.token" ) ?. map ( |p| p. val ) )
341347 }
342348 } ;
343349
344350 Ok ( RegistryConfig { index, token } )
345351}
346352
353+ /// Returns the `Registry` and `Source` based on command-line and config settings.
354+ ///
355+ /// * `token`: The token from the command-line. If not set, uses the token
356+ /// from the config.
357+ /// * `index`: The index URL from the command-line. This is ignored if
358+ /// `registry` is set.
359+ /// * `registry`: The registry name from the command-line. If neither
360+ /// `registry`, or `index` are set, then uses `crates-io`, honoring
361+ /// `[source]` replacement if defined.
362+ /// * `force_update`: If `true`, forces the index to be updated.
363+ /// * `validate_token`: If `true`, the token must be set.
347364fn registry (
348365 config : & Config ,
349366 token : Option < String > ,
@@ -352,13 +369,17 @@ fn registry(
352369 force_update : bool ,
353370 validate_token : bool ,
354371) -> CargoResult < ( Registry , SourceId ) > {
372+ if index. is_some ( ) && registry. is_some ( ) {
373+ // Otherwise we would silently ignore one or the other.
374+ bail ! ( "both `--index` and `--registry` should not be set at the same time" ) ;
375+ }
355376 // Parse all configuration options
356377 let RegistryConfig {
357378 token : token_config,
358379 index : index_config,
359380 } = registry_configuration ( config, registry. clone ( ) ) ?;
360- let token = token . or ( token_config ) ;
361- let sid = get_source_id ( config, index_config . or ( index ) , registry) ?;
381+ let opt_index = index_config . as_ref ( ) . or ( index . as_ref ( ) ) ;
382+ let sid = get_source_id ( config, opt_index , registry. as_ref ( ) ) ?;
362383 if !sid. is_remote_registry ( ) {
363384 bail ! (
364385 "{} does not support API commands.\n \
@@ -386,10 +407,51 @@ fn registry(
386407 cfg. and_then ( |cfg| cfg. api )
387408 . ok_or_else ( || format_err ! ( "{} does not support API commands" , sid) ) ?
388409 } ;
389- let handle = http_handle ( config) ?;
390- if validate_token && token. is_none ( ) {
391- bail ! ( "no upload token found, please run `cargo login`" ) ;
410+ let token = match ( & index, & token, & token_config) {
411+ // No token.
412+ ( None , None , None ) => {
413+ if validate_token {
414+ bail ! ( "no upload token found, please run `cargo login` or pass `--token`" ) ;
415+ }
416+ None
417+ }
418+ // Token on command-line.
419+ ( _, Some ( _) , _) => token,
420+ // Token in config, no --index, loading from config is OK for crates.io.
421+ ( None , None , Some ( _) ) => {
422+ // Check `is_default_registry` so that the crates.io index can
423+ // change config.json's "api" value, and this won't affect most
424+ // people. It will affect those using source replacement, but
425+ // hopefully that's a relatively small set of users.
426+ if registry. is_none ( )
427+ && !sid. is_default_registry ( )
428+ && !crates_io:: is_url_crates_io ( & api_host)
429+ {
430+ if validate_token {
431+ config. shell ( ) . warn (
432+ "using `registry.token` config value with source \
433+ replacement is deprecated\n \
434+ This may become a hard error in the future; \
435+ see <https://github.com/rust-lang/cargo/issues/xxx>.\n \
436+ Use the --token command-line flag to remove this warning.",
437+ ) ?;
438+ token_config
439+ } else {
440+ None
441+ }
442+ } else {
443+ token_config
444+ }
445+ }
446+ // --index, no --token
447+ ( Some ( _) , None , _) => {
448+ if validate_token {
449+ bail ! ( "command-line argument --index requires --token to be specified" )
450+ }
451+ None
452+ }
392453 } ;
454+ let handle = http_handle ( config) ?;
393455 Ok ( ( Registry :: new_handle ( api_host, token, handle) , sid) )
394456}
395457
@@ -739,10 +801,14 @@ pub fn yank(
739801 Ok ( ( ) )
740802}
741803
804+ /// Gets the SourceId for an index or registry setting.
805+ ///
806+ /// The `index` and `reg` values are from the command-line or config settings.
807+ /// If both are None, returns the source for crates.io.
742808fn get_source_id (
743809 config : & Config ,
744- index : Option < String > ,
745- reg : Option < String > ,
810+ index : Option < & String > ,
811+ reg : Option < & String > ,
746812) -> CargoResult < SourceId > {
747813 match ( reg, index) {
748814 ( Some ( r) , _) => SourceId :: alt_registry ( config, & r) ,
0 commit comments