Skip to content

Instantly share code, notes, and snippets.

@altrive
Created January 24, 2014 14:29
Show Gist options
  • Save altrive/8598301 to your computer and use it in GitHub Desktop.
Save altrive/8598301 to your computer and use it in GitHub Desktop.
Sample code to use NuGet as PowerShell package manager

Usage

#Initialize NuGet package manager with SMB share custom repository
Initialize-NuGetPackageManager -Repositories ([ordered] @{ CustomReposirory = "\\172.16.0.1\Shared\NuGet" }) -UseOfficialRepository:$true -Verbose

#Install NuGet packages
Use-NuGetPackage -PackageId "ClosedXML" -Verbose
<#
Use-NuGetPackage -PackageId "RazorMachine" -Verbose
Use-NuGetPackage -PackageId "Windows7APICodePack-Shell" -Verbose
Use-NuGetPackage -PackageId "Nuget.Server" -Verbose
Use-NuGetPackage -PackageId "Tx.Windows" -Verbose
#>

#Use imported NuGet packages
#Set .Net current path
[IO.Directory]::SetCurrentDirectory((Get-Location).Path)
 
#Output Excel file using ClosedXML
$workbook = New-Object ClosedXML.Excel.XLWorkbook
$worksheet = $workbook.Worksheets.Add("Sample Sheet");
$worksheet.Cell("A1").Value = "Hello World!";
$workbook.SaveAs("HelloWorld.xlsx");
 
$worksheet.Dispose()

TODO

  • Support strict NuGet package version dependency check.
  • Support NuGet package installation events hoook(init.ps1/install.ps1/uninstall.ps1)
  • Implement IProjectSystem interface to support project.
  • Support MSBuild instructions
  • Support NuGet package restore
  • PowerShell ISE integration
  • Configuration transformations
  • Source code transformations
$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
$Script:PackageManager = $null
function Initialize-NuGetPackageManager
{
[CmdletBinding()]
param (
[hashtable] $Repositories = @{},
[switch] $IgnoreFailingRepositories = $false,
[switch] $UseOfficialRepository = $true,
[string] $PackageInstallPath
)
#Initialize
if (!([String]::IsNullOrEmpty($PSScriptRoot)) -and (Test-Path (Join-Path $PSScriptRoot "NuGet.Core.dll")))
{
Add-Type -Path (Join-Path $PSScriptRoot "NuGet.Core.dll")
}
else
{
$loadedDll = [AppDomain]::CurrentDomain.GetAssemblies() | where { $_.FullName.StartsWith("NuGet")}
if ($loadedDll -eq $null)
{
Write-Verbose ("Download nuget.exe from '{0}'" -f "http://nuget.org/nuget.exe")
$client = New-Object Net.WebClient
$task = $client.DownloadDataTaskAsync("http://nuget.org/nuget.exe")
$task.Wait()
Write-Verbose ("Load nuget.exe to current AppDomain")
[System.Reflection.Assembly]::Load($task.Result) > $null
$client.Dispose()
}
}
$officialRepository = "https://packages.nuget.org/api/v2"
if ($UseOfficialRepository -and !$Repositories.ContainsValue($officialRepository))
{
$Repositories.Add("OfficialRepository", $officialRepository)
}
#Convert to string array
[string[]] $packageSources = $Repositories.Values | select
#Create NuGet repository
$repository = New-Object NuGet.AggregateRepository([NuGet.PackageRepositoryFactory]::Default, $packageSources, $IgnoreFailingRepositories) #Need array wrappping?
#NuGet package directory(%MyDocuments%\WindowsPowerShell\packages)
if ([String]::IsNullOrEmpty($PackageInstallPath))
{
$PackageInstallPath = Join-Path (Split-Path $profile -Parent) "packages"
}
if (!(Test-Path $PackageInstallPath))
{
[IO.Directory]::CreateDirectory($PackageInstallPath) > $null
}
#Create NuGet PackageManager
$manager = New-Object NuGet.PackageManager($repository, $PackageInstallPath)
<#
#Register event handler callback
$manager.add_PackageInstalled({
param (
[NuGet.PackageManager] $obj,
$args
)
#Write-Verbose ("Install package{ 0 } ({ 1 }) " -f $args.Package.Id, $args.Package.Version)
})
#>
$script:PackageManager = $manager
}
function Find-LocalNuGetPackage
{
[OutputType([NuGet.IPackage])]
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string] $PackageId,
[string] $Version
)
$ErrorActionPreference = "Stop"
#Initialize packagemanaer if not call
if ($script:PackageManager -eq $null){
Initialize-NuGetPackageManager
}
[NuGet.PackageManager] $manager = $script:PackageManager
if ([String]::IsNullOrEmpty($Version))
{
return $manager.LocalRepository.FindPackagesById($PackageId) | sort version -Descending | select -First 1
}
else
{
$Version = [NuGet.SemanticVersion]::ParseOptionalVersion($Version)
return $manager.LocalRepository.FindPackage($PackageId, $Version)
}
}
function Use-NuGetPackage
{
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string] $PackageId,
[string] $Version,
[switch] $IncludePreRelease = $true,
[switch] $Force
)
$ErrorActionPreference = "Stop"
#Initialize packagemanaer if not call
if ($script:PackageManager -eq $null){
Initialize-NuGetPackageManager
}
[NuGet.PackageManager] $manager = $script:PackageManager
#Find installed package
[NuGet.IPackage] $package = Find-LocalNuGetPackage -PackageId $PackageId -Version $Version
#If local package is not found. install it.
if ($package -ne $null)
{
Write-Verbose ("Use NuGet package: {0}" -f $package)
}
else
{
$ignoreDependency = $false
#Check PackageId is valid
if (!($PackageManager.SourceRepository.Exists($PackageId, $Version))){
Write-Error ("Specified package is not found in repository: PackageId='{0}', Version={1}", $PackageId, $Version)
}
#Install NuGet package(ignore dependent packages)
$manager.InstallPackage($PackageId, $Version, $true, $IncludePreRelease)
#Get installed packages
$package = Find-LocalNuGetPackage -PackageId $PackageId -Version $Version
#Output package install log
Write-Verbose ("Install NuGet package: {0}" -f $Package.ToString())
}
#TODO: Need to support other frameworks
$frameworkName = ".NETFramework,Version=v4.5"
#Load dependent NuGet packages
foreach ($dependency in [NuGet.PackageExtensions]::GetCompatiblePackageDependencies($package, $frameworkName))
{
#TODO:Need to specify compatible version
Use-NuGetPackage -PackageId $dependency.Id
}
#Load referenced assemblies
$items = $null
if ([NuGet.VersionUtility]::TryGetCompatibleItems($frameworkName, $package.AssemblyReferences, [ref] $items))
{
foreach ($item in $items)
{
Write-Verbose ("`tLoad assembly: {0} {1}" -f $item.Name, $item.TargetFramework)
#TODO:Resolve version conflicts
Add-Type -Path $item.SourcePath
}
}
#TODO:Load framework assemblies
#TODO:Import .ps1 script files under "tools" directory
foreach ($file in [NuGet.PackageExtensions]::GetToolFiles($package)){
#Write-Verbose $file.EffectivePath
}
#TODO:Import content files under "content" directory
foreach ($file in [NuGet.PackageExtensions]::GetContentFiles($package)){
#Write-Verbose $file.EffectivePath
}
}
#Export-ModuleMember -Function @(Initialize-NuGetPackageManager,Use-NuGetPackage)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment