@@ -12,6 +12,7 @@ pub struct InstallLayout {
1212 bin_dir : PathBuf ,
1313 cache_dir : PathBuf ,
1414 venvs_dir : PathBuf ,
15+ versions_dir : PathBuf ,
1516 os : HostOs ,
1617}
1718
@@ -30,12 +31,47 @@ impl InstallLayout {
3031 let venvs_dir = env:: var_os ( "MULTI_PWSH_VENV_DIR" )
3132 . map ( PathBuf :: from)
3233 . unwrap_or_else ( || home. join ( "venv" ) ) ;
34+ let versions_dir = home. join ( "multi" ) ;
3335
3436 Ok ( InstallLayout {
3537 home,
3638 bin_dir,
3739 cache_dir,
3840 venvs_dir,
41+ versions_dir,
42+ os,
43+ } )
44+ }
45+
46+ pub fn from_root ( os : HostOs , home : PathBuf ) -> Result < Self > {
47+ Self :: from_root_with_versions_dir ( os, home. clone ( ) , home. join ( "multi" ) )
48+ }
49+
50+ pub fn from_root_with_versions_dir ( os : HostOs , home : PathBuf , versions_dir : PathBuf ) -> Result < Self > {
51+ Self :: from_parts (
52+ os,
53+ home. clone ( ) ,
54+ home. join ( "bin" ) ,
55+ home. join ( "cache" ) ,
56+ home. join ( "venv" ) ,
57+ versions_dir,
58+ )
59+ }
60+
61+ pub fn from_parts (
62+ os : HostOs ,
63+ home : PathBuf ,
64+ bin_dir : PathBuf ,
65+ cache_dir : PathBuf ,
66+ venvs_dir : PathBuf ,
67+ versions_dir : PathBuf ,
68+ ) -> Result < Self > {
69+ Ok ( InstallLayout {
70+ home,
71+ bin_dir,
72+ cache_dir,
73+ venvs_dir,
74+ versions_dir,
3975 os,
4076 } )
4177 }
@@ -65,7 +101,7 @@ impl InstallLayout {
65101 }
66102
67103 pub fn versions_dir ( & self ) -> PathBuf {
68- self . home . join ( "multi" )
104+ self . versions_dir . clone ( )
69105 }
70106
71107 pub fn preferred_version_dir ( & self , version : & Version ) -> PathBuf {
@@ -80,6 +116,10 @@ impl InstallLayout {
80116 self . os . executable_name ( )
81117 }
82118
119+ pub fn os ( & self ) -> HostOs {
120+ self . os
121+ }
122+
83123 pub fn version_dir ( & self , version : & Version ) -> PathBuf {
84124 let preferred = self . preferred_version_dir ( version) ;
85125 if preferred. exists ( ) {
@@ -317,4 +357,71 @@ mod tests {
317357 assert_eq ! ( layout. installed_versions( ) . unwrap( ) , vec![ new_version, legacy_version] ) ;
318358 } ) ;
319359 }
360+
361+ #[ test]
362+ fn from_root_ignores_multi_pwsh_env_overrides ( ) {
363+ let temp_dir = TempDir :: new ( ) . unwrap ( ) ;
364+ let explicit_home = temp_dir. path ( ) . join ( "package-root" ) ;
365+ let ignored_home = temp_dir. path ( ) . join ( "ignored-home" ) ;
366+ let overridden_bin = temp_dir. path ( ) . join ( "override-bin" ) ;
367+ let overridden_cache = temp_dir. path ( ) . join ( "override-cache" ) ;
368+ let overridden_venv = temp_dir. path ( ) . join ( "override-venv" ) ;
369+
370+ with_layout_env (
371+ Some ( & ignored_home) ,
372+ Some ( & overridden_bin) ,
373+ Some ( & overridden_cache) ,
374+ Some ( & overridden_venv) ,
375+ || {
376+ let layout = InstallLayout :: from_root ( HostOs :: Windows , explicit_home. clone ( ) ) . unwrap ( ) ;
377+ assert_eq ! ( layout. home( ) , explicit_home. as_path( ) ) ;
378+ assert_eq ! ( layout. bin_dir( ) , explicit_home. join( "bin" ) ) ;
379+ assert_eq ! ( layout. cache_dir( ) , explicit_home. join( "cache" ) ) ;
380+ assert_eq ! ( layout. venvs_dir( ) , explicit_home. join( "venv" ) ) ;
381+ assert_eq ! ( layout. versions_dir( ) , explicit_home. join( "multi" ) ) ;
382+ } ,
383+ ) ;
384+ }
385+
386+ #[ test]
387+ fn from_root_with_versions_dir_supports_direct_version_roots ( ) {
388+ let temp_dir = TempDir :: new ( ) . unwrap ( ) ;
389+ let explicit_home = temp_dir. path ( ) . join ( "package-root" ) ;
390+
391+ let layout =
392+ InstallLayout :: from_root_with_versions_dir ( HostOs :: Windows , explicit_home. clone ( ) , explicit_home. clone ( ) )
393+ . unwrap ( ) ;
394+
395+ assert_eq ! ( layout. home( ) , explicit_home. as_path( ) ) ;
396+ assert_eq ! ( layout. bin_dir( ) , explicit_home. join( "bin" ) ) ;
397+ assert_eq ! ( layout. cache_dir( ) , explicit_home. join( "cache" ) ) ;
398+ assert_eq ! ( layout. venvs_dir( ) , explicit_home. join( "venv" ) ) ;
399+ assert_eq ! ( layout. versions_dir( ) , explicit_home) ;
400+ }
401+
402+ #[ test]
403+ fn from_parts_supports_custom_bin_and_versions_dirs ( ) {
404+ let temp_dir = TempDir :: new ( ) . unwrap ( ) ;
405+ let home = temp_dir. path ( ) . join ( "state-root" ) ;
406+ let bin_dir = temp_dir. path ( ) . join ( "shared-bin" ) ;
407+ let cache_dir = temp_dir. path ( ) . join ( "cache-root" ) ;
408+ let venvs_dir = temp_dir. path ( ) . join ( "venv-root" ) ;
409+ let versions_dir = temp_dir. path ( ) . join ( "payload-root" ) ;
410+
411+ let layout = InstallLayout :: from_parts (
412+ HostOs :: Linux ,
413+ home. clone ( ) ,
414+ bin_dir. clone ( ) ,
415+ cache_dir. clone ( ) ,
416+ venvs_dir. clone ( ) ,
417+ versions_dir. clone ( ) ,
418+ )
419+ . unwrap ( ) ;
420+
421+ assert_eq ! ( layout. home( ) , home. as_path( ) ) ;
422+ assert_eq ! ( layout. bin_dir( ) , bin_dir) ;
423+ assert_eq ! ( layout. cache_dir( ) , cache_dir) ;
424+ assert_eq ! ( layout. venvs_dir( ) , venvs_dir) ;
425+ assert_eq ! ( layout. versions_dir( ) , versions_dir) ;
426+ }
320427}
0 commit comments