1
+ //! Cargo's config system.
2
+ //!
3
+ //! The `Config` object contains general information about the environment,
4
+ //! and provides access to Cargo's configuration files.
5
+ //!
6
+ //! ## Config value API
7
+ //!
8
+ //! The primary API for fetching user-defined config values is the
9
+ //! `Config::get` method. It uses `serde` to translate config values to a
10
+ //! target type.
11
+ //!
12
+ //! There are a variety of helper types for deserializing some common formats:
13
+ //!
14
+ //! - `value::Value`: This type provides access to the location where the
15
+ //! config value was defined.
16
+ //! - `ConfigRelativePath`: For a path that is relative to where it is
17
+ //! defined.
18
+ //! - `PathAndArgs`: Similar to `ConfigRelativePath`, but also supports a list
19
+ //! of arguments, useful for programs to execute.
20
+ //! - `StringList`: Get a value that is either a list or a whitespace split
21
+ //! string.
22
+ //!
23
+ //! ## Map key recommendations
24
+ //!
25
+ //! Handling tables that have arbitrary keys can be tricky, particularly if it
26
+ //! should support environment variables. In general, if possible, the caller
27
+ //! should pass the full key path into the `get()` method so that the config
28
+ //! deserializer can properly handle environment variables (which need to be
29
+ //! uppercased, and dashes converted to underscores).
30
+ //!
31
+ //! A good example is the `[target]` table. The code will request
32
+ //! `target.$TRIPLE` and the config system can then appropriately fetch
33
+ //! environment variables like `CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER`.
34
+ //! Conversely, it is not possible do the same thing for the `cfg()` target
35
+ //! tables (because Cargo must fetch all of them), so those do not support
36
+ //! environment variables.
37
+ //!
38
+ //! ## Internal API
39
+ //!
40
+ //! Internally config values are stored with the `ConfigValue` type after they
41
+ //! have been loaded from disk. This is similar to the `toml::Value` type, but
42
+ //! includes the definition location. The `get()` method uses serde to
43
+ //! translate from `ConfigValue` and environment variables to the caller's
44
+ //! desired type.
45
+
1
46
use std:: cell:: { RefCell , RefMut } ;
2
47
use std:: collections:: hash_map:: Entry :: { Occupied , Vacant } ;
3
48
use std:: collections:: { HashMap , HashSet } ;
@@ -321,6 +366,7 @@ impl Config {
321
366
. map ( AsRef :: as_ref)
322
367
}
323
368
369
+ /// Gets profiles defined in config files.
324
370
pub fn profiles ( & self ) -> CargoResult < & ConfigProfiles > {
325
371
self . profiles . try_borrow_with ( || {
326
372
let ocp = self . get :: < Option < ConfigProfiles > > ( "profile" ) ?;
@@ -340,16 +386,28 @@ impl Config {
340
386
} )
341
387
}
342
388
389
+ /// Which package sources have been updated, used to ensure it is only done once.
343
390
pub fn updated_sources ( & self ) -> RefMut < ' _ , HashSet < SourceId > > {
344
391
self . updated_sources
345
392
. borrow_with ( || RefCell :: new ( HashSet :: new ( ) ) )
346
393
. borrow_mut ( )
347
394
}
348
395
396
+ /// Gets all config values from disk.
397
+ ///
398
+ /// This will lazy-load the values as necessary. Callers are responsible
399
+ /// for checking environment variables. Callers outside of the `config`
400
+ /// module should avoid using this.
349
401
pub fn values ( & self ) -> CargoResult < & HashMap < String , ConfigValue > > {
350
402
self . values . try_borrow_with ( || self . load_values ( ) )
351
403
}
352
404
405
+ /// Gets a mutable copy of the on-disk config values.
406
+ ///
407
+ /// This requires the config values to already have been loaded. This
408
+ /// currently only exists for `cargo vendor` to remove the `source`
409
+ /// entries. This doesn't respect environment variables. You should avoid
410
+ /// using this if possible.
353
411
pub fn values_mut ( & mut self ) -> CargoResult < & mut HashMap < String , ConfigValue > > {
354
412
match self . values . borrow_mut ( ) {
355
413
Some ( map) => Ok ( map) ,
@@ -368,17 +426,25 @@ impl Config {
368
426
}
369
427
}
370
428
429
+ /// Reloads on-disk configuration values, starting at the given path and
430
+ /// walking up its ancestors.
371
431
pub fn reload_rooted_at < P : AsRef < Path > > ( & mut self , path : P ) -> CargoResult < ( ) > {
372
432
let values = self . load_values_from ( path. as_ref ( ) ) ?;
373
433
self . values . replace ( values) ;
374
434
self . merge_cli_args ( ) ?;
375
435
Ok ( ( ) )
376
436
}
377
437
438
+ /// The current working directory.
378
439
pub fn cwd ( & self ) -> & Path {
379
440
& self . cwd
380
441
}
381
442
443
+ /// The `target` output directory to use.
444
+ ///
445
+ /// Returns `None` if the user has not chosen an explicit directory.
446
+ ///
447
+ /// Callers should prefer `Workspace::target_dir` instead.
382
448
pub fn target_dir ( & self ) -> CargoResult < Option < Filesystem > > {
383
449
if let Some ( dir) = & self . target_dir {
384
450
Ok ( Some ( dir. clone ( ) ) )
@@ -430,7 +496,7 @@ impl Config {
430
496
Ok ( Some ( val. clone ( ) ) )
431
497
}
432
498
433
- // Helper primarily for testing.
499
+ /// Helper primarily for testing.
434
500
pub fn set_env ( & mut self , env : HashMap < String , String > ) {
435
501
self . env = env;
436
502
}
@@ -477,7 +543,11 @@ impl Config {
477
543
self . get :: < Option < Value < String > > > ( key)
478
544
}
479
545
480
- /// Get a config value that is expected to be a
546
+ /// Get a config value that is expected to be a path.
547
+ ///
548
+ /// This returns a relative path if the value does not contain any
549
+ /// directory separators. See `ConfigRelativePath::resolve_program` for
550
+ /// more details.
481
551
pub fn get_path ( & self , key : & str ) -> CargoResult < OptValue < PathBuf > > {
482
552
self . get :: < Option < Value < ConfigRelativePath > > > ( key) . map ( |v| {
483
553
v. map ( |v| Value {
@@ -532,6 +602,7 @@ impl Config {
532
602
get_value_typed ! { get_bool, bool , Boolean , "true/false" }
533
603
get_value_typed ! { get_string_priv, String , String , "a string" }
534
604
605
+ /// Generate an error when the given value is the wrong type.
535
606
fn expected < T > ( & self , ty : & str , key : & ConfigKey , val : & CV ) -> CargoResult < T > {
536
607
val. expected ( ty, & key. to_string ( ) )
537
608
. map_err ( |e| failure:: format_err!( "invalid configuration for key `{}`\n {}" , key, e) )
0 commit comments