Converting a Powershell script to a NuGet command

Last week I posted about the NuGet.Downloader package, which had begun life as a Powershell script. If you've got a Powershell commands that you'd like to make available in NuGet packages, here's how.

Write Powershell scripts that are easy to convert to NuGet packages

I've been looking at the contents of NuGet packages for a while. Since a .nupkg file is really just a zip file, you can extract them if you want, but it's just gotten even easier with the new NuGet Package Explorer. Download the Package Explorer, open the MvcScaffolding package (File / Open From NuGet Feed) and browse through the Powershell scripts in the tools folder.

The main lesson I'd learned from reading other peoples' scripts was that you add Package Manager commands by writing functions in the global namespace with parameters, like this:

Init.ps1 runs the first time a package is installed in a solution. If the same package is installed into additional projects in the solution, the script is not run during those installations. The script also runs every time the solution is opened. For example, if you install a package, close Visual Studio, and then start Visual Studio and open the solution, the Init.ps1 script runs again

Install.ps1 runs when a package is installed in a project. If the same package is installed in multiple projects in a solution, the script runs each time the package is installed. If a package is not installed into a project (such as the MvcScaffold package), the script runs when the package is installed into the solution. The package must have content/dll that will be added to the project for this to run. Just having something in the tools folder will not kick this off.

Uninstall.ps1 runs every time a package is uninstalled.

The init script is where you add Package Manager commands to a package – although it can load scripts in other directories as well - you can really see this in action in the MvcScaffolding package, which adds a lot of commands to create scaffolds.

There are two ways to go here - you can use the NuGet Package Explorer or you can go the manual way. I wanted experience with the manual approach first, so that's what I did. In the future, I think I'd probably just use the Package Explorer.

A .nupkg is just a zip file which contains some standard things:

/lib contains binaries that you'll be adding as references

/content contains code, configuration, and other non-dll files that you'll be adding to the project

/tools contains command-line programs and scripts to support the package

This bundle also includes a manifest which is built from a simple XML specification file (.nuspec).

In this case, it looks like this:

Creating the nuspec file is pretty simple. You can just build one based on the specification, or you can create a shell nuspec file by running the NuGet.exe with the spec option:

C:\path\>nuget spec
Created 'Package.nuspec' successfully.

That creates an empty Package.nuspec file in the same directory with the following contents:

From there, it's just fill in the blanks. Here's the nuspec file for the NuGet.Downloader package:

<?xml version="1.0"?>
<package>
<metadata>
<id>Nuget.Downloader</id>
<version>1.0.0.5</version>
<authors>Jon Galloway,Eric Hexter</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Download packages from a remote feed to a local directory</description>
<summary>Download packages from a remote feed to a local directory. Adds one command: Download-Packages By default, only pulls the top 100 packages by download count. Inspired by Steve Michelotti's local repository PowerShell script.</summary>
<language>en-US</language>
<projectUrl>http://weblogs.asp.net/jgalloway/archive/2011/02/02/downloading-a-local-nuget-repository-with-powershell.aspx</projectUrl>
<tags>nuget</tags>
</metadata>
</package>

One important thing to notice here is the version - you'll need to update that when you build. There are all kinds of smart ways to automate this - e.g. adding this to you build process - but, hey, this is a one file package so I will mark that as Closed - Won't Fix for now.

Now it's time to build the package. With everything in place, we can just run NuGet.exe with the pack command. I'd recommend - at least as you're getting started - to pack test the package locally (adding it to your local repository), then do a push.

Yes, I should probably use pushd and popd instead of cd. Running that builds and pushes the package, though:

C:\what\are\you\looking\at>..\Nuget.exe pack
Attempting to build package from 'Nuget.Downloader.nuspec'.
Successfully created package 'C:\path\Nuget.Downloader.1.0.0.5.nupkg'.
C:\stop\looking\at\the\path\>..\Nuget.exe push nuget.downloader.1.0.0.6.nupkg APIKEYGOESHERE
Publishing Nuget.Downloader 1.0.0.6 to the live feed...
Your package was published to the feed.

And just like that, your Powershell command has become a NuGet package that's published for all the world to use.

suppose you added a little content? I mean, I don't wish to tell you how to run your website, but what if you added something that makes people want more? I mean Converting a Powershell script to a NuGet command - Jon Galloway is kinda plain. You could glance at Yahoo's front page and watch
how they create news titles to grab viewers interested. You might add a
related video or a picture or two to grab people excited about everything've written. In my opinion, it would bring your website a little livelier.