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