Last active
August 10, 2016 15:15
-
-
Save alexhsamuel/d477ab16caf87a42f0ea8357f4546bc6 to your computer and use it in GitHub Desktop.
Tool to clone all open PRs of a GitHub repo into a subdirectory.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
// -*- javascript -*- | |
/** | |
* Tool to clone all open PRs of a GitHub repo into a subdirectory. | |
* | |
* Usage: | |
* | |
* clone-open-prs USER/REPO DIR | |
* | |
* USER/REPO is the GitHub username and repo name, and DIR is the output | |
* directory name, which must not already exist. | |
* | |
* For each PR, creates a subdirectory under DIR, clones the corresponding head | |
* repo into it, and resets it to the PR's head SHA hash. | |
* | |
*/ | |
//------------------------------------------------------------------------------ | |
var spawnSync = require('child_process').spawnSync; | |
var fs = require('fs'); | |
var https = require('https'); | |
var path = require('path'); | |
var API_HOST = 'api.github.com'; | |
//------------------------------------------------------------------------------ | |
/** | |
* Gets all open pulls for `repo` from GitHub. | |
*/ | |
function getPulls(repo, callback) { | |
https.request({ | |
host: API_HOST, | |
path: '/repos/' + repo + '/pulls?state=open', | |
headers: { | |
'User-Agent': 'node.js' | |
} | |
}, function (response) { | |
var data = []; | |
response.on('data', function (chunk) { | |
data.push(chunk); | |
}); | |
response.on('end', function() { | |
var pulls = JSON.parse(data.join('')); | |
callback(pulls); | |
}); | |
}).end(); | |
} | |
/** | |
* Clones a git repo with URL `repo` into `dir` and resets it to SHA `hash`. | |
*/ | |
function cloneRepoHash(repo, hash, dir) { | |
var clone = spawnSync('git', ['clone', repo, dir]); | |
if (clone.status !== 0) { | |
console.warn('failed to clone repo: ' + repo); | |
return false; | |
} | |
var reset = spawnSync('git', ['reset', '--hard', hash], {cwd: dir}); | |
if (reset.status !== 0) { | |
console.warn('failed to reset ' + dir + ' to hash: ' + hash); | |
return false; | |
} | |
return true; | |
} | |
//------------------------------------------------------------------------------ | |
if (process.argv.length != 4) { | |
console.error('usage: clone-open-prs REPONAME OUTDIR'); | |
process.exit(2); | |
} | |
var repo = process.argv[2]; | |
var outDir = process.argv[3]; | |
fs.mkdirSync(outDir, function (err) { | |
if (err) { | |
console.log('failed to create ' + outDir + ': ' + err); | |
process.exit(1); | |
} | |
}); | |
getPulls(repo, function (pulls) { | |
for (var i = 0; i < pulls.length; ++i) { | |
var pull = pulls[i]; | |
var number = pull.number; | |
var username = pull.user.login; | |
var repoUrl = pull.head.repo.git_url; | |
var hash = pull.head.sha; | |
// The clone goes here. | |
var subdir = path.join(outDir, username + '-' + number); | |
cloneRepoHash(repoUrl, hash, subdir); | |
} | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment