<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Rob Reynolds - The Fervent Coder : NuGet</title><link>http://devlicio.us/blogs/rob_reynolds/archive/tags/NuGet/default.aspx</link><description>Tags: NuGet</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>this.Log– Source, NuGet Package &amp; Performance</title><link>http://devlicio.us/blogs/rob_reynolds/archive/2012/12/19/this-log-source-nuget-package-amp-performance.aspx</link><pubDate>Thu, 20 Dec 2012 05:24:08 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:70723</guid><dc:creator>Rob Reynolds</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_reynolds/rsscomments.aspx?PostID=70723</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_reynolds/commentapi.aspx?PostID=70723</wfw:comment><comments>http://devlicio.us/blogs/rob_reynolds/archive/2012/12/19/this-log-source-nuget-package-amp-performance.aspx#comments</comments><description>&lt;p&gt;Recently I mentioned &lt;a href="http://devlicio.us/blogs/rob_reynolds/archive/2012/12/15/introducing-this-log.aspx"&gt;this.Log&lt;/a&gt;. Given the amount of folks that were interested in this.Log, I decided to pull this source out and make a NuGet package (well, several packages).&lt;/p&gt;  &lt;h4&gt;Source&lt;/h4&gt;  &lt;p&gt;The source is now located at &lt;a title="https://github.com/ferventcoder/this.log" href="https://github.com/ferventcoder/this.log"&gt;https://github.com/ferventcoder/this.log&lt;/a&gt;. Please feel free to send pull requests (with tests of course). When you clone it, if you open visual studio prior to running build.bat, you will notice build errors. Don’t send me a pull request fixing this, I want it to work the way it does now. Use build.bat appropriately.&lt;/p&gt;  &lt;p&gt;To try to cut down on the version number being listed everywhere, I created a SharedAssembly.cs (and a SharedAssembly.vb for the VB.NET samples). That helped, but it didn’t solve the problem where it was in the nuspecs as dependencies. So I took it a step further and created a file named VERSION. When you run the build, it updates all the files that contain version information. Having one place to handle the version is nice.&lt;/p&gt;  &lt;h4&gt;NuGet&lt;/h4&gt;  &lt;p&gt;When moving this.Log to a NuGet package (or in this case 9 NuGet packages), I was able to play with some features of NuGet I had not previously, symbol servers and packing a csproj. With packing a csproj, I was able to quickly (well mostly) set up the build to package up every project with NuGet packages. &lt;/p&gt;  &lt;p&gt;All packages can be found by searching for &lt;a href="http://nuget.org/packages?q=this.Log"&gt;this.log on NuGet.org&lt;/a&gt;.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://nuget.org/packages/this.Log"&gt;this.Log Logging Extension&lt;/a&gt; – does nothing by itself except brings the LogExtensions and this.Log.dll. You need to install one of the plugins to get this. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/packages/this.Log-log4net"&gt;this.Log Logging Extension (log4net Plugin)&lt;/a&gt; – the log4net plugin to this.Log &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/packages/this.Log-log4net.Sample"&gt;this.Log Logging Extension (log4net Plugin) SAMPLE&lt;/a&gt; – this is a sample showing how this.Log-log4net works in action. Add it to a console application. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/packages/this.Log-log4net.VB.Sample"&gt;this.Log Logging Extension (log4net Plugin) SAMPLE for VB.NET&lt;/a&gt; – same as the previous sample, except for VB.NET &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/packages/this.Log-NLog"&gt;this.Log Logging Extension (NLog Plugin)&lt;/a&gt; – the NLog plugin to this.Log &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/packages/this.Log-NLog.Sample"&gt;this.Log Logging Extension (NLog Plugin) SAMPLE&lt;/a&gt; – this is a sample showing how this.Log-NLog works in action. Add it to a console application. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/packages/this.Log-NLog.VB.Sample"&gt;this.Log Logging Extension (NLog Plugin) SAMPLE for VB.NET&lt;/a&gt; – same as the previous sample, except for VB.NET &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/packages/this.Log-RhinoMocks"&gt;this.Log Logging Extension (Rhino Mocks Plugin)&lt;/a&gt; – MockLogger for Rhino Mocks &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/packages/this.log-moq"&gt;this.Log Logging Extension (Moq Plugin)&lt;/a&gt; – MockLogger for Moq &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; If you’ve installed any of these prior to this post, you will want to uninstall and reinstall them (there was an particular issue with the version on the Rhino Mocks version). I’ve fixed and updated quite a bit on them from version 0.0.1.0 to 0.0.2.0.&lt;/p&gt;  &lt;h4&gt;Performance&lt;/h4&gt;  &lt;p&gt;Performance testing with log4net showed this only has an overhead of 42 ticks tested over 100,000 iterations. That’s a pretty good start given that it has a reflection hit on every call.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=70723" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/NuGet/default.aspx">NuGet</category></item><item><title>Introducing this.Log</title><link>http://devlicio.us/blogs/rob_reynolds/archive/2012/12/15/introducing-this-log.aspx</link><pubDate>Sat, 15 Dec 2012 15:29:09 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:70702</guid><dc:creator>Rob Reynolds</dc:creator><slash:comments>13</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_reynolds/rsscomments.aspx?PostID=70702</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_reynolds/commentapi.aspx?PostID=70702</wfw:comment><comments>http://devlicio.us/blogs/rob_reynolds/archive/2012/12/15/introducing-this-log.aspx#comments</comments><description>&lt;p&gt;One of my favorite creations over the past year has been this.Log(). It works everywhere including static methods and in razor views. Everything about how to create it and set it up is in this &lt;a href="https://gist.github.com/3099122"&gt;gist&lt;/a&gt;.&lt;/p&gt;  &lt;h4&gt;How it looks&lt;/h4&gt;  &lt;pre class="c#" name="code"&gt;public class SomeClass {
 
  public void SomeMethod() {
    this.Log().Info(() =&amp;gt; &amp;quot;Here is a log message with params which can be in Razor Views as well: &amp;#39;{0}&amp;#39;&amp;quot;.FormatWith(typeof(SomeClass).Name));

    this.Log().Debug(&amp;quot;I don&amp;#39;t have to be delayed execution or have parameters either&amp;quot;);
  }

  public static void StaticMethod() {
    &amp;quot;SomeClass&amp;quot;.Log().Error(&amp;quot;This is crazy, right?!&amp;quot;);
  }
 
}&lt;/pre&gt;

&lt;h4&gt;Why It’s Awesome&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;It does no logging if you don’t have a logging engine set up. &lt;/li&gt;

  &lt;li&gt;It works everywhere in your code base (where you can write C#). This means in your razor views as well! &lt;/li&gt;

  &lt;li&gt;It uses deferred execution, which means you don’t have to mock it to use it with testing (your tests won’t fail on logging lines). &lt;/li&gt;

  &lt;li&gt;You can mock it easily and use that as a means of testing. &lt;/li&gt;

  &lt;li&gt;You have no references to your actual logging engine anywhere in your codebase, so swapping it out (or upgrading) becomes a localized event to one class where you provide the adapter. &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Some Internals&lt;/h4&gt;

&lt;p&gt;This uses the awesome static logging gateway that &lt;a href="http://blog.developwithpassion.com/"&gt;JP Boodhoo&lt;/a&gt; showed me a long time ago at a &lt;a href="http://ferventcoder.com/archive/2008/11/17/nothing-but-.net-developer-boot-camp---day-one-eod.aspx"&gt;developer bootcamp&lt;/a&gt;, except it takes the concept further. One thing that always bothered me about the static logging gateway is that it would construct an object EVERY time you called the logger if you were using anything but log4net or NLog. Internally it likely continued to reuse the same object, but at the codebase level it appeared as that was not so.&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;/// &amp;lt;summary&amp;gt;
/// Logger type initialization
/// &amp;lt;/summary&amp;gt;
public static class Log
{
    private static Type _logType = typeof(NullLog);
    private static ILog _logger;
 
    /// &amp;lt;summary&amp;gt;
    /// Sets up logging to be with a certain type
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;The type of ILog for the application to use&amp;lt;/typeparam&amp;gt;
    public static void InitializeWith&amp;lt;T&amp;gt;() where T : ILog, new()
    {
        _logType = typeof(T);
    }
 
    /// &amp;lt;summary&amp;gt;
    /// Sets up logging to be with a certain instance. The other method is preferred.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;loggerType&amp;quot;&amp;gt;Type of the logger.&amp;lt;/param&amp;gt;
    /// &amp;lt;remarks&amp;gt;This is mostly geared towards testing&amp;lt;/remarks&amp;gt;
    public static void InitializeWith(ILog loggerType)
    {
        _logType = loggerType.GetType();
        _logger = loggerType;
    }
 
    /// &amp;lt;summary&amp;gt;
    /// Initializes a new instance of a logger for an object.
    /// This should be done only once per object name.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;objectName&amp;quot;&amp;gt;Name of the object.&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;ILog instance for an object if log type has been intialized; otherwise null&amp;lt;/returns&amp;gt;
    public static ILog GetLoggerFor(string objectName)
    {
        var logger = _logger;
 
        if (_logger == null)
        {
            logger = Activator.CreateInstance(_logType) as ILog;
            if (logger != null)
            {
                logger.InitializeFor(objectName);
            }
        }
 
        return logger;
    }
}&lt;/pre&gt;

&lt;p&gt;You see how when it calls InitializeFor, that’s when you get something like the following in the actual implemented method:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;_logger = LogManager.GetLogger(loggerName);&lt;/pre&gt;

&lt;p&gt;So we take the idea a step further by implementing the following in the root namespace of our project:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;/// &amp;lt;summary&amp;gt;
/// Extensions to help make logging awesome
/// &amp;lt;/summary&amp;gt;
public static class LogExtensions
{
    /// &amp;lt;summary&amp;gt;
    /// Concurrent dictionary that ensures only one instance of a logger for a type.
    /// &amp;lt;/summary&amp;gt;
    private static readonly Lazy&amp;lt;ConcurrentDictionary&amp;lt;string,ILog&amp;gt;&amp;gt; _dictionary = new Lazy&amp;lt;ConcurrentDictionary&amp;lt;string, ILog&amp;gt;&amp;gt;(()=&amp;gt;new ConcurrentDictionary&amp;lt;string, ILog&amp;gt;());
 
    /// &amp;lt;summary&amp;gt;
    /// Gets the logger for &amp;lt;see cref=&amp;quot;T&amp;quot;/&amp;gt;.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;type&amp;quot;&amp;gt;The type to get the logger for.&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;Instance of a logger for the object.&amp;lt;/returns&amp;gt;
    public static ILog Log&amp;lt;T&amp;gt;(this T type)
    {
        string objectName = typeof(T).FullName;
        return Log(objectName);
   }
 
    /// &amp;lt;summary&amp;gt;
    /// Gets the logger for the specified object name.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;objectName&amp;quot;&amp;gt;Either use the fully qualified object name or the short. If used with Log&amp;amp;lt;T&amp;amp;gt;() you must use the fully qualified object name&amp;quot;/&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;Instance of a logger for the object.&amp;lt;/returns&amp;gt;
    public static ILog Log(this string objectName)
    {
        return _dictionary.Value.GetOrAdd(objectName, Infrastructure.Logging.Log.GetLoggerFor);
    }
}&lt;/pre&gt;

&lt;p&gt;You can see I’m using a concurrent dictionary which really speeds up the operation of going and getting a logger. I get the initial performance hit the first time I add the object, but from there it’s really fast. I do take a hit with a reflection call every time, but this is acceptable for me since I’ve been doing that with most logging engines for awhile.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;If you are interested in the details, see this &lt;a href="https://gist.github.com/3099122"&gt;gist&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Extensions are awesome if used sparingly. Is this.Log perfect? Probably not, but it does have a lot of benefits in use. Feel free to take my work and make it better. Find a way to get me away from the reflection call every time. I’ve been using it for almost a year now and have improved it a little here and there.&lt;/p&gt;

&lt;p&gt;If there is enough interest, I can create a NuGet package with this as well.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=70702" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/NuGet/default.aspx">NuGet</category></item><item><title>Chocolatey - Guidance on Packaging Apps with Both an Install and Executable/Zip Option</title><link>http://devlicio.us/blogs/rob_reynolds/archive/2012/02/25/chocolatey-guidance-on-packaging-apps-with-both-an-install-and-executable-zip-option.aspx</link><pubDate>Sat, 25 Feb 2012 17:35:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:69537</guid><dc:creator>Rob Reynolds</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_reynolds/rsscomments.aspx?PostID=69537</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_reynolds/commentapi.aspx?PostID=69537</wfw:comment><comments>http://devlicio.us/blogs/rob_reynolds/archive/2012/02/25/chocolatey-guidance-on-packaging-apps-with-both-an-install-and-executable-zip-option.aspx#comments</comments><description>&lt;p&gt;&lt;span&gt;One of the thoughts I&amp;#39;ve been considering recently with &lt;a href="http://chocolatey.org"&gt;chocolatey&lt;/a&gt; is consistency with packages and naming conventions as chocolatey continues to grow. It&amp;#39;s fine to name packages by the app/tool name, that&amp;#39;s both intuitive and expected. What I am more interested in is when an application has multiple installation options (ie. an MSI and a ZIP). It can become confusing for people to install these when they don&amp;#39;t know what they are getting if they call a package that has both. If you start with one that has a .zip and later they release an MSI (nodejs anyone?), what do you call the package that installs the MSI? Do you keep around the executable? Do you rename the original package in response to the other option? Is there a third option?&lt;/span&gt;
&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h4&gt;&lt;strong&gt;&lt;span style="text-decoration:underline;"&gt;One Option&lt;/span&gt;&lt;/strong&gt;&lt;/h4&gt;
&lt;div&gt;If there is only one option available, you are fine to make the package name the same as the application/tool. This makes it intuitive and reduces confusion.&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;
&lt;h4&gt;&lt;strong&gt;&lt;span style="text-decoration:underline;"&gt;Multiple Options&lt;/span&gt;&lt;/strong&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;To start putting together guidance on this and alleviate confusion, I see that we would move forward in these cases with three packages. One with no suffix, one with &amp;quot;.app&amp;quot; suffix, and one with &amp;quot;.tool&amp;quot; suffix. This brings in chocolatey&amp;#39;s idea of applications versus tools (
&lt;a href="https://github.com/chocolatey/chocolatey/wiki/ChocolateyFAQs"&gt;https://github.com/chocolatey/chocolatey/wiki/ChocolateyFAQs&lt;/a&gt;&amp;nbsp;- apps are installed on the system, tools are not).&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;div&gt;If you would take a quick look at Instant EyeDropper (
&lt;a href="http://chocolatey.org/packages?q=instanteyedropper"&gt;http://chocolatey.org/packages?q=instanteyedropper&lt;/a&gt;&amp;nbsp;), you will notice there are three packages here.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;InstantEyeDropper is what will ultimately be a virtual package&lt;/li&gt;
&lt;li&gt;InstantEyeDropper.app is the package name for a package that uses a native installer (i.e. MSI, exe)&lt;/li&gt;
&lt;li&gt;InstantEyeDropper.tool is the package name for a package that has an executable / downloads &amp;amp; unpacks an archive / etc&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;InstantEyeDropper&amp;nbsp;right now is taking a dependency on&amp;nbsp;
InstantEyeDropper.app (which makes it a meta package). When virtual packages (see Virtual Packages below) are ready, that dependency will be removed and the chocolateyinstall.ps1 file will look something like the following (this is not definitive of what it will look like though):&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;div&gt;&amp;nbsp;Install-VirtualPackage &amp;#39;7zip.tool&amp;#39; &amp;#39;7zip.app&amp;#39;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;You will notice I put the &amp;quot;.tool&amp;quot; ahead of &amp;quot;.app&amp;quot;. In the end, I think the behavior of a virtual package should default to a command line version. Why? There are folks that do not have administrative access to their machines. Chocolatey is really nice for them because they can install and use chocolatey without ever needing to assert administrative privileges. Marcel Hoyer (&lt;a href="https://twitter.com/#!/pixelplastic"&gt;https://twitter.com/pixelplastic&lt;/a&gt;) first proposed the idea of being able to use chocolatey without administrative privileges. Him and I took pains to make chocolatey work for these scenarios. This did complicate chocolatey a little bit for the package maker, but in the end I think it is a really good thing. As a person inspecting a package to decide whether to install or not, they can see every point that the package maker mentioned they needed administrative privileges.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;That said, the default will be the one on the leftmost side. You are beholden to the community in justifying why you didn&amp;#39;t put the command line version first if you decide not to in the virtual package.&amp;nbsp;&lt;span&gt;But chocolatey won&amp;#39;t constrain you on that because you may have a really good reason.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;h4&gt;&lt;span style="text-decoration:underline;"&gt;App Now has Multiple Options&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;When an application/tool moves to where it has multiple options, like an installer it didn&amp;#39;t used to have, that&amp;#39;s when it is time to break the package out to a virtual (meta for now until virtual is available) and create the other two packages with the correct suffixes as outlined in the guidance above.&lt;/div&gt;
&lt;h4&gt;&lt;span style="text-decoration:underline;"&gt;Virtual Packages&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;For those confused about the idea of a virtual package, it allows folks to say I need to take a dependency on a PDFReader. PDFReader becomes a virtual package that does nothing other than point to all of the different pdf readers available. When someone installs the package that has a dependency on PDFReader, chocolatey looks at the virtual options and sees you have adobereader installed (one of the options in the list). So it moves on because you have met the virtual package requirements. If you have foxitreader installed, it moves on. Otherwise it picks the first item in the virtual tree and installs it as the default. More information?&amp;nbsp;&lt;a href="https://github.com/chocolatey/chocolatey/issues/7"&gt;https://github.com/chocolatey/chocolatey/issues/7&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;h4&gt;&lt;span style="text-decoration:underline;"&gt;Virtual Packages vs Meta Packages&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;A meta package is one that points to other packages. If you think of a package that does nothing more than take on dependencies to other packages, that is a meta package. A virtual package is like a meta package, except it has the concept of optional dependencies.&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;h4&gt;&lt;span style="text-decoration:underline;"&gt;Ending Thoughts&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;This seems to be on the surface the best way to provide an intuitive user experience. There may be some things we learn along the way and adjust this as we go.&amp;nbsp;If you are a package owner and you have packages that have both options, you may want to start getting them into this format. I myself have some work to do in this aspect.&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;Thoughts?&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;Original Discussion:&amp;nbsp;&lt;a href="http://groups.google.com/group/chocolatey/browse_thread/thread/a1d208b022dfc30f"&gt;http://groups.google.com/group/chocolatey/browse_thread/thread/a1d208b022dfc30f&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=69537" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/HowTo/default.aspx">HowTo</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/Tools/default.aspx">Tools</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/NuGet/default.aspx">NuGet</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/chocolatey/default.aspx">chocolatey</category></item><item><title>Software Release Management - Why You Can’t And Shouldn’t Force People to Use the Latest Version</title><link>http://devlicio.us/blogs/rob_reynolds/archive/2012/01/25/software-release-management-why-you-can-t-and-shouldn-t-force-people-to-use-the-latest-version.aspx</link><pubDate>Wed, 25 Jan 2012 16:29:19 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:69366</guid><dc:creator>Rob Reynolds</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_reynolds/rsscomments.aspx?PostID=69366</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_reynolds/commentapi.aspx?PostID=69366</wfw:comment><comments>http://devlicio.us/blogs/rob_reynolds/archive/2012/01/25/software-release-management-why-you-can-t-and-shouldn-t-force-people-to-use-the-latest-version.aspx#comments</comments><description>&lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;As software creators we don&amp;#39;t get to decide what version of our tools / libraries that people use. If we try to force them, our users will go somewhere else.&lt;/b&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h4&gt;Update: What Type of Software This Applies To&lt;/h4&gt;  &lt;p&gt;This post talks of tools, applications and libraries. Things that end up in the users hands. This does not apply to SaaS or websites. These do not end up in the hands of the users in the same sense. &lt;/p&gt;  &lt;p&gt;For those of you who immediately think of Chrome or Firefox, which are applications that end up in the users hands, those apply to this post as well. They have nearly perfected a silent upgrade experience, but if they ever mess up that experience, users can choose to use something else. And I believe there is a way to opt out as well (not easily achieved but possible).&lt;/p&gt;  &lt;h4&gt;Software Release Management&lt;/h4&gt;  &lt;p&gt;I write software. Much of it is open source. I have multiple versions of my products out there. Even with newer versions available that fix bugs and bring about new features, I still find people using older versions. Even though I have a better newer version that fixes some of the bugs they are dealing with, they are still using an older version. Think about that for a second. There must be a good reason right? Let’s state this in an official sense. &lt;/p&gt;  &lt;p&gt;As a software creator you release software. You put a release out there and people use that release. You delineate different releases by a concept of versioning. People use a particular version of your release. You release newer versions of your software that has fixes and enhancements. You hope users upgrade to the latest release when it is available. &lt;/p&gt;  &lt;p&gt;I’ve stated five facts and finished with a hope. If you can accept those as facts, we can move on. If we can’t, then you might want to stop reading now because we are never going to agree. If you are a developer like me, you really want people to always use the latest version of your software, so you might be able to accept the last statement as a fact for you. I really want people to always use the latest release of my software as I have went through the trouble of testing it and making it better. &lt;/p&gt;  &lt;p&gt;Now let me change some terms for you. Software release management is really a fancy way of saying package management. A software release could be better termed a package. So to restate, as a software creator, you release &lt;strong&gt;&lt;em&gt;packages&lt;/em&gt;&lt;/strong&gt;. You put a &lt;em&gt;package&lt;/em&gt; out there and people use that &lt;em&gt;package&lt;/em&gt;. You delineate different &lt;em&gt;packages&lt;/em&gt; by a concept of versioning. People use a particular version of your &lt;em&gt;package&lt;/em&gt;. You release newer versions of your &lt;em&gt;package&lt;/em&gt; that has fixes and enhancements. You hope users upgrade to the latest &lt;em&gt;package&lt;/em&gt; when it is available. &lt;/p&gt;  &lt;h4&gt;The Hope Versus The Force&lt;/h4&gt;  &lt;p&gt;I say “&lt;strong&gt;hope they upgrade&lt;/strong&gt;” because you really can’t control that aspect. You can try. You can delete the older versions. You can refuse to have older versions available. You can tell users that they should and need to upgrade. But you put it out there once and it is now out there forever. People will find a way to get to the particular version they need. Or they will go elsewhere. Users speak with their feet. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;I find attempting to force a user to do something is both an exercise in futility and a great way to guarantee that you have less users overall.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So people must &lt;em&gt;want&lt;/em&gt; to use a particular version of a product. Let’s examine this a little more. &lt;strong&gt;Why on earth would someone use an older version of a product when a newer, better, less buggier version is available?&lt;/strong&gt; &lt;/p&gt;  &lt;h4&gt;Why Do Users Use Older Versions?&lt;/h4&gt;  &lt;p&gt;Users use older versions of our packages and they have great fundamental reasons for doing so: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;It reduces their risk. &lt;/li&gt;    &lt;li&gt;It guarantees that users of their library (that has a dependency on your library) have a good experience. &lt;/li&gt;    &lt;li&gt;It guarantees that the product that they have tested is the same product that gets into the hands of consumers. &lt;/li&gt;    &lt;li&gt;It guarantee their product builds successfully and the same way each time. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In fixing a product and making it better and less buggier, you may actually be breaking someone’s ability to use a newer version. And you have no guarantee to the user that this version doesn’t have flaws of it’s own. Right? Otherwise there would only be one version that ever had fixes in it. We wouldn’t need to release newer versions with fixes, only enhancements. But we don’t. We fix things we thought worked and we fix things we tested but missed some crazy edge case. This is why we go down this path of release management. This is software development.&lt;/p&gt;  &lt;p&gt;So people get a certain version and they use it. &lt;strong&gt;Users upgrade to the latest version of software when they are ready, not when the software creator is ready.&lt;/strong&gt; People depend on certain versions or on a range of versions. In reality I can&amp;#39;t force someone to use the latest version. If I try, they will find the version they need through the powers of the internet or find another way. Accepting that, I can give them a way to see it and help them fall into the pit of success. &lt;/p&gt;  &lt;h4&gt;From the User Perspective&lt;/h4&gt;  &lt;p&gt;Shifting to the perspective of the user, I might use your library in my own software. Being able to build my product, even if it means it is using an older version of your package that has bugs, is worlds more important to me and my users. &lt;strong&gt;We&amp;#39;ll get to your latest version when we can test that it doesn&amp;#39;t break our product.&lt;/strong&gt; But don&amp;#39;t try to force me to upgrade to your latest version or I will find another way. I&amp;#39;m not saying that with your package but in all packages the newer version may be buggier than the current buggy version we are using. We don&amp;#39;t know and you can’t guarantee that it doesn’t, even with extensive testing. Testing doesn’t &lt;a href="http://c2.com/cgi/wiki?TestsCantProveTheAbsenceOfBugs"&gt;prove the absence of bugs&lt;/a&gt;, only the absence of errors that you know. I digress. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;It’s an evil that we know versus and evil that we don’t. Or put another way, it&amp;#39;s a buggy version we know versus a buggy version we don&amp;#39;t.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;If it’s a tool, we need to ensure that our usage of your product still meets our expectations. We need to test it even though you did and make sure it still works for our needs and scenarios. Where it doesn’t we need to decide if that means we can shift our expectations and upgrade. But we are not going to blindly upgrade and just use the latest version because the software creator believes that is best. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Can you cover the millions of dollars that we might lose by taking on a newer version of your product? If you can give me that guarantee, as a user I will gladly pass that risk on to you.&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h4&gt;Final Thoughts&lt;/h4&gt;  &lt;p&gt;Whether you agree or not, as software creators we don&amp;#39;t get to decide what version of our tools / libraries that people use. We just don’t have that luxury. If we try to our users will go somewhere else. So we make it easy for them to upgrade so they will want to. We make the upgrade experience painless so they will want to. We need to be good stewards.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=69366" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/Tools/default.aspx">Tools</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/Gems/default.aspx">Gems</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/NuGet/default.aspx">NuGet</category></item><item><title>Let’s Get Chocolatey! Kind of like apt-get for Windows</title><link>http://devlicio.us/blogs/rob_reynolds/archive/2011/10/07/let-s-get-chocolatey-kind-of-like-apt-get-for-windows.aspx</link><pubDate>Fri, 07 Oct 2011 12:32:28 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:68256</guid><dc:creator>Rob Reynolds</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_reynolds/rsscomments.aspx?PostID=68256</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_reynolds/commentapi.aspx?PostID=68256</wfw:comment><comments>http://devlicio.us/blogs/rob_reynolds/archive/2011/10/07/let-s-get-chocolatey-kind-of-like-apt-get-for-windows.aspx#comments</comments><description>&lt;p&gt;“If only there was some way to quickly and silently install applications and tools on my windows machine.”&lt;/p&gt;  &lt;p&gt;&lt;a href="http://chocolatey.org"&gt;Chocolatey&lt;/a&gt; is kind of like an apt-get, but for Windows. It is a machine level package manager that is built on top of &lt;a href="http://nuget.org"&gt;NuGet&lt;/a&gt; command line and the NuGet infrastructure. &lt;a href="http://elegantcode.com/about/jason-jarrett/"&gt;Jason Jarrett&lt;/a&gt; recently described it as &lt;a href="http://elegantcode.com/2011/10/05/chocolatey-the-free-and-open-source-windows-app-store/"&gt;the free/OSS windows app store&lt;/a&gt;. What that means for you is that you can install and update software (applications and tools) on your machine with a few keystrokes and chocolatey does the rest! &lt;/p&gt;  &lt;p&gt;Just how easy is it to install an application? From the command line, PowerShell, or Package Manager Console in visual studio you can type something like:&lt;/p&gt;  &lt;pre&gt;cinst windirstat&lt;/pre&gt;

&lt;p&gt;and watch it download and silently install &lt;a href="http://windirstat.info"&gt;WinDirStat&lt;/a&gt; on your machine. &lt;/p&gt;

&lt;p&gt;A picture is worth a thousand words in this case:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/chocolateyFlash_5F00_640D17A6.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="cinst msysgit - The chocolatey gods have answered your request!" border="0" alt="cinst msysgit - The chocolatey gods have answered your request!" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/chocolateyFlash_5F00_thumb_5F00_47437CC4.png" width="527" height="319" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to try a tool (something that doesn’t actually install on your machine), try baretail, nodejs, or ravendb. &lt;/p&gt;

&lt;p&gt;Creating Packages is also very simple: &lt;a href="https://github.com/chocolatey/chocolatey/wiki/CreatePackages"&gt;https://github.com/chocolatey/chocolatey/wiki/CreatePackages&lt;/a&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Below is all that is required to install WinDirStat on your machine.&lt;/p&gt;

&lt;pre&gt;Install-ChocolateyPackage &amp;#39;windirstat&amp;#39; &amp;#39;exe&amp;#39; &amp;#39;/S&amp;#39; &amp;#39;http://windirstat.info/wds_current_setup.exe&amp;#39;&lt;/pre&gt;

&lt;p&gt;Include chocolatey in your development environment setup! &lt;a href="https://github.com/chocolatey/chocolatey/wiki/DevelopmentEnvironmentSetup"&gt;https://github.com/chocolatey/chocolatey/wiki/DevelopmentEnvironmentSetup&lt;/a&gt;&amp;#160; Check out a living example - &lt;a href="https://github.com/davidalpert/nuserve#readme"&gt;https://github.com/davidalpert/nuserve#readme&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;FAQ&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;What can I do with chocolatey?&lt;/strong&gt; Since it uses PowerShell, you can do nearly anything you can do with .NET. Install applications, download tools and put them on the path, set up contributors machines for hacking on your code, install powershell commands, etc. Your imagination is the limit!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What’s your best example of the power of chocolatey?&lt;/strong&gt; One line Ruby DevKit install. Seriously. &lt;a href="http://groups.google.com/group/rubyinstaller/browse_thread/thread/8245c53f990d1ea6"&gt;http://groups.google.com/group/rubyinstaller/browse_thread/thread/8245c53f990d1ea6&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I’m convinced! How do I install chocolatey?&lt;/strong&gt; We try to make that simple as well. Open powershell, make sure execution policy is unrestricted (Set-ExecutionPolicy Unrestricted), and paste &lt;/p&gt;

&lt;pre&gt;iex ((new-object net.webclient).DownloadString(&amp;quot;http://bit.ly/psChocInstall&amp;quot;))&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;I have included tools (executables) in my &lt;/strong&gt;&lt;a href="http://nuget.org"&gt;&lt;strong&gt;nuget.org&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; packages, like Statlight and Fubu. Can I use chocolatey to “install” them?&lt;/strong&gt; Yes, just call install like normal, it will check chocolatey.org first and then nuget.org. If it finds an executable in the package, it will automatically put it on the path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How is chocolatey different from other windows machine package managers?&lt;/strong&gt; It has PowerShell instructions for how to download native installers from the distribution source and install applications on your machine. It uses PowerShell so you can give it any instruction you want for install and configuration. It automatically makes batch command file links for executables you have included in your package or have downloaded to the package directory with the PowerShell script.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is chocolatey awesome?&lt;/strong&gt; I’m biased, but YES!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is chocolatey version 1?&lt;/strong&gt; Not yet, we have a few things going into the &lt;a href="https://github.com/chocolatey/chocolatey/wiki/Roadmap"&gt;roadmap&lt;/a&gt; and enhancements being logged: &lt;a title="https://github.com/chocolatey/chocolatey/issues" href="https://github.com/chocolatey/chocolatey/issues"&gt;https://github.com/chocolatey/chocolatey/issues&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I’m not convinced, where do I find more information?&lt;/strong&gt; I’ve listed quite a few resources below. I am likely missing some.&lt;/p&gt;

&lt;h4&gt;References&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://chocolatey.org/"&gt;http://chocolatey.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/chocolatey/chocolatey/wiki"&gt;https://github.com/chocolatey/chocolatey/wiki&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://groups.google.com/group/chocolatey"&gt;http://groups.google.com/group/chocolatey&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://twitter.com/chocolateynuget"&gt;http://twitter.com/chocolateynuget&lt;/a&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Videos&lt;/h4&gt;

&lt;p&gt;Chocolatey In Action (11 apps/tools in less than 7 minutes!): &lt;a href="http://www.youtube.com/watch?v=N-hWOUL8roU"&gt;http://www.youtube.com/watch?v=N-hWOUL8roU&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a Chocolatey Package: &lt;a href="http://www.youtube.com/watch?v=Wt_unjS_SUo"&gt;http://www.youtube.com/watch?v=Wt_unjS_SUo&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Blog Posts&lt;/h4&gt;

&lt;p&gt;This dates all the way back to March 2011. Chocolatey has been actively worked on for awhile… &lt;/p&gt;

&lt;p&gt;&lt;a href="http://nuget.codeplex.com/discussions/251435"&gt;http://nuget.codeplex.com/discussions/251435&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://nuget.codeplex.com/discussions/257341"&gt;http://nuget.codeplex.com/discussions/257341&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://chrisortman.wordpress.com/2011/04/01/getting-started-with-chocolatey/"&gt;http://chrisortman.wordpress.com/2011/04/01/getting-started-with-chocolatey/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.lessthandot.com/index.php/DesktopDev/MSTech/chocolatey-apt-get-for-windows"&gt;http://blogs.lessthandot.com/index.php/DesktopDev/MSTech/chocolatey-apt-get-for-windows&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.lessthandot.com/index.php/DesktopDev/MSTech/getting-chocolatey-to-work-when"&gt;http://blogs.lessthandot.com/index.php/DesktopDev/MSTech/getting-chocolatey-to-work-when&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.lessthandot.com/index.php/DesktopDev/MSTech/chocolatey-gui"&gt;http://blogs.lessthandot.com/index.php/DesktopDev/MSTech/chocolatey-gui&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.lessthandot.com/index.php/DesktopDev/MSTech/making-a-chocolatey-package"&gt;http://blogs.lessthandot.com/index.php/DesktopDev/MSTech/making-a-chocolatey-package&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.counity.at/blog/archives/253"&gt;http://www.counity.at/blog/archives/253&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.xavierdecoster.com/post/2011/09/30/An-overview-of-the-NuGet-ecosystem.aspx"&gt;http://www.xavierdecoster.com/post/2011/09/30/An-overview-of-the-NuGet-ecosystem.aspx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.codiceplastico.com/melkio/index.php/2011/10/06/chocolatey-un-package-manager-per-windows/"&gt;http://blog.codiceplastico.com/melkio/index.php/2011/10/06/chocolatey-un-package-manager-per-windows/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://elegantcode.com/2011/10/05/chocolatey-the-free-and-open-source-windows-app-store"&gt;http://elegantcode.com/2011/10/05/chocolatey-the-free-and-open-source-windows-app-store&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=68256" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/Git/default.aspx">Git</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/Tools/default.aspx">Tools</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/Gems/default.aspx">Gems</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/NuGet/default.aspx">NuGet</category></item><item><title>Extend NuGet Command Line</title><link>http://devlicio.us/blogs/rob_reynolds/archive/2011/07/15/extend-nuget-command-line.aspx</link><pubDate>Fri, 15 Jul 2011 08:00:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:67993</guid><dc:creator>Rob Reynolds</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_reynolds/rsscomments.aspx?PostID=67993</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_reynolds/commentapi.aspx?PostID=67993</wfw:comment><comments>http://devlicio.us/blogs/rob_reynolds/archive/2011/07/15/extend-nuget-command-line.aspx#comments</comments><description>&lt;p&gt;Yesterday I started a &lt;a href="http://nuget.codeplex.com/discussions/265199"&gt;discussion&lt;/a&gt; about adding a new command to &lt;a href="http://nuget.org/list/packages/nuget.commandline"&gt;nuget.exe&lt;/a&gt;. It ended in creating an &lt;a href="https://github.com/ferventcoder/nuget.copy.extension"&gt;extension&lt;/a&gt; to the command line that behaves in the same way without having to dive into the nuget code base or add more complexity to it. &lt;/p&gt;
&lt;p&gt;I haven&amp;rsquo;t seen any blog posts or documentation surrounding this new concept (new in nuget 1.4) of extending the command line except for Matt Hamilton&amp;rsquo;s posts on using &lt;a href="http://matthamilton.net/nuget-for-plug-ins"&gt;NuGet for plug-ins&lt;/a&gt; and &lt;a href="http://matthamilton.net/nuget-with-mef"&gt;NuGet with MEF&lt;/a&gt; (which are not quite this concept).&lt;/p&gt;
&lt;p&gt;Here is my experience. I found looking at the commands in nuget.exe (&lt;a href="http://nuget.codeplex.com/SourceControl/changeset/view/28eda598a096#src%2fCommandLine%2fCommands%2fCommand.cs"&gt;NuGet.Commands&lt;/a&gt;) to make it easy to create my own command and extend NuGet.&amp;nbsp; Some of this information may not be exactly what you should do, but it worked for me.&lt;/p&gt;
&lt;h4&gt;The Code&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Create a new Visual Studio Solution and add a Class Library (full .NET 4.0 framework). &lt;/li&gt;
&lt;li&gt;Add A NuGet Reference to Nuget.CommandLine. &lt;/li&gt;
&lt;li&gt;Now manually add a reference to nuget.exe. Yes, you can add references to .NET executables. &lt;/li&gt;
&lt;li&gt;Adding a reference to nuget.exe gives you access to &lt;a href="http://nuget.codeplex.com/SourceControl/changeset/view/28eda598a096#src%2fCommandLine%2fCommands%2fCommand.cs"&gt;Command&lt;/a&gt; and the &lt;a href="http://nuget.codeplex.com/SourceControl/changeset/view/28eda598a096#src%2fCommandLine%2fAttributes%2fCommandAttribute.cs"&gt;CommandAttribute&lt;/a&gt;. These are what I see as necessary to extending NuGet. &lt;/li&gt;
&lt;li&gt;Add a reference to &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.aspx"&gt;System.ComponentModel.Composition&lt;/a&gt; (MEF). &lt;/li&gt;
&lt;li&gt;Now you provide a class and resource file per command. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The resource file contains the command descriptions:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_73075634.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="CopyResources.resx " border="0" alt="CopyResources.resx" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_thumb_5F00_6DB86F83.png" width="644" height="293" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The class is attributed with &lt;a href="http://nuget.codeplex.com/SourceControl/changeset/view/28eda598a096#src%2fCommandLine%2fAttributes%2fCommandAttribute.cs"&gt;CommandAttribute&lt;/a&gt; and inherits from &lt;a href="http://nuget.codeplex.com/SourceControl/changeset/view/28eda598a096#src%2fCommandLine%2fCommands%2fCommand.cs"&gt;Command&lt;/a&gt;.&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;[Command(typeof (CopyResources), &amp;quot;copy&amp;quot;, &amp;quot;Description&amp;quot;, MinArgs = 1, MaxArgs = 5, UsageSummaryResourceName = &amp;quot;UsageSummary&amp;quot;,UsageDescriptionResourceName = &amp;quot;UsageDescription&amp;quot;)]
public class Copy : Command {}&lt;/pre&gt;
&lt;p&gt;The &lt;strong&gt;Command Attribute&lt;/strong&gt; asks for a few things: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;typeof (CopyResources)&lt;/em&gt; &amp;ndash; &lt;strong&gt;ResourceClass&lt;/strong&gt; - What is the resx file that the command will draw its help information from? &lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;copy&amp;rdquo;&lt;/em&gt; &amp;ndash; &lt;strong&gt;CommandName&lt;/strong&gt; - what is the name of the command? &lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;Description&amp;rdquo;&lt;/em&gt; &amp;ndash; &lt;strong&gt;Description&lt;/strong&gt; - resource name in the resource file that gives the description on the command line. 
    &lt;br /&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_0A05B1A4.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Description - Copies a package from one source to another source" border="0" alt="Description - Copies a package from one source to another source" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_thumb_5F00_0DA3CC81.png" width="404" height="75" /&gt;&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;em&gt;MinArgs=1&lt;/em&gt; &amp;ndash; &lt;strong&gt;Minimum Arguments&lt;/strong&gt; - what are the minimum number of arguments that can be passed to this command and satisfy its needs? &lt;/li&gt;
&lt;li&gt;&lt;em&gt;MaxArgs = 5&lt;/em&gt; &amp;ndash; &lt;strong&gt;Maximum Arguments&lt;/strong&gt; - what are the maximum number of arguments that can be passed to this command? &lt;/li&gt;
&lt;li&gt;&lt;em&gt;UsageSummaryResourceName = &amp;ldquo;UsageSummary&amp;rdquo;&lt;/em&gt; &amp;ndash; &lt;strong&gt;UsageSummary&lt;/strong&gt; - a very short amount of information that explains the usage of the command. &lt;/li&gt;
&lt;li&gt;&lt;em&gt;UsageDescription = &amp;ldquo;Usage Description&amp;rdquo;&lt;/em&gt; &amp;ndash; &lt;strong&gt;UsageDescription&lt;/strong&gt; - more detailed information about how to use the command. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here is what the command looks like when run with help. Notice where from the CopyResources.resx these items match up to the screen.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_41D7F5C7.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="The help command showing the items from the resx file." border="0" alt="The help command showing the items from the resx file." src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_thumb_5F00_481ECC55.png" width="644" height="120" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now that we have the command attribute finished, let&amp;rsquo;s work on the command itself.&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;private readonly IPackageRepositoryFactory _repositoryFactory;
private readonly IPackageSourceProvider _sourceProvider;

[ImportingConstructor]
public Copy(IPackageRepositoryFactory repositoryFactory, IPackageSourceProvider sourceProvider)
{
    _repositoryFactory = repositoryFactory;
    _sourceProvider = sourceProvider;
}

[Option(typeof (CopyResources), &amp;quot;SourceDescription&amp;quot;, AltName = &amp;quot;src&amp;quot;)]
public string Source { get; set; }

[Option(typeof (CopyResources), &amp;quot;DestinationDescription&amp;quot;, AltName = &amp;quot;dest&amp;quot;)]
public string Destination { get; set; }

[Option(typeof (CopyResources), &amp;quot;VersionDescription&amp;quot;)]
public string Version { get; set; }

[Option(typeof (CopyResources), &amp;quot;ApiKeyDescription&amp;quot;)]
public string ApiKey { get; set; }

public override void ExecuteCommand()
{
    string packageId = base.Arguments[0];

    Console.WriteLine(&amp;quot;Copying {0} from {1} to {2}.&amp;quot;, string.IsNullOrEmpty(Version) ? packageId : packageId + &amp;quot; &amp;quot; + Version,
                      string.IsNullOrEmpty(Source) ? &amp;quot;any source&amp;quot; : Source, Destination);

    //do work son
 
}&lt;/pre&gt;
&lt;p&gt;Important things to note:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;[ImportingConstructor]&lt;/strong&gt; is the constructor that will be called. Notice I am having it get passed an IPackageRepositoryFactory and an IPackageSourceProvider. Most of my work is already done for me setting these up in the command line application. &lt;/li&gt;
&lt;li&gt;Each command line option has &lt;strong&gt;[Option(typeof (CopyResources), &amp;quot;DestinationDescription&amp;quot;, AltName = &amp;quot;dest&amp;quot;)] &lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;Notice again with the options we specify the Resource File with an Option Description (&lt;em&gt;&amp;ldquo;DestinationDescription&amp;rdquo;&lt;/em&gt;) and an optional short parameter for the Option (&lt;em&gt;AltName&lt;/em&gt;). Notice how that translates into options on the help command. 
    &lt;br /&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_382F8791.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="options available with the custom command" border="0" alt="options available with the custom command" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_thumb_5F00_69BAF526.png" width="504" height="102" /&gt;&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;I am overriding &lt;strong&gt;ExecuteCommand&lt;/strong&gt; and pulling the packageId as the first item from base.Arguments.&amp;nbsp; &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;From here I can do all the work necessary for my custom command.&lt;/p&gt;
&lt;h4&gt;Get NuGet to Recognize It&lt;/h4&gt;
&lt;p&gt;Nuget looks for custom commands in &lt;strong&gt;%LocalAppData%\NuGet\Commands&lt;/strong&gt;. Drop your DLL in there and then call nuget. See if it registers your command. This will allow you to continue to tweak your package prior to releasing it in the wild.&lt;/p&gt;
&lt;h4&gt;Use AddExtension to Add New Commands&lt;/h4&gt;
&lt;p&gt;NuGet Extend (AddConsoleExtension) makes installing new commands to the console from NuGet packages super easy. You install it by typing the following:&lt;/p&gt;
&lt;p&gt;NuGet.exe Install /ExcludeVersion /OutputDir %LocalAppData%\NuGet\Commands AddConsoleExtension&lt;/p&gt;
&lt;p&gt;From then on, adding a new extension is as easy as &lt;/p&gt;
&lt;pre&gt;nuget.exe addExtension packageName&lt;/pre&gt;
&lt;pre&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_4FE6BEF7.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="nuget addExtension nuget.copy.extension" border="0" alt="nuget addExtension nuget.copy.extension" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_thumb_5F00_646C0E75.png" width="404" height="47" /&gt;&lt;/a&gt;&lt;/pre&gt;
&lt;h4&gt;Distribute Your Extension as a NuGet Package And Enjoy Your New Custom Command&lt;/h4&gt;
&lt;p&gt;When I created &lt;a href="http://nuget.org/List/Packages/nuget.copy.extension"&gt;my package&lt;/a&gt;, I noted in the nuspec description that &lt;a href="http://nuget.org/list/packages/addconsoleextension"&gt;Nuget Extend&lt;/a&gt; should be installed first.&amp;nbsp; I also added the tag &lt;strong&gt;ConsoleExtension&lt;/strong&gt; since that is what NuGet Extend used. All I package up is the DLL. The nuspec has ZERO dependencies specified (I do &lt;strong&gt;not&lt;/strong&gt; include that I have a dependency on NuGet.CommandLine). I don&amp;rsquo;t need to include the nuget dependency since that will be resolved when the extension is run with nuget.exe.&lt;/p&gt;
&lt;p&gt;Now that you have your custom command, enjoy life a little easier. And tell others about it.&lt;/p&gt;
&lt;h4&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_43E4CEC3.png"&gt;&lt;img style="background-image:none;padding-left:0px;padding-right:0px;display:inline;padding-top:0px;border-width:0px;border:0;" title="nuget copy castle.windsor -destination awesome" border="0" alt="nuget copy castle.windsor -destination awesome" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_thumb_5F00_7C2345DB.png" width="504" height="144" /&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://nuget.org/List/Packages/nuget.copy.extension"&gt;NuGet Copy Extension&lt;/a&gt; is the extension I wrote that pulls packages from one source and pushes them to another. If you are a company that wants to house packages in a company feed and perhaps shut off the official feed for the rest of your developers, then this command may come in very handy.&lt;/p&gt;
&lt;p&gt;Have Fun!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=67993" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/Tools/default.aspx">Tools</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/NuGet/default.aspx">NuGet</category></item><item><title>Iowa Code Camp Presentations</title><link>http://devlicio.us/blogs/rob_reynolds/archive/2011/05/06/iowa-code-camp-presentations.aspx</link><pubDate>Fri, 06 May 2011 05:04:21 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:67230</guid><dc:creator>Rob Reynolds</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_reynolds/rsscomments.aspx?PostID=67230</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_reynolds/commentapi.aspx?PostID=67230</wfw:comment><comments>http://devlicio.us/blogs/rob_reynolds/archive/2011/05/06/iowa-code-camp-presentations.aspx#comments</comments><description>&lt;p&gt;Last weekend I went up to &lt;a href="http://www.iowacodecamp.com/"&gt;Iowa Code Camp&lt;/a&gt; in Cedar Rapids and had the opportunity to do two presentations, one on NuGet and one known as the Automation Tools Roundup.&amp;#160; ICC is one of my favorite conferences every year. It is twice a year and I try to make it to at least one of them. The people that attend this conference really make it worth the money you spend in travel expenses. Definitely recommended.&lt;/p&gt;  &lt;h4&gt;&lt;u&gt;Automation Tools Roundup&lt;/u&gt;&lt;/h4&gt;  &lt;p&gt;This is my favorite session to give because it requires crowd participation and it is never the same presentation twice. We just start going through automation tools of any sort that can help people be more productive through their use. The crowd picks which ones we talk about (for the most part). If there is time at the end we find ourselves trying to learn new tools.&lt;/p&gt;  &lt;p&gt;We talked about several tools and as part of the session people from the audience are invited to come up and talk about a tool they like. &lt;a href="http://lostechies.com/keithdahlby/"&gt;Keith Dahlby&lt;/a&gt; came up and talked about &lt;a href="https://github.com/dahlbyk/posh-git"&gt;Posh-Git&lt;/a&gt; which has an awesome interface for showing me my git status right on the prompt.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_416F462F.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="poshgit" border="0" alt="poshgit" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_reynolds/image_5F00_thumb_5F00_3977A3CD.png" width="450" height="99" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Other tools covered:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://nuget.org/List/Packages/chocolatey"&gt;Chocolatey&lt;/a&gt; – I am going to talk about this tool soon. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/list/packages/launchy"&gt;Launchy&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/list/packages/console2"&gt;Console2&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;ChuckNorrisFramework: &lt;a href="http://projectuppercut.org"&gt;UppercuT&lt;/a&gt; &amp;amp; &lt;a href="http://nuget.org/list/packages/warmup"&gt;WarmuP&lt;/a&gt; were demoed, &lt;a href="http://nuget.org/list/packages/roundhouse"&gt;RoundhousE&lt;/a&gt; &amp;amp; &lt;a href="https://github.com/chucknorris/dropkick"&gt;DropkicK&lt;/a&gt; were mentioned &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/list/packages/stexbar"&gt;StExBar&lt;/a&gt; &amp;amp; &lt;a href="http://nuget.org/list/packages/grepwin"&gt;grepWin&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/List/Packages/notepadplusplus"&gt;Notepad++&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/list/packages/psake"&gt;PSake&lt;/a&gt; was mentioned &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/list/packages/sysinternals"&gt;SysInternals&lt;/a&gt; was mentioned, ZoomIt was shown &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I believe we talked about a few more tools. If you were there and you remember, please hit the comments! Because this presentation is so dynamic, there are no slides. &lt;/p&gt;  &lt;h4&gt;&lt;u&gt;FREE as in BEER!! Manage Your Packages w/NuGet&lt;/u&gt;&lt;/h4&gt;  &lt;p&gt;I enjoy showing people what is possible out there, even with some of the things that are not perfect. &lt;a href="http://nuget.codeplex.com"&gt;NuGet&lt;/a&gt; has a few kinks, but the community is helping and the team is committed to continually making the product better. This presentation is dedicated to showing you how to get started to building your own packages to hosting your own feed. We look at the GUI, the powershell console, the command line and the package explorer. The last 10 minutes of the presentation are dedicated to a new tool that can help make you hyper productive! This presentation is a lot of fun and seeing people really understand what NuGet can do for them is awesome! &lt;/p&gt;  &lt;p&gt;Here are the slides: &lt;a title="http://dl.dropbox.com/u/9391884/NuGet.ppsx" href="http://dl.dropbox.com/u/9391884/NuGet.ppsx"&gt;http://dl.dropbox.com/u/9391884/NuGet.ppsx&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=67230" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/HowTo/default.aspx">HowTo</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/Tools/default.aspx">Tools</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/Events/default.aspx">Events</category><category domain="http://devlicio.us/blogs/rob_reynolds/archive/tags/NuGet/default.aspx">NuGet</category></item></channel></rss>