Skip to content

Commit 10fa727

Browse files
committed
Enables support for installing Unity to any disk location by leveraging sparse bundle disks.
1 parent 8f34065 commit 10fa727

File tree

1 file changed

+48
-14
lines changed

1 file changed

+48
-14
lines changed

UnitySetup/UnitySetup.psm1

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -438,11 +438,14 @@ function Test-UnitySetupInstance {
438438
[parameter(Mandatory = $false)]
439439
[UnityVersion] $Version,
440440

441+
[parameter(Mandatory = $false)]
442+
[string] $BasePath,
443+
441444
[parameter(Mandatory = $false)]
442445
[string] $Path
443446
)
444447

445-
$instance = Get-UnitySetupInstance | Select-UnitySetupInstance -Version $Version -Path $Path
448+
$instance = Get-UnitySetupInstance -BasePath $BasePath | Select-UnitySetupInstance -Version $Version -Path $Path
446449
return $null -ne $instance
447450
}
448451

@@ -680,11 +683,11 @@ function Install-UnitySetupPackage {
680683
throw "Install-UnitySetupPackage has not been implemented on the Linux platform. Contributions welcomed!";
681684
}
682685
([OperatingSystem]::Mac) {
683-
# Note, ignores $Destination on Mac.
686+
# Note that $Destination has to be a disk path.
684687
# sudo installer -package $Package.Path -target /
685688
$startProcessArgs = @{
686689
'FilePath' = 'sudo';
687-
'ArgumentList' = @("installer", "-package", $Package.Path, "-target", "/");
690+
'ArgumentList' = @("installer", "-package", $Package.Path, "-target", $Destination);
688691
'PassThru' = $true;
689692
'Wait' = $true;
690693
}
@@ -786,15 +789,28 @@ function Install-UnitySetupInstance {
786789
}
787790

788791
if ($currentOS -eq [OperatingSystem]::Mac) {
789-
# On macOS we must notify the user to take an action if the default location
790-
# is currently in use. Either there's a previous version of Unity installed
791-
# manually or another install through UnitySetup possibly failed.
792-
if (Test-UnitySetupInstance -Path /Applications/Unity/) {
793-
# TODO: Work in a `$host.ui.PromptForChoice` / -Force param for resolving this.
794-
throw "Install-UnitySetupInstance has not yet handled working around the base install directory already existing. Please move this manually and try again. Contributions welcomed!";
792+
# Creating sparse bundle to host installing Unity in other locations
793+
$unitySetupBundlePath = [io.path]::Combine($Cache, "UnitySetup.sparsebundle")
794+
if (-not (Test-Path $unitySetupBundlePath)) {
795+
Write-Verbose "Creating new sparse bundle disk image for installation."
796+
& hdiutil create -size 32g -fs 'HFS+' -type 'SPARSEBUNDLE' -volname 'UnitySetup' $unitySetupBundlePath
795797
}
798+
Write-Verbose "Mounting sparse bundle disk."
799+
& hdiutil mount $unitySetupBundlePath
796800

797-
# TODO: Test if $installPath contains a/this version of Unity to move back to /Applications/Unity/
801+
# Previous version failed to remove. Cleaning up!
802+
if (Test-Path /Volumes/UnitySetup/Applications/) {
803+
Write-Verbose "Previous install did not clean up properly. Doing that now."
804+
& sudo rm -Rf /Volumes/UnitySetup/Applications/
805+
}
806+
807+
# Copy installed version back to the sparse bundle disk for Unity component installs.
808+
if (Test-UnitySetupInstance -Path $installPath -BasePath $BasePath) {
809+
Write-Verbose "Copying current installation to sparse bundle disk."
810+
# -a for improved recursion to preserve file attributes and symlinks.
811+
# appended '.' is to allow the copy of all files and folders, even hidden.
812+
& sudo cp -a [io.path]::Combine($installPath, '.') /Volumes/UnitySetup/Applications/Unity/
813+
}
798814
}
799815

800816
# TODO: Strip out components already installed in the destination.
@@ -807,10 +823,17 @@ function Install-UnitySetupInstance {
807823
([OperatingSystem]::Linux) { [UnitySetupComponent]::Linux }
808824
([OperatingSystem]::Mac) { [UnitySetupComponent]::Mac }
809825
}
826+
827+
$packageDestination = $installPath
828+
# Installers in macOS get installed to the sparse bundle disk first.
829+
if ($currentOS -eq [OperatingSystem]::Mac) {
830+
$packageDestination = "/Volumes/UnitySetup/"
831+
}
832+
810833
$editorInstaller = $installerPaths | Where-Object { $_.ComponentType -band $editorComponent }
811834
if ($null -ne $editorInstaller) {
812835
Write-Verbose "Installing $($editorInstaller.ComponentType)"
813-
Install-UnitySetupPackage -Package $editorInstaller -Destination $installPath
836+
Install-UnitySetupPackage -Package $editorInstaller -Destination $packageDestination
814837
}
815838

816839
$installerPaths | ForEach-Object {
@@ -820,12 +843,23 @@ function Install-UnitySetupInstance {
820843
}
821844

822845
Write-Verbose "Installing $($_.ComponentType)"
823-
Install-UnitySetupPackage -Package $_ -Destination $installPath
846+
Install-UnitySetupPackage -Package $_ -Destination $packageDestination
824847
}
825848

826-
# Move the install from the staging area to the desired destination
849+
# Move the install from the sparse bundle disk to the install directory.
827850
if ($currentOS -eq [OperatingSystem]::Mac) {
828-
Move-Item -Path /Applications/Unity/ -Destination $installPath
851+
Write-Verbose "Copying install to $installPath."
852+
# Copy the files to the install directory.
853+
& sudo cp -af /Volumes/UnitySetup/Applications/Unity/ $installPath
854+
Write-Verbose "Freeing sparse bundle disk space and unmounting."
855+
# Ensure the drive is cleaned up.
856+
& sudo rm -Rf /Volumes/UnitySetup/Applications/
857+
858+
& hdiutil eject /Volumes/UnitySetup/
859+
# Free up disk space since deleting items in the volume send them to the trash
860+
# Also note that -batteryallowed enables compacting while not connected to
861+
# power. The compact is quite quick since the volume is small.
862+
& hdiutil compact $unitySetupBundlePath -batteryallowed
829863
}
830864
}
831865
}

0 commit comments

Comments
 (0)