Getting Branches from Codeplex in Strider

After my last post, I was at the point where strider would list my repos, and I could even see a little checkbox by their name. Unfortunately, clicking on the configure buttons would do nothing. This is because clicking those buttons calls getBranches, and I am not yet doing anything in that method.

Unfortunately, the Codeplex API doesn't include any functionality for getting the branches for a given repository. This means I am going to have to do this work manually, and I'm going to have to go through the source control provider.

For Mercurial branches, I thought it would be somewhat of a rigamorale. You see, Mercurial requires the repository to be on a local computer before you can see the branches. It turns out, stackoverflow has a question (and answer!) about how to query a remote repository. Since Codeplex uses hgweb to serve the repo, we can query it directly:

if (sourceType === 'mercurial') {  
    request(config.sourceUrl + '/branches?style=raw', function(error, response, body) {
        if (error) return callback(error, null);
        var branches = [];
        var rows = rawText.split(/\r\n|\r|\n/g);

        // ignore the last row... it is always blank
        for (var i = rows.length - 2; i >= 0; i--) {
            var branchInfo = rows[i].split(/\t/g);
            if (branchInfo[2] !== 'closed') {
                branches.push(branchInfo[0]);
            }
        }

        callback(null, branches);
    });
}

Mercurial branches can be marked closed, but they are never deleted. Since Codeplex returns all Mercurial branches, I must filter out the closed ones.

For git repositories, my first thought was to use strider-git. Unfortunately, it requires a context object, but the context is only available when jobs are being run. Since the branch retrieval is happening long before that, I decided to use git-node. It is almost as easy to use as the mercurial setup:

if (sourceType === 'git') {  
    var remote = git.remote(config.sourceUrl);
    remote.discover(function(err, refs) {
        if (err) {
            callback(err, null);
        } else {
            remote.close(function(error) {
                if (error) {
                    callback(error, null);
                } else if (!refs) {
                    callback("No data returned for the repo.", null);
                } else {
                    var branches = Object.keys(refs).filter(function (ref) { return ref.indexOf('refs/heads/') == 0; }).map(function (ref) {
                        return ref.replace('refs/heads/', '');
                    });

                    callback(null, branches);
                }
            });
        }
    });
}

I don't want to get anything but branches, hence the filter. If I wanted to use tags, removing this filter will allow me to do so.

Now when I go to the configure screen, it navigates correctly, but the UI seems... off. It appears that I have missed something... Oh yes, the config.html and config.js. I haven't implemented anything to configure, but after throwing (basically) blank config files at strider, things seem to be working fine:

<div class="row-fluid">  
</div>  
app.controller('CodeplexController', ['$scope', function ($scope) {  
  $scope.config = $scope.providerConfig();

  $scope.save = function () {
    $scope.providerConfig($scope.config, function () {});
  };
}]);

And with that, I can successfully add projects to strider, open the config screen, and you can get autocomplete in the branch selection box! Woot! Maybe I can soon have it actually fetching and running tests... maybe. As always, you can grab the code on github.

-AH


View or Post Comments