@@ -809,9 +809,12 @@ pub struct EnvConfig {
809809 basedirs : Option < Vec < String > > ,
810810}
811811
812+ fn string_from_env_var ( env_var_name : & str ) -> Option < String > {
813+ env:: var ( env_var_name) . ok ( ) . filter ( |s| !s. is_empty ( ) )
814+ }
815+
812816fn key_prefix_from_env_var ( env_var_name : & str ) -> String {
813- env:: var ( env_var_name)
814- . ok ( )
817+ string_from_env_var ( env_var_name)
815818 . as_ref ( )
816819 . map ( |s| s. trim_end_matches ( '/' ) )
817820 . filter ( |s| !s. is_empty ( ) )
@@ -823,7 +826,7 @@ fn number_from_env_var<A: std::str::FromStr>(env_var_name: &str) -> Option<Resul
823826where
824827 <A as FromStr >:: Err : std:: fmt:: Debug ,
825828{
826- let value = env :: var ( env_var_name) . ok ( ) ?;
829+ let value = string_from_env_var ( env_var_name) ?;
827830
828831 value
829832 . parse :: < A > ( )
@@ -832,8 +835,7 @@ where
832835}
833836
834837fn bool_from_env_var ( env_var_name : & str ) -> Result < Option < bool > > {
835- env:: var ( env_var_name)
836- . ok ( )
838+ string_from_env_var ( env_var_name)
837839 . map ( |value| match value. to_lowercase ( ) . as_str ( ) {
838840 "true" | "on" | "1" => Ok ( true ) ,
839841 "false" | "off" | "0" => Ok ( false ) ,
@@ -847,12 +849,12 @@ fn bool_from_env_var(env_var_name: &str) -> Result<Option<bool>> {
847849
848850fn config_from_env ( ) -> Result < EnvConfig > {
849851 // ======= AWS =======
850- let s3 = if let Ok ( bucket) = env :: var ( "SCCACHE_BUCKET" ) {
851- let region = env :: var ( "SCCACHE_REGION" ) . ok ( ) ;
852+ let s3 = if let Some ( bucket) = string_from_env_var ( "SCCACHE_BUCKET" ) {
853+ let region = string_from_env_var ( "SCCACHE_REGION" ) ;
852854 let no_credentials = bool_from_env_var ( "SCCACHE_S3_NO_CREDENTIALS" ) ?. unwrap_or ( false ) ;
853855 let use_ssl = bool_from_env_var ( "SCCACHE_S3_USE_SSL" ) ?;
854856 let server_side_encryption = bool_from_env_var ( "SCCACHE_S3_SERVER_SIDE_ENCRYPTION" ) ?;
855- let endpoint = env :: var ( "SCCACHE_ENDPOINT" ) . ok ( ) ;
857+ let endpoint = string_from_env_var ( "SCCACHE_ENDPOINT" ) ;
856858 let key_prefix = key_prefix_from_env_var ( "SCCACHE_S3_KEY_PREFIX" ) ;
857859 let enable_virtual_host_style = bool_from_env_var ( "SCCACHE_S3_ENABLE_VIRTUAL_HOST_STYLE" ) ?;
858860
@@ -879,18 +881,18 @@ fn config_from_env() -> Result<EnvConfig> {
879881
880882 // ======= redis =======
881883 let redis = match (
882- env :: var ( "SCCACHE_REDIS" ) . ok ( ) ,
883- env :: var ( "SCCACHE_REDIS_ENDPOINT" ) . ok ( ) ,
884- env :: var ( "SCCACHE_REDIS_CLUSTER_ENDPOINTS" ) . ok ( ) ,
884+ string_from_env_var ( "SCCACHE_REDIS" ) ,
885+ string_from_env_var ( "SCCACHE_REDIS_ENDPOINT" ) ,
886+ string_from_env_var ( "SCCACHE_REDIS_CLUSTER_ENDPOINTS" ) ,
885887 ) {
886888 ( None , None , None ) => None ,
887889 ( url, endpoint, cluster_endpoints) => {
888890 let db = number_from_env_var ( "SCCACHE_REDIS_DB" )
889891 . transpose ( ) ?
890892 . unwrap_or ( DEFAULT_REDIS_DB ) ;
891893
892- let username = env :: var ( "SCCACHE_REDIS_USERNAME" ) . ok ( ) ;
893- let password = env :: var ( "SCCACHE_REDIS_PASSWORD" ) . ok ( ) ;
894+ let username = string_from_env_var ( "SCCACHE_REDIS_USERNAME" ) ;
895+ let password = string_from_env_var ( "SCCACHE_REDIS_PASSWORD" ) ;
894896
895897 let ttl = number_from_env_var ( "SCCACHE_REDIS_EXPIRATION" )
896898 . or_else ( || number_from_env_var ( "SCCACHE_REDIS_TTL" ) )
@@ -919,11 +921,11 @@ fn config_from_env() -> Result<EnvConfig> {
919921 }
920922
921923 // ======= memcached =======
922- let memcached = if let Ok ( url) =
923- env :: var ( "SCCACHE_MEMCACHED" ) . or_else ( |_| env :: var ( "SCCACHE_MEMCACHED_ENDPOINT" ) )
924+ let memcached = if let Some ( url) = string_from_env_var ( "SCCACHE_MEMCACHED" )
925+ . or_else ( || string_from_env_var ( "SCCACHE_MEMCACHED_ENDPOINT" ) )
924926 {
925- let username = env :: var ( "SCCACHE_MEMCACHED_USERNAME" ) . ok ( ) ;
926- let password = env :: var ( "SCCACHE_MEMCACHED_PASSWORD" ) . ok ( ) ;
927+ let username = string_from_env_var ( "SCCACHE_MEMCACHED_USERNAME" ) ;
928+ let password = string_from_env_var ( "SCCACHE_MEMCACHED_PASSWORD" ) ;
927929
928930 let expiration = number_from_env_var ( "SCCACHE_MEMCACHED_EXPIRATION" )
929931 . transpose ( ) ?
@@ -951,35 +953,35 @@ fn config_from_env() -> Result<EnvConfig> {
951953 }
952954
953955 // ======= GCP/GCS =======
954- if ( env :: var ( "SCCACHE_GCS_CREDENTIALS_URL" ) . is_ok ( )
955- || env :: var ( "SCCACHE_GCS_OAUTH_URL" ) . is_ok ( )
956- || env :: var ( "SCCACHE_GCS_KEY_PATH" ) . is_ok ( ) )
957- && env :: var ( "SCCACHE_GCS_BUCKET" ) . is_err ( )
956+ if ( string_from_env_var ( "SCCACHE_GCS_CREDENTIALS_URL" ) . is_some ( )
957+ || string_from_env_var ( "SCCACHE_GCS_OAUTH_URL" ) . is_some ( )
958+ || string_from_env_var ( "SCCACHE_GCS_KEY_PATH" ) . is_some ( ) )
959+ && string_from_env_var ( "SCCACHE_GCS_BUCKET" ) . is_none ( )
958960 {
959961 bail ! (
960962 "If setting GCS credentials, SCCACHE_GCS_BUCKET and an auth mechanism need to be set."
961963 ) ;
962964 }
963965
964- let gcs = env :: var ( "SCCACHE_GCS_BUCKET" ) . ok ( ) . map ( |bucket| {
966+ let gcs = string_from_env_var ( "SCCACHE_GCS_BUCKET" ) . map ( |bucket| {
965967 let key_prefix = key_prefix_from_env_var ( "SCCACHE_GCS_KEY_PREFIX" ) ;
966968
967- if env :: var ( "SCCACHE_GCS_OAUTH_URL" ) . is_ok ( ) {
969+ if string_from_env_var ( "SCCACHE_GCS_OAUTH_URL" ) . is_some ( ) {
968970 eprintln ! ( "SCCACHE_GCS_OAUTH_URL has been deprecated" ) ;
969971 eprintln ! ( "if you intend to use vm metadata for auth, please set correct service account instead" ) ;
970972 }
971973
972- let credential_url = env :: var ( "SCCACHE_GCS_CREDENTIALS_URL" ) . ok ( ) ;
974+ let credential_url = string_from_env_var ( "SCCACHE_GCS_CREDENTIALS_URL" ) ;
973975
974- let cred_path = env :: var ( "SCCACHE_GCS_KEY_PATH" ) . ok ( ) ;
975- let service_account = env :: var ( "SCCACHE_GCS_SERVICE_ACCOUNT" ) . ok ( ) ;
976+ let cred_path = string_from_env_var ( "SCCACHE_GCS_KEY_PATH" ) ;
977+ let service_account = string_from_env_var ( "SCCACHE_GCS_SERVICE_ACCOUNT" ) ;
976978
977- let rw_mode = match env :: var ( "SCCACHE_GCS_RW_MODE" ) . as_ref ( ) . map ( String :: as_str ) {
978- Ok ( "READ_ONLY" ) => CacheModeConfig :: ReadOnly ,
979- Ok ( "READ_WRITE" ) => CacheModeConfig :: ReadWrite ,
979+ let rw_mode = match string_from_env_var ( "SCCACHE_GCS_RW_MODE" ) . as_deref ( ) {
980+ Some ( "READ_ONLY" ) => CacheModeConfig :: ReadOnly ,
981+ Some ( "READ_WRITE" ) => CacheModeConfig :: ReadWrite ,
980982 // TODO: unsure if these should warn during the configuration loading
981983 // or at the time when they're actually used to connect to GCS
982- Ok ( _) => {
984+ Some ( _) => {
983985 warn ! ( "Invalid SCCACHE_GCS_RW_MODE -- defaulting to READ_ONLY." ) ;
984986 CacheModeConfig :: ReadOnly
985987 }
@@ -1000,7 +1002,7 @@ fn config_from_env() -> Result<EnvConfig> {
10001002 } ) ;
10011003
10021004 // ======= GHA =======
1003- let gha = if let Ok ( version) = env :: var ( "SCCACHE_GHA_VERSION" ) {
1005+ let gha = if let Some ( version) = string_from_env_var ( "SCCACHE_GHA_VERSION" ) {
10041006 // If SCCACHE_GHA_VERSION has been set, we don't need to check
10051007 // SCCACHE_GHA_ENABLED's value anymore.
10061008 Some ( GHACacheConfig {
@@ -1019,9 +1021,9 @@ fn config_from_env() -> Result<EnvConfig> {
10191021 } ;
10201022
10211023 // ======= Azure =======
1022- let azure = if let ( Ok ( connection_string) , Ok ( container) ) = (
1023- env :: var ( "SCCACHE_AZURE_CONNECTION_STRING" ) ,
1024- env :: var ( "SCCACHE_AZURE_BLOB_CONTAINER" ) ,
1024+ let azure = if let ( Some ( connection_string) , Some ( container) ) = (
1025+ string_from_env_var ( "SCCACHE_AZURE_CONNECTION_STRING" ) ,
1026+ string_from_env_var ( "SCCACHE_AZURE_BLOB_CONTAINER" ) ,
10251027 ) {
10261028 let key_prefix = key_prefix_from_env_var ( "SCCACHE_AZURE_KEY_PREFIX" ) ;
10271029 Some ( AzureCacheConfig {
@@ -1034,11 +1036,11 @@ fn config_from_env() -> Result<EnvConfig> {
10341036 } ;
10351037
10361038 // ======= WebDAV =======
1037- let webdav = if let Ok ( endpoint) = env :: var ( "SCCACHE_WEBDAV_ENDPOINT" ) {
1039+ let webdav = if let Some ( endpoint) = string_from_env_var ( "SCCACHE_WEBDAV_ENDPOINT" ) {
10381040 let key_prefix = key_prefix_from_env_var ( "SCCACHE_WEBDAV_KEY_PREFIX" ) ;
1039- let username = env :: var ( "SCCACHE_WEBDAV_USERNAME" ) . ok ( ) ;
1040- let password = env :: var ( "SCCACHE_WEBDAV_PASSWORD" ) . ok ( ) ;
1041- let token = env :: var ( "SCCACHE_WEBDAV_TOKEN" ) . ok ( ) ;
1041+ let username = string_from_env_var ( "SCCACHE_WEBDAV_USERNAME" ) ;
1042+ let password = string_from_env_var ( "SCCACHE_WEBDAV_PASSWORD" ) ;
1043+ let token = string_from_env_var ( "SCCACHE_WEBDAV_TOKEN" ) ;
10421044
10431045 Some ( WebdavCacheConfig {
10441046 endpoint,
@@ -1052,8 +1054,8 @@ fn config_from_env() -> Result<EnvConfig> {
10521054 } ;
10531055
10541056 // ======= OSS =======
1055- let oss = if let Ok ( bucket) = env :: var ( "SCCACHE_OSS_BUCKET" ) {
1056- let endpoint = env :: var ( "SCCACHE_OSS_ENDPOINT" ) . ok ( ) ;
1057+ let oss = if let Some ( bucket) = string_from_env_var ( "SCCACHE_OSS_BUCKET" ) {
1058+ let endpoint = string_from_env_var ( "SCCACHE_OSS_ENDPOINT" ) ;
10571059 let key_prefix = key_prefix_from_env_var ( "SCCACHE_OSS_KEY_PREFIX" ) ;
10581060
10591061 let no_credentials = bool_from_env_var ( "SCCACHE_OSS_NO_CREDENTIALS" ) ?. unwrap_or ( false ) ;
@@ -1079,8 +1081,8 @@ fn config_from_env() -> Result<EnvConfig> {
10791081 }
10801082
10811083 // ======= COS =======
1082- let cos = if let Ok ( bucket) = env :: var ( "SCCACHE_COS_BUCKET" ) {
1083- let endpoint = env :: var ( "SCCACHE_COS_ENDPOINT" ) . ok ( ) ;
1084+ let cos = if let Some ( bucket) = string_from_env_var ( "SCCACHE_COS_BUCKET" ) {
1085+ let endpoint = string_from_env_var ( "SCCACHE_COS_ENDPOINT" ) ;
10841086 let key_prefix = key_prefix_from_env_var ( "SCCACHE_COS_KEY_PREFIX" ) ;
10851087
10861088 Some ( COSCacheConfig {
@@ -1094,9 +1096,7 @@ fn config_from_env() -> Result<EnvConfig> {
10941096
10951097 // ======= Local =======
10961098 let disk_dir = env:: var_os ( "SCCACHE_DIR" ) . map ( PathBuf :: from) ;
1097- let disk_sz = env:: var ( "SCCACHE_CACHE_SIZE" )
1098- . ok ( )
1099- . and_then ( |v| parse_size ( & v) ) ;
1099+ let disk_sz = string_from_env_var ( "SCCACHE_CACHE_SIZE" ) . and_then ( |v| parse_size ( & v) ) ;
11001100
11011101 let mut preprocessor_mode_config = PreprocessorCacheModeConfig :: activated ( ) ;
11021102 let preprocessor_mode_overridden = if let Some ( value) = bool_from_env_var ( "SCCACHE_DIRECT" ) ? {
@@ -1106,18 +1106,16 @@ fn config_from_env() -> Result<EnvConfig> {
11061106 false
11071107 } ;
11081108
1109- let ( disk_rw_mode, disk_rw_mode_overridden) = match env:: var ( "SCCACHE_LOCAL_RW_MODE" )
1110- . as_ref ( )
1111- . map ( String :: as_str)
1112- {
1113- Ok ( "READ_ONLY" ) => ( CacheModeConfig :: ReadOnly , true ) ,
1114- Ok ( "READ_WRITE" ) => ( CacheModeConfig :: ReadWrite , true ) ,
1115- Ok ( _) => {
1116- warn ! ( "Invalid SCCACHE_LOCAL_RW_MODE -- defaulting to READ_WRITE." ) ;
1117- ( CacheModeConfig :: ReadWrite , false )
1118- }
1119- _ => ( CacheModeConfig :: ReadWrite , false ) ,
1120- } ;
1109+ let ( disk_rw_mode, disk_rw_mode_overridden) =
1110+ match string_from_env_var ( "SCCACHE_LOCAL_RW_MODE" ) . as_deref ( ) {
1111+ Some ( "READ_ONLY" ) => ( CacheModeConfig :: ReadOnly , true ) ,
1112+ Some ( "READ_WRITE" ) => ( CacheModeConfig :: ReadWrite , true ) ,
1113+ Some ( _) => {
1114+ warn ! ( "Invalid SCCACHE_LOCAL_RW_MODE -- defaulting to READ_WRITE." ) ;
1115+ ( CacheModeConfig :: ReadWrite , false )
1116+ }
1117+ _ => ( CacheModeConfig :: ReadWrite , false ) ,
1118+ } ;
11211119
11221120 let any_overridden = disk_dir. is_some ( )
11231121 || disk_sz. is_some ( )
@@ -1555,6 +1553,32 @@ fn test_parse_size() {
15551553 assert_eq ! ( Some ( 1024 * TEN_GIGS ) , parse_size( "10T" ) ) ;
15561554}
15571555
1556+ #[ test]
1557+ fn test_string_from_env_var ( ) {
1558+ let var_name = "TEST_SCCACHE_VAR" ;
1559+ for value in [ None , Some ( "" ) , Some ( "foo" ) ] {
1560+ match value {
1561+ None => unsafe {
1562+ std:: env:: remove_var ( var_name) ;
1563+ } ,
1564+ Some ( value) => unsafe {
1565+ std:: env:: set_var ( var_name, value) ;
1566+ } ,
1567+ }
1568+ let result = string_from_env_var ( var_name) ;
1569+ unsafe {
1570+ std:: env:: remove_var ( var_name) ;
1571+ }
1572+
1573+ let expected = match value {
1574+ None | Some ( "" ) => None ,
1575+ Some ( value) => Some ( value. to_string ( ) ) ,
1576+ } ;
1577+
1578+ assert_eq ! ( result, expected) ;
1579+ }
1580+ }
1581+
15581582#[ test]
15591583fn config_overrides ( ) {
15601584 let env_conf = EnvConfig {
0 commit comments