nixpkgs/pkgs/applications/networking/browsers/chromium/update.py
Michael Weiss 240a8f746e
ungoogled-chromium: Move ungoogled-src.nix into upstream-info.json
This also adds a dedicated channel for ungoogled-chromium that enables
us to update ungoogled-chromium independently of chromium.
TODO: Automate ungoogled-chromium updates via update.py (currently it
needs to be updated manually).

Note: Unfortunately this changes the ungoogled-chromium derivation
because common.nix passes the channel as an argument to
stdenv.mkDerivation (this makes it more difficult to verify this commit
but the result should remain the same).
2020-12-10 17:41:22 +01:00

125 lines
4.7 KiB
Python
Executable file

#! /usr/bin/env nix-shell
#! nix-shell -i python -p python3 nix nix-prefetch-git
import csv
import json
import re
import subprocess
import sys
from codecs import iterdecode
from collections import OrderedDict
from datetime import datetime
from os.path import abspath, dirname
from urllib.request import urlopen
HISTORY_URL = 'https://omahaproxy.appspot.com/history?os=linux'
DEB_URL = 'https://dl.google.com/linux/chrome/deb/pool/main/g'
BUCKET_URL = 'https://commondatastorage.googleapis.com/chromium-browser-official'
JSON_PATH = dirname(abspath(__file__)) + '/upstream-info.json'
def load_json(path):
with open(path, 'r') as f:
return json.load(f)
def nix_prefetch_url(url, algo='sha256'):
print(f'nix-prefetch-url {url}')
out = subprocess.check_output(['nix-prefetch-url', '--type', algo, url])
return out.decode('utf-8').rstrip()
def nix_prefetch_git(url, rev):
print(f'nix-prefetch-git {url} {rev}')
out = subprocess.check_output(['nix-prefetch-git', '--quiet', '--url', url, '--rev', rev])
return json.loads(out)
def get_file_revision(revision, file_path):
url = f'https://raw.githubusercontent.com/chromium/chromium/{revision}/{file_path}'
with urlopen(url) as http_response:
return http_response.read()
def get_matching_chromedriver(version):
# See https://chromedriver.chromium.org/downloads/version-selection
build = re.sub('.[0-9]+$', '', version)
chromedriver_version_url = f'https://chromedriver.storage.googleapis.com/LATEST_RELEASE_{build}'
with urlopen(chromedriver_version_url) as http_response:
chromedriver_version = http_response.read().decode()
def get_chromedriver_url(system):
return f'https://chromedriver.storage.googleapis.com/{chromedriver_version}/chromedriver_{system}.zip'
return {
'version': chromedriver_version,
'sha256_linux': nix_prefetch_url(get_chromedriver_url('linux64')),
'sha256_darwin': nix_prefetch_url(get_chromedriver_url('mac64'))
}
def get_channel_dependencies(channel):
deps = get_file_revision(channel['version'], 'DEPS')
gn_pattern = b"'gn_version': 'git_revision:([0-9a-f]{40})'"
gn_commit = re.search(gn_pattern, deps).group(1).decode()
gn = nix_prefetch_git('https://gn.googlesource.com/gn', gn_commit)
return {
'gn': {
'version': datetime.fromisoformat(gn['date']).date().isoformat(),
'url': gn['url'],
'rev': gn['rev'],
'sha256': gn['sha256']
}
}
channels = {}
last_channels = load_json(JSON_PATH)
print(f'GET {HISTORY_URL}', file=sys.stderr)
with urlopen(HISTORY_URL) as resp:
builds = csv.DictReader(iterdecode(resp, 'utf-8'))
for build in builds:
channel_name = build['channel']
# If we've already found a newer build for this channel, we're
# no longer interested in it.
if channel_name in channels:
continue
# If we're back at the last build we used, we don't need to
# keep going -- there's no new version available, and we can
# just reuse the info from last time.
if build['version'] == last_channels[channel_name]['version']:
channels[channel_name] = last_channels[channel_name]
continue
channel = {'version': build['version']}
suffix = 'unstable' if channel_name == 'dev' else channel_name
try:
channel['sha256'] = nix_prefetch_url(f'{BUCKET_URL}/chromium-{build["version"]}.tar.xz')
channel['sha256bin64'] = nix_prefetch_url(f'{DEB_URL}/google-chrome-{suffix}/google-chrome-{suffix}_{build["version"]}-1_amd64.deb')
except subprocess.CalledProcessError:
# This build isn't actually available yet. Continue to
# the next one.
continue
channel['deps'] = get_channel_dependencies(channel)
if channel_name == 'stable':
channel['chromedriver'] = get_matching_chromedriver(channel['version'])
channels[channel_name] = channel
with open(JSON_PATH, 'w') as out:
def get_channel_key(item):
channel_name = item[0]
if channel_name == 'stable':
return 0
elif channel_name == 'beta':
return 1
elif channel_name == 'dev':
return 2
elif channel_name == 'ungoogled-chromium':
return 3
else:
print(f'Error: Unexpected channel: {channel_name}', file=sys.stderr)
sys.exit(1)
channels['ungoogled-chromium'] = last_channels['ungoogled-chromium'] # Keep ungoogled-chromium unchanged
sorted_channels = OrderedDict(sorted(channels.items(), key=get_channel_key))
json.dump(sorted_channels, out, indent=2)
out.write('\n')