Skip to content

Commit

Permalink
Merge pull request #41 from pwsh-cs-tools/feat-v0.5.0
Browse files Browse the repository at this point in the history
Features: 0.5.0 - Add caching of -Path packages and add support for SemVer2 packages
  • Loading branch information
anonhostpi committed Jan 16, 2024
2 parents 733cf47 + 7c6bfcd commit 32bedf6
Show file tree
Hide file tree
Showing 8 changed files with 463 additions and 82 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
publish.ps1
*.dll
*.dll
Import-Package/Packages
Import-Package/Temp
2 changes: 1 addition & 1 deletion Import-Package/Import-Package.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
RootModule = '.\Import-Package.psm1'

# Version number of this module.
ModuleVersion = '0.4.4'
ModuleVersion = '0.5.0'

# Supported PSEditions
# CompatiblePSEditions = @()
Expand Down
92 changes: 54 additions & 38 deletions Import-Package/Import-Package.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -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..."
Expand All @@ -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"
Expand Down Expand Up @@ -174,51 +178,60 @@ 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
}
"Managed" {
Write-Verbose "[Import-Package:ParameterSet] Managed"

Build-PackageData -From "Install" -Options @{
"CachePath" = $CachePath
"TempPath" = $TempPath

"Offline" = $Offline # If true, do not install
Expand All @@ -231,6 +244,7 @@ function Import-Package {
Write-Verbose "[Import-Package:ParameterSet] Unmanaged"

Build-PackageData -From "File" -Options @{
"CachePath" = $CachePath
"TempPath" = $TempPath

"Source" = $Path
Expand Down Expand Up @@ -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"
}
Expand All @@ -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"
}
Expand Down Expand Up @@ -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
}
}
}
}
Expand Down
33 changes: 33 additions & 0 deletions Import-Package/packaging.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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 `
Expand Down
19 changes: 15 additions & 4 deletions Import-Package/src/Build-PackageData.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,38 @@ 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[ $_ ]
}
}
}

$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
Expand Down Expand Up @@ -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 ){
Expand Down
84 changes: 84 additions & 0 deletions Import-Package/src/ConvertTo-SemVerObject.ps1
Original file line number Diff line number Diff line change
@@ -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
}
Loading

0 comments on commit 32bedf6

Please sign in to comment.