Skip to content

Instantly share code, notes, and snippets.

@andrewandante
Created November 20, 2019 14:58
Show Gist options
  • Save andrewandante/4de8c7c8feefb87fb234fbe245fa92b4 to your computer and use it in GitHub Desktop.
Save andrewandante/4de8c7c8feefb87fb234fbe245fa92b4 to your computer and use it in GitHub Desktop.
Bitbucket Pull Request Participation Checker (Partychecker)
<?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