diff --git a/.gitignore b/.gitignore index d645536..877b9fa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ publish.ps1 -*.dll \ No newline at end of file +*.dll +Import-Package/Packages +Import-Package/Temp \ No newline at end of file diff --git a/Import-Package/Import-Package.psd1 b/Import-Package/Import-Package.psd1 index c280657..8676be1 100644 --- a/Import-Package/Import-Package.psd1 +++ b/Import-Package/Import-Package.psd1 @@ -12,7 +12,7 @@ RootModule = '.\Import-Package.psm1' # Version number of this module. -ModuleVersion = '0.4.4' +ModuleVersion = '0.5.0' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/Import-Package/Import-Package.psm1 b/Import-Package/Import-Package.psm1 index 54af871..298e7c5 100644 --- a/Import-Package/Import-Package.psm1 +++ b/Import-Package/Import-Package.psm1 @@ -6,6 +6,9 @@ $loaded = @{ } $mutexes = @{} +New-Item (Join-Path $PSScriptRoot "Packages") -Force -ItemType Directory +New-Item (Join-Path $PSScriptRoot "Temp") -Force -ItemType Directory + & { # Clear the Cache Write-Verbose "[Import-Package:Init] Clearing Temp Files..." @@ -21,6 +24,7 @@ $mutexes = @{} } +. "$PSScriptRoot\src\ConvertTo-SemVerObject.ps1" . "$PSScriptRoot\src\Resolve-DependencyVersions.ps1" . "$PSScriptRoot\src\Resolve-CachedPackage.ps1" . "$PSScriptRoot\src\Build-PackageData.ps1" @@ -174,44 +178,52 @@ function Import-Package { [string] $Path, [switch] $Offline, - # [string] $CachePath = "$PSScriptRoot\Packages" - [string] $TempPath = (& { - $parent = & { - [System.IO.Path]::GetTempPath() - # Join-Path ($CachePath | Split-Path -Parent) "Temp" - } - [string] $uuid = [System.Guid]::NewGuid() - - # Cut dirname in half by compressing the UUID from base16 (hexadecimal) to base36 (alphanumeric) - $id = & { - $bigint = [uint128]::Parse( $uuid.ToString().Replace("-",""), 'AllowHexSpecifier') - $compressed = "" - - # Make hex-string more compressed by encoding it in base36 (alphanumeric) - $chars = "0123456789abcdefghijklmnopqrstuvwxyz" - While( $bigint -gt 0 ){ - $remainder = $bigint % 36 - $compressed = $chars[$remainder] + $compressed - $bigint = $bigint/36 - } - Write-Verbose "[Import-Package:Directories] UUID $uuid (base16) converted to $compressed (base$( $chars.Length ))" - - $compressed - } - - $mutexes."$id" = New-Object System.Threading.Mutex($true, "Global\ImportPackage-$id") # Lock the directory from automatic removal - - New-Item -ItemType Directory -Path (Join-Path $parent $id) -Force - # Resolve-Path "." - }) + [string] $CachePath = "$PSScriptRoot\Packages", + [string] $TempPath ) Process { + + $temp_path_generated = If( [string]::IsNullOrWhiteSpace( $TempPath ) ){ + $TempPath = & { + $parent = & { + Join-Path ($CachePath | Split-Path -Parent) "Temp" + } + [string] $uuid = [System.Guid]::NewGuid() + + # Cut dirname in half by compressing the UUID from base16 (hexadecimal) to base36 (alphanumeric) + $id = & { + $bigint = [uint128]::Parse( $uuid.ToString().Replace("-",""), 'AllowHexSpecifier') + $compressed = "" + + # Make hex-string more compressed by encoding it in base36 (alphanumeric) + $chars = "0123456789abcdefghijklmnopqrstuvwxyz" + While( $bigint -gt 0 ){ + $remainder = $bigint % 36 + $compressed = $chars[$remainder] + $compressed + $bigint = $bigint/36 + } + Write-Verbose "[Import-Package:Preparation] UUID $uuid (base16) converted to $compressed (base$( $chars.Length ))" + + $compressed + } + + $mutexes."$id" = New-Object System.Threading.Mutex($true, "Global\ImportPackage-$id") # Lock the directory from automatic removal + + New-Item -ItemType Directory -Path (Join-Path $parent $id) -Force + # Resolve-Path "." + } + $true + } Else { + $false + } + $PackageData = Switch( $PSCmdlet.ParameterSetName ){ "Managed-Object" { Write-Verbose "[Import-Package:ParameterSet] Managed Object" Build-PackageData -From "Object" -Options @( $Package, @{ + "CachePath" = $CachePath "TempPath" = $TempPath }) -Bootstrapper $bootstrapper } @@ -219,6 +231,7 @@ function Import-Package { Write-Verbose "[Import-Package:ParameterSet] Managed" Build-PackageData -From "Install" -Options @{ + "CachePath" = $CachePath "TempPath" = $TempPath "Offline" = $Offline # If true, do not install @@ -231,6 +244,7 @@ function Import-Package { Write-Verbose "[Import-Package:ParameterSet] Unmanaged" Build-PackageData -From "File" -Options @{ + "CachePath" = $CachePath "TempPath" = $TempPath "Source" = $Path @@ -333,9 +347,9 @@ function Import-Package { } Else { Write-Verbose "[Import-Package:Dependency-Handling] ($($PackageData.Name) Dependency) Loading $($_.Name) - $($_.Version) (Framework $( $package_framework.GetShortFolderName() ))" If( $PackageData.Offline ){ - Import-Package $_.Name -Version $_.Version -TargetFramework $package_framework -Offline + Import-Package $_.Name -Version $_.Version -TargetFramework $package_framework -TempPath $PackageData.TempPath -Offline } Else { - Import-Package $_.Name -Version $_.Version -TargetFramework $package_framework + Import-Package $_.Name -Version $_.Version -TargetFramework $package_framework -TempPath $PackageData.TempPath } Write-Verbose "[Import-Package:Dependency-Handling] ($($PackageData.Name) Dependency) $($_.Name) Loaded" } @@ -357,9 +371,9 @@ function Import-Package { } Else { Write-Verbose "[Import-Package:Dependency-Handling] ($($PackageData.Name) Dependency) Loading $($_.Name) - $($_.Version) (Framework $( ([NuGet.Frameworks.NuGetFramework]$package_framework).GetShortFolderName() ))" If( $PackageData.Offline ){ - Import-Package $_.Name -Version $_.Version -TargetFramework $package_framework -Offline + Import-Package $_.Name -Version $_.Version -TargetFramework $package_framework -TempPath $PackageData.TempPath -Offline } Else { - Import-Package $_.Name -Version $_.Version -TargetFramework $package_framework + Import-Package $_.Name -Version $_.Version -TargetFramework $package_framework -TempPath $PackageData.TempPath } Write-Verbose "[Import-Package:Dependency-Handling] ($($PackageData.Name) Dependency) $($_.Name) Loaded" } @@ -483,10 +497,12 @@ function Import-Package { Write-Warning "[Import-Package:Loading] $($PackageData.Name) is not needed for $( $bootstrapper.Runtime )`:$($TargetFramework.GetShortFolderName())" } - If( Test-Path (Join-Path $TempPath "*") ){ - Write-Verbose "[Import-Package:Loading] Temp files: $TempPath" - } Else { - Remove-Item -Path $TempPath -ErrorAction Stop + If( $temp_path_generated ){ + If( Test-Path (Join-Path $TempPath "*") ){ + Write-Verbose "[Import-Package:Loading] Temp files: $TempPath" + } Else { + Remove-Item -Path $TempPath -ErrorAction Stop + } } } } diff --git a/Import-Package/packaging.ps1 b/Import-Package/packaging.ps1 index ed621df..8f186d9 100644 --- a/Import-Package/packaging.ps1 +++ b/Import-Package/packaging.ps1 @@ -34,6 +34,39 @@ } } + $Exported | Add-Member ` + -MemberType ScriptMethod ` + -Name GetPreRelease ` + -Value { + param( $Name, $Wanted ) + $resource = $this.APIs.resources | Where-Object { + $_."@type" -eq "PackageBaseAddress/3.0.0" + } + $id = $resource."@id" + + $versions = @( + $id, + $Name, + "/index.json" + ) -join "" + + $versions = Invoke-WebRequest $versions + $versions = (ConvertFrom-Json $versions).versions + + If( $Wanted ){ + $out = $versions | Where-Object { + $_ -eq $Wanted + } + If( $out ){ + $out + } Else { + $versions | Select-Object -last 1 + } + } Else { + $versions | Select-Object -last 1 + } + } + $Exported | Add-Member ` -MemberType ScriptMethod ` -Name ReadNuspec ` diff --git a/Import-Package/src/Build-PackageData.ps1 b/Import-Package/src/Build-PackageData.ps1 index a5f913e..2b8b059 100644 --- a/Import-Package/src/Build-PackageData.ps1 +++ b/Import-Package/src/Build-PackageData.ps1 @@ -14,19 +14,21 @@ function Build-PackageData { "Name" = "Undefined" "Version" = "Undefined" "Source" = "Undefined" + "CachePath" = "Undefined" "TempPath" = "Undefined" "Offline" = $false + "Stable" = $true "Unmanaged" = $false } - $Options = If( $Options.Count -gt 1 ){ + $Options = If( @($Options).Count -gt 1 ){ $temp_options = @{} $Options | ForEach-Object { $iter_options = $_ $Defaults.Keys | ForEach-Object { $temp_options[ $_ ] = If( $iter_options[ $_ ] ){ $iter_options[ $_ ] - } Elseif( $Defaults[ $_ ] -ne "Undefined") { + } Elseif( $Defaults[ $_ ].ToString() -ne "Undefined") { $Defaults[ $_ ] } } @@ -34,7 +36,16 @@ function Build-PackageData { $temp_options } Else { - $Options + $temp_options = @{} + $Defaults.Keys | ForEach-Object { + $temp_options[ $_ ] = If( $Options[ $_ ] ){ + $Options[ $_ ] + } Elseif( $Defaults[ $_ ].ToString() -ne "Undefined") { + $Defaults[ $_ ] + } + } + + $temp_options } Resolve-CachedPackage -From $From -Options $Options -Bootstrapper $Bootstrapper @@ -73,7 +84,7 @@ function Build-PackageData { $versions_available = $nuspec_version -and $Out.Version $names_available = $nuspec_id -and $Out.Name - $version_mismatch = $nuspec_version -ne $Out.Version + $version_mismatch = -not( $nuspec_version -like "$($Out.Version)*" ) $names_mismatch = $nuspec_id -ne $Out.Name If( $names_available -and $versions_available ){ diff --git a/Import-Package/src/ConvertTo-SemVerObject.ps1 b/Import-Package/src/ConvertTo-SemVerObject.ps1 new file mode 100644 index 0000000..718e96b --- /dev/null +++ b/Import-Package/src/ConvertTo-SemVerObject.ps1 @@ -0,0 +1,84 @@ +# Custom function to convert SemVer string to a comparable object +# Using this over Automation.SemanticVersion, since Automation.SemanticVersion only works in pwsh 7.2+ +function ConvertTo-SemVerObject( [string]$semVerString ) { + + $semVerParts = $semVerString -split '[-\+]' + If( $semVerParts.Count -gt 2 ){ + $semVerParts = @( + $semVerParts[0], + (($semVerParts | Select-Object -Skip 1) -join "-") + ) + } + $versionParts = $semVerParts[0] -split '\.' + + $versionParts = $versionParts | ForEach-Object { + [int]$_ + } + + # Convert main version parts to integers + $major = $versionParts[0] + $minor = $versionParts[1] + $patch = $versionParts[2] + $legacyPrerelease = If( $versionParts.Count -gt 3 ){ + $versionParts[3..($versionParts.Length-1)] + } + + $preRelease = $null + if ($semVerParts.Length -gt 1) { + $preRelease = $semVerParts[1] + } + + # Create a custom object + New-Object PSObject -Property @{ + Major = $major + Minor = $minor + Patch = $patch + LegacyPrerelease = $legacyPrerelease + PreRelease = $preRelease + Original = $semVerString + } + +} + +# Custom comparison function for SemVer +function Compare-SemVerObject($x, $y) { + if ($x.Major -ne $y.Major) { + return $x.Major - $y.Major + } + if ($x.Minor -ne $y.Minor) { + return $x.Minor - $y.Minor + } + if ($x.Patch -ne $y.Patch) { + return $x.Patch - $y.Patch + } + if ($x.LegacyPrerelease -and $y.LegacyPrerelease){ + $max_length = [Math]::Max( + $x.LegacyPrerelease.Count, + $y.LegacyPrerelease.Count + ) + for ($i = 0; $i -lt $max_length; $i++) { + $xlp = $x.LegacyPrerelease[ $i ] + $ylp = $y.LegacyPrerelease[ $i ] + If( $null -eq $xlp ){ + return 1 + } + If( $null -eq $ylp ){ + return -1 + } + If( $xlp -ne $ylp ){ + return $xlp - $ylp + } + } + } + # Handle pre-release comparison + if ($x.PreRelease -and $y.PreRelease) { + return [string]::Compare($x.PreRelease, $y.PreRelease) + } + if ($x.PreRelease) { + return -1 + } + if ($y.PreRelease) { + return 1 + } + return 0 +} \ No newline at end of file diff --git a/Import-Package/src/Resolve-CachedPackage.ps1 b/Import-Package/src/Resolve-CachedPackage.ps1 index 7251fb6..ab02a3c 100644 --- a/Import-Package/src/Resolve-CachedPackage.ps1 +++ b/Import-Package/src/Resolve-CachedPackage.ps1 @@ -14,67 +14,284 @@ function Resolve-CachedPackage { "Object" {} "Install" { - $package_attempts = @{} + # Check desired version against PackageManagement's local cache + # Check desired version against NuGet (both stable and prerelease) + + # **Fallback** to internal local cache. + <# + **Reasoning: - $package_attempts.local_latest = Get-Package $Options.Name -ProviderName NuGet -ErrorAction SilentlyContinue + PackageManagement is to be prioritized. The purpose of this module is not to reproduce the efforts of PackageManagement + - Import-Package's purpose is to patch in features that you would expect PackageManagement (PM) to include. + + One such feature is that at this time, PM's Install-Package doesn't support SemVer 2 while NuGet's Install-Package does. + So, any package not installable by PM will be installed by Import-Package to an internal cache directory. + - The reason for not using NuGet's Install-Package is that NuGet may or may not be installed on the target system. - $version_available = Try{ - If( $Options.Version ){ - $Options.Version - } Elseif( $Options.Offline ) { - $package_attempts.local_latest.Version + Additionally, any package imported using the -Path parameter will be cached here. + + The Import-Package module is also designed in such a way that if PM were to update from SemVer 1 to SemVer 2, + PM packages will still be prioritized. In the long run, this will help reduce Import-Package's file bloat. + #> + + $versions = @{} + $versions.wanted = $Options.Version + $versions.pm = @{} + + # Check for a locally installed version from PackageManagement (pm) + # Also, cache the pm package in memory for faster loading, if it is available + $pm_package = Get-Package $Options.Name -RequiredVersion (& { + # Scripting the -RequiredVersion parameter is more performant than several calls to Get-Package + If( [string]::IsNullOrWhiteSpace( $versions.wanted ) ){ + $null } Else { - $Bootstrapper.GetLatest( $Options.Name ) + $versions.wanted.ToString() + } + }) -ProviderName NuGet -ErrorAction SilentlyContinue + + $versions.pm.local = $pm_package.Version + + If( -not $Options.Offline ){ + # Check for the upstream version (from NuGet) + + If( $Options.Stable ){ + $versions.pm.upstream = Try { + $Bootstrapper.GetLatest( $Options.Name ) + } Catch {} + } + + # If Options.Stable was false or an upstream stable version could not be found, try for a prerelease version + If( [string]::IsNullOrWhiteSpace( "$( $versions.pm.upstream )" ) ){ + $versions.pm.upstream = Try { + $Bootstrapper.GetPreRelease( $Options.Name, $versions.wanted ) + } Catch {} + + # If a prerelease was selected ensure $Options.Stable gets forced to false + If( -not [string]::IsNullOrWhiteSpace( "$( $versions.pm.upstream )" ) ){ + $Options.Stable = $false + } } - } Catch { - $package_attempts.local_latest.Version } - $install_conditions = @( - (-not $package_attempts.local_latest), # Package not Installed - ($package_attempts.local_latest.Version -ne $version_available ) # Package either not up to date, or isn't required version - ) + $versions.cached = @{}; & { + $root = $Options.CachePath - if( $install_conditions ){ + $cached_packages = Join-Path $root "*" + $cached_packages = Resolve-Path $cached_packages + $cached_packages = Split-Path $cached_packages -Leaf - $version_wanted = $version_available # For the purpose of self-documenting code + # Get all cached packages with the same name + $candidate_packages = $cached_packages | Where-Object { + "$_" -like "$( $Options.Name )*" + } - $package_attempts.local_corrected_ver = Try { - - # Check if the wanted version exists in the old version cache - Get-Package $Options.Name -RequiredVersion $version_wanted -ProviderName NuGet -ErrorAction Stop + If( $candidate_packages ){ + + # Get all versions in the directory + $candidate_versions = $candidate_packages | ForEach-Object { + # Exact replace (.Replace()) followed by regex-replace (-replace) + $out = "$_".Replace( $Options.Name, "" ) -replace "^\.","" + If( $out -eq $versions.wanted ){ + $versions.cached.local = $out + } + $out + } + + $candidate_versions = [string[]] $candidate_versions + + [Array]::Sort[string]( $candidate_versions, [System.Comparison[string]]({ + param($x, $y) + $x = ConvertTo-SemVerObject $x + $y = ConvertTo-SemVerObject $y + + Compare-SemVerObject $x $y + })) + + If( -not $versions.cached.local ){ + $versions.cached.local = $candidate_versions | Select-Object -Last 1 + } + + If(@( + $PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent, + ($VerbosePreference -ne 'SilentlyContinue') + ) -contains $true ){ + Write-Host + Write-Verbose "[Import-Packge:Preparation] Detected cached packages for $( $Options.Name ) for versions:" + $candidate_versions | ForEach-Object { + If( $_ -eq $versions.cached.local ){ + Write-Host ">" $_ -ForegroundColor Green + } Else { + Write-Host "-" $_ + } + } + Write-Host + Write-Host "> = either latest or selected version in cache" -ForegroundColor Green + Write-Host + } } - Catch { + } + + # At this point we have checked both the PM and Cached Packages for the desired version + # We have also selected the latest from each in the case that the desired version was not found + + $no_local = -not (& { + $versions.pm.local -or $versions.cached.local + }) + $no_upstream = -not (& { + $versions.pm.upstream + }) + + $versions.best = @{} + If( -not $no_local ){ + $versions.best.local = & { + If( $versions.wanted ){ + switch( $versions.wanted ){ + $versions.pm.local { "pm"; break; } + $versions.cached.local { "cached" } + } + } Elseif( $versions.pm.local ){ + "pm" + } Elseif( $versions.cached.local ){ + "cached" + } + } + } + If( -not $no_upstream ){ + $versions.best.upstream = & { + "pm" + } + } - # If it doesn't install it: - Write-Verbose "[Import-Package:Preparation] Installing $( $Options.Name ) $version_wanted" + If(@( + $PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent, + ($VerbosePreference -ne 'SilentlyContinue') + ) -contains $true ){ + Write-Host + Write-Verbose "[Import-Packge:Preparation] Version control data for $( $Options.Name ):" + + Write-Host "Wanted version:" $versions.wanted -ForegroundColor (& { + If( $versions.wanted ){ + "Green" + } Else { + "DarkGray" + } + }) + Write-Host + Write-Host "No upstream:" $no_upstream -ForegroundColor Cyan "(if -offline is used, this should be True)" + Write-Host "No local:" $no_local -ForegroundColor Cyan + Write-Host + Write-Host "Best local source:" $versions.best.local + Write-Host "Best upstream source:" $versions.best.upstream + Write-Host + Write-Host "Cached version:" $versions.cached.local -ForegroundColor (& { + If( $versions.best.local -eq "cached" ){ + "Green" + } Else { + "DarkGray" + } + }) + Write-Host "PM version:" $versions.pm.local -ForegroundColor (& { + If( $versions.best.local -eq "pm" ){ + "Green" + } Else { + "DarkGray" + } + }) + Write-Host "Upstream version:" $versions.pm.upstream -ForegroundColor (& { + If( $no_upstream ){ + "DarkGray" + } Else { + "Magenta" + } + }) + Write-Host + } + + $install_condition = -not( $no_upstream ) -and (& { + $no_local -or (& { + $best_upstream = $versions[ $versions.best.upstream ].upstream + $best_local = $versions[ $versions.best.local ].local + + $best_upstream -ne $best_local + }) + }) + + $Options.Source = If( $install_condition ){ + If( $Options.Stable ){ + Write-Verbose "[Import-Package:Preparation] Installing $( $Options.Name ) $( $versions[ $versions.best.upstream ].upstream )" Try { Install-Package $Options.Name ` -ProviderName NuGet ` - -RequiredVersion $version_wanted ` + -RequiredVersion $versions[ $versions.best.upstream ].upstream ` -SkipDependencies ` -Force ` -ErrorAction Stop | Out-Null } Catch { Install-Package $Options.Name ` -ProviderName NuGet ` - -RequiredVersion $version_wanted ` + -RequiredVersion $versions[ $versions.best.upstream ].upstream ` -SkipDependencies ` -Scope CurrentUser ` -Force | Out-Null } # Error check it and return it: - Get-Package $Options.Name -RequiredVersion $version_wanted -ProviderName NuGet -ErrorAction Stop + $pm_package = Get-Package $Options.Name -RequiredVersion $versions[ $versions.best.upstream ].upstream -ProviderName NuGet -ErrorAction Stop + If( $pm_package ){ + $Options.Version = $versions[ $versions.best.upstream ].upstream + + $pm_package.Source + } Else { + throw "[Import-Package:Preparation] Autoinstall of $( $Options.Name ) $( $versions[ $versions.best.upstream ].upstream ) failed." + } + } Else { + $Options.Version = $versions[ $versions.best.upstream ].upstream + $package_name = "$( $Options.Name ).$( $Options.Version )" + + $output_path = Join-Path $Options.CachePath "$package_name" "$package_name.nupkg" + + Try{ + Resolve-Path $output_path -ErrorAction Stop + } Catch { + $resource = $bootstrapper.APIs.resources| Where-Object { + $_."@type" -eq "PackageBaseAddress/3.0.0" + } + $id = $resource."@id" + + $url = @( + $id, + $Options.Name, "/", + $Options.Version, "/", + $package_name, ".nupkg" + ) -join "" + + If(@( + $PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent, + ($VerbosePreference -ne 'SilentlyContinue') + ) -contains $true ){ + Write-Verbose "[Import-Package:Preparation] Installed $( $Options.Name ) $( $Options.Version ) from:" + Write-Host "-" $url -ForegroundColor Cyan + Write-Host + } + + New-Item (Split-Path $output_path) -Force -ItemType Directory | Out-Null + Invoke-WebRequest -Uri $url -OutFile $output_path -ErrorAction Stop | Out-Null + [System.IO.Compression.ZipFile]::ExtractToDirectory( $output_path, (Split-Path $output_path), $true ) | Out-Null + + $output_path + } } - } + } Elseif( -not( $no_local ) ){ + $Options.Version = $versions[ $versions.best.local ].local - If( $package_attempts.local_corrected_ver ){ - $Options.Version = $package_attempts.local_corrected_ver.Version - $Options.Source = $package_attempts.local_corrected_ver.Source + If( $versions.best.local -eq "cached" ){ + $package_name = "$( $Options.Name ).$( $Options.Version )" + Join-Path $Options.CachePath "$package_name" "$package_name.nupkg" + } Else { + $pm_package.Source + } } Else { - $Options.Version = $package_attempts.local_latest.Version - $Options.Source = $package_attempts.local_latest.Source + throw "[Import-Package:Preparation] Could not retrieve any packages for $( $Options.Name )" } } "File" { @@ -83,14 +300,23 @@ function Resolve-CachedPackage { # This needs to be corrected by the .nuspec, if it is specified in the nuspec # Additionally, if the version is specifed in the .nuspec, it needs to be provided here - $Options.Name = (Split-Path $Options.Source -Leaf) + $Options.Name = (Split-Path $Options.Source -LeafBase) + + $cache = Join-Path $Options.CachePath $Options.Name + + # Unpack the package to the cache directory + If( -not( Test-Path $cache ) ){ + [System.IO.Compression.ZipFile]::ExtractToDirectory( $Options.Source.ToString(), $cache.ToString() ) + } + + $cache_nupkg = Join-Path $cache (Split-Path $Options.Source -Leaf) - # Unpack the package to the TempPath temporary directory - [System.IO.Compression.ZipFile]::ExtractToDirectory( $Options.Source.ToString(), $Options.TempPath.ToString() ) - # Copy the nupkg to the temporary directory as well - Copy-Item -Path $Options.Source.ToString() -Destination $Options.TempPath.ToString() -Force + # Copy the nupkg to the cache directory as well + If( -not( Test-Path $cache_nupkg ) ){ + Copy-Item -Path $Options.Source.ToString() -Destination $cache -Force + } - $Options.Source = Join-Path $Options.TempPath.ToString() (Split-Path $Options.Source -Leaf) + $Options.Source = $cache_nupkg.ToString() } } } \ No newline at end of file diff --git a/Test.ps1 b/Test.ps1 index 1d8eb0a..933a916 100644 --- a/Test.ps1 +++ b/Test.ps1 @@ -61,6 +61,15 @@ If( $ImportPackage ){ Write-Host "[Import-Package:Testing] Testing the Unmanaged Parameterset with a complex package is complete. Continue Testing?" pause; + Import-Package IronRuby.Libraries + Write-Host "[Import-Package:Testing] Testing the Semver2 packages (and the package cache) is complete. Continue Testing?" + + [Microsoft.ClearScript.V8.V8ScriptEngine] + [Avalonia.Application] + [Newtonsoft.Json.JsonConverter] + [NLua.Lua] + [IronRuby.Ruby] + Write-Host Write-Host "System Runtime ID:" (Get-Runtime) }