@@ -5,6 +5,7 @@ use std::collections::HashSet;
5
5
use std:: env;
6
6
use std:: fmt;
7
7
use std:: fs:: { self , File } ;
8
+ use std:: io:: SeekFrom ;
8
9
use std:: io:: prelude:: * ;
9
10
use std:: mem;
10
11
use std:: path:: { Path , PathBuf } ;
@@ -429,28 +430,50 @@ impl Config {
429
430
Ok ( ( ) )
430
431
} ) . chain_err ( || "Couldn't load Cargo configuration" ) ?;
431
432
432
- let mut map = match cfg {
433
- CV :: Table ( map, _) => map,
433
+ self . load_credentials ( & mut cfg) ?;
434
+ match cfg {
435
+ CV :: Table ( map, _) => Ok ( map) ,
434
436
_ => unreachable ! ( ) ,
435
- } ;
437
+ }
438
+ }
436
439
440
+ fn load_credentials ( & self , cfg : & mut ConfigValue ) -> CargoResult < ( ) > {
437
441
let home_path = self . home_path . clone ( ) . into_path_unlocked ( ) ;
438
- let token = load_credentials ( & home_path) ?;
439
- if let Some ( t) = token {
440
- if !t. is_empty ( ) {
441
- let mut registry = map. entry ( "registry" . into ( ) )
442
- . or_insert ( CV :: Table ( HashMap :: new ( ) , PathBuf :: from ( "." ) ) ) ;
443
- match * registry {
444
- CV :: Table ( ref mut m, _) => {
445
- m. insert ( "token" . into ( ) ,
446
- CV :: String ( t, home_path. join ( "credentials" ) ) ) ;
447
- }
448
- _ => unreachable ! ( ) ,
449
- }
450
- }
442
+ let credentials = home_path. join ( "credentials" ) ;
443
+ if !fs:: metadata ( & credentials) . is_ok ( ) {
444
+ return Ok ( ( ) ) ;
451
445
}
452
446
453
- Ok ( map)
447
+ let mut contents = String :: new ( ) ;
448
+ let mut file = File :: open ( & credentials) ?;
449
+ file. read_to_string ( & mut contents) . chain_err ( || {
450
+ format ! ( "failed to read configuration file `{}`" , credentials. display( ) )
451
+ } ) ?;
452
+
453
+ let toml = cargo_toml:: parse ( & contents,
454
+ & credentials,
455
+ self ) . chain_err ( || {
456
+ format ! ( "could not parse TOML configuration in `{}`" , credentials. display( ) )
457
+ } ) ?;
458
+
459
+ let value = CV :: from_toml ( & credentials, toml) . chain_err ( || {
460
+ format ! ( "failed to load TOML configuration from `{}`" , credentials. display( ) )
461
+ } ) ?;
462
+
463
+ let mut cfg = match * cfg {
464
+ CV :: Table ( ref mut map, _) => map,
465
+ _ => unreachable ! ( ) ,
466
+ } ;
467
+
468
+ let mut registry = cfg. entry ( "registry" . into ( ) )
469
+ . or_insert ( CV :: Table ( HashMap :: new ( ) ,
470
+ PathBuf :: from ( "." ) ) ) ;
471
+ registry. merge ( value) . chain_err ( || {
472
+ format ! ( "failed to merge configuration at `{}`" ,
473
+ credentials. display( ) )
474
+ } ) ?;
475
+
476
+ Ok ( ( ) )
454
477
}
455
478
456
479
/// Look for a path for `tool` in an environment variable or config path, but return `None`
@@ -567,6 +590,21 @@ impl ConfigValue {
567
590
}
568
591
}
569
592
593
+ fn into_toml ( self ) -> toml:: Value {
594
+ match self {
595
+ CV :: Boolean ( s, _) => toml:: Value :: Boolean ( s) ,
596
+ CV :: String ( s, _) => toml:: Value :: String ( s) ,
597
+ CV :: Integer ( i, _) => toml:: Value :: Integer ( i) ,
598
+ CV :: List ( l, _) => toml:: Value :: Array ( l
599
+ . into_iter ( )
600
+ . map ( |( s, _) | toml:: Value :: String ( s) )
601
+ . collect ( ) ) ,
602
+ CV :: Table ( l, _) => toml:: Value :: Table ( l. into_iter ( )
603
+ . map ( |( k, v) | ( k, v. into_toml ( ) ) )
604
+ . collect ( ) ) ,
605
+ }
606
+ }
607
+
570
608
fn merge ( & mut self , from : ConfigValue ) -> CargoResult < ( ) > {
571
609
match ( self , from) {
572
610
( & mut CV :: String ( ..) , CV :: String ( ..) ) |
@@ -774,8 +812,21 @@ pub fn save_credentials(cfg: &Config,
774
812
"credentials' config file" ) ?
775
813
} ;
776
814
777
- file. write_all ( token. as_bytes ( ) ) ?;
778
- file. file ( ) . set_len ( token. len ( ) as u64 ) ?;
815
+ let mut contents = String :: new ( ) ;
816
+ file. read_to_string ( & mut contents) . chain_err ( || {
817
+ format ! ( "failed to read configuration file `{}`" ,
818
+ file. path( ) . display( ) )
819
+ } ) ?;
820
+ let mut toml = cargo_toml:: parse ( & contents, file. path ( ) , cfg) ?;
821
+ toml. as_table_mut ( )
822
+ . unwrap ( )
823
+ . insert ( "token" . to_string ( ) ,
824
+ ConfigValue :: String ( token, file. path ( ) . to_path_buf ( ) ) . into_toml ( ) ) ;
825
+
826
+ let contents = toml. to_string ( ) ;
827
+ file. seek ( SeekFrom :: Start ( 0 ) ) ?;
828
+ file. write_all ( contents. as_bytes ( ) ) ?;
829
+ file. file ( ) . set_len ( contents. len ( ) as u64 ) ?;
779
830
set_permissions ( file. file ( ) , 0o600 ) ?;
780
831
781
832
return Ok ( ( ) ) ;
@@ -796,19 +847,3 @@ pub fn save_credentials(cfg: &Config,
796
847
Ok ( ( ) )
797
848
}
798
849
}
799
-
800
- fn load_credentials ( home : & PathBuf ) -> CargoResult < Option < String > > {
801
- let credentials = home. join ( "credentials" ) ;
802
- if !fs:: metadata ( & credentials) . is_ok ( ) {
803
- return Ok ( None ) ;
804
- }
805
-
806
- let mut token = String :: new ( ) ;
807
- let mut file = File :: open ( & credentials) ?;
808
- file. read_to_string ( & mut token) . chain_err ( || {
809
- format ! ( "failed to read configuration file `{}`" ,
810
- credentials. display( ) )
811
- } ) ?;
812
-
813
- Ok ( Some ( token. trim ( ) . into ( ) ) )
814
- }
0 commit comments