@@ -428,11 +428,12 @@ impl Config {
428428 pub fn load_values ( & self ) -> CargoResult < HashMap < String , ConfigValue > > {
429429 let mut cfg = CV :: Table ( HashMap :: new ( ) , PathBuf :: from ( "." ) ) ;
430430
431- walk_tree ( & self . cwd , |mut file , path| {
431+ walk_tree ( & self . cwd , |path| {
432432 let mut contents = String :: new ( ) ;
433+ let mut file = File :: open ( & path) ?;
433434 file. read_to_string ( & mut contents) . chain_err ( || {
434435 format ! ( "failed to read configuration file `{}`" ,
435- path. display( ) )
436+ path. display( ) )
436437 } ) ?;
437438 let toml = cargo_toml:: parse ( & contents,
438439 & path,
@@ -450,13 +451,52 @@ impl Config {
450451 Ok ( ( ) )
451452 } ) . chain_err ( || "Couldn't load Cargo configuration" ) ?;
452453
453-
454+ self . load_credentials ( & mut cfg ) ? ;
454455 match cfg {
455456 CV :: Table ( map, _) => Ok ( map) ,
456457 _ => unreachable ! ( ) ,
457458 }
458459 }
459460
461+ fn load_credentials ( & self , cfg : & mut ConfigValue ) -> CargoResult < ( ) > {
462+ let home_path = self . home_path . clone ( ) . into_path_unlocked ( ) ;
463+ let credentials = home_path. join ( "credentials" ) ;
464+ if !fs:: metadata ( & credentials) . is_ok ( ) {
465+ return Ok ( ( ) ) ;
466+ }
467+
468+ let mut contents = String :: new ( ) ;
469+ let mut file = File :: open ( & credentials) ?;
470+ file. read_to_string ( & mut contents) . chain_err ( || {
471+ format ! ( "failed to read configuration file `{}`" , credentials. display( ) )
472+ } ) ?;
473+
474+ let toml = cargo_toml:: parse ( & contents,
475+ & credentials,
476+ self ) . chain_err ( || {
477+ format ! ( "could not parse TOML configuration in `{}`" , credentials. display( ) )
478+ } ) ?;
479+
480+ let value = CV :: from_toml ( & credentials, toml) . chain_err ( || {
481+ format ! ( "failed to load TOML configuration from `{}`" , credentials. display( ) )
482+ } ) ?;
483+
484+ let mut cfg = match * cfg {
485+ CV :: Table ( ref mut map, _) => map,
486+ _ => unreachable ! ( ) ,
487+ } ;
488+
489+ let mut registry = cfg. entry ( "registry" . into ( ) )
490+ . or_insert ( CV :: Table ( HashMap :: new ( ) ,
491+ PathBuf :: from ( "." ) ) ) ;
492+ registry. merge ( value) . chain_err ( || {
493+ format ! ( "failed to merge configuration at `{}`" ,
494+ credentials. display( ) )
495+ } ) ?;
496+
497+ Ok ( ( ) )
498+ }
499+
460500 /// Look for a path for `tool` in an environment variable or config path, but return `None`
461501 /// if it's not present.
462502 fn maybe_get_tool ( & self , tool : & str ) -> CargoResult < Option < PathBuf > > {
@@ -575,6 +615,21 @@ impl ConfigValue {
575615 }
576616 }
577617
618+ fn into_toml ( self ) -> toml:: Value {
619+ match self {
620+ CV :: Boolean ( s, _) => toml:: Value :: Boolean ( s) ,
621+ CV :: String ( s, _) => toml:: Value :: String ( s) ,
622+ CV :: Integer ( i, _) => toml:: Value :: Integer ( i) ,
623+ CV :: List ( l, _) => toml:: Value :: Array ( l
624+ . into_iter ( )
625+ . map ( |( s, _) | toml:: Value :: String ( s) )
626+ . collect ( ) ) ,
627+ CV :: Table ( l, _) => toml:: Value :: Table ( l. into_iter ( )
628+ . map ( |( k, v) | ( k, v. into_toml ( ) ) )
629+ . collect ( ) ) ,
630+ }
631+ }
632+
578633 fn merge ( & mut self , from : ConfigValue ) -> CargoResult < ( ) > {
579634 match ( self , from) {
580635 ( & mut CV :: String ( ..) , CV :: String ( ..) ) |
@@ -676,21 +731,6 @@ impl ConfigValue {
676731 wanted, self . desc( ) , key,
677732 self . definition_path( ) . display( ) ) . into ( ) )
678733 }
679-
680- fn into_toml ( self ) -> toml:: Value {
681- match self {
682- CV :: Boolean ( s, _) => toml:: Value :: Boolean ( s) ,
683- CV :: String ( s, _) => toml:: Value :: String ( s) ,
684- CV :: Integer ( i, _) => toml:: Value :: Integer ( i) ,
685- CV :: List ( l, _) => toml:: Value :: Array ( l
686- . into_iter ( )
687- . map ( |( s, _) | toml:: Value :: String ( s) )
688- . collect ( ) ) ,
689- CV :: Table ( l, _) => toml:: Value :: Table ( l. into_iter ( )
690- . map ( |( k, v) | ( k, v. into_toml ( ) ) )
691- . collect ( ) ) ,
692- }
693- }
694734}
695735
696736impl Definition {
@@ -762,17 +802,14 @@ pub fn homedir(cwd: &Path) -> Option<PathBuf> {
762802}
763803
764804fn walk_tree < F > ( pwd : & Path , mut walk : F ) -> CargoResult < ( ) >
765- where F : FnMut ( File , & Path ) -> CargoResult < ( ) >
805+ where F : FnMut ( & Path ) -> CargoResult < ( ) >
766806{
767807 let mut stash: HashSet < PathBuf > = HashSet :: new ( ) ;
768808
769809 for current in paths:: ancestors ( pwd) {
770810 let possible = current. join ( ".cargo" ) . join ( "config" ) ;
771811 if fs:: metadata ( & possible) . is_ok ( ) {
772- let file = File :: open ( & possible) ?;
773-
774- walk ( file, & possible) ?;
775-
812+ walk ( & possible) ?;
776813 stash. insert ( possible) ;
777814 }
778815 }
@@ -786,40 +823,52 @@ fn walk_tree<F>(pwd: &Path, mut walk: F) -> CargoResult<()>
786823 } ) ?;
787824 let config = home. join ( "config" ) ;
788825 if !stash. contains ( & config) && fs:: metadata ( & config) . is_ok ( ) {
789- let file = File :: open ( & config) ?;
790- walk ( file, & config) ?;
826+ walk ( & config) ?;
791827 }
792828
793829 Ok ( ( ) )
794830}
795831
796- pub fn set_config ( cfg : & Config ,
797- loc : Location ,
798- key : & str ,
799- value : ConfigValue ) -> CargoResult < ( ) > {
800- // TODO: There are a number of drawbacks here
801- //
802- // 1. Project is unimplemented
803- // 2. This blows away all comments in a file
804- // 3. This blows away the previous ordering of a file.
805- let mut file = match loc {
806- Location :: Global => {
807- cfg. home_path . create_dir ( ) ?;
808- cfg. home_path . open_rw ( Path :: new ( "config" ) , cfg,
809- "the global config file" ) ?
810- }
811- Location :: Project => unimplemented ! ( ) ,
832+ pub fn save_credentials ( cfg : & Config ,
833+ token : String ) -> CargoResult < ( ) > {
834+ let mut file = {
835+ cfg. home_path . create_dir ( ) ?;
836+ cfg. home_path . open_rw ( Path :: new ( "credentials" ) , cfg,
837+ "credentials' config file" ) ?
812838 } ;
839+
813840 let mut contents = String :: new ( ) ;
814- let _ = file. read_to_string ( & mut contents) ;
841+ file. read_to_string ( & mut contents) . chain_err ( || {
842+ format ! ( "failed to read configuration file `{}`" ,
843+ file. path( ) . display( ) )
844+ } ) ?;
815845 let mut toml = cargo_toml:: parse ( & contents, file. path ( ) , cfg) ?;
816846 toml. as_table_mut ( )
817847 . unwrap ( )
818- . insert ( key. to_string ( ) , value. into_toml ( ) ) ;
848+ . insert ( "token" . to_string ( ) ,
849+ ConfigValue :: String ( token, file. path ( ) . to_path_buf ( ) ) . into_toml ( ) ) ;
819850
820851 let contents = toml. to_string ( ) ;
821852 file. seek ( SeekFrom :: Start ( 0 ) ) ?;
822853 file. write_all ( contents. as_bytes ( ) ) ?;
823854 file. file ( ) . set_len ( contents. len ( ) as u64 ) ?;
824- Ok ( ( ) )
855+ set_permissions ( file. file ( ) , 0o600 ) ?;
856+
857+ return Ok ( ( ) ) ;
858+
859+ #[ cfg( unix) ]
860+ fn set_permissions ( file : & File , mode : u32 ) -> CargoResult < ( ) > {
861+ use std:: os:: unix:: fs:: PermissionsExt ;
862+
863+ let mut perms = file. metadata ( ) ?. permissions ( ) ;
864+ perms. set_mode ( mode) ;
865+ file. set_permissions ( perms) ?;
866+ Ok ( ( ) )
867+ }
868+
869+ #[ cfg( not( unix) ) ]
870+ #[ allow( unused) ]
871+ fn set_permissions ( file : & File , mode : u32 ) -> CargoResult < ( ) > {
872+ Ok ( ( ) )
873+ }
825874}
0 commit comments