While trying to get a nuget build workflow working on Linux/mono, I've noticed an odd thing.
Being on Linux, I cannot use the nuget Visual Studio plugin or the Powershell console, but I have the nuget.exe command-line utility. This utility has an "install" command which properly fetches packages and places them in my packages directory.
However, nuget.exe's install (as opposed to the Visual Studio install) doesn't appear to update packages.config with the packages it added, nor does it add project references to my .csproj. The latter is less important (I can do it manually), since the packages.config needs to contain recursive dependencies as well I can't do it manually...
Has anyone else tried to install new packages solely using nuget.exe or has any insight into this? Am I barking up the wrong tree entirely?
As it currently (Nuget 2.8.1) stands, this is still not possible and a major shortcoming of the nuget command line client, as I see it.
Nuget.exe must be able to install a package and add it to the packages.config with all dependencies to be usable for anything more than the most simple cases.
I have created an issue, see https://nuget.codeplex.com/workitem/4258
Workaround
For the time being, the following approach can be used. Note that it is far from optimal, but at least enables you to use nuget and resolve dependent packages correctly.
Resort to managing the packages.config manually. Add the packages you need, but omit their dependencies. Note that this is different from "ordinary" packages.config files, which do list the dependencies as well.
Use a script to walk the packages.config and issue a nuget install <package-id> -Version <version> for each package. This will install the package and its dependencies.
I think a better workaround is to use the technique described here to generate a PCM command that will install multiple packages in one go.
Here's a small proof of concept that copies the final command to the clipboard:
param([string[]]$dependencies)
$command = "";
foreach($dependency in $dependencies)
{
$name = $item.Name
if($dependency)
{
$command += ('"{0}", ' -f $dependency)
}
}
$command = $command.Substring(0, $command.Length - 2) + " | foreach {Install-Package `$_}"
$command | Set-Clipboard
Related
We have a solution that contains a project that uses TestFramework from NuGet.
We've another solution that references that project.
The project/solution file system structure looks like this:
- Tests
- Tests
- Properties
- AssemblyInfo.cs
- packages.config
- Tests.csproj
- Tests.sln
- RefToTests
- RefToTests.sln
RefToTests.sln contains a reference to Tests.csproj.
If I open the Tests.sln and try to build it I get an error that tells me that the referenced NuGet dependencies could not be found. No problem - open the NuGet management for solution, click restore and build it again. Works fine.
The same clean folder but now open RefToTests.sln. Same error. Same workflow. That restores the packages to RefToTest\packages. The project is looking for them at ..\packages what means Tests\packages. That will not build.
We tried to fix that by manually change the folder to the packages in the project file from ..\packages to $(SolutionDir)packages. That worked great. The missing packages are downloaded automatically (wow that doesn't work without that change).
But now let's update the package. The package manager is not able to find that references in the project file, leaves the old entries untouched and added completely new references. The project won't build in any solution. That seams to be a bug in NuGet project management. In my opinion the package resolution should crash if it finds $(SolutionDir) or the package management should be able to handle that.
But what is the solution? Changing the directory to $(SolutionDir) and check every project file after every update? Leave the specified folder as it is and never do a cleanup on the repository?
I am using git, nuget, and Visual Studio 2015 on a Windows machine.
I have a project that I have made that gets built into a content-only nuget package. The content of the package is two files:
File1.ttinclude
File2.ttinclude
These files MUST have CRLF line endings. I thought this was the default for Windows. I've tried all sorts of git settings and have settled on the following in my global git settings:
autocrlf = false
I can push the files to a remote repo and clone the remote remote and the files appear to still have CRLF line endings.
My issue is when I try to include that nuget package into another project.
Whenever I run install-package (or do it from the package manager) the files get added to the project with LF line endings and all hell breaks loose.
I've tried autocrl=true, I've tried adding *.ttinclude text eol=crlf to .gitattributes for the nuget package and the project that needs to include the package. Nothing seems to work and I'm at a loss.
How can I get nuget to install the content-only package and keep the correct line endings?
I've created the following git alias that I currently use when adding that nuget package to a project. It fixes the line ending issue until that nuget package is updated.
alias.fixeol=!git add . -u && git commit -m "start eol fix" && git rm --cache -r . && git reset --hard && git add . && git commit -m "end eol fix"
UPDATE 1:
I just thought of this, because it also may be the issue. We use TeamCity as our build server and that's what's building the nuget package from my source. I didn't set it up though so I'm not 100% how it's setup. Does git on the build server also need to be setup a certain way? What about TeamCity settings?
UPDATE 2:
So I just inspected the nuget package contents of the .nupkg and the line endings are LF, so it must be the build server. Now I just need to figure out what git needs to be set to on the build server and will changing it screw up other projects?
UPDATE 3 - SOLVED:
It was a TeamCity issue.
https://confluence.jetbrains.com/pages/viewpage.action?pageId=48105844
Setting 'Convert line-endings to CRLF' option to true fixed the issue. Of course, I'm not sure why it was an issue to begin with. I have autocrlf=false locally. The files are CRLF. If not setting that feature is equivalent to TC having autocrlf=false then shouldn't it have just worked? Currently I've only set that option to true on this particular project since it's just a content-only package which requires CRLF. I'm not sure how it would affect other projects.
I've tried adding *.ttinclude text eol=crlf to .gitattributes for the nuget package
That is the right solution: always set core.autocrlf to false, and rely on eol directives. Although see "Why isn’t eol=crlf honored in .gitattributes?":
I’d misunderstood what git actually does when marking a file with the text attribute. It always stores the files with LF line endings internally and only converts to CRLF on checkout
So another approach, if you don't need to compare version and if those .ttinclude files don't change much or ever, is to:
use *.ttinclude -text
save and commit them with CRLF.
Note that with TeamCity (which is using JGit), .gitattributes were not supported (until recently?):
issue TW-16530
Bug 301775
issue TW-44834
I hired a contractor to do some coding for me. He setup nuget.config in the solution folder with the following repository path:
<configuration>
<solution>
<add key="disableSourceControlIntegration"
value="true" />
</solution>
<config>
<add key="repositoryPath"
value="../lib" />
</config>
</configuration>
And I'm not too happy about his decision: this will place the nuget package folder outside the solution folder. I can easily change the repository path, simply by setting:
value="../<mySolutionFolder>/lib" />
However when I do this a curious thing happens: every single reference that I use in my solution is now broken. And nothing that I change in the .csproj files or other *.config files will allow my projects to find their references.
The only workaround is to re-create each project in my solution by starting from scratch, and add->existing items, etc. and reference->manage nuget packages, and install every reference again.
I have many projects in my solution and performing this for every one is understandably time consuming.
I would like to know if there is an easy way?
It seems like there should be a way for Nuget and VS to play nicely so that I can easily move the repository folder to a different path location.
One way to fix the reference paths is to use the Package Manager Console.
From the Package Manager Console you can run the following command to reinstall the NuGet packages which will fix the hint paths for the references.
Update-Package -reinstall
This will reinstall all NuGet packages in the solution. I am assuming you have the code under source control so you can see what changes are made to the projects if you need to revert them after this reinstall.
There is more documentation on reinstalling NuGet packages on the NuGet documentation site.
Another way to fix this is to do a find and replace in the .csproj files to fix the hint path.
I encountered this problem when I moved the actual folders around in my solution. I usually do a find/replace with VS Code looking for >..\packages\ and replace it with >..\..\packages\. This time I did the following:
Perform Update-Package -Reinstall
this worked for everything with hint paths
does not work when your project uses NuGet packages to build your project because there are custom MSBuild statements that need to be manually fixed, see next step.
Edit the .csproj files manually that do not build, in my example:
<Import Project="..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.8\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.8\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
<Import Project="..\..\packages\Microsoft.Net.Compilers.2.4.0\build\Microsoft.Net.Compilers.props" Condition="Exists('..\..\packages\Microsoft.Net.Compilers.2.4.0\build\Microsoft.Net.Compilers.props')" />
Notice that there are 2 condition statements in the <Import> that use relative pathing to ..\..\packages.
Hopefully these steps will help someone else.
Package.config is used for put file somewhere else from the folder, it help best to not upload package unusually when you add something in your project through Nuget.
Try to copy the package to that folder (new path you set) or simply close the project, open it again and click on Restore after going to Manage project reference.
After trying all solutions posted here I could not escape one primary issue: references to non nuget items, such as System and System.Core remained invalid (yellow triangle listed next to them). Removing them and adding them did not make them valid again. Further (as we all know) Visual Studio is terrible and giving reasons for why a reference is considered invalid.
So while Matt's solution does indeed relocate the nuget package folder, the solution in not left in a working state. Further, updating hint paths did not help because those are specific to the nuget packages. I cannot explain why basic references suchas System also become invalid. Perhaps someone reading this a year from now can leave a message with an explanation.
What I ended up doing is rebuilding my entire project without a nuget.config file (I deleted it). This causes nuget to use all defaults. Downloaded packages get stored in \\<solution_folder>\packages\. After the solution was working again, I added back the nuget.config file but with the following removed:
<config>
<add key="repositoryPath"
value="../lib" />
</config>
...and removing that section causes nuget to rely on default behavior which turns out to be exactly what I wanted (installing packages to \packages, etc).
If anyone else is about to undertake this laborious effort, I found this SO solution helpful for moving folders and files from the old solution to the new one.
I managed to do this to my own solution without realising how (and ended up with a packages folder at the *.sln level and another one at The level below that) - but I'm pretty sure now that this all has to do with migrating from using a packages config file, to the new method of using package references. This can occur if you use a newer version of visual studio (which is possibly what your contractor did) or via a button/commend in NuGet, or via a right-click context menu.
One of the things that happens is the creation of a 'global' packages folder (the one at .sln level) which is meant to save your space since it means you can have multiple solutions using the same package without having huge duplicate package folders repeated in every solution.
I found this out when I was merging The text is two csproj files and needed to Google: import project difference to package reference
See https://learn.microsoft.com/en-us/nuget/reference/migrate-packages-config-to-package-reference
I have put a library that my team uses into a nuget package that is deployed from TeamCity into a network folder. I cannot debug into this code though! SymbolSource is one solution I have read about but I would much rather find some way to have access to the .pdb/source files directly from TeamCity. Does anyone know how to do this?
Edit. When I check 'Include Symbols and Source' in the Nuget Pack build step, TeamCity creates a .Symbol.nupkg in addition to the .nupkg file in the network folder. The .Symbol.nupkg contains the src and the .pdb file.
Edit. I unchecked 'Include Symbols and Source' on TeamCity and added the following to my nuspec file:
<files>
<file src="..\MyLibrary\bin\release\MyLibrary.dll" target="lib\net40" />
<file src="..\MyLibrary\bin\release\MyLibrary.pdb" target="lib\net40" />
<file src="..\MyLibrary\*.cs" target="src" />
<file src="..\MyLibrary\**\*.cs" target="src" />
</files>
This added the dll, the pdb, and the source files for my library in the nuget package and didn't generate a .Symbols file which I think is only needed for symbol servers.
Traditional method
Put the pdb in the NuGet package alongside the dll.
Add the source code to the Debug Source Files for the solution that references the package.
This means you'll be able to step through code and view exceptions, but you might have to find a file on disk and open it before you can set a breakpoint. Obviously you need to be careful that the source is at the right revision.
More detail on step
If you're currently packaging without a Nuspec, you'll need to create a Nuspec, then add the pdb to the list of files in the lib folder "NuGet spec" may be a useful command for generating the initial spec as defined in NuGet docs. Then ensure the Team City Nuget Pack step is referencing your new nuspec.
More detail on step 2
When you have a solution open, right click on Solution, select Properties...Common Properties...Debug Source Files, and add the root source directory for the relevant binary reference. Or see MSDN.
Note, you can't open the solution properties while debugging.
Still not hitting breakpoints?
Try disabling this from Tools->Options:
Modern way for public or private repos
To ensure the exact version of the source is available, embed it at build time.
From Visual Studio 2017 15.5+ you can add the EmbedAllSources property:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<EmbedAllSources>true</EmbedAllSources>
Modern way for public repos
To keep your nuget and library size small, you can use the sourcelink package.
It generates a pdb that directs the debugger to the correct version of the file from your VCS provider (e.g. GitHub, BitBucket).
The latest version of dotPeek (free!) can act as a symbol server and generate pdb files on the fly. This has allowed me to debug into the dlls that are served via teamcity.
Download it here:
http://blog.jetbrains.com/dotnet/2014/04/09/introducing-dotpeek-1-2-early-access-program/
Instructions on how to set it up here.
https://web.archive.org/web/20160220163146/http://confluence.jetbrains.com/display/NETCOM/dotPeek+Symbol+Server+and+PDB+Generation
You could of course set-up & configure your own symbol server, but it's probably easiest to...
download and install Inedo's ProGet
enable symbol serving on the target feed
publish packages from TeamCity to the ProGet feed
use ProGet as your primary feed source (as it can aggregate multiple feeds including nuget.org)
All of this can be done with the free edition of ProGet.
disclaimer -- my day job is at Inedo
In your .nuspec (directly under <package>):
<files>
<file src="bin\$configuration$\$id$.pdb" target="lib\net451\" />
</files>
(change net451 to the platform you're compiling for)
If you have the source code for the package, then the foolproof (but possibly laborious) method is:
Add the source code for the package to your solution (right click Solution -> Add Existing Project)
Go through all of your projects in the solution and remove the NuGet reference to the library (i.e. open the References folder under each project and delete the reference to the package.) Then, add a reference to the NuGet package project in your solution. (i.e. Right click References, add Reference, choose Projects and tick the box for the project)
I had to do it this way when I the method I wanted to debug inside the NuGet package was called by the framework and not by my code, thus I couldn't step into it. (In my case, the method was an ASP.NET DelegatingHandler).
Once you're done you'll want to undo all your changes via source control so that the NuGet package is referenced correctly.
I've found a super simple way to do this, which I have blogged about here:
https://mattfrear.com/2017/11/29/speed-up-development-in-a-nuget-package-centric-solution/
This only works if you're using the new .NET Core style .csproj with <PackageReference> (on either .NET Core or .NET Framework).
This again assumes you have access to the source code of the NuGet package.
Build and compile the NuGet package on your local machine
Copy the .dll you've just compiled into your local NuGet packages feed folder (On my machine, this is C:\Users\matt\.nuget\packages\), overwriting the existing NuGet package .dll.
That's it! You should be able to step into the package while debugging. No messing around with .pdbs or source servers. This has greatly sped up my development cycle.
Since this question was originally posted, Jetbrains have written an entire blog post on how to accomplish this. The steps can be summarised as:
Install Debugging Tools for Windows on the agents.
Install & Enable the Symbol Server plugin.
Add Symbol Files Indexer build feature to your build configurations.
Ensure PDB files are output as an artefact.
Configure Visual Studio to use TeamCity as source server.
If you are using Nuget Package build steps, you can check 'Include Symbols and Source' to output a .symbol.nupkg which contains the PDBs. Depending on whether the Symbol Files Indexer is smart enough to look inside this file or not, you may need to change the file extension for things to work.
The full details are given here:
https://blog.jetbrains.com/teamcity/2015/02/setting-up-teamcity-as-symbol-and-source-server/
This is what I have found to work, but all the steps are probably not required...
Note: this doesn't allow you to debug both, only either the nuget
package or the solution in which it is installed.
Run Visual Studio as Administrator
Open and Start the host application (the one in which you installed the Nuget package) without debugging (Ctrl + F5)
In the Nuget package solution, ensure that Tools > Options > Debugging > General > "Require source files to exactly match the original version" is NOT checked.
Ensure that "Enable just my code" is NOT checked
Add a new folder in Tools > Options > Debugging > Symbols pointing to the source directory of the Nuget package. (You literally enter the folder path , see image below)
Click Debug > Attach to Process...
Find iisexpress (there may be multiple, it won't do any harm attaching to all)
If your code is in a public Git repository, or, at least in your network, is accessible without authentication, then GitLink would be an option:
https://github.com/GitTools/GitLink
GitLink makes symbol servers obsolete by changing the PDB to point to the Git server. But, as said before, this makes it necessary for the Git repository to be public - until now there's no "proper" way to authenticate when accessing a private repository.
Microsoft has now integrated the SourceLink NuGet package at https://github.com/dotnet/sourcelink/ which allows source code to be downloaded on demand while debugging if the publisher of the NuGet package sets it up.
How can I download a NuGet package? I don't have the NuGet Visual Studio extension or the command line program nuget.exe. How can I download the .nupack file from the web? As I understand I will be able to extract the .dll files from it (with 7-zip) to use as normal.
The package I happen to be interested in is http://nuget.org/packages/Microsoft.Bcl.Async, but I would like to know how to do this generally.
In the world of Ruby this would be easy - every package page on the RubyGems website has a download link to a .gem file, e.g.: https://rubygems.org/gems/pony
The argument over NuGet's manifest destiny belongs elsewhere. It doesn't matter to this question why I eschew it. I'm not the only one though.
Either make an account on the Nuget.org website, then log in, browse to the package you want and click on the Download link on the left menu.
Or guess the URL. They have the following format:
https://www.nuget.org/api/v2/package/{packageID}/{packageVersion}
Then simply unzip the .nupkg file and extract the contents you need.
Although building the URL or using tools is still possible, it is not needed anymore.
https://www.nuget.org/ currently has a download link named "Download package", that is available even if you don't have an account on the site.
(at the bottom of the right column).
Example of EntityFramework's detail page: https://www.nuget.org/packages/EntityFramework/:
(Updated after comment of kwitee.)
Based on Xavier's answer, I wrote a Google chrome extension NuTake to add links to the Nuget.org package pages.
To obtain the current stable version of the NuGet package use:
https://www.nuget.org/api/v2/package/{packageID}
I haven't tried it yet, but it looks like NuGet Package Explorer should be able to do it:
https://github.com/NuGetPackageExplorer/NuGetPackageExplorer
(or like Colonel Panic says, 7-zip should probably do it)
Go to http://www.nuget.org
Search for desired package. For example: Microsoft.Owin.Host.SystemWeb
Download the package by clicking the Download link on the left.
Do step 3 for the dependencies which are not already installed.
Store all downloaded packages in a custom folder. The default is c:\Package source.
Open Nuget Package Manager in Visual Studio and make sure you have an "Available package source" that points to the specified address in step 5; If not, simply add one by providing a custom name and address. Click OK.
At this point you should be able to install the package exactly the same way you would install an online package through the interface. You probably won't be able to install the package using NuGet console.
Don't know if this is what you want, but here it is:
Download nuget.exe (∼6.5MB, no install required) from the official NuGet site: https://www.nuget.org/downloads
In CLI type following to retrieve list of available packages: nuget.exe list -source <source-url-here>
Then download the package by typing this: nuget.exe install <package-name> -source <source-url-here> -OutputDirectory <download-directory>
Contents of the downloaded package are the .nupkg file, .dll files for x86 and x64 as well as .props and .targets files. BTW: .nupkg can be opened as a .zip file.