Skip to content

Instantly share code, notes, and snippets.

@anonhostpi
Last active October 7, 2023 11:29
Show Gist options
  • Save anonhostpi/f385e0ec2bca28cc5cc2a136627a4c69 to your computer and use it in GitHub Desktop.
Save anonhostpi/f385e0ec2bca28cc5cc2a136627a4c69 to your computer and use it in GitHub Desktop.
NuGet.Frameworks and Microsft.NETCore.Platforms wrappers for PowerShell (bootstrap code for writing an Import-Package cmdlet)
& {
Add-Type -AssemblyName System.Runtime # Useful for RID detection
Add-Type -AssemblyName System.IO.Compression.FileSystem # Useful for reading nupkg/zip files
# Exported methods and properties
$Exported = New-Object psobject
$Exported | Add-Member `
-MemberType ScriptMethod `
-Name GetLatest `
-Value {
param( $Name )
$apis = Invoke-WebRequest https://api.nuget.org/v3/index.json
$apis = ConvertFrom-Json $apis
$resource = $apis.resources | Where-Object {
($_."@type" -eq "SearchQueryService") -and
($_.comment -like "*(primary)*")
}
$id = $resource."@id"
$results = Invoke-WebRequest "$id`?q=packageid:$Name&prerelease=false&take=1"
$results = ConvertFrom-Json $results
$results.data[0].version
}
$Exported | Add-Member `
-MemberType ScriptMethod `
-Name ReadNuspec `
-Value {
param( $Package )
$nupkg = $Package.Source
$nupkg = [System.IO.Compression.ZipFile]::OpenRead( $nupkg )
$nuspec = $nupkg.Entries | Where-Object { $_.FullName -eq "$($Package.Name).nuspec" }
$stream = $nuspec.Open()
$reader = New-Object System.IO.StreamReader( $stream )
[xml]($reader.ReadToEnd())
$reader.Close()
$stream.Close()
$nupkg.Dispose()
}
$Exported | Add-Member `
-MemberType ScriptMethod `
-Name Load `
-Value {
param(
[string] $Path,
[bool] $Partial = $false
)
# todo: add handling of native/unmanaged assemblies
try {
$AddTypeParams = @{
# PassThru = $false
}
if( $Partial ) {
$AddTypeParams.AssemblyName = $Path
} elseif ( Test-Path $Path ) {
$AddTypeParams.Path = $Path
} else {
Write-Host "Unable to load $Path"
return
}
Add-Type @AddTypeParams
} catch { Write-Host "Unable to load $Path" }
}
$Exported | Add-Member `
-MemberType ScriptMethod `
-Name Init `
-Value {
$Loaded = Try {
[NuGet.Frameworks.FrameworkConstants+FrameworkIdentifiers]
} Catch {
$false
}
If( -not( $Loaded )){
$load_order = [System.Collections.ArrayList]::new()
$load_order.Add( "NuGet.Frameworks" ) | Out-Null
# Loop init
$i = 0
$package_name = ""
# Caching for performance
$package_table = @{}
while( $i -lt $load_order.count ){
$package_name = $load_order[$i]
If( -not( $package_table.ContainsKey( $package_name ) ) ){
$package = Get-Package $package_name -ProviderName NuGet -ErrorAction SilentlyContinue
$latest = Try {
$this.GetLatest( $package_name )
} Catch { $package.Version }
if( (-not $package) -or ($package.Version -ne $latest) ){
Try {
Install-Package $package_name `
-ProviderName NuGet `
-SkipDependencies `
-Force | Out-Null
} Catch {}
$package = Get-Package $package_name -ProviderName NuGet -ErrorAction Stop
}
$package_table[ $package_name ] = $package.Source.ToString()
$dependencies = ($this.ReadNuspec( $package ).package.metadata.dependencies.group | Where-Object { $_.targetframework -eq "netstandard2.0" }).dependency | Where-Object { $_.id }
foreach( $dependency in $dependencies ){
$load_order.Add( $dependency.id ) | Out-Null
}
} else {
$oldindex = $load_order.IndexOf( $package_name )
$load_order.RemoveAt( $oldindex )
$load_order.Add( $package_name )
}
$i += 1
}
$this | Add-Member `
-MemberType NoteProperty `
-Name Dependencies `
-Value ($load_order | Select-Object -Unique)
[array]::Reverse( $this.Dependencies )
$this.Dependencies | ForEach-Object {
$package_source = $package_table[ $_ ]
$dll = Resolve-Path "$(Split-Path $package_source -ErrorAction SilentlyContinue)\lib\netstandard2.0\$_.dll" -ErrorAction SilentlyContinue
$this.Load( $dll )
}
}
$this
}
$Exported
} | % { $_.Init() }
@anonhostpi
Copy link
Author

anonhostpi commented Oct 6, 2023

Optimization 1:

@anonhostpi
Copy link
Author

anonhostpi commented Oct 6, 2023

Improvement 2:

@anonhostpi
Copy link
Author

anonhostpi commented Oct 6, 2023

Improvement 3:

@anonhostpi
Copy link
Author

anonhostpi commented Oct 7, 2023

Improvement 4:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment