Git tooling for .NET developers

Many developers working on Windows stay away from Git. There are many reasons for this but from my observations and discussions I’ve had, the most common can be summarized by this tweet by my friend Paul Stovell:

 

can everyone please stop using Git? Mercurial has a better UI (TortoiseHG), I'm sick of Git UI's

I’m not getting into holy wars, and I’m not trying to convince anyone that Git is better than any other VCS. Instead I’ll walk you through the tooling I use to interact with Git on Windows, with Visual Studio.

Git Extensions

First thing you should be getting is Git Extensions.

Git Extensions context menu

With that, similar to TortoiseX family of tools you get nice context menu that gives you access to most common operations quickly, via GUI, and with no need to memorize command line options if you want to avoid it. You can also launch Git command line in the selected folder and then all power of git is at your disposal.

Visual Studio

If you’re a .NET developer, you’ll want to work from within Visual Studio. I’m sure you’ll be happy to learn that Git Extensions has a really nice Visual Studio integration as well.

git_extensions_visual_studio

You get two things – a menu with all the options that Explorer context menu gives you and more, including ability to edit .gitignore file (also the tool will generate a new .gitignore file for you with Visual Studio specific rules!) and to launch a Git bash. Also you get a Git toolbar with most commonly used commands: Commit, browse, push, pull, stash and access to settings.

The way I usually work with it, is I use Git bash for most operations. There’s one exception to that rule though – committing.

git_extensions_commit_window

I think Git Extensions’s Commit window is the best of all VCS I’ve worked with. It clearly separates files you want to commit (in your Index) and files you leave out for now. It clearly shows you status of each file (new, deleted, modified) with distinctive, large icons, also it shows you an on-the-fly diff of what changed in any given file, and it’s blazing fast. Mostly the readability benefits are why I stick to the UI for this operation.

Visual Studio Git Source Control Provider

In addition to Git Extensions I use another tool called Git Source Control Provider which plugs into standard Visual Studio VCS provider mechanism to give me some additional functionality (you can get the tool via Visual Studio extension manager).

git_source_control_provider

There are a few useful capabilities provided by this tool that I tend to rely on quite often (there are more than that as you can read on the tool’s page):

  1. Overlay icons showing you status of each file in Solution Explorer.
  2. It shows you name of the current branch in the Solution Explorer bar at the top (see “(master)” on the screenshot below), and you will work a lot with branches in Git.
  3. It gives some additional options in the context menu.

git_source_control_provider_screenshot

This (plus command line) makes the job very, very simple and quick, and that’s what I stick to on my machine.

There’s one more thing that makes working with Git a pleasure (especially if you’re working on a team that’s not completely co-located).

Github

I love Github. It has a very clean, simple interface that makes going through project history, diffing commits and code reviews a very simple and frictionless process.

 

Summary

Yes, perhaps those tools lack some eye candy that other tools have but frankly – I don’t care, and neither should you. They are more than enough to let you quickly do whatever you need to do with your code and don’t stand in your way. And that’s what a good VCS and tooling around it should be – something you don’t really have to think about and you can rely on to keep track of what is happening with your code with confidence. And that’s precisely what Git is – so if you’ve been held back, go ahead, install those tools and give Git a shot – you won’t look back.

My Visual Studio (with ReSharper) color settings

That’s a post I’ve been meaning to write for quite a long time, yet I never got around to really doing it. Now, here it is – my Visual Studio color theme and it looks like this:

vs_scheme

The theme works with Visual Studio 2010 and requires Resharper 5.1 or newer with “Color Identifiers” option turned on.

Some things to notice.

Instance classes, static classes and interfaces have all very similar but slightly different shade of yellow/green.

Extension methods are slightly lighter than regular methods.

Mutable locals, immutable locals and constants have also similar but slightly different color.

The background is dark, but not completely black.

 

Hope you enjoy it. If you do – you can grab it here.

Twitt.Poster reinvented – introducing Ty (Twitter for LaunchY)

I was really surprised that quite a few people started using my… hack that let you post to Twitter using Launchy. Due to popular demand (hey, few people really asked for that) I decided to create an actual Launchy plugin that would let you do that.

And so Ty was born. I know it’s not the best name in the world, but all Launchy plugins are required by law to end with y and Twitty was already taken, so I abbreviated it to simply Ty. The word ty means also ‘you’ in Polish.

Ty2

All the details, along with download link are here. Grab it if you want, and if you have any feedback (or feature request) post them to the issue tracker on the site.

Technorati Tags: ,,

Mommy, there be dragons in my code.

Every developer, and every shop has a Acme.Commons, or Acme.Core library, where they keep useful helper classes and extensions used in almost every project. Ayende has his Rhino Commons that I’ve seen him blogging about a few times but I never quite got around to actually take a look at the code…

…until today, and I’m shocked. In a mostly positive way. There are few good ideas there, that I would like to discuss.

The first class I found astonishing was HackExpiredException. My first reaction looked something like this:

Then I looked for some code that throws this exception and found this class:

/// <summary>
/// Helper class that allow to specify temporary hacks in a 
/// simple fashion
/// </summary>
/// <example>
/// <code>
/// TimeBombHack.Until(new DateTime(2007,12,31), "Ignoring security for the client demo");
/// </code>
/// </example>
public static class TimeBombHack
{
    /// <summary>
    /// Will throw with the specified message after the 
    /// <param name="expiredAt">The expiry date</param>
    /// <param name="message">The message.</param>
    /// </summary>
    public static void Until(DateTime expiredAt, string message)    
    {
        if (DateTime.Today > expiredAt)
            throw new HackExpiredException(
                string.Format(
                    "The hack ({0}) expired on ({1}). You really should fix it already",
                    message,
                    expiredAt));
    }
}

I really like the idea of being able to mark some parts of code as TODO and have it blown into your face in a controlled fashion when you forget about it. Too many times a forgotten quick and dirty hack slips under the radar and get left behind, forgotten waiting to blow up in production or during very important presentation.

Another, very neat idea I found in the library is the ThereBeDragonsAttribute class.

This marker attribute decorate dangerous parts of the code where for some reason the developer decided to do something in a way that is not straight-forward. This usually means that this is using some functionality that is not fully supported.

Using wacky, unsupported or hackish code is something everyone does occasionally. I usually comment this piece of code, be it a method or a class, but comments are often not enough. With little help of NDepend to bring these pieces of code to everyone’s attention this may be a very useful warning sign for everyone on the team to handle this code with special care.

There are many other useful classes in Rhino Commons, but most of them are pretty standard stuff (maybe with the exception of property indexers).

What other non-standard, helpful little (or not so little) classes do you use in your code?

Learning Wix (the hard way)

I spent few last days at work, trying to create an installer for an application I’ve been working on. There aren’t many free tools to help you with that task: Wix, NSIS or Inno Setup as far as I know. I thought Wix was a reasonable choice. I don’t think that anymore.

Wix’s documentation ranges from poor to nonexistent. Many things are done in a very awkward way. And the best (and in many cases only) way to get any help, is the discussion group wix-users.

I’ve had my share of wrestling with Wix. Here’s what I learned.

  • You can define properties, call predefined properties, and change their values using [propertyName] syntax. This however does not work everywhere. If you for example want to pass some dynamic data to your Custom Action, you need another Custom Action, that will set the parameters for you before you can use them.

For example.

    <CustomAction Id="SetParameter" Property="MyAction" Value="&quot;[#myProgramToCall.exe]&quot;  -param [A_PROPERTY]" Execute="immediate" Return="check"  />
    <CustomAction Id="MyAction" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="check" Impersonate="no"/>
    <InstallExecuteSequence>
      <Custom Action="SetParameter" After="CostFinalize">
        (Not Installed) AND (NOT REMOVE)
      </Custom>
      <Custom Action="MyAction" Before="InstallFinalize">
        (Not Installed) AND (NOT REMOVE)
      </Custom>
    </InstallExecuteSequence>

