Skip to content

Instantly share code, notes, and snippets.

@flodolo
Last active January 27, 2025 12:45
Show Gist options
  • Save flodolo/eaed76d43e5c7858ed596a35838eec1d to your computer and use it in GitHub Desktop.
Save flodolo/eaed76d43e5c7858ed596a35838eec1d to your computer and use it in GitHub Desktop.
Script to extract l10n builds changeset for Firefox 68–127
import json
import requests
base_url = "https://product-details.mozilla.org/1.0/l10n/"
changesets = {}
for version in range(68, 128):
version_str = f"{version}.0"
for build_number in range(1, 6):
file_name = f"Firefox-{version_str}-build{build_number}.json"
url = f"{base_url}{file_name}"
try:
response = requests.get(url)
if response.status_code == 404:
if build_number == 1:
print(f"Build not found: {version_str}-build{build_number}.")
continue
data = response.json()
changesets[version_str] = {}
for locale, locale_data in data["locales"].items():
changesets[version_str][locale] = locale_data["changeset"]
break
except requests.HTTPError as e:
print(f"Failed to fetch {url}: {e}")
except ValueError:
print(f"Invalid JSON response for {url}.")
with open("hg-changesets.json", "w") as f:
f.write(json.dumps(changesets, indent=2))
import json
import os
import subprocess
hg_path = "locales"
commits = {}
hg_changesets = {}
with open("hg-changesets.json", "r") as f:
hg_changesets = json.loads(f.read())
for version, locales in hg_changesets.items():
print(f"Analyzing {version}")
for locale, changeset in locales.items():
try:
hg_locale_path = os.path.join(hg_path, locale)
# Run the hg log command to get the commit date and message
result = subprocess.run(
[
"hg",
"-R",
hg_locale_path,
"log",
"-r",
changeset,
"--template",
"{date|isodate}\\n{desc|firstline}\\n",
],
capture_output=True,
text=True,
check=True,
)
# Split the output into date and commit message
output = result.stdout.strip()
commit_date, commit_message = output.split("\n", 1)
if version not in commits:
commits[version] = {}
commits[version][locale] = {"date": commit_date, "message": commit_message}
except subprocess.CalledProcessError as e:
print(f"Error retrieving commit {changeset} info for {version}: {e}")
with open("hg-commits.json", "w") as f:
f.write(json.dumps(commits, indent=2))
import json
import subprocess
from datetime import datetime, timedelta
with open("hg-commits.json", "r") as f:
hg_commits = json.load(f)
git_path = "/Users/flodolo/mozilla/mercurial/firefox-l10n/"
git_commits = {}
for version, locales in hg_commits.items():
print(f"Analyzing {version}")
for locale, locale_data in locales.items():
try:
target_datetime = datetime.strptime(
locale_data["date"], "%Y-%m-%d %H:%M %z"
)
since = (target_datetime - timedelta(hours=2)).strftime("%Y-%m-%dT%H:%M:%S%z")
until = (target_datetime + timedelta(hours=2)).strftime("%Y-%m-%dT%H:%M:%S%z")
# Run git log in the locale's folder to get commits within +/- 2 hours
# from the hg commit
result = subprocess.run(
[
"git",
"-C",
git_path,
"log",
"--since",
since,
"--until",
until,
"--pretty=format:%H %ci",
locale,
],
capture_output=True,
text=True,
check=True,
)
commits = result.stdout.strip().split("\n")
if not commits or commits == [""]:
print(f"No commits found in the time range for {locale} and version {version}.")
continue
closest_commit = None
closest_diff = float("inf")
for commit in commits:
hash_, commit_date = commit.split(" ", 1)
commit_datetime = datetime.strptime(commit_date, "%Y-%m-%d %H:%M:%S %z")
diff = abs((commit_datetime - target_datetime).total_seconds())
if diff < closest_diff:
closest_commit = hash_
closest_diff = diff
if version not in git_commits:
git_commits[version] = {}
git_commits[version][locale] = {
"date": target_datetime.strftime("%Y-%m-%d %H:%M %z"),
"changeset": closest_commit,
}
except subprocess.CalledProcessError as e:
print(f"Error running git log: {e}")
except Exception as e:
print(f"Error processing version {version}: {e}")
with open("git-commits.json", "w") as file:
json.dump(git_commits, file, indent=2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment