Thursday, April 14, 2011

The easy way to publish NuGet packages with sources

The standard way to create NuGet packages today is to:

  • Create a nuspec file with all the metadata and package dependencies
  • Lay out the files that to want to include
  • Run ‘nuget pack’ to create the package
  • Run ‘nuget push’ to push them to the gallery

See Phil’s post more more details on those steps.

While this is pretty straightforward, it can be made yet easier if we take advantage of the fact that your VS project already contains a lot of information that shouldn’t have to be repeated.

Today, we are releasing a new nuget.exe feature of that makes this a lot easier.

Debugging support via SymbolSource.org

The other really exciting thing we’d like to announce today is that we have partnered with the folks at http://www.symbolsource.org/ to offer a really simple way of publishing your sources and PDB’s along with your package.

Up until now, there really wasn’t a great way for package authors to let their users debug into the package’s binaries. The user would have needed to download the sources separately from wherever the project is hosted, making sure that they exactly match the state of the binary. They would also need to locate the matching PDBs. That’s pretty hard to get right, and most users would generally not bother.

Now with almost no additional effort, package authors can publish their symbols and sources, and package consumers can debug into them from Visual Studio.

What the package author needs to do

Let’s first play the part of the author of a package that contains an assembly, which itself makes use of a library from another package. Let’s say that other package is Clay as an example.

Step 1: create a project

Let’s start by creating a new Class Library project in VS. I’ll call it DavidSymbolSourceTest.

Step 2: set some metadata on it

This is an often forgotten step, but it is important to set some basic metadata on your assembly. As you’ll see later, it’s particularly important with this workflow. To do this, just open the Properties\AssemblyInfo.cs file and change a few values:

[assembly: AssemblyTitle("DavidSymbolSourceTest")]
[assembly: AssemblyDescription("David's little test package to demonstrate easy package creation")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("David Ebbo")]
// Stuff omitted
[assembly: AssemblyVersion("0.5.0.0")]

Here, I set a description for the assembly, and put my name as the ‘Company’ (which is basically the author). I also changed the assembly version to 0.5.

Step 3: bring in our dependencies using NuGet

Next, let’s use NuGet to bring in our Clay dependency. I assume you’re familiar with the steps to do this, but in case you’re not, start here.

Note that because Clay itself has dependencies, this ends up bringing in 4 packages:

image

Step 4: let’s write some code!

In our library, we’ll just write some simple code that uses Clay:

namespace DavidSymbolSourceTest {
 public class Demo {
     public static dynamic GetPersonObject(string first, string last) {
         dynamic New = new ClaySharp.ClayFactory();

         return New.Person(new {
             FirstName = first,
             LastName = last
         });
     }
 }
}

It just has a little test method with builds a Clay object based on two fields. Pretty boring stuff, but enough to demonstrate the concepts.

Step 5: save your NuGet.org access key

From here on, we’ll be using the NuGet.exe command line tool. Make sure you get the latest from here, or if you already have an older build, run ‘nuget update’ to self-update it.

Now go to http://nuget.org/Contribute/MyAccount to get your access key, and use nuget.exe save it so you don’t have to deal with it every time (so this is a one-time step, not for every project!). e.g.

D:\>nuget setapikey 5a50d497-522a-4436-bf90-b65362e65f52
The API Key '5a50d497-522a-4436-bf90-b65362e65f52' was saved for the NuGet
gallery feed (http://go.microsoft.com/fwlink/?LinkID=207106) and the symbol
server (http://nuget.gw.symbolsource.org/Public/NuGet).

Note: no, this is not actually my key, but thanks for asking! :)

Step 6: specify additional metadata using a nuspec file

In step 2, we added some metadata in AssemblyInfo.cs, which NuGet can directly understand. Unfortunately, some of the NuGet concepts don’t have a matching CLR attribute yet, so we still need a nuspec file to specify the rest.

To create one, just run ‘nuget spec’ from the folder where the csproj is.

D:\DavidSymbolSourceTest\DavidSymbolSourceTest>nuget spec
Created 'DavidSymbolSourceTest.nuspec' successfully.

NuGet.exe detects that the nuspec file is meant as a ‘companion’ to a VS project, and will generate a file with replacement tokens. e.g.

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
  <id>$id$</id>
  <version>$version$</version>
  <authors>$author$</authors>
  <owners>$author$</owners>
  <licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
  <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
  <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>
  <requireLicenseAcceptance>false</requireLicenseAcceptance>
  <description>$description$</description>
  <tags>Tag1 Tag2</tags>
</metadata>
</package>
Note how a number of the fields use a token syntax like $version$. This basically means: I don’t want to repeat what’s already in my AssemblyInfo.cs, so just get values from there.

Now all you need to do is:

  • Fill in the fields you care about, like <projectUrl>
  • Remove the ones you don’t care about. e.g. <iconUrl> if you don’t have an icon.

Note that technically, this whole step is optional, and you can omit the nuspec file entirely if you don’t need any metadata other than what’s in AssemblyInfo.cs. However, since all packages are supposed to specify a <projectUrl> and a <licenseUrl>, in practice it’s not a step you’ll want to skip.

Step 7: create the package

This is where the new and exciting stuff really starts. Go to the folder where the csproj file is and run:

D:\DavidSymbolSourceTest\DavidSymbolSourceTest>nuget pack -sym DavidSymbolSourceTest.csproj
Attempting to build package from 'DavidSymbolSourceTest.csproj'.
Building project for target framework '.NETFramework,Version=v4.0'.
Packing files from 'D:\DavidSymbolSourceTest\DavidSymbolSourceTest\bin\Release'.
Found packages.config. Using packages listed as dependencies
Successfully created package 'D:\DavidSymbolSourceTest\DavidSymbolSourceTest\DavidSymbolSourceTest.0.5.nupkg'.

Attempting to build symbols package for 'DavidSymbolSourceTest.csproj'.
Building project for target framework '.NETFramework,Version=v4.0'.
Packing files from 'D:\DavidSymbolSourceTest\DavidSymbolSourceTest\bin\Release'.
Found packages.config. Using packages listed as dependencies
Successfully created package 'D:\DavidSymbolSourceTest\DavidSymbolSourceTest\DavidSymbolSourceTest.0.5.symbols.nupkg'.

Note that we are passing the -sym flag to the ‘nuget pack’ command, and that we’re giving it as input the csproj file!

The command will build the project if needed, and then create both a regular package (DavidSymbolSourceTest.0.5.nupkg) and a ‘symbolsource’ package (DavidSymbolSourceTest.0.5.symbols.nupkg).

Note how it used the version we had specified in AssemblyInfo.cs in step 2. Likewise, the Author and Description in the package came from there. This happens because of the token replacement logic from step 6.

In addition to the metadata inherited from AssemblyInfo.cs, the package will contain the metadata you explicitly added to the nuspec file, like the Project Url.

And one more thing: it also found our dependency on Clay and added that in the package, again without having to add that explicitly to the nuspec file!

Step 8: push the packages to NuGet.org and SymbolSource.org

Now that we created the packaged, we just need to push them out: one goes to NuGet.org and the other one the SymbolSource.org. This can all be done in one command:

D:\DavidSymbolSourceTest\DavidSymbolSourceTest>nuget push DavidSymbolSourceTest.0.5.nupkg
Pushing DavidSymbolSourceTest 0.5 to the NuGet gallery feed (http://go.microsoft.com/fwlink/?LinkID=207106)...
Publishing DavidSymbolSourceTest 0.5 to the NuGet gallery feed (http://go.microsoft.com/fwlink/?LinkID=207106)...
Your package was published.

Pushing DavidSymbolSourceTest 0.5 to the symbol server (http://nuget.gw.symbolsource.org/Public/NuGet)...
Publishing DavidSymbolSourceTest 0.5 to the symbol server (http://nuget.gw.symbolsource.org/Public/NuGet)...
Your package was published.

Note that we ran ‘nuget push’ on the main package, and it automatically pushed the symbol package at the same time.
And now we’re done, our package is live and ready to be installed from NuGet and debugged with full sources!

What the package Consumer needs to do

Now let’s play the part of the package Consumer that uses this package. Here I’ll demonstrate using a simple Console app, though the steps apply equally well to other apps.

Important note: these steps are more interesting when done on a different machine than the ‘Package Author’ steps! If you do them on the same machine, rename or delete the Author project to make sure VS doesn’t take any shortcuts on you when debugging (which it will!).

Step 1: set up the VS debugger settings

This is a one time setup step. In VS, go under Debug / Options and Settings, and make a few changes:

  • Under General, turn off “Enable Just My Code”
  • Under General, turn on “Enable source server support”. You may have to Ok a security warning.
  • Under Symbols, add “http://srv.symbolsource.org/pdb/Public” t the list. Dialog will look like this:

image

Step 2: create a test console app

Make sure you set its Target Framework to the Server profile (see my previous post).

Step 3: use NuGet to bring in our test package

Here is what you’ll see in the Online tab of the NuGet dialog:

image

Notice that not only our new package shows up on the public feed, but all the metadata and package dependencies are there as well!

Now click Install to install the package and its dependencies.

Step 4: write some test code to use the package

We’ll just call the method we defined and display some output:

using System;

namespace ConsoleApplication12 {
 class Program {
     static void Main(string[] args) {
         var person = DavidSymbolSourceTest.Demo.GetPersonObject("David", "Ebbo");
         Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
     }
 }
}

Step 5: debug into the package!

This is the final step that makes it all worth it! Set a breakpoint on the line that calls our GetPersonObject method and press F5 to start debugging.

When you hit the breakpoint, click F11 and be amazed!

image

Here we are debugging into our new package. Here both the sources and PDB files are coming straight from SymbolSource.org!

Registering with SymbolSource.org

Note that in all the steps below, we never actually went to the http://www.symbolsource.org/ web site. The nice thing is that everything can work without even setting up an account on there. Note that SymbolSource does verify that you own the package by checking with nuget.org using your key.

But even though the registration step is optional, it is recommended that you register with the site in order to be able to manage the symbol packages that you upload there. To register, just go to http://www.symbolsource.org/ and follow the instructions. During registration, you’ll be asked for your NuGet key, which is how your account will get associated with your submissions.

Monday, April 4, 2011

Open your solution files as admin

When you run under UAC (User Account Control), nothing runs as admin by default, and that’s a good thing! But sometimes, you do need to run some things as administrator.

There are a few well known ways of doing this. You can right click on an EXE and choose ‘Run As Admin’. Or if you have the app pinned on your taskbar, you can Ctrl-Shift click it to run as admin. If you don’t know those tricks, you should learn them as they often come handy.

However, there is one common scenario for which there is no well documented technique: how do you launch a program as admin from a data file? Taking a particularly interesting example, how do you launch Visual Studio as admin from a .sln file?

First, you try the obvious and right click it, hoping to see the familiar ‘Run As Administrator’ item. But no luck there:

image

While this at first appears hopeless, it turns that there is a way to do this by adding some simple things to your registry.

The general technique is explained here (thanks to @meligy for pointing me to it). The post describes how to do it for any file type, but I can save you a bit of time by giving you the reg change you need to make (and it’s not scary!):

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\VisualStudio.Launcher.sln\Shell\runas\Command]
@="\"C:\\Program Files (x86)\\Common Files\\Microsoft Shared\\MSEnv\\VSLauncher.exe\" \"%1\""

Just save that in a foo.reg file somewhere and run it. After you do that, right clicking on a .sln file will look like this:

image

And that’s it, just what we wanted!

Final note: my reg file above is hard coded to “C:\\Program Files (x86)”, which won’t work on all systems so you may need to adjust things. I tried to change it to use the ProgramFiles(x86) env variable but I couldn’t make that work in the registry. Seems default values can’t be REG_EXPAND_SZ? Let me know if you know how to do this!

Friday, April 1, 2011

New pricing model for NuGet

Update: In case that's not totally obvious, this post was an April Fool's hoax. A number of people got briefly fooled on the day, which was the idea! Now that April 1st is behind us, I may as well make this super clear :)

Since we launched NuGet in January, its popularity has grown faster than we anticipated. A couple days ago, we reached an important milestone with over 1000 unique packages (see http://stats.nuget.org/ for more fun numbers).

Up until now, NuGet has an been entirely free offering both for package authors and consumers. This free model has surely helped contribute to the growth of NuGet, and we are glad to have taken this approach.

Now that NuGet is more mature and has reached fairly wide acceptance, we have decided to switch to a pay model. This is actually something we had been planning from the start, but we chose not to announce early as it may have hindered our initial growth.

How will the pay model work

For the most part, it will be similar to the pricing models used in popular phone app stores (though apparently we can’t use that term!). There will be a mix of free and pay packages, based on the author’s decision.

As an example, the basic Fart package might be free, while SuperFarter will be priced at 99c. The more feature rich MegaFarter package may cost as much as $2.99 with all the bells and whistles, though in the end the pricing decision is up to the author.

When you buy a package, you will be allowed 10 downloads of that package for free, after which you will be able to ‘reload’ your purchase at the original price to get 5 more downloads. Why not allow unlimited downloads once you buy a package? Based on our studies, we found that not only the patented ‘reload’ model will end up being more profitable, but by making the user think a bit more about where they choose to use a package, the average quality of the resulting software actually increases (this surprised us as well, but the results were clear).

So that’s the story for the consumer, but what about the author? We deliberated for a while on this, and decided on sharing as much as 5% of the package income with the author. That number was partially inspired by the fact that it is tax season, and that the Beatles wisely wrote in their Taxman song:

Let me tell you how it will be. There’s one for you, nineteen for me. Should five per cent appear too small. Be thankful I don’t take it all.

The last part is key, as we will in fact reserve the right to take it all in certain scenarios.

Everyone is #winning!

While this is a departure from the current model, this new pricing model will end up benefiting everyone:

Authors win by getting a share of the revenue. To put the 5% in perspective, everyone 20 million downloads of your 99c package, you’ll be making almost a million dollars. We’re talking real money!

Consumers win by getting higher quality packages. With the current free model, there isn’t as much incentive for authors to put hard work into their packages. But with money at stake, we expect it’ll be a different landscape. So packages will do things that you don’t even know are possible today.

Last but not least, the NuGet team wins. Most of the money will end up there, so that should be self-obvious. But we will put it to good use. For instance we will upgrade our cars, which will allow us to get to work fresher in the morning, and make NuGet even more awesome that it is today.

I hope you are all sharing our excitement about this game changing announcement!