When doing "install-package", nuget will get the latest version from the package source. If I want to constrain the selected version I need to explicitly set the version number. Is there a way to tell nuget to resolve the version from the local packages already installed in the solution?
Example:
package in solution packages folder:
Castle.Core.3.2.0
install-package castle.Core -projectname SomeProjectRequiringCastle
This will download the newest version of Castle (3.3.0), and add it to my packages folder. This is not what I want to do 99% of the time. In order to constrain nuget to select the version number already installed I have to remember the already installed version number:
install-package castle.Core -projectname SomeProjectRequiringCastle -version 3.2.0
My current workflow includes browsing to the packages folder to see whats already installed or opening a packages.config file from a project which already has a dependency on the requested assembly. Ideally I want something like this:
install-package castle.Core -localRepositoryVersion
Is there a way to achieve this behaviour? Or perhaps some nifty commands which can make my workflow around this a bit smoother? Note: The "manage" option under the nuget package manager (GUI) is to mouse-heavy and has already been rejected by my mouse-allergic fingers.
Edit
I wrapped Matts answer (credit to Matt, thanks) up in a function, here is a full solution for the lazy ones:
installLocal.psm1
<#
.Synopsis
Installs a package
#>
function install-local
{
[cmdletbinding()]
Param(
[Parameter(Mandatory=$true, Position=0)]
[String] $Id,
[Parameter(Mandatory=$true, Position=1)]
[string]$ProjectName
)
$version = get-package | ? { $_.Id -eq $Id } | % { $_.Version }
if (-not $version) {
throw "A package with id $Id has not been installed in the solution"
} else {
write-host "Found version: $version of $Id installed in solution"
}
install-package -Id $Id -ProjectName $ProjectName -Version $version
}
export-modulemember -function install-local
Added this line to the powershell profile used by visual studio (which in my case was located at: C:\Data\WindowsPowerShell\NuGet_profile.ps1)
import-module <path to file>\installLocal.psm1
Then I can write one-liners from the package manager console:
PM> install-local moq -projectname LibWhichNeedsDeps
Found version: 4.0.10827 of moq installed in solution
'Moq 4.0.10827' already installed.
Adding 'Moq 4.0.10827' to LibWhichNeedsDeps.
Successfully added 'Moq 4.0.10827' to LibWhichNeedsDeps.
You can probably use the Get-Package command. This lists all the packages installed in the solution.
So you could something similar to:
$version = Get-Package | where-object { $_.Id -eq 'NUnit' } | % { $_.Version }
Install-Package NUnit -version $version
You can turn this into a function and add it to your profile. That would allow you to use a one line command instead of typing all of it in each time. You would want to add some error checking if there is no package that is already installed using that package id.
Another approach would be to just run Get-Package, copy the version you need from the output, then run the Install-Package command with the version number.
Related
I have a local nuget repository (Nuget Server). I need to upload packages from Nuget.Org to my local repository for offline building.
How can I list all packages missing for some solution? I need it to list all missing packages and thier depedecies (if it's missing too).
Is there a way to do it with nuget command line, other tools, powershell script (any other way)?
Found the solution. The powershell command Find-Package can list the package and it's depedencies. Next we can use the same command on each of the required packages to verify they exists in the target nuget reposiroy.
The following powershell script uses that command. It will enumerate the required packages for the specfied package (in nuget.org repository). And than check each package existence in the target repository. It will write to CSV files:
RequiredPackages.csv - The packages that are needed for the specified package
MissingPackages.csv - The missing packages in the target nuget repository
For example, set $inputPackage to "BenchmarkDotNet", replace $inputPackage with you own repository, and the script will write all the missing packages (including BenchmarkDotNet itself if it's missing) that Benchmark dot net uses and are missing in your repository.
$inputPackage = "<Package name>"
$inputPackage = "<target package source url>" #"local nuget repository url"
Write-Output "Enumerating needed packages"
$packages = Find-Package -Source https://api.nuget.org/v3/index.json -Name $inputPackage -IncludeDependencies
Write-Output "Writing needed packages to c:\temp\RequiredPackages.csv"
$packages | Export-Csv .\RequiredPackages.csv
#$packages = Import-Csv c:\temp\RequiredPackages.csv
Write-Output "Checking package existance in local nuget repository"
$missingPackages = #()
foreach($package in $packages)
{
try {
Find-Package -Source $targetNugetRepository -Name $package.Name -RequiredVersion $package.Version -ErrorAction Stop
}
catch {
$missingPackages += $package
}
}
$missingPackages | Export-Csv -Path .\MissingPackages.csv
Write-Output "Done"
The above sciprt can be used manually on the top level packages a solution needs (Or can be automated to read the projects files first).
is there any way to update all packages except one?
For instance when I created new project I need to update all packages except jQuery. It should stay at same version.
You could write a custom script for updating the packages like the following and execute it in the package manager console
$list = Get-package -project {Add project name here}
for($i=0; $i -lt $list.Length;$i ++ ) { if($list[$i].Id -ne "jquery") { Update-Package -project {Add project name here} $list[$i].Id } }
no there is no direct way of doing that. May be you can update all, then uninstall JQuery and install the version of jquery you want.
I'm working on a nuget package that depends on the Unity and Unity.Mvc4 packages. My nuspec file has them listed as dependencies. Everything works, but when my package is installed the dependencies are installed first.
The Unity dependencies deploy files to the root of the project that my package has moved to a different location and customized, as such I don't want those files to exist in the root after my package is installed.
Is there any way to override dependency files in nuspec, or run a powershell script after install to clean them up?
You might add a Powershell script that move those files created by Unity to your actual project root.
For information about executing Powershell scripts during Nuget package installation, see the Nuget documentation. Note that these scripts must be placed within the tools folder of your Nuget package to be automatically executed.
Here's the code in my install.ps1 that did the trick if anyone wants it for reference.
# Runs every time a package is installed in a project
param($installPath, $toolsPath, $package, $project)
# $installPath is the path to the folder where the package is installed.
# $toolsPath is the path to the tools directory in the folder where the package is installed.
# $package is a reference to the package object.
# $project is a reference to the project the package was installed to.
#EnvDTE Project Reference
#https://msdn.microsoft.com/en-us/library/envdte.project.projectitems.aspx
function deleteProjectItem($fileName) {
$file = $null
foreach ($item in $project.ProjectItems) {
if ($item.Name.Equals($fileName, "InvariantCultureIgnoreCase")) {
$file = $item
break
}
}
if ($file -ne $null) {
Write-Host "Deleting: $($item.Name) ..." -NoNewline
$item.Delete()
Write-Host "Deleted!"
}
}
deleteProjectItem "BootStrapper.cs"
deleteProjectItem "job_scheduling_data_2_0.xsd"
deleteProjectItem "Unity.Mvc4.README.txt"
What NuGet PowerShell command will return a list of all versions of a specific package?
I have tried the following, but it only returns one version of NUnit along with a number of other (un)related packages, each having only one version.
Get-Package -Source https://go.microsoft.com/fwlink/?LinkID=206669 -ListAvailable -Filter NUnit -AllVersions
Note: I specify the source URI because we have our own internal package source as our default remote.
My understanding is that the -AllVersions switch should pull back every version of each matching package.
I can't seem to figure out:
Am I doing it wrong?
If not, are project maintainers (or someone else) removing older versions from the package source?
If they are, why?
Your source resolves to the version 1 of the feed which doesn't seem to work with -AllVersions (I filed an issue: https://github.com/NuGet/NuGetGallery/issues/563)
Using the V2 feed works for me:
get-package -ListAvailable -AllVersions -filter nunit -source https://nuget.org/api/v2/
But note that -filter is not for a specific package, but more like a search term.
As a workaround, I'd use tab autocomplete to get the versions list of a specific package:
install-package -source https://nuget.org/api/v2/ -id nunit -version <tab>
As of version 3.x, get-package -ListAvailable -AllVersions will still work, but will issue the following warning about imminent deprecation:
This Command/Parameter combination has been deprecated and will be removed in the next release. Please consider using the new command that replaces it: 'Find-Package [-Id] -AllVersions'.
In addition, Find-Package supports an -ExactMatch switch which will avoid the wildcard matching issues that -Filter has:
Find-Package NUnit -AllVersions -ExactMatch -Source https://api.nuget.org/v3/index.json
To extend on the already provided solutions and address the follow-up questions by King King and JohnKoz, it is possible to get the full list of versions for a specific package as follows:
Find-Package -AllVersions -source https://nuget.org/api/v2/ Newtonsoft.Json -ExactMatch | foreach { $_.Versions } | Select-Object Version
The package Newtonsoft.Json is an example. Replace it as needed.
It works by first getting all versions for a single package (via -ExactMatch). This returns a package object that has a Versions property, which is an array of version objects. The foreach iterates over all these and the Select-Object ensures that each version object is output as a single line (by only selecting its main property).
I have a version of a package installed in my project but during testing I have found a problem with it. I tried the obvious thing Update-Package -Id Foo.Bar -Version 1.0.0 -Force but the Update-Package cmdlet doesn't have a -Force parameter, and it doesn't allow updates to an earlier version. How do I downgrade my package dependencies (without taking advantage of source control!)
NOTE: This question is now irrelevant because Update-Package MyPackage -Version [an earlier version] works out of the box in recent versions of NuGet Package Manager. You don't even need a -Force switch.
I think I already have a solution to this so I place it here for (constructive) criticism.
function Reinstall-Package {
param(
[Parameter(Mandatory = $true)]
[string]
$Id,
[Parameter(Mandatory = $true)]
[string]
$Version,
[Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[string]
$ProjectName,
[switch]
$Force
)
if (-not $ProjectName) {
$ProjectName = (get-project).ProjectName
}
Uninstall-Package -ProjectName $ProjectName -Id $Id -Force:$Force
Install-Package -ProjectName $ProjectName -Id $Id -Version $Version
}
This allows us to use a call such as the following to update all references to a package within the current solution.
Get-Project -All |
?{ $_ | Get-Package | ?{ $_.Id -eq 'Foo.Bar' } } |
%{ $_ | Reinstall-Package -Id Foo.Bar -version 1.0.0 -Force }
The -Force switch allows the package to be reinstalled even if it has dependent packages within the project.
https://docs.nuget.org/consume/package-manager-console-powershell-reference
With NuGet 2.8 client or higher, Install-Package can be used to downgrade the existing packages in your project, if necessary. For example, if you had installed a pre-release version of a package to try out new features but would like to go back to a previous stable version you can do so using Install-Package (or Update-Package).
I had Foo.Bar v1 that depended on log4net v2, I needed to downgrade the log4net dependency to 1.2.10 so i made Foo.Bar v1.1 depend on log4net v1.2.10.
I found that if you Update-Package Foo.Bar it will update to the latest version (it won't reinstall dependencies)
But then you can Update-Package -Id Foo.Bar -Reinstall and that should reinstall the whole thing with the current dependencies.