Update:
How I NuGet - Creating a NuGet Package – Without a batch file
I started toying around with the MvcContrib project a couple of months ago. Since then, I created a few UI extensions that use the MvcContrib project. I wanted to contribute to the project; however, Jeremy Skinner recommended that I create a NuGet package and distribute my contributions that way. So, that's what I did and this post describes/outlines the steps I used to create the NuGet package.
The source for the MvcContrib UI extensions suggested above is available on CodePlex here:
MvcContrib UI Extensions - Themed Grid & Menu
My assumption is that you are familiar with NuGet. If not, you can read all about it at its
CodePlex project site.
Here is a high level outline of the steps that I used to create my NuGet package:
- Download the NuGet Command Line tool
- Create a generic nuget nuspec file - the nuget manifest file
- Update the nuget manifest with project specific settings
- Create a batch file (.bat) file that will serve as the main entry point into the nuget package creation process
- Create the nuget package
- Submit and contribute the package to the NuGet Gallery
For reference, the following is a snippet of my directory structure used in the MvcContrib UI Extensions. I will reference this structure in the steps below. This image will also help with understanding the batch file used in the steps below.
1. Dowload the NuGet Command Line tool
Easy - download the NuGet command line tool
here. Using our structure above, put the .exe into the MvcContrib.Shp/nuspec/ directory.
2. Create a generic nuget nuspec file - the nuget manifest file
Create the .nuspec file by running the following command from the dos prompt:
nuget spec
This will create a file by with the name of Package.nuspec. All this is is an xml file that describes the details of the package - formally called a package manifest or specification. While renaming this file is not required, I think it makes sense to give it the same name as that of the resulting NuGet package - in our scenario, MvcContrib.Shp.nuspec.
3. Update the nuget manifest with project specific settings
The NuGet
.nuspec file format specification contains many configuration details; however, for our scenario I’ve updated the .nuspec file to contain the following content:
<?xml version="1.0"?>
<package xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<id>MvcContrib.Shp</id>
<version>1.0.0.0</version>
<authors>Dan Ryan</authors>
<owners>Dan Ryan</owners>
<licenseUrl>http://mvcxgridmenu.codeplex.com/license</licenseUrl>
<projectUrl>http://mvcxgridmenu.codeplex.com/</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>UI Extensions to the MvcContrib Project - Themed Grid & Menu</description>
<tags>MVC MVC3 ASP.NET MvcContrib</tags>
<dependencies>
<dependency id="MicrosoftWebMvc" version="2.0" />
<dependency id="MvcContrib.Mvc3-ci" version="3.0.57.0" />
</dependencies>
</metadata>
</package>
The XML elements are pretty self-explanatory; however, I recommend reading the NuGet
.nuspec file format specification for details on each element.
4. Create a batch file (.bat) that will serve as the main entry point into the nuget package creation process
This step is not necessary; however, I like batch files. Batch files give us the ability to place simple, repeatable logic into a batch file and execute that logic by double-clicking the batch file. The following batch file creates a temp directory with subdirectories for the NuGet package content, copies the files (.dll, and .js files) from the source directories and places these files in the temp content directories, executes the NuGet.exe pack command, and then cleans up by removing the temp directories. Again, this could have all been done via the .nuspec file, but I just prefer to use the batch. Here’s the batch file contents:
echo OFF
:: root nuspec directory
set rootDirectory=%cd%
:::::::::::::::::::::::::::::::::
:: 1) build the destination directory structure
:::::::::::::::::::::::::::::::::
:: destination structure
set baseDirectory=basenuspec
set contentDirectory=content
set libDirectory=lib
set scriptsDirectory=Scripts
:: make directory command
set makeDirectoryCommand=MKDIR
:: delete directory command
::set deleteDirectoryCommand=DEL /f
set deleteDirectoryCommand=RMDIR /s /q
:: delete the previous package build files and directories - if they were not deleted before
%deleteDirectoryCommand% %baseDirectory%
:: build the directory structure
%makeDirectoryCommand% %baseDirectory%
cd %baseDirectory%
%makeDirectoryCommand% %libDirectory%
%makeDirectoryCommand% %contentDirectory%
cd %contentDirectory%
%makeDirectoryCommand% %scriptsDirectory%
:: navigate to the root directory
cd %rootDirectory%
:::::::::::::::::::::::::::::::::
:: 2) copy files from source to destination
:::::::::::::::::::::::::::::::::
:: relative path to the MvcContrib.Shp.dll
set srcLibDirectory=..\src\MvcContrib.Shp\MvcContrib.Shp\bin\Release\
:: relative path to source script files
set srcScriptsDirectory=..\src\MvcContrib.Shp\Shp.Web\Scripts\
:: lib files to copy
set libFiles=MvcContrib.Shp.dll
:: script files to copy
set scriptFiles=jquery.mvccontrib*.* superfish.js *jquery.hoverIntent*
:: copy commnad
set copyCommand=COPY /y
:: copy the source dll to the lib destination directory
%copyCommand% %srcLibDirectory%\%libFiles% %rootDirectory%\%baseDirectory%\%libDirectory%\
:: navigate to the root directory
cd %rootDirectory%
:: navigate to the source scripts directory
cd %srcScriptsDirectory%
:: copy the source scripts to the scripts destination directory
for %%F in (%scriptFiles%) do %copyCommand% %%F %rootDirectory%\%baseDirectory%\%contentDirectory%\%scriptsDirectory%\
:: navigate to the root directory
cd %rootDirectory%
:::::::::::::::::::::::::::::::::
:: 3) create the nuget package
:::::::::::::::::::::::::::::::::
:: nuget pack command
set packCommand=NuGet.exe pack
:: nuspec manifest file
set manifest=MvcContrib.Shp.nuspec
:: run the nuget package command
%packCommand% %manifest% -b %baseDirectory%
:: delete the temp package build files and directories
%deleteDirectoryCommand% %baseDirectory%
::PAUSE
The above batch file is pretty much fully documented, so it shouldn’t take too much to understand the logic.
Could I have used PowerShell to do this? Absolutely; however, I really haven't spent much time diving into PowerShell. Until then, the batch solution works just fine.
As a side note - NuGet gives you the ability to add Content to the package (this is essentially what the previous batch file is doing); add pre-processing of files to the client project (the project importing the NuGet package); add XML elements to be merged with the client project's .config files; add PowerShell scripts to do anything else that the NuGet package requires; and a whole laundry list of other functionality. Again, if you're interested, check out the
NuGet Project and Documentation on CodePlex.
5. Create the nuget package
In our scenario, creating the NuGet package is simple. All you have to do is double-click the .bat file and the batch file handles the command to create the NuGet package. The resulting package is compiled into a single file. In our scenario and using the .nuspec file from above, the resulting package is compiled into:
MvcContrib.Shp.1.0.0.0.nupkg. How is the package name composed? The following image identifies the package name components:
6. Submit and contribute the package to the NuGet Gallery
Log into the
NuGet Gallery and contribute your package. What? If you don’t already have an account, request one from the NuGet Gallery. The process of submitting/contributing you package for distribution is as simple as uploading and following the NuGet package wizard.
Useful Links:
Anyway, thanks for reading…