Visual Studio Online and SourceTree

I really like Visual Studio Online, and I tend to use it for my various pet projects. It’s free for up to 5 users, and you get issue/backlog tracking and source control all in one spot. Perfect for my needs!

A few months back, we made the switch from TFS to Git at work. The Git integration with Visual Studio 2012 has proven suspect, so I’ve taken to using SourceTree for all of my source control needs, and I really like it. So, when it came time to create my next team project, I decided to go stick with Git/SourceTree in Visual Studio Online. Setup was pretty easy but not entirely intuitive, and you know what that means. Yep, we’re gettin’ bloggy wit it. I’m going to walk you through the steps of creating a new Visual Studio Online team project and connecting to it with SourceTree.

Create a Visual Studio Online Account

In order to create a new project, you’ll need a Visual Studio Online account. It’s free to get one, and it links to your Microsoft Live account. Head on over to visualstudio.com and sign up!

create-new-account

You’ll be prompted for an account URL, which will be whateveryouwant.visualstudio.com. Remember this, you’ll need it later.

Create a Team Project

Now that you’ve got your account, the next step is to create a new team project. If you browse to your account URL (whateveryouwant.visualstudio.com), you should see a link to create a new project. Click that and a dialog pops up to collect details about the new project. Note that you’ll want to change the version control option to Git.

create-new-project

Enable Alternate Credentials

Here’s the trickiest part of the setup: you need to enable alternate credentials in order for SourceTree to access the repository. Go to your user profile by clicking your name in the upper-right corner, then click My Profile.

click-my-profile

The User Profile dialog will be displayed. Click to the Credentials tab to enable alternate credentials, then enter a secondary user name and password.

enable-alternate-creds

Make note of these values, too. They’ll also be needed when you configure SourceTree.

Configure SourceTree

Okay, Visual Studio Online’s all ready to go at this point, and now it’s time to put it all together! Download and install SourceTree, if you haven’t already. Open it up and click the Clone/New button. For the source path/URL, enter the following:

https://USERNAME:PASSWORD@ACCOUNT.visualstudio.com/defaultcollection/_git/PROJECT

Note that USERNAME and PASSWORD will be the secondary user name and password you created in your Visual Studio Online profile. ACCOUNT will be the value entered for your Account URL when creating your Visual Studio Online account, and PROJECT will be the name of the Visual Studio Online team project.

clone-new-repository

With the URL entered correctly, SourceTree should recognize it as a Git repository and display a message. Change the destination path if you’d like, then click the Clone button and you’re done!

Advertisement

Mountek nGroove Snap 3

Back before everybody’s cell phone had built-in GPS, I had a TomTom GPS. It came with a suction cup so you could stick it to the window, but that never really worked that well for me. It would constantly fall off the window, and it drove me nuts. So, I bought a beanbag friction mount that I could stick it to, and it would sit nicely on the dashboard whenever I was driving somewhere that I needed directions.

Fast forward to present day. I use my cell phone for directions when I need them, but I prop it up in a little groove below my car’s instrument panel. If I turn too fast, it goes flying, and it’s low enough that I’m constantly looking down for the next turn. The solution is a cell phone mount, and I’ve been shopping for the perfect one for a long time.

I didn’t want something that used a suction cup because of my previous bad experience, and I didn’t want something that used an adhesive because I worry about it doing permanent damage or failing over time. The vents in my car are not in a good location, so any clip-on mount’s not so great. I was considering going for a suction cup to re-use with my beanbag, but I was turned off by storing it. I wouldn’t want to leave it out all the time because the rubber could melt on a really hot day, it’s too big to store with the base & mount assembled, and the idea of disassembling & reassembling with each use is less than ideal, too.

Enter the Mountek nGroove Snap 3 magnetic car mount.

mountek_ngroove_snap3

This thing is great. First, it attaches to the CD slot in my car which is perfect. It’s right where I want it in the middle of the instrument panel, and I don’t think I’ll ever put another CD in there, anyway. The mount is small and reasonably unobtrusive, so I won’t have some big, bulky bracket that’s either out all the time or being stored with each use. It’s magnetic, so I just stick a metal badge under my phone’s case and it just sticks–super easy to mount and remove with one hand. There are no brackets, so I can put it in any orientation with whatever cables I might need (charging, stereo). It’s universal, so it’ll work with phones or tablets or anything else that’s light enough to be held by the magnet (which is pretty strong). It can also be used as a desktop stand for your phone, if you’re into that kind of thing, too.

The only thing that I can even think to complain about is that my phone blocks the clock a bit when it’s mounted, but I can still see the time by leaning a little to my left. (So be sure to think about what controls or displays it might be blocking.) Other than that, it’s amazing. Even my wife was impressed, which is really saying something. Best mount ever.

Greenshot for Screenshots

I used to knock on Snagit from TechSmith. I didn’t get why somebody would pay for a screenshot utility when Windows comes with one built-in. Then I got a license, and I was converted. I loved not having to hand-draw crappy arrows, boxes, and highlights. It upped my screenshot game, big-time!

snipping_tool

But, like all good things, my time with Snagit came to an end. I left the job that brought us together, and with it, my license. I was back to living in the screenshot dark ages with Snipping Tool and Paint. After a few months, I’d had enough. I was ready to put down $50 for a personal Snagit license so that I’d never be without it again. I’m pretty sure I even went as far as putting it into my cart on the TechSmith website, but I never quite pulled the trigger.

I don’t know why it took me so long to think of this, but I finally headed over to Google and searched for Snagit alternatives. And that’s where I met one of my new best friends: Greenshot.

Greenshot has all the features that I’d grown to love about Snagit, but it’s free & open-source. Here’s a quick list of what I love most:

  • PrtSc to select a region (Ctrl+PrtSc for entire desktop, Alt+PrtSc for current window)
  • Screen grabs open in editor with drawing tools like rectangles, ellipses, arrows, highlighter, textboxes, and speechbubbles
  • Obfuscation tool to draw a box around & blur sensitive data
  • Auto-incrementing counter circles — perfect for giving directions!

greenshot

The only thing I didn’t love right out of the gate is that the default keybinding for copying the image from the editor to the clipboard is Ctrl+Shift+S instead of just Ctrl+C. But I’ve gotten used to it, and it’s nice being able to use Ctrl+C/Ctrl+V to copy/paste elements in the editor. It lets me do things like have arrows that are the exact same size and parallel, which is great since I’m super anal about stuff like that!

So, if you’re stilling using Snipping Tool and/or Paint or looking for a great alternative to Snagit, give Greenshot a try. You won’t be disappointed! Unless you want something that also takes videos. Then you’d be disappointed and would probably want to go get Snagit. But for screenshot editing, go Greenshot!

Broadcast Changes to Angular Factory Properties

I was making a little website with Angular the other day, and I wanted to have a search box in my nav bar that could be used from any page. When the search control is used, the user is sent to a search page that displays results but also lets users run additional searches. Both search functions use the same angular factory to execute their searches. Unfortunately, I was finding that the nav bar search control wouldn’t update search results when used from the search page.

I was able to solve the problem by using $broadcast and $on. It’s pretty simple, and it looks a lot cleaner than a lot of $watch solutions that I ran into while looking for a solution.

Here’s what my factory looks like:

app.factory('searchService', ['$rootScope', '$http', function ($rootScope, $http) {
    var factory = {
        search: search,
        getResults: getResults
    };
    
    var _results = [];
    
    function search(criteria) {
        return $http.post(_serviceBase + 'api/search', criteria).then(function (results) {
            _results = results.data;
            $rootScope.$broadcast('searchCompleted', _results);
            return results;
        });
    };

    function getResults() {
        return _results;
    }

    return factory;
}]);

And here’s my searchController that handles the broadcast event with $on:

app.controller('searchController', ['$scope', 'searchService', function ($scope, searchService) {
    $scope.criteria = {};
    $scope.results = searchService.getResults();

    $scope.search = function () {
        searchService.search($scope.criteria).then(function (results) {
            $scope.results = results.data;
        }, function (error) {
            console.error(error.data.message);
        });
    };

    $scope.$on('searchCompleted', function (results) {
        $scope.results = searchService.getResults();
    });
}]);

Note the use of $rootScope in the factory. Broadcasting the change is a single line of code, and handling the event in relevant controllers is pretty simple, too. Nice!

String Formatting with Regex

My latest favorite trick with regular expressions is to shortcut string formatting. We’ve all written some code like this:

if (/* string is not formatted a certain way */)
{
    /* make it formatted that way */
}

Now, there’s nothing wrong with that code, but for simple examples you could do it all in one step with a regular expression!

Here are a few examples:

// remove "www." from a domain if one exists
// domain.com     -> domain.com
// www.domain.com -> domain.com
Regex.Replace(input, @"^(?:www.)?(.+)$", "$1");

// format phone number
// 1234567890       -> 123-456-7890
// (123) 456-7890   -> 123-456-7890
// (123) 456 - 7890 -> 123-456-7890
Regex.Replace(input, @"^\(?(\d{3})\)?\s*(\d{3})\s*-?\s*(\d{4})$", "$1-$2-$3");

Yay, regular expressions!

A Better Table.CreateInstance() for SpecFlow

SpecFlow remains my top choice for automated integration testing. I love writing cute little cukes and putting them together in different ways to create different test scenarios. And one of my favorite cuke tricks is using tables to define an object, which I wrote about some time ago.

The CreateInstance<T> extension method provides an easy way to convert that table data into objects for testing, but I really think there should be a better way to populate child properties of complex objects.

Consider this example:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}

It would be nice if you could write a cuke like this:

Given a person
	| field          | value         |
	| firstName      | adam          |
	| lastName       | prescott      |
	| address.street | 123 number ln |
	| address.city   | anytown       |
	| address.state  | ny            |
	| address.zip    | 10000         |

And then convert it to a person like this:

[Given(@"a person")]
public void GivenAPerson(Table table)
{
    var person = table.CreateInstance<Person>();
    ScenarioContext.Current.Set(person);
}

But you can’t. Well, you can, but the address property won’t be populated. I didn’t like that, so I decided to grow my own. It works by identifying the child properties in the table and creating sub-tables, then using reflection to find and set the property on the result object. It works recursively, too, so you could even go n properties deep (i.e., address.state.abbreviation).

At its core, it’s just using CreateInstance<T> so you get all the niceties that go along with that. Note also that it only works with the 2-column, vertical tables with field and value columns. I called my extension method BuildInstance since CreateInstance was already taken. Here it is… Enjoy!

using System;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using TechTalk.SpecFlow;
using TechTalk.SpecFlow.Assist;

public static class TableExtensions
{
    public static T BuildInstance<T>(this Table table)
    {
        T result = table.CreateInstance<T>();

        // find sub-properties by looking for "."
        var propNames = table.Rows.OfType<TableRow>()
            .Where(x => x[0].Contains("."))
            .Select(x => Regex.Replace(x[0], @"^(.+?)\..+$", "$1"));

        foreach (var propName in propNames)
        {
            // look for matching property in result object
            var prop = typeof(T).GetProperty(
                propName,
                BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);

            if (prop != null)
            {
                // create sub-table with relevant rows (field == propName.something)
                var subTable = new Table("field", "value");
                var re = new Regex(string.Format(@"^{0}\.([^\.]*)$", propName), RegexOptions.IgnoreCase);
                table.Rows.OfType<TableRow>().Where(x => re.IsMatch(x[0]))
                    .Select(x => new[] { re.Replace(x[0], "$1"), x[1] })
                    .ToList()
                    .ForEach(x => subTable.AddRow(x));

                // make recursive call to create child object
                var createInstance = typeof(TableExtensions)
                    .GetMethod(
                        "BuildInstance",
                        BindingFlags.Public | BindingFlags.Static,
                        null,
                        CallingConventions.Any,
                        new Type[] { typeof(Table) },
                        null);
                createInstance = createInstance.MakeGenericMethod(prop.PropertyType);
                object propValue = createInstance.Invoke(null, new object[] { subTable });

                // assign child object to result
                prop.SetValue(result, propValue);
            }
        }

        return result;
    }
}

Selective Revert in Git

Uh oh, a mistake was made in your Git repository, and it needs to be undone. I use SourceTree for the majority of my Git-in’, and reverting changes is really easy. Just right-click a commit, choose “Reverse Commit,” answer “Yes” in the confirmation box, and the deed is one. On one hand, it’s nice because it’s so simple. On the other, it doesn’t give you much control.

I recently had to deal with a bad merge that contained many files. Some of the merge was legit, but part of it was also undoing valid changes. I wanted to partially revert the commit and pick which files/changes to keep. Unfortunately, I couldn’t find a way to do this in SourceTree, but it’s pretty simple to do from the command line.

git revert can be run with -n or –no-commit to revert a commit but not automatically commit the result.

git revert --no-commit <sha-1>

My commit was a merge, and undoing merges can be more complicated. For my purpose, simply adding -m 1 was sufficient.

git revert --no-commit -m 1 <sha-1>
%d bloggers like this: