One thing we’ve ran into while developing our .NET core test automation framework is dealing with local nuget packages. If your workflow remotely resembles the one that we use around here for our framework then you’ve undoubtedly run into the same issues. Imagine that you have multiple projects, one of those projects generates a nuget package that you need to use in your other projects. You want this setup to be available to you even without internet. This rules out pushing the package to a remote location or cloud. Perhaps we can install the nuget package into the project directly from the nuget package project build folder? Bonus points if nuget manager keeps working with the online repository as well.
meat and potatoes
We’ll be focusing on Linux and .NET core, as that is what I’m using at the time of writing this blog post. To keep things short we’ll assume that you have the .NET core SDK installed and a project or two set up and ready to go. Let us also avoid using Mono and its way of managing nuget packages as that will only complicate things further
Cut the crap, how do I do this?
Method 1: passing the source as parameter
We can just tell dotnet where to go looking for the package. For this we use the –source flag followed by the directory our nuget packages resides in. The full command would look something like this:
dotnet add package seleniumdotnetcoreframework --source /mnt/shared/source/SeleniumCoreFrameworkNet/ClassLibrary1/bin/Debug or dotnet add package --source
Method 2: configuration file
If for some reason you are lazy like me and don’t want to add a source parameter behind every command then this is a solution for you. This method relies on a config file that needs to be set in the root of your project directory (that is where your csproj file resides). Do note that the filename is CaSe SeNsiTive, including the extension part. If you mess this part up then it will not work as dotnet will not be able to find the file. When the file has been created we add some magic sauce within this file. If you’ve used dotnet to create your project from scratch then this file might already exist. In that case edit the file to look like the example below. In Nuget.Config, add the following lines:
<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <add key="local-packages" value="../SeleniumCoreFrameworkNet/ClassLibrary1/bin/Debug" /> </packageSources> </configuration>
Now try adding the package again as you normally would, but omit the –source parameter this time. The command would then look like dotnet add package seleniumdotnetcoreframework. Do not forget to change the value to the correct path. As far as I’m aware the path can only be relative to the Nuget.Config file and cannot be an absolute path. (may change in future versions of .NET core)
Doesn’t work? Try these tips
As already declared above, Nuget.Config is case sensitive and the path you put within the value parameter must be a relative path to your Nuget.Config file. Still doesn’t work? There are some other things to take into account. When your local package ID matches a package ID on the online repository of nuget.org then the online repository takes precedence over your local package. This can have a myriad of side effects from installing the wrong package to throwing odd errors like error:
Package 'seleniumdotnetcoreframework' is incompatible with 'all' frameworks in project '/mnt/shared/source/demo-dotnetcorefra mework/demo-dotnetcoreframework.csproj'.
Setting up a local nuget package source is not that hard in retrospect. There are a few gotchas you need to keep in mind but with some Google-fu or this post it should be smooth sailing. I have not yet found a way to set a package source globally instead of on a per project basis. Perhaps that can be the subject for a future post. I can’t guarantee that this method works on Windows or MacOs seeing as I only tested this out on Linux, but I don’t see an immediate issue that would cause different behavior under those operating systems. I’d wager it just works on those as well.
QA Test Engineer