Created
November 20, 2019 14:58
-
-
Save andrewandante/4de8c7c8feefb87fb234fbe245fa92b4 to your computer and use it in GitHub Desktop.
Bitbucket Pull Request Participation Checker (Partychecker)
This file contains hidden or 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
<?php | |
/** | |
* Sample usage: php ./PartyChecker.php 'Guybrush Threepwood' 2019-01-01 2019-03-31 | |
* | |
* Sample Output: | |
* | |
* ....xxxxxx.xx.xx..xx..xx.x.....xx.....x.x.x.x....xx.....x.....x...........xx......xxx.x.....x.x..........xxx | |
* .......x....x..........x...............x.....x.....x.....x............xx.....xxx.......x.................... | |
* ..........x....xxxx.x......x.....x.xx.....x......x.......x..xxx..x.x.....x.x.x...x.xx.............xx..xxxxxx | |
* ..........x.x..x.x x.xx....x... | |
* Total PRs: 354 | |
* PRs I touched: 265 | |
* Percentage: 74.858757062147 | |
*/ | |
function doCurl($url) { | |
// get an app_password from this link https://bitbucket.org/account/user/<your_username>/app-passwords | |
// and make sure it has at least read permissions on basically everything | |
// set your username and app_password in ~/.atlassian/bitbucket | |
// ie. gthreepwood:password | |
if (file_exists(getenv('HOME') . "/.atlassian/bitbucket")) { | |
$credsFile = getenv('HOME') . "/.atlassian/bitbucket"; | |
} elseif (file_exists(__DIR__ . "/.credentials/bitbucket")) { | |
$credsFile = __DIR__ . "/.credentials/bitbucket"; | |
} else { | |
echo "No credentials found - exiting" . PHP_EOL; | |
exit(1); | |
} | |
$auth = trim(file_get_contents($credsFile)); | |
$auth_enc = base64_encode($auth); | |
$curl = curl_init(); | |
curl_setopt_array($curl, array( | |
CURLOPT_URL => $url, | |
CURLOPT_RETURNTRANSFER => true, | |
CURLOPT_ENCODING => "", | |
CURLOPT_MAXREDIRS => 10, | |
CURLOPT_TIMEOUT => 30, | |
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, | |
CURLOPT_CUSTOMREQUEST => "GET", | |
CURLOPT_POSTFIELDS => "", | |
CURLOPT_HTTPHEADER => array( | |
"Authorization: Basic " . $auth_enc, | |
"cache-control: no-cache" | |
), | |
)); | |
$response = curl_exec($curl); | |
$err = curl_error($curl); | |
curl_close($curl); | |
if ($err) { | |
echo "cURL Error #:" . $err; | |
} else { | |
return json_decode($response, true); | |
} | |
} | |
$count = 0; | |
$partyCount = 0; | |
$pullRequests = []; | |
$displayName = $argv[1]; // Get this from your settings page | |
$from = $argv[2]; // Must be a date in the format Y-m-d i.e 2019-01-01 | |
$to = $argv[3]; // Must be a date in the format Y-m-d i.e 2019-03-31 | |
// Gets all PRs to the target repo in the given time bracket | |
$url = "https://api.bitbucket.org/2.0/repositories/<org>/<repo>/pullrequests" | |
. "?state=DECLINED&state=MERGED&state=OPEN" | |
. "&q=created_on+%3E%3D+" . $from . "+AND+created_on+%3C%3D+" . $to; | |
do { | |
$response = doCurl($url); | |
foreach ($response['values'] as $pr) { | |
if (!in_array($pr['id'], $pullRequests)) { | |
$pullRequests[] = $pr['id']; | |
++$count; | |
$wasTouched = false; | |
$detailsURL = "https://api.bitbucket.org/2.0/repositories/<org>/<repo>/pullrequests/" . $pr['id']; | |
$details = doCurl($detailsURL); | |
if ($details['author']['display_name'] === $displayName) { | |
$wasTouched = true; | |
echo "."; | |
$partyCount++; | |
continue; | |
} | |
foreach ($details['participants'] as $participant) { | |
if ($participant['user']['display_name'] === $displayName) { | |
$partyCount++; | |
$wasTouched = true; | |
continue; | |
} | |
} | |
if ($wasTouched) { | |
echo "."; | |
} else { | |
echo 'x'; | |
} | |
} | |
} | |
$url = array_key_exists('next', $response) ? $response['next'] : null; | |
} while ($url !== null); | |
$numOfPullRequests = count($pullRequests); | |
echo PHP_EOL . "Total PRs: {$numOfPullRequests}" . PHP_EOL; | |
if ($numOfPullRequests > 0) { | |
echo "PRs I touched: " . $partyCount . PHP_EOL; | |
echo "Percentage: " . ($partyCount / count($pullRequests)) * 100; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment