Brandon Pugh's Blog

Condensing fact from the vapor of nuance.

Avoid Committing Dumb Mistakes With Git Hooks

| Comments

TLDR: Git hooks are an awesome way to automatically verify your code as you commit your changes

I’m sure we’ve all been there where we accidentally committed a change that we were supposed to undo or wasn’t ready to be pushed and don’t realize it until the build breaks or QA finds a bug.

The first step I take to avoid is instead of just running git add -A I make sure to review all the changes in the files I’m potentially committing. This is where a graphical tool like Gitk or SmartGit comes in handy as they allow you to click on your modified files and easily view a diff and then select with ones to stage. Unfortunately changes still slip through as happened to me yesterday when a change of mine got pushed all the way to Test before it was noticed. This led me to create an additional safety net.

Enter Git hooks

Client side Git hooks are simply scripts that reside in you local repo in the .git/hooks directory. These scripts get run at specific times during your local workflow depending on the name of the hook. So for me I wrote a pre-commit hook that checks all the files that are about to be committed and looks for the string 'todo: remove'

1
2
3
4
5
6
# Redirect output to stderr.
exec 1>&2
FORBIDDEN='todo: remove'
git diff --cached --name-only | \
    xargs grep --with-filename -i -n "$FORBIDDEN" && echo "COMMIT REJECTED Found '$FORBIDDEN' references. Please remove them before commiting" && exit 1
exit

So now if I make any change that I want to undo before committing, say like commenting out a conditional to make testing easier, I just add a comment like //todo: remove and git won’t let me commit the changes.

You could also have it look for common debug statements like console.log in javascript files or even have it run a code analysis tool against the files staged for commit.

Has anyone used git hooks before? Have any useful ones to share?

Checking if a Dom Element Exists With JQuery [Byte Sized Tips]

| Comments

This is a simple tip but one I feel makes my code a bit easier to read.

I was never very pleased with the standard way of checking if a dom element exits in jquery:

1
2
3
if($('#userName').length !== 0){
    //do something with $('#firstName')
}

The solution I like is to create a very simple jQuery plugin to encapsulate this logic:

1
2
3
4
// this extension reads better when selecting elements
$.fn.exists = function () {
    return this .length !== 0;
};

You can place this anywhere you like such as in a ‘utils.js’ file, so long as it loads after jQuery. Now your code would like so:

1
2
3
if($('#userName').exists()){
    //do something with $('#firstName')
}

How to Use jQuery .on() Instead of .live()

| Comments

One of the most used features of jQuery is the easy methods it provides to to attach event handlers to dom elements like this simple example:

1
2
3
$('.submitButton').click(function() {
    validateForm();
});

It doesn’t get much easier than that. However, a lot of times we’ll want to attach events to elements that were loaded after the initial page load such as from the result of an ajax request. This is where the .live() method comes in really handy:

1
2
3
$('.submitButton').live('click', function() {
    validateForm();
});

However if you’re using jQuery 1.7 and up you now have access to the .on() method which is a very versatile method offering a number of improvements over .live(). This post does a good job of explaining the main issues with using live, all of which you can avoid by using .on().

So how do you go about using .on()? Well .on() basically provides a consistent interface for practically all your event binding needs. You can replace the first example with:

1
2
3
$('.submitButton').on('click', function() {
    validateForm();
});

and you can obviously replace 'click' with whatever event you wish to handle.

Now to replace the previous live() example with .on() requires the tiniest bit more effort. The way .on() works is it will attach the event to the first selector you specify and if you specify a second selector it will look at all the events that bubble up to it and will only execute the event handler for events that came child elements matching the second selector. So we could replace the example with this:

1
2
3
$('#userForm').on('click', '.submitButton', function() {
    validateForm();
});

Since the submitButton element is a child of the userForm element, the click event from the button will bubble up the dom and when it reaches the form element our event handler will be called. This is how we can dynamically insert as many elements with the calls submitbutton and have them be automatically handled. This is essentially the same thing that .live() accomplishes however it does so by automatically attaching the event handler to the document element which can have performance implications as now our click event would have to bubble all the way up the dom tree to the document before the handler will see it. It would look like this:

1
2
3
$('document').on('click', '#submitButton', function() {
    validateForm();
});

Let’s look at one last examle:

1
2
3
$("#dataTable tr").live("click", function(event){
    alert($(this).text());
});

This is a fairly common scenario where #dataTable is populated dynamically by data retrieved asynchronously from the server. Again the issue here is that all the events have to bubble up to the document before they are seen by the handler. We can instead replace this with:

1
2
3
$("#dataTable tbody").on("click", "tr", function(event){
    alert($(this).text());
});

My Thoughts on the Global Day of Coderetreat

| Comments

Last weekend I attended the Global Day of Coderetreat in Dallas, TX which was not only my first Coderetreat but also my first time attending a developer community event and I have to say that it was a great and worthwhile experience.

If you’re unfamiliar with the format of a Coderetreat you can read all about it at coderetreat.com but its basically a code kata where you spend most of the day pairing up in 45 min sessions and attempt to solve Conway’s Game of Life (a fascinating problem by itself). I had only first heard about it a couple weeks before when Corey Haines went on the Herding code podcast to talk about it and I’m glad I went because I feel took away a few key benefits.

Getting to know my community

I hadn’t realized what a strong development community there was in my city and I met some really cool people who were not only fun to talk to but who I could learn lots of new things from. I found out that there are other regular meet ups such as the Dallas Hack Club which I plan to start attending. I even found out that there are quite a few other people besides me who still like to use Vim or Vi key mappings!

The value of TDD

In school and the places I’ve worked there hasn’t been a very strong emphasis on the importance of TDD or even unit testing so I had only ever dabbled in it after reading about in various books and blog posts. After the Coderetreat however, I was sold. The Coderetreat very strongly encourages following TDD practices and pairing up with an experienced unit tester or TDD practitioner is a great way to learn. Its true that you can get addicted to the quick feedback you get from unit tests and the safety in knowing that whenever we went back and refactored one of our methods we didn’t have to worry that we broke something since the unit tests still passed. One of my partners suggested that I read Michael Feathers book Working Effectively with Legacy Code and it is looking to be a great read. The bulk of what I’m currently doing at work is maintaining existing systems and now I’m working on incorporating unit tests into my updates.

Exposure to new languages

Coderetreat is language agnostic so they encourage pairing up with someone with development experience fairly different from your own which is a great way to see other programming languages in action. I probably spent most of the morning with Ruby guys and it was impressive to see how quickly we could go from a blank project to our first failing test! I also saw some of the cool things you can do with Rake as far as automatically building .net projects and I got some exposure to NSpec.

So I highly recommend attending a Coderetreat if you get the chance but at the very least get out in your community by attending some local user groups or conferences.

Getting Started With PetaPoco and Postgres

| Comments

I’m currently working on a project I’ve inherited that uses a Postgres sql backend and I was looking for an easy way to make writing our data access layer less time consuming and painful. My first thought was to use a micro-ORM like Massive but while I’ve heard some really great things about Massive, I felt it might be a tough sell to my team members who aren’t too comfortable with Expandos and its dynamic nature (I know, but change in baby steps I suppose). Then I came across PetaPoco and it seemed to fit the bill. Its basically a mico-ORM like Massive with built in support for Postgres except that it also works with POCOs (Plain old CLR Objects) and was pretty easy to get up and running with.

First if you’re not already working with Postgres you’ll need to install a provider like Npgsql. You can get the assemblies from their site or use Nuget with the command “Install-Package Npgsql”. If you were already using Postgres like I was you’ll have to add a bit more to the web.config/app.config in order to use PetaPoco.

1
2
3
4
5
6
7
8
9
<system.data>
  <DbProviderFactories>
    <add name="Npgsql Data Provider" invariant="Npgsql" support="FF" description=".Net Framework Data Provider for Postgresql Server"
         type="Npgsql.NpgsqlFactory, Npgsql, Version=2.0.11.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7" />
  </DbProviderFactories>
</system.data>
<connectionStrings>
  <add name="Postgres" connectionString="Server=localhost;Port=5432;User Id=testuser;Password=secret;Database=testdb;" providerName="Npgsql"/>
</connectionStrings>

Notice you have to add the DbProviderFactories to the system.data section (you can also do this in the machine.config though you may run into issues when you deploy) and be sure to specify that as the providerName in the connection string.

Next install PetaPoco which you can get from Nuget with “Install-Package PetaPoco” which installs it in your project with some handy T4 templates for generating pocos from your database schema but all you really need is the single PetaPoco.cs file somewhere in your project and you should be ready to go. Check out their site for some great examples to get coding.

Its also worth noting though that if you’re targeting .Net 3.5 you’ll need to define PETAPOCO_NO_DYNAMIC as a conditional compile symbol in your project settings or it won’t compile since PetaPoco now also supports dynamics.

GhostDoc [Dev Tool of the Week]

| Comments

Thought I would try to make it a thing where I post about a particular tool I’m using that makes life easier for me as a developer.

GhostDoc is a cool little Visual Studio plugin that makes commenting your methods and properties much easier. With a keyboard shortcut or right clicking on a method name, GhostDoc will automatically generate xml documentation comments by intelligently looking at the method name and parameters:

I know how we can all get lazy when it comes to documenting our code especially when we’re on a time crunch but I’ve definitely found GhostDoc helps minimize a bit of the friction when it comes to writing documentation comments and your team members will definitely thank you for it.

GhostDoc

Allow Pasting Multiple Lines in IE Textbox

| Comments

You may have noticed before that if you try to paste more than one line of text into a textbox in Internet explorer it will on only paste in the first line and disregard the rest. Firefox and Chrome on the other hand will automatically paste all lines of the text onto the one line of the textbox. This issue came up in one of the projects I’m currently working on where we wanted users to be able to paste in a list of ID numbers they wanted to run a search on.

I knew it was possible to get it working in IE since I had seen it done with the search box on Google Maps. I figured the way to do it would be to be to capture the text from the clipboard when the user is attempting to paste it into the textbox and reformat the text into a single line. In the end this is what the javascript looked liked:

1
2
3
4
5
6
7
8
if (window.clipboardData) {
        $('#textboxId').bind('paste', function (e) {
            var clipped = window.clipboardData.getData('Text');
            clipped = clipped.replace(/(\r\n|\n|\r)/gm, " "); //replace newlines with spaces
            $(this).val(clipped);
            return false; //cancel the pasting event
        });
    }

To begin with, I’m using jQuery because it’s incredibly powerful and it’s 2011 and if you’re not using a javascript library then you are missing out. This allows me to bind an event handler for the paste event to the textbox element. Note that the paste event is supported in practically all browsers however for security reasons accessing the clipboard is only supported in IE. Fortunately for this purpose I’m only interested in Intenet Explorer and we can get the text with window.clipboardData object. Passing ‘Text’ into the getData() function is required to return the data as text.

Next calling .replace() on the text to replace all of the newline characters with spaces (or any delimeter we choose). Then we simply set the value of the textbox to the newly formatted text.

1
2
clipped = clipped.replace(/(\r\n|\n|\r)/gm, " "); //replace newlines with spaces
$(this).val(clipped);

Also don’t forget to call return false; to prevent the original text from still being pasted in.

Lastly we need to handle what will happen in all other browsers. We only want to attempt to read from clipboardData in IE since it will be undefined in all other browsers. One way to accomplish this is by detecting what browser the user has however this is not recommended. The trend nowadays is to use feature detection and there are entire javascript libraries such as Modernizr dedicated to detecting which features a browser supports and then degrading gracefully when it doesn’t. In this case we can simply surround our code with an if statement to ensure our code won’t cause any errors outside of Internet Explorer.

1
if (window.clipboardData){}

And there you go, overcoming one of Internet Explorer’s shortcomings with some simple and concise javascript.

My Development Journal

| Comments

After having just watched one Rob Conery’s excellent screencasts at Tekpub on going from Coder to Developer, I’ve finally decided to start my own blog. Rob suggested possibly making it something of a development journal if you’re learning a new language or technology and being relatively new to the industry and being a lead developer, it feels like I’m learning so much so fast. So this is my outlet for recording/sharing my experiences, knowledge, trials, triumphs, and mistakes with anyone who might find it interesting or useful.