Private/Install-ModuleForNonWindows.ps1

function Install-ModuleForNonWindows {
    param (
        [string]$Name,
        [string]$Version,
        [string]$Scope,
        [string]$BucketName,
        [string]$BucketRegion,
        [string]$ObjectKey
    )

    # The command is ran inside another PowerShell core process to avoid issues with the current process
    # More specifically the AWS PowerShell module needed to install the module might not be compatible
    # with the requirements of the module we are trying to install.
    try {
        $WarningPreference = "SilentlyContinue"
        $ProgressPreference = "SilentlyContinue"

        # Check if the module is already installed
        if (Get-Module -Name $Name -ListAvailable) {
            # Check if the candidate version is already installed
            if (Get-Module -Name $Name -ListAvailable | Where-Object { $_.Version -eq $Version }) {
                # If the module version is already installed, skip the installation
                return "ALREADY_INSTALLED"
            }
        }

        Write-Host "Installing $($Name) version $($Version)..."

        # Download the module from S3
        Write-Host "Downloading $($Name) version $($Version) from S3 object $($ObjectKey) in bucket $($BucketName)."
        $tempFile = Read-S3Object -BucketName $BucketName -Region $BucketRegion -Key $ObjectKey -File ([System.IO.Path]::GetTempFileName())

        if (-not (Test-Path -Path $tempFile.FullName)) {
            throw "Failed to download $($Name) version $($Version) from S3 object $($ObjectKey) in bucket $($BucketName)."
        }

        $tempPath = [System.IO.Path]::GetTempPath()
        Expand-Archive -Path $tempFile.FullName -DestinationPath $tempPath -Force

        # Get the path to the module version
        # Linux/MacOS are case sensitive, so we need to find the correct path using the case insensitive name
        $tempModuleVersionPath = Get-ChildItem -Path $tempPath | Where-Object { $_.Name -like $Name } | Select-Object -ExpandProperty FullName
        $newTempModuleVersionPath = Join-Path -Path $tempPath -ChildPath $Version

        # Rename the folder to the module version so dtx.cloud.management > 0.6.1
        if (Test-Path -Path $newTempModuleVersionPath) {
            Remove-Item -Path $newTempModuleVersionPath -Recurse -Force
        }
        Rename-Item -Path $tempModuleVersionPath -NewName $newTempModuleVersionPath -Force

        switch ($Scope) {
            "CurrentUser" {
                $modulePath = Join-Path -Path $HOME -ChildPath ".local" -AdditionalChildPath "share", "powershell", "Modules", $Name
            }
            "AllUsers" {
                $modulePath = Join-Path -Path "/" -ChildPath "usr" -AdditionalChildPath "local", "share", "powershell", "Modules", $Name
            }
        }
        $modulePathInclVersion = Join-Path -Path $modulePath -ChildPath $Version

        # Check if the module exist
        if (Test-Path -Path $modulePath) {
            # Check if the module version is already installed
            Write-Host "Checking if $($modulePathInclVersion) exists..."
            if (Test-Path -Path $modulePathInclVersion) {
                # If we reached this point, we do not expect the version dir for this module to exist.
                # We need to remove it before proceeding
                Remove-Item -Path $modulePathInclVersion -Recurse -Force
            }
        }
        else {
            # If the module doesn't exist, create its path
            Write-Host "Creating $($modulePath)..."
            [void]$(New-Item -ItemType Directory -Path $modulePath -Force)
        }

        # Move the module to the modules folder
        Write-Host "Installing $Name version $Version to $modulePath"

        Move-Item -Path $newTempModuleVersionPath -Destination $modulePath -Force
                
        Write-Host "Module installed successfully."

        return "INSTALLED_SUCCESSFULLY"
    }
    catch {
        throw $_
    }
}