Skip to content

Commit fb5d0fb

Browse files
committed
Address review point for directories separator
1 parent 9ccabc3 commit fb5d0fb

File tree

3 files changed

+172
-10
lines changed

3 files changed

+172
-10
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,10 +287,10 @@ By default, sccache requires absolute paths to match for cache hits. To enable c
287287
export SCCACHE_BASEDIRS=/home/user/project
288288
```
289289

290-
You can also specify multiple base directories by separating them with `|` (pipe character). When multiple directories are provided, the longest matching prefix is used:
290+
You can also specify multiple base directories by separating them by `;` on Windows hosts and by `:` on any other. When multiple directories are provided, the longest matching prefix is used:
291291

292292
```bash
293-
export SCCACHE_BASEDIRS="/home/user/project|/home/user/workspace"
293+
export SCCACHE_BASEDIRS="/home/user/project:/home/user/workspace"
294294
```
295295

296296
Path matching is **case-insensitive** on Windows and **case-sensitive** on other operating systems.
@@ -301,7 +301,7 @@ This is similar to ccache's `CCACHE_BASEDIR` and helps when:
301301
* Multiple developers working with different username paths
302302
* Working with multiple project checkouts simultaneously
303303

304-
**Note:** Only absolute paths are supported. Relative paths will be ignored with a warning.
304+
**Note:** Only absolute paths are supported. Relative paths will prevent server from start.
305305

306306
You can also configure this in the sccache config file:
307307

docs/Configuration.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ server_startup_timeout_ms = 10000
1717
# users in a shared environment.
1818
# When multiple paths are provided, the longest matching prefix
1919
# is applied.
20-
#
20+
#
2121
# Path matching is case-insensitive on Windows and case-sensitive on other OSes.
2222
#
2323
# Example:
@@ -154,7 +154,7 @@ Note that some env variables may need sccache server restart to take effect.
154154

155155
* `SCCACHE_ALLOW_CORE_DUMPS` to enable core dumps by the server
156156
* `SCCACHE_CONF` configuration file path
157-
* `SCCACHE_BASEDIRS` base directory (or directories) to strip from paths for cache key computation. This is similar to ccache's `CCACHE_BASEDIR` and enables cache hits across different absolute paths when compiling the same source code. Multiple directories can be separated by `|` (pipe character). When multiple directories are specified, the longest matching prefix is used. Path matching is **case-insensitive** on Windows and **case-sensitive** on other operating systems. Environment variable takes precedence over file configuration. Only absolute paths are supported; relative paths will be ignored with a warning.
157+
* `SCCACHE_BASEDIRS` base directory (or directories) to strip from paths for cache key computation. This is similar to ccache's `CCACHE_BASEDIR` and enables cache hits across different absolute paths when compiling the same source code. Multiple directories can be separated by `;` on Windows hosts and by `:` on any other. When multiple directories are specified, the longest matching prefix is used. Path matching is **case-insensitive** on Windows and **case-sensitive** on other operating systems. Environment variable takes precedence over file configuration. Only absolute paths are supported; relative paths will be ignored with a warning.
158158
* `SCCACHE_CACHED_CONF`
159159
* `SCCACHE_IDLE_TIMEOUT` how long the local daemon process waits for more client requests before exiting, in seconds. Set to `0` to run sccache permanently
160160
* `SCCACHE_STARTUP_NOTIFY` specify a path to a socket which will be used for server completion notification

src/config.rs

Lines changed: 167 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -950,11 +950,17 @@ fn config_from_env() -> Result<EnvConfig> {
950950
};
951951

952952
// ======= Base directory =======
953-
// Support multiple paths separated by '|' (a character forbidden in paths)
953+
// Support multiple paths separated by ';' on Windows and ':' on other platforms
954+
// to match PATH behavior.
955+
let split_symbol = if cfg!(target_os = "windows") {
956+
';'
957+
} else {
958+
':'
959+
};
954960
let basedirs = env::var_os("SCCACHE_BASEDIRS")
955961
.map(|s| {
956962
s.to_string_lossy()
957-
.split('|')
963+
.split(split_symbol)
958964
.map(|p| PathBuf::from(p.trim()))
959965
.filter(|p| !p.as_os_str().is_empty())
960966
.collect()
@@ -1386,6 +1392,61 @@ fn config_overrides() {
13861392
}
13871393

13881394
#[test]
1395+
#[cfg(target_os = "windows")]
1396+
fn config_basedirs_overrides() {
1397+
use std::path::PathBuf;
1398+
1399+
// Test that env variable takes precedence over file config
1400+
let env_conf = EnvConfig {
1401+
cache: Default::default(),
1402+
basedirs: vec![PathBuf::from("C:/env/basedir")],
1403+
};
1404+
1405+
let file_conf = FileConfig {
1406+
cache: Default::default(),
1407+
dist: Default::default(),
1408+
server_startup_timeout_ms: None,
1409+
basedirs: vec![PathBuf::from("C:/file/basedir")],
1410+
};
1411+
1412+
let config = Config::from_env_and_file_configs(env_conf, file_conf).unwrap();
1413+
assert_eq!(config.basedirs, vec![PathBuf::from("C:\\env\\basedir")]);
1414+
1415+
// Test that file config is used when env is empty
1416+
let env_conf = EnvConfig {
1417+
cache: Default::default(),
1418+
basedirs: vec![],
1419+
};
1420+
1421+
let file_conf = FileConfig {
1422+
cache: Default::default(),
1423+
dist: Default::default(),
1424+
server_startup_timeout_ms: None,
1425+
basedirs: vec![PathBuf::from("C:/file/basedir")],
1426+
};
1427+
1428+
let config = Config::from_env_and_file_configs(env_conf, file_conf).unwrap();
1429+
assert_eq!(config.basedirs, vec![PathBuf::from("C:\\file\\basedir")]);
1430+
1431+
// Test that both empty results in empty
1432+
let env_conf = EnvConfig {
1433+
cache: Default::default(),
1434+
basedirs: vec![],
1435+
};
1436+
1437+
let file_conf = FileConfig {
1438+
cache: Default::default(),
1439+
dist: Default::default(),
1440+
server_startup_timeout_ms: None,
1441+
basedirs: vec![],
1442+
};
1443+
1444+
let config = Config::from_env_and_file_configs(env_conf, file_conf).unwrap();
1445+
assert_eq!(config.basedirs, Vec::<PathBuf>::new());
1446+
}
1447+
1448+
#[test]
1449+
#[cfg(not(target_os = "windows"))]
13891450
fn config_basedirs_overrides() {
13901451
use std::path::PathBuf;
13911452

@@ -1439,6 +1500,7 @@ fn config_basedirs_overrides() {
14391500
}
14401501

14411502
#[test]
1503+
#[cfg(not(target_os = "windows"))]
14421504
fn test_deserialize_basedirs() {
14431505
use std::path::PathBuf;
14441506

@@ -1482,6 +1544,7 @@ fn test_deserialize_basedirs_missing() {
14821544

14831545
#[test]
14841546
#[serial]
1547+
#[cfg(not(target_os = "windows"))]
14851548
fn test_env_basedirs_single() {
14861549
use std::path::PathBuf;
14871550

@@ -1497,13 +1560,33 @@ fn test_env_basedirs_single() {
14971560

14981561
#[test]
14991562
#[serial]
1563+
#[cfg(target_os = "windows")]
1564+
fn test_env_basedirs_single() {
1565+
use std::path::PathBuf;
1566+
1567+
unsafe {
1568+
std::env::set_var("SCCACHE_BASEDIRS", "C:/home/user/project");
1569+
}
1570+
let config = config_from_env().unwrap();
1571+
assert_eq!(
1572+
config.basedirs,
1573+
vec![PathBuf::from("C:\\home\\user\\project")]
1574+
);
1575+
unsafe {
1576+
std::env::remove_var("SCCACHE_BASEDIRS");
1577+
}
1578+
}
1579+
1580+
#[test]
1581+
#[serial]
1582+
#[cfg(not(target_os = "windows"))]
15001583
fn test_env_basedirs_multiple() {
15011584
use std::path::PathBuf;
15021585

15031586
unsafe {
15041587
std::env::set_var(
15051588
"SCCACHE_BASEDIRS",
1506-
"/home/user/project|/home/user/workspace",
1589+
"/home/user/project:/home/user/workspace",
15071590
);
15081591
}
15091592
let config = config_from_env().unwrap();
@@ -1521,14 +1604,40 @@ fn test_env_basedirs_multiple() {
15211604

15221605
#[test]
15231606
#[serial]
1607+
#[cfg(target_os = "windows")]
1608+
fn test_env_basedirs_multiple() {
1609+
use std::path::PathBuf;
1610+
1611+
unsafe {
1612+
std::env::set_var(
1613+
"SCCACHE_BASEDIRS",
1614+
"C:/home/user/project;C:/home/user/workspace",
1615+
);
1616+
}
1617+
let config = config_from_env().unwrap();
1618+
assert_eq!(
1619+
config.basedirs,
1620+
vec![
1621+
PathBuf::from("C:\\home\\user\\project"),
1622+
PathBuf::from("C:\\home\\user\\workspace")
1623+
]
1624+
);
1625+
unsafe {
1626+
std::env::remove_var("SCCACHE_BASEDIRS");
1627+
}
1628+
}
1629+
1630+
#[test]
1631+
#[serial]
1632+
#[cfg(not(target_os = "windows"))]
15241633
fn test_env_basedirs_with_spaces() {
15251634
use std::path::PathBuf;
15261635

15271636
// Test that spaces around paths are trimmed
15281637
unsafe {
15291638
std::env::set_var(
15301639
"SCCACHE_BASEDIRS",
1531-
" /home/user/project | /home/user/workspace ",
1640+
" /home/user/project : /home/user/workspace ",
15321641
);
15331642
}
15341643
let config = config_from_env().unwrap();
@@ -1546,14 +1655,41 @@ fn test_env_basedirs_with_spaces() {
15461655

15471656
#[test]
15481657
#[serial]
1658+
#[cfg(target_os = "windows")]
1659+
fn test_env_basedirs_with_spaces() {
1660+
use std::path::PathBuf;
1661+
1662+
// Test that spaces around paths are trimmed
1663+
unsafe {
1664+
std::env::set_var(
1665+
"SCCACHE_BASEDIRS",
1666+
" C:/home/user/project ; C:/home/user/workspace ",
1667+
);
1668+
}
1669+
let config = config_from_env().unwrap();
1670+
assert_eq!(
1671+
config.basedirs,
1672+
vec![
1673+
PathBuf::from("C:\\home\\user\\project"),
1674+
PathBuf::from("C:\\home\\user\\workspace")
1675+
]
1676+
);
1677+
unsafe {
1678+
std::env::remove_var("SCCACHE_BASEDIRS");
1679+
}
1680+
}
1681+
1682+
#[test]
1683+
#[serial]
1684+
#[cfg(not(target_os = "windows"))]
15491685
fn test_env_basedirs_empty_entries() {
15501686
use std::path::PathBuf;
15511687

15521688
// Test that empty entries are filtered out
15531689
unsafe {
15541690
std::env::set_var(
15551691
"SCCACHE_BASEDIRS",
1556-
"/home/user/project||/home/user/workspace",
1692+
"/home/user/project::/home/user/workspace",
15571693
);
15581694
}
15591695
let config = config_from_env().unwrap();
@@ -1569,6 +1705,32 @@ fn test_env_basedirs_empty_entries() {
15691705
}
15701706
}
15711707

1708+
#[test]
1709+
#[serial]
1710+
#[cfg(target_os = "windows")]
1711+
fn test_env_basedirs_empty_entries() {
1712+
use std::path::PathBuf;
1713+
1714+
// Test that empty entries are filtered out
1715+
unsafe {
1716+
std::env::set_var(
1717+
"SCCACHE_BASEDIRS",
1718+
"c:/home/user/project;;c:/home/user/workspace",
1719+
);
1720+
}
1721+
let config = config_from_env().unwrap();
1722+
assert_eq!(
1723+
config.basedirs,
1724+
vec![
1725+
PathBuf::from("c:\\home\\user\\project"),
1726+
PathBuf::from("c:\\home\\user\\workspace")
1727+
]
1728+
);
1729+
unsafe {
1730+
std::env::remove_var("SCCACHE_BASEDIRS");
1731+
}
1732+
}
1733+
15721734
#[test]
15731735
#[serial]
15741736
fn test_env_basedirs_not_set() {

0 commit comments

Comments
 (0)