You need all of that just to call myProgramToCall.exe during your installation with command line ‘-param whatever_the_value_of_A_PROPERTY_is’. You also need to set exactly those attributes on CustomAction tags, in order for that to work. This is different than in the documentation of QtExec, that sais:

<CustomAction Id="QtExecDeferredExampleWithProperty_Cmd" Property="QtExecDeferredExampleWithProperty"
              Value="&quot;[#MyExecutable.exe]&quot;" Execute="immediate" Return="ignore"/>
<CustomAction Id="QtExecDeferredExampleWithProperty" BinaryKey="WixCA" DllEntry="CAQuietExec"
              Execute="deferred" Return="check" Impersonate="no"/>
.
.
.
<InstallExecuteSequence>
    <Custom Action="QtExecDeferredExampleWithProperty_Cmd" After="CostFinalize"/>
    <Custom Action="QtExecDeferredExampleWithProperty" After="TheActionYouWantItAfter"/>
</InstallExecuteSequence>

If you set Return=”ignore” on Custom Action that sets the parameter, you’ll get an exception:

Error	1	ICE68: Invalid custom action type for action 'SetCertsBatPath'.

  • The (Not Installed) AND (NOT REMOVE)  is needed, if you want to run the action only when program is being installed, and not when it’s being removed.
  • If you have Votive project as part of your Visual Studio Solution and you want to reference files in other projects, you can use relative paths. Also use Configuration environmental variable to include the right version of files (Release/Debug). In order for this to compile, you also need to add project reference to My.Actual.Project in your Wix project.
<File Id="Microsoft.Practices.ObjectBuilder2.dll" Name="Microsoft.Practices.ObjectBuilder2.dll" DiskId="1"
Source="../My.Actual.Project/bin/$(var.My.Actual.Project.Configuration)/Microsoft.Practices.ObjectBuilder2.dll"/>
  • If you want to install a windows service as part of your installation, you use ServiceInstall tag, like this:
<ServiceInstall Id="MyService"
   Name="MyService"
   DisplayName="MyService"
   Type="ownProcess"
   Start="auto"
   ErrorControl="normal"  Vital="yes" Account="[SERVICE_USERNAME]" Password="[SERVICE_PASSWORD]"
   Description="Desc">
   <util:ServiceConfig FirstFailureActionType="restart" SecondFailureActionType="restart" 
      ThirdFailureActionType="restart" RestartServiceDelayInSeconds="10" ResetPeriodInDays="1" />
</ServiceInstall>
<ServiceControl Id="MyServiceControl"
   Name="MyService" Start="install" Stop="both" Remove="uninstall" Wait="yes"/>

Notice that there is no reference to the actual file containing the service. If you have many <File /> tags ServiceInstall will pick, and try to install as service the first one of them from the top. Alternatively you can explicitly designate a file by setting KeyPath attribute to yes.

<File KeyPath="yes"/>
  • Notice I passed username of a user that should be used to run a service, and password with [SERVICE_PASSWORD] and [SERVICE_USERNAME] properties. Where did they come from? – I customized the UI, and added a step to the installer, where user types in the username and the password.

    It requires quite a lot of work, but it’s actually quite straightforward process. I created another file in my Wix project, that holds the UI. I took one of the standard ones, and customized it as follows:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <WixVariable Id="WixUIBannerBmp" Value="My.Banner.bmp" />
        <WixVariable Id="WixUILicenseRtf" Value="License.rtf" />
        <UI Id="WixUI_MyUI">
            <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
            <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
            <TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
            <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
            <DialogRef Id="BrowseDlg" />
            <DialogRef Id="DiskCostDlg" />
            <DialogRef Id="ErrorDlg" />
            <DialogRef Id="FatalError" />
            <DialogRef Id="FilesInUse" />
            <DialogRef Id="MsiRMFilesInUse" />
            <DialogRef Id="PrepareDlg" />
            <DialogRef Id="ProgressDlg" />
            <DialogRef Id="ResumeDlg" />
            <DialogRef Id="UserExit" />
 
            <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
            <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="ServiceUserCredentialsDlg">1</Publish>
            <Publish Dialog="ServiceUserCredentialsDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
            <Publish Dialog="ServiceUserCredentialsDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">1</Publish>
            <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="ServiceUserCredentialsDlg">1</Publish>
            <Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
            <Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="2">1</Publish>
            <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
            <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
            <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">NOT Installed</Publish>
            <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed</Publish>
            <Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
            <Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
            <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
            <Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
            <Property Id="ARPNOMODIFY" Value="1" />
 
            <Dialog Id="ServiceUserCredentialsDlg" Width="370" Height="270" Title="[ProductName] Setup">
                <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="{\WixUI_Font_Title}User Information" />
                <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes" Text="Description" />
                <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.InstallDirDlgBannerBitmap)" />
                <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
                <Control Id="TextLabel1" Type="Text" NoWrap="no" X="20" Y="50" Width="290" Height="40" Text="A description" />
                <Control Id="UserNameLabel" Type="Text"   X="20" Y="110" Width="290" Height="13" Text="User Name:" />
                <Control Id="UserName" Type="Edit"        X="20" Y="122" Width="320" Height="18" Property="SERVICE_USERNAME" Text="47"/>
                <Control Id="PassLabel" Type="Text"    X="20" Y="143" Width="290" Height="13" Text="Password:" />
                <Control Id="Password" Type="Edit" Password="yes"  X="20" Y="155" Width="320" Height="18" Property="SERVICE_PASSWORD"/>
                <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
                <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="Next">
                    <Condition Action="disable">(SERVICE_USERNAME = "") OR (SERVICE_PASSWORD = "")</Condition>
                    <Condition Action="enable">
                        <![CDATA[(SERVICE_USERNAME <> "") AND (SERVICE_PASSWORD <> "")]]> </Condition>
                </Control>
                <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="Back" />
                <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="Cancel">
                    <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
                </Control>
            </Dialog>
        </UI>
 
        <UIRef Id="WixUI_Common" />
    </Fragment>
</Wix>

The Dialog tag, defines the look of the added window. It has some labels, and two textboxes, where user types username and password, that get saved to their respective properties. There is also a condition set on the Next button, which disables it, unless both fields are filled out.

The series of Publish above that, defines transitions between windows (which window should be shown when you click Next/Back).

Now, to actually instruct Wix to use this particular UI, we need to add in the first file the following line within Product tag:

<UIRef Id="WixUI_MyUI"/>

Hope this helps.

Technorati Tags:

AnkhSVN 2.0 – Visual Studio SVN integration reinvented

Along with Subversion 1.5 and TortoiseSVN 1.5 a new version of AnkhSVN has been released some time ago.

AnkhSVN_Solution_Explorer

AnkhSVN v1.x used to suffer from many issues. It was instable, used far too much resources, and had many usability bugs, that repelled many people. For version 2.0 many parts of the tool have been rewritten from ground up, and now it’s a very descent tool that you should give second chance if you abandoned it after trying out previous version.

I was very pleasantly surprised by it, when I fired up my Visual Studio today, and I saw this:

AnkhSVN

Geee, now it even checks for updates, cool.

Good stuff. If you passed on it before, you definitely should give it another try – really, new version is a whole other tool.

Free ebook: “Foundation of Programming” (the ALT.NET way)

Karl Seguin, has created, and made available for free and ebook, called “Foundation of Programming”. Don’t be fooled by its name however. If you’re thinking, “Foundation? I’m a senior level developer, what possibly could I learn from a foundation book?” and intend to pass by it, think again.

The topic range spreads from Domain Driven Development, Persistence, Dependency Injection, Unit Testing, Mocking, Object/Relational Mapping to Memory Management, Exceptions and Proxies. Looks like a solid weekend read.

Thanks a lot Karl!

Posting to Twitter with Launchy

[UPDATE2]

This tool has been deprecated. I leave the download links as they are, but if you want to interact with Twitter from within Launchy you better check out updated version of this tool here.

[UPDATE]

I uploaded a binary version of the tool, for those who don’t want/can’t deal with source code.

Grab it here.

I’ve been using Twitter for few days now, and I’ve tried quite a few options to use it. Currently I’ve settled on three different ways of interaction with the services (excluding browsing its website)

  • When I’m in Firefox I use TwitterBar extension, that allows me to write posts in my address bar.
  • When I read posts (tweets?) of other users in Twihrl and I want to comment on them, I use Twihrl to post.
  • When I’m just doing something on my computer and I want to post without running Firefox or Twihrl I use my beloved app launcher – Launchy to post.

This last option is a little bit tricky and it required a little bit of work to set up. I assume you have Launchy already installed. If not, go get it here.

You’ll also need Twitt.Poster that we’ll be invoking from Launchy to do actual work for us. Just compile the project, set your username and password in app.config, and put the compiled files in some directory.

Next, open Launchy, right-click it, and select “Options”. Then navigate to “Plugins” tab, and select “Runny”. This is the plugin, that will invoke Twitt.Poster.

To make it do so, click the ‘+’ button at the bottom and add new entry to the grid. Name is the name of the command in Launchy – “twitt” in my example but you can call it whatever you like. Then Program is the fully qualified path to the executable of the poster application. Last column is command line arguments and you should set it to “$$”. Notice that you need to put dollar sings in quotation marks, otherwise it won’t work. When you’re done just click OK, and we’re all set.

launchy_twitter

Now you can invoke the command in Launchy, press tab, and enter your message. When you’re done just press enter and your message should get posted to Twitter.

launchy_twitter2

That’s it. So far this is my favorite way of posting to Twitter.

As for Twitter.Poster, use it however you like and don’t sue me if it breaks something. I publish it on terms of BSD licence. However, it uses Twitterizer library, that is licensed under terms of GPL v3, so take that into account when creating derivative work.

This is just a sample application that I created mostly for myself. However you can post bugs and feature requests in comments. I don’t want to promise anything, but I may implement some of them if there’s demand and I find some time.

Technorati Tags: ,

ALT.NET Thunderbird configuration

ALT.NET discussion group is quite active.

altnet_activity

There are around 1700, to over 2000 posts per month. It’s easy to drown in the flood of information, and if you want to benefit from the group you need to develop a strategy.

Here’s mine:

I use Thunderbird, as my email client, and for the group as well. In its basic form, it’s not so well suited for the job of handling threaded discussion, but same as Firefox – you can expand its capabilities with extensions.

altnet_thunderbird_threads

The first thing to do, even before you go looking for extensions is viewing your messages by threads. [via Lifehacker]

To do this, go to Tools–>Options–>Advanced–>General, and select “Config Editor”. Find mailnews.thread_pane_column_unthreads and change its value to false. And you’re done. You should have now your messages grouped in threads and sorted by date, like I have on the screenshot above.

altnet_sort_by_thread

 altnet_extensions_quotecollapse

My favorite extension is QuoteCollapse. Its name is quite self-explanatory – it collapses quoted text in messages, so that you can only see what the person actually has written, without seeing all previous posts that you probably already read before.

 

altnet_extensions_quotecollapse_sample

  The small picture you see on the above screenshot was put there by MessageFaces extension. It gets those images from gravatar.com, or some other places. I don’t exactly know, but it’s good to visually recognize the author of the message. Even if you remember the author as “tape-measure guy”, it’s still easier to connect those posts to earlier posts by the same author, at least for me.

SearchBar, is a small but useful extension that allows you to quickly find some message very easily.

Url Link, is an extension that I use in both: Firefox and Thunderbird, that allows you to click links that are inserted as plain text, like this: www.goo… eeeer I mean www.live.com.

altnet_extensions_QuickTextQuickText allows you to easily insert parts of text, with some level of flexibility, i.e. you can do something like: [[TO=firstname]]. I use it for my header and footer mostly.

GMailUI sets a few usefull shortcuts, so that you can with one key, move to next unread message, mark all thread as read, and so on. I believe those are the same shortcuts as for GMail, but I’m to lazy to verify that.

And that’s about it. How about you? What do you use?