From 65a8090215e93812ba5ca5c43ff3aaa5e78be9aa Mon Sep 17 00:00:00 2001 From: networkException Date: Tue, 20 Jun 2023 21:09:13 +0200 Subject: [PATCH] hunspellDictsChromium: init at 115.0.5790.170 chromium requires a custom format for hunspell dictionaries which they provide as blobs in an upstream repository. building from source (using convert_dict from the chromium monorepo and applying it to already packaged dictionaries) would not yield the same results (chromium packages adjustments to the dictionaries themselves) and would increase the maintainance cost. this patch adds a new hunspellDictsChromium attribute which includes dictionaries from chromium. --- .../hunspell/dictionaries-chromium.nix | 70 +++++++++++++++++ .../hunspell/update-chromium-dictionaries.py | 77 +++++++++++++++++++ pkgs/top-level/all-packages.nix | 2 + 3 files changed, 149 insertions(+) create mode 100644 pkgs/development/libraries/hunspell/dictionaries-chromium.nix create mode 100755 pkgs/development/libraries/hunspell/update-chromium-dictionaries.py diff --git a/pkgs/development/libraries/hunspell/dictionaries-chromium.nix b/pkgs/development/libraries/hunspell/dictionaries-chromium.nix new file mode 100644 index 00000000000..6f834147d00 --- /dev/null +++ b/pkgs/development/libraries/hunspell/dictionaries-chromium.nix @@ -0,0 +1,70 @@ +{ lib, stdenv, fetchgit }: + +let + mkDictFromChromium = { shortName, dictFileName, shortDescription }: + stdenv.mkDerivation { + pname = "hunspell-dict-${shortName}-chromium"; + version = "115.0.5790.170"; + + src = fetchgit { + url = "https://chromium.googlesource.com/chromium/deps/hunspell_dictionaries"; + rev = "41cdffd71c9948f63c7ad36e1fb0ff519aa7a37e"; + hash = "sha256-67mvpJRFFa9eMfyqFMURlbxOaTJBICnk+gl0b0mEHl8="; + }; + + dontBuild = true; + + installPhase = '' + cp ${dictFileName} $out + ''; + + passthru = { + # As chromium needs the exact filename in ~/.config/chromium/Dictionaries, + # this value needs to be known to tools using the package if they want to + # link the file correctly. + inherit dictFileName; + + updateScript = ./update-chromium-dictionaries.py; + }; + + meta = { + homepage = "https://chromium.googlesource.com/chromium/deps/hunspell_dictionaries/"; + description = "Chromium compatible hunspell dictionary for ${shortDescription}"; + longDescription = '' + Humspell directories in Chromium's custom bdic format + + See https://www.chromium.org/developers/how-tos/editing-the-spell-checking-dictionaries/ + ''; + license = with lib.licenses; [ gpl2 lgpl21 mpl11 lgpl3 ]; + maintainers = with lib.maintainers; [ networkexception ]; + platforms = lib.platforms.all; + }; + }; +in +rec { + + /* ENGLISH */ + + en_US = en-us; + en-us = mkDictFromChromium { + shortName = "en-us"; + dictFileName = "en-US-10-1.bdic"; + shortDescription = "English (United States)"; + }; + + en_GB = en-us; + en-gb = mkDictFromChromium { + shortName = "en-gb"; + dictFileName = "en-GB-10-1.bdic"; + shortDescription = "English (United Kingdom)"; + }; + + /* GERMAN */ + + de_DE = de-de; + de-de = mkDictFromChromium { + shortName = "de-de"; + dictFileName = "de-DE-3-0.bdic"; + shortDescription = "German (Germany)"; + }; +} diff --git a/pkgs/development/libraries/hunspell/update-chromium-dictionaries.py b/pkgs/development/libraries/hunspell/update-chromium-dictionaries.py new file mode 100755 index 00000000000..eb24fc32937 --- /dev/null +++ b/pkgs/development/libraries/hunspell/update-chromium-dictionaries.py @@ -0,0 +1,77 @@ +#! /usr/bin/env nix-shell +#! nix-shell -i python3 -p python3 nix nix-prefetch-git + +import base64 +import fileinput +import json +import os +import re +import subprocess +import sys + +from urllib.request import urlopen, Request + + +DICTIONARIES_CHROMIUM_NIX = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'dictionaries-chromium.nix') + + +def get_latest_chromium_stable_release(): + RELEASES_URL = 'https://versionhistory.googleapis.com/v1/chrome/platforms/linux/channels/stable/versions/all/releases' + print(f'GET {RELEASES_URL}') + with urlopen(RELEASES_URL) as resp: + return json.load(resp)['releases'][0] + + +def get_file_revision(revision, file_path): + """Fetches the requested Git revision of the given Chromium file.""" + url = f'https://chromium.googlesource.com/chromium/src/+/refs/tags/{revision}/{file_path}?format=TEXT' + with urlopen(url) as http_response: + resp = http_response.read() + return base64.b64decode(resp) + + +def nix_prefetch_git(url, rev): + """Prefetches the requested Git revision of the given repository URL.""" + 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_current_revision(): + with open(DICTIONARIES_CHROMIUM_NIX) as f: + for line in f: + rev = re.search(r'^ rev = "(.*)";', line) + if rev: + return rev.group(1) + sys.exit(1) + + +print('Getting latest chromium version...') +chromium_release = get_latest_chromium_stable_release() +chromium_version = chromium_release['version'] +print(f'chromium version: {chromium_version}') + +print('Getting corresponding hunspell_dictionaries commit...') +deps = get_file_revision(chromium_version, 'DEPS') +hunspell_dictionaries_pattern = r"^\s*Var\('chromium_git'\)\s*\+\s*'\/chromium\/deps\/hunspell_dictionaries\.git'\s*\+\s*'@'\s*\+\s*'(\w*)',$" +hunspell_dictionaries_commit = re.search(hunspell_dictionaries_pattern, deps.decode(), re.MULTILINE).group(1) +print(f'hunspell_dictionaries commit: {hunspell_dictionaries_commit}') + +current_commit = get_current_revision() +if current_commit == hunspell_dictionaries_commit: + print('Commit is already packaged, no update needed.') + sys.exit(0) + +print('Commit has changed compared to the current package, updating...') + +print('Getting hash of hunspell_dictionaries revision...') +hunspell_dictionaries_git = nix_prefetch_git("https://chromium.googlesource.com/chromium/deps/hunspell_dictionaries", hunspell_dictionaries_commit) +hunspell_dictionaries_hash = hunspell_dictionaries_git['hash'] +print(f'hunspell_dictionaries commit hash: {hunspell_dictionaries_hash}') + +with fileinput.FileInput(DICTIONARIES_CHROMIUM_NIX, inplace=True) as file: + for line in file: + result = re.sub(r'^ version = ".+";', f' version = "{chromium_version}";', line) + result = re.sub(r'^ rev = ".*";', f' rev = "{hunspell_dictionaries_commit}";', result) + result = re.sub(r'^ hash = ".+";', f' hash = "{hunspell_dictionaries_hash}";', result) + print(result, end='') diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 4bb79eaebcf..9da99f0b7d8 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -21341,6 +21341,8 @@ with pkgs; hunspellDicts = recurseIntoAttrs (callPackages ../development/libraries/hunspell/dictionaries.nix {}); + hunspellDictsChromium = recurseIntoAttrs (callPackages ../development/libraries/hunspell/dictionaries-chromium.nix {}); + hunspellWithDicts = dicts: callPackage ../development/libraries/hunspell/wrapper.nix { inherit dicts; }; hwloc = callPackage ../development/libraries/hwloc { };