Created
February 26, 2024 12:25
-
-
Save valenting/a124a49ae7f18071acb9bd9ac1e387be to your computer and use it in GitHub Desktop.
This script lists all of the WIP revisions in your Gecko mercurial repo and prunes those that have already been published
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
import subprocess | |
import re | |
import requests | |
import os | |
# Retrieve the API token from an environment variable | |
API_TOKEN = os.getenv('PHABRICATOR_API_TOKEN') | |
PHABRICATOR_URL = 'https://phabricator.services.mozilla.com/api/differential.revision.search' | |
def get_wip_commits(): | |
command = ["hg", "log", "-r", "draft() and not obsolete()", "--template", "{node}|{desc}\n\n"] | |
try: | |
result = subprocess.run(command, check=True, stdout=subprocess.PIPE, universal_newlines=True) | |
commit_messages = result.stdout | |
return commit_messages | |
except subprocess.CalledProcessError as e: | |
print(f"Error executing hg: {e}") | |
return "" | |
def extract_differential_revision_numbers(commit_messages): | |
pattern = re.compile(r"([a-f0-9]+)\|(.*?)(?:Differential Revision: https://phabricator.services.mozilla.com/D(\d+))?", re.DOTALL) | |
for commit in commit_messages.strip().split("\n\n"): | |
match = pattern.search(commit) | |
if match: | |
commit_hash = match.group(1) | |
revision_number = match.group(3) if match.group(3) else "" | |
yield commit_hash, revision_number | |
def check_revision_status(revision_number): | |
if not API_TOKEN: | |
print("API token not found. Please set the PHABRICATOR_API_TOKEN environment variable.") | |
return None | |
payload = { | |
'api.token': API_TOKEN, | |
'constraints[ids][0]': revision_number, | |
} | |
response = requests.post(PHABRICATOR_URL, data=payload) | |
if response.status_code == 200: | |
data = response.json() | |
if data['result']['data']: | |
status = data['result']['data'][0]['fields']['status']['value'] | |
return status | |
return None | |
def prune_revision(commit_hash): | |
command = ["hg", "prune", "--rev", commit_hash] | |
try: | |
subprocess.run(command, check=True) | |
print(f"Pruned commit {commit_hash}") | |
except subprocess.CalledProcessError as e: | |
print(f"Error pruning commit {commit_hash}: {e}") | |
def main(): | |
if not API_TOKEN: | |
print("API token not set. Exiting...") | |
return | |
commit_messages = get_wip_commits() | |
if commit_messages: | |
for commit_hash, revision_number in extract_differential_revision_numbers(commit_messages): | |
if revision_number == "": | |
print(f"Commit {commit_hash} does not have an associated Phabricator Differential Revision. Skipping...") | |
continue | |
status = check_revision_status(revision_number) | |
if status in ['closed', 'abandoned', 'published']: | |
print(f"Revision {revision_number} (commit {commit_hash}) is {status}. Pruning...") | |
prune_revision(commit_hash) | |
else: | |
print(f"Revision {revision_number} status is {status}. No action taken.") | |
else: | |
print("No draft (WIP) commits found or error occurred.") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment