I hinted about this in my blog post last night, but I've been working on a proof of concept application meant to judge the relative "health" of your GitHub repositories.

My idea was that there are various things we could check within a repository to judge how well it is being maintained. Things like the age of the last update, number of open bugs, etc. Obviously there is no way to fully automate this type of scan, but I wanted to give it a shot and see if I could learn anything interesting.

I was initially going to build it in Node.js so I could OAuth against the GitHub API, but I decided I'd give hello.js a try. hello.js provided a client-side method of doing OAuth against a variety of services. In some cases it uses an app proxy on its own server and you have to do a bit of registration beforehand, but for the most part, it worked pretty well. As an example, this hits the GitHub API to read the current user's repositories.

hello('github').api("/users/repos",{"type":"owner"}).then( function(r) {
    console.log("repos", r);
});

In my application, I built a simple function that looped over your repos and added each one to a global array.

function startFetchingRepositories(path) {
    if(!path) path = '/user/repos';
    console.log('fetching repos with '+path);
    hello('github').api(path,{"type":"owner"}).then( function(r){
        Array.prototype.push.apply(repos, r.data);
        console.dir(r.data[0]);
        if(r.paging && r.paging.next) {
            startFetchingRepositories(r.paging.next);   
        } else {
            displayRepos();   
        }
    });

}

This is called after the authorization is complete which is also fairly easy in the hello.js library:

hello('github').login();

Yeah, that's it. You tie this with an event handler as well:

hello.on('auth.login', function() { ...});

So... ok. That part didn't take too much time. The next part was actually figuring out how to determine the health of a repo. I decided to start simple - I'd check the age of the last update and the number of open issues - which luckily is part of the repository object information.

/*
I take in a data object (right now it's the crap I'm sending to the template, not the full github

I'm a bootstrap class representing how 'bad' the repo is
range from bad to good is: danger (red), warning (yellow), default(gray), info (blue), success (green)
I didn't do primary, too bright
*/
function determineLevel(data) {
    //points are bad. you don't want points
    var points = 0;
    
    //First rule, check age
    if(data.lastago > 360) {
        points += 7;
    } else if(data.lastago > 160) {
        points += 5;
    } else if(data.lastago > 120) {
        points += 3;
    } else if(data.lastago > 60) {
        points += 1;
    }

    //check open issues
    if(data.open_issues_count > 50) {
        points += 4;
    } else if(data.open_issues_count > 25) {
        points += 2;
    } else if(data.open_issues_count > 10) {
        points += 1;   
    }
    
    switch(points) {
        case 0: return "success";
        case 1:
        case 2: return "info";
        case 3:
        case 4: return "default";
        case 5:
        case 6: return "warning";
        default: return "danger";    
    }
    
}

As you can see - I simply apply some arbitrary points based on how bad I think certain values are. I spent some time trying to figure out how many points certain things should get, but, then I said screw it. Let me ship this first version and let smarter folks then I figure it out.

To display everything, I just used Bootstrap. Why? Because.

shot

Want to see the full source code - and help make it better? It's up (of course) on GitHub: https://github.com/cfjedimaster/githubhealth.

Want to run it yourself? You can see it in action here: https://static.raymondcamden.com/githubhealth.

As always, I'm curious to know what you think. Is this helpful? Should I keep hacking away at it?