Friday, September 4, 2015

Automatic Restore from Nuget

Package managers like Npm,NuGet etc. in short span of time became the first choice for managing any external/internal dependency. It not only makes resolving dependency easy but also imposes to best practice like versioning. If you are still skeptical about it, I recommend open your visual studio and give it a try. Here is a nice article about it https://docs.nuget.org/create/hosting-your-own-nuget-feeds

I spent quite an amount of time figuring the best way to use Nu-Get and how can we make hassle free.I don't recommend throwing all your internal dependency as NuGet package rather you should divide your application into independent components and if each component is candidate for independent development and can have multiple versions in future then NuGet is your best bet.

Working with NuGet in visual studio is very easy, all you have to do is add your local nuget server address in available package source and use it to resolve any dependency.




When any nuget reference is added to a solution, Nuget will maintain its own artifacts in solution and project level.
Project level will contain only one file called package.config which contain the dependent package information like version,framework,id.

Solution level will contain a hidden folder of .nuget which contain
  1. NuGet Config 
  2. NuGet.exe (Can be excluded from source control)
  3. NuGet.targets


.NuGet folder is important if you want to have automatic restore - which means when you build visual studio will try to look for external dependencies and in case its not able to locate it will initiate nuget.exe application to resolve them using details from configurations present either in NuGet.config in solution directory or %ProgramData%\NuGet\Config\.Nuget also maintain its own local cache @ %LOCALAPPDATA%\NuGet\Cache\ and in case if its able to find the NuGet package in local cache it won't go out to probe your NuGet feed server.

So if we want automatic restore this .nuget folder is of great significance.I think the best way to maintain a coherent restore mechanism is by defining the configurations as part of NuGet config file and add it to source control. When other member downloads a version of code he will have exact same configuration to restore which will save lot of hassles.To enable automatic restore you can either go to solution right click and there will option of Enabling automatic restore or you can do via configuration

So two important thing to add in configuration to enable automatic restore, is  add true key for package restore  and add NuGet server address optionally, in-case you want to use your own server.





This will allow us to force the configuration for everyone who downloads the code.To make this more fun we can automate the NuGet restore by creating a small batch file.


 @echo off  
 REM Check the nuget application is installed as part of Local App Data   
 SETLOCAL  
 SET CACHED_NUGET_LOCATION=%LocalAppData_LOCATION%\NuGet\NuGet.exe  
 REM If installed then copy to local project folder   
 IF EXIST %CACHED_NUGET_LOCATION% goto copynuget  
 REM Download the file   
 echo Downloading latest version of NuGet.exe...  
 IF NOT EXIST %LocalAppData_LOCATION%\NuGet md %LocalAppData_LOCATION%\NuGet  
 REM - This is command which need the powershell latest version so discontinue it as many CDK systems run old window 7   
 REM powershell -NoProfile -ExecutionPolicy unrestricted -Command "$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest 'https://www.nuget.org/nuget.exe' -OutFile '%CACHED_NUGET_LOCATION%'"  
 powershell -NoProfile -ExecutionPolicy unrestricted -Command "$ProgressPreference = 'SilentlyContinue'; (New-Object System.Net.WebClient).DownloadFile('https://www.nuget.org/nuget.exe', '%CACHED_NUGET_LOCATION%')   
 REM Copy the nuget to local directory   
 :copynuget  
 echo NuGet.exe exists.Initiating package restore.....  
 IF EXIST .nuget\nuget.exe goto restore  
 md .nuget  
 copy %CACHED_NUGET_LOCATION% .nuget\nuget.exe > nul  
 REM Run package restore command   
 :restore  
 echo Deleting cached package .....  
  del %LocalAppData_LOCATION%\NuGet\Cache\*.nupkg /q  
  echo Initiating package restore.....  
 .nuget\NuGet.exe restore -ConfigFile ".nuget\NuGet.Config"  
 echo Success!!!  


Place this batch file in solution root folder in same path of .NuGet and execute this. Remember to not add package folder to source control,it will defy the whole purpose of adding using NuGet.

Okay so guys enjoy flexibility!

Update - Newer versions of msbuild already have the nuget restore feature out of the box so if you need to do restore during build. Just enable NuGet Restore and you are good.

No comments:

Post a Comment