···8899}:
1010# The return value of this function will be an attrset with arbitrary depth and
1111-# the `anything` returned by callTest at its test leafs.
1111+# the `anything` returned by callTest at its test leaves.
1212# The tests not supported by `system` will be replaced with `{}`, so that
1313# `passthru.tests` can contain links to those without breaking on architectures
1414# where said tests are unsupported.
···655655 jool = import ./jool.nix { inherit pkgs runTest; };
656656 jotta-cli = handleTest ./jotta-cli.nix { };
657657 k3s = handleTest ./k3s { };
658658- kafka = handleTest ./kafka.nix { };
658658+ kafka = handleTest ./kafka { };
659659 kanboard = runTest ./web-apps/kanboard.nix;
660660 kanidm = handleTest ./kanidm.nix { };
661661 kanidm-provisioning = handleTest ./kanidm-provisioning.nix { };
···4343 doCheck = false;
44444545 meta = with lib; {
4646- description = "Cargo plugin to generate list of all licenses for a crate";
4646+ description = "Cargo plugin for linting your dependencies";
4747 mainProgram = "cargo-deny";
4848 homepage = "https://github.com/EmbarkStudios/cargo-deny";
4949 changelog = "https://github.com/EmbarkStudios/cargo-deny/blob/${version}/CHANGELOG.md";
···11-{
22- lib,
33- stdenv,
44- fetchFromGitHub,
55- ncurses,
66- hdate,
77- lua5_2,
88-}:
99-1010-stdenv.mkDerivation rec {
1111- version = "12010904";
1212- pname = "dozenal";
1313- src = fetchFromGitHub {
1414- owner = "dgoodmaniii";
1515- repo = "dozenal";
1616- rev = "v${version}";
1717- sha256 = "1ic63gpdda762x6ks3al71dwgmsy2isicqyr2935bd245jx8s209";
1818- };
1919- makeFlags = [
2020- # author do not use configure and prefix directly using $prefix
2121- "prefix=$(out)"
2222- # graphical version of dozdc requires xforms, which is not i nixpkgs so I turned it down
2323- "XFORMS_FLAGS=-UXFORMS"
2424- "LUALIB=-llua"
2525- "bindir=$(prefix)/bin/"
2626- ];
2727- # some include hardcodes the lua libraries path. This is a patch for that
2828- patches = [ ./lua-header.patch ];
2929- preBuild = "cd dozenal";
3030- buildInputs = [
3131- ncurses
3232- hdate
3333- lua5_2
3434- ];
3535-3636- # Parallel builds fail due to no dependencies between subdirs.
3737- # As a result some subdirs are atempted to build twice:
3838- # ../dec/dec.c:39:10: fatal error: conv.h: No such file or directory
3939- # Let's disable parallelism until it's fixed upstream:
4040- # https://gitlab.com/dgoodmaniii/dozenal/-/issues/8
4141- enableParallelBuilding = false;
4242-4343- # I remove gdozdc, as I didn't figure all it's dependency yet.
4444- postInstall = "rm $out/bin/gdozdc";
4545-4646- meta = {
4747- description = "Complete suite of dozenal (base twelve) programs";
4848- longDescription = ''
4949- Programs
5050-5151- doz --- a converter; converts decimal numbers into dozenal. Accepts
5252- input in standard or exponential notation (i.e., "1492.2" or "1.4922e3").
5353- dec --- a converter; converts dozenal numbers into decimal. Accepts input
5454- in standard or exponential notation (i.e., "X44;4" or "X;444e2").
5555- dozword --- converts a dozenal number (integers only) into words,
5656- according to the Pendlebury system.
5757- dozdc --- a full-featured scientific calculator which works in the
5858- dozenal base. RPN command line.
5959- tgmconv --- a converter for all standard measurements; converts to and
6060- from TGM, Imperial, customary, and SI metric.
6161- dozpret --- a pretty-printer for dozenal numbers; inserts spacing (or
6262- other characters) as desired, and can also transform transdecimal digits
6363- from 'X' to 'E' into any character or sequence of characters desired.
6464- dozdate --- a more-or-less drop-in replacement for GNU and BSD date, it
6565- outputs the date and time in dozenal, as well as containing some TGM
6666- extensions.
6767- dozstring --- a simple byte converter; absorbs a string either from
6868- standard input or a command line argument, leaving it identical but
6969- for the numbers, which it converts into dozenal. Options for padding
7070- and for not converting specific numbers.
7171- doman --- a converter which takes a dozenal integer and
7272- emits its equivalent in a non-place-value system, such as
7373- Roman numerals. Arbitrary ranks and symbols may be used.
7474- Defaults to dozenal Roman numerals.
7575- '';
7676- homepage = "https://github.com/dgoodmaniii/dozenal/";
7777- maintainers = with lib.maintainers; [ CharlesHD ];
7878- license = lib.licenses.gpl3;
7979- };
8080-}
···1111 # and make sure the version regex is up to date here.
1212 # Ensure you also check ../mattermost/package.nix for ESR releases.
1313 regex = "^v(10\\.[0-9]+\\.[0-9]+)$";
1414- version = "10.6.0";
1515- srcHash = "sha256-GnXxhhbOKJezUAyKRBbn5IE22gzsn80mwnPANOT9Qu4=";
1414+ version = "10.6.1";
1515+ srcHash = "sha256-xCrjJc6JCZXnCZ5lJ3o1bRbt7sxlEmcWeiw2cKmyWG0=";
1616 vendorHash = "sha256-wj+bAQNJSs9m2SSfl+Ipm965iAhKQ2v1iMjH7I79qf4=";
1717 npmDepsHash = "sha256-MdLfjLmizFbLfSqOdAZ+euXomB2ZPjZOqspQYnyHcuk=";
1818 lockfileOverlay = ''
···5151 find . -type f -name "CMakeLists.txt" -exec sed -i "/BridgeSetup\\.cmake/d" {} \;
52525353 # Use the available ICU version
5454- sed -i "s/libicu\(i18n\|uc\|data\)\.so\.56/libicu\1.so/g" bridge-gui/DeployLinux.cmake
5454+ sed -i "s/libicu\(i18n\|uc\|data\)\.so\.[0-9][0-9]/libicu\1.so/g" bridge-gui/DeployLinux.cmake
55555656 # Create a Desktop Entry that uses a `protonmail-bridge-gui` binary without upstream's launcher
5757 sed "s/^\(Icon\|Exec\)=.*$/\1=protonmail-bridge-gui/" ../../../dist/proton-bridge.desktop > proton-bridge-gui.desktop
···11#! /usr/bin/env nix-shell
22-#! nix-shell -i python -p python3.pkgs.joblib python3.pkgs.click python3.pkgs.click-log nix nix-prefetch-git nurl prefetch-yarn-deps prefetch-npm-deps
22+#! nix-shell -i python -p python3.pkgs.joblib python3.pkgs.click python3.pkgs.click-log nix nix-prefetch-git prefetch-yarn-deps prefetch-npm-deps gclient2nix
33"""
44electron updater
5566-A script for updating both binary and source hashes.
66+A script for updating electron source hashes.
7788It supports the following modes:
99···1111|------------- | ----------------------------------------------- |
1212| `update` | for updating a specific Electron release |
1313| `update-all` | for updating all electron releases at once |
1414-| `eval` | just print the necessary sources to fetch |
15141616-The `eval` and `update` commands accept an optional `--version` flag
1717-to restrict the mechanism only to a given major release.
1515+The `update` commands requires a `--version` flag
1616+to specify the major release to be updated.
1717+The `update-all command updates all non-eol major releases.
18181919The `update` and `update-all` commands accept an optional `--commit`
2020flag to automatically commit the changes for you.
2121-2222-The `update` and `update-all` commands accept optional `--bin-only`
2323-and `--source-only` flags to restict the update to binary or source
2424-releases.
2521"""
2622import base64
2727-import csv
2823import json
2924import logging
3025import os
···3328import subprocess
3429import sys
3530import tempfile
3636-import traceback
3731import urllib.request
3232+import click
3333+import click_log
38343939-from abc import ABC
4040-from codecs import iterdecode
4135from datetime import datetime
4242-from typing import Iterable, Optional, Tuple
3636+from typing import Iterable, Tuple
4337from urllib.request import urlopen
4444-4545-import click
4646-import click_log
4747-4838from joblib import Parallel, delayed, Memory
4949-5050-depot_tools_checkout = tempfile.TemporaryDirectory()
5151-subprocess.check_call(
5252- [
5353- "nix-prefetch-git",
5454- "--builder",
5555- "--quiet",
5656- "--url",
5757- "https://chromium.googlesource.com/chromium/tools/depot_tools",
5858- "--out",
5959- depot_tools_checkout.name,
6060- "--rev",
6161- "452fe3be37f78fbecefa1b4b0d359531bcd70d0d"
6262- ]
6363-)
6464-sys.path.append(depot_tools_checkout.name)
6565-6666-import gclient_eval
6767-import gclient_utils
3939+from update_util import *
684069417042# Relative path to the electron-source info.json
7143SOURCE_INFO_JSON = "info.json"
72447373-# Relatice path to the electron-bin info.json
7474-BINARY_INFO_JSON = "binary/info.json"
7575-7676-# Relative path the the electron-chromedriver info.json
7777-CHROMEDRIVER_INFO_JSON = "chromedriver/info.json"
7878-7979-# Number of spaces used for each indentation level
8080-JSON_INDENT = 4
8181-8245os.chdir(os.path.dirname(__file__))
83468447memory: Memory = Memory("cache", verbose=0)
···8649logger = logging.getLogger(__name__)
8750click_log.basic_config(logger)
88518989-nixpkgs_path = os.path.dirname(os.path.realpath(__file__)) + "/../../../.."
90525353+def get_gclient_data(rev: str) -> any:
5454+ output = subprocess.check_output(
5555+ ["gclient2nix", "generate",
5656+ f"https://github.com/electron/electron@{rev}",
5757+ "--root", "src/electron"]
5858+ )
91599292-class Repo:
9393- fetcher: str
9494- args: dict
6060+ return json.loads(output)
95619696- def __init__(self) -> None:
9797- self.deps: dict = {}
9898- self.hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
9962100100- def get_deps(self, repo_vars: dict, path: str) -> None:
101101- print(
102102- "evaluating " + json.dumps(self, default=vars, sort_keys=True),
103103- file=sys.stderr,
104104- )
105105-106106- deps_file = self.get_file("DEPS")
107107- evaluated = gclient_eval.Parse(deps_file, vars_override=repo_vars, filename="DEPS")
108108-109109- repo_vars = dict(evaluated.get("vars", {})) | repo_vars
110110-111111- prefix = f"{path}/" if evaluated.get("use_relative_paths", False) else ""
112112-113113- self.deps = {
114114- prefix + dep_name: repo_from_dep(dep)
115115- for dep_name, dep in evaluated.get("deps", {}).items()
116116- if (
117117- gclient_eval.EvaluateCondition(dep["condition"], repo_vars)
118118- if "condition" in dep
119119- else True
120120- )
121121- and repo_from_dep(dep) != None
122122- }
123123-124124- for key in evaluated.get("recursedeps", []):
125125- dep_path = prefix + key
126126- if dep_path in self.deps and dep_path != "src/third_party/squirrel.mac":
127127- self.deps[dep_path].get_deps(repo_vars, dep_path)
128128-129129- def prefetch(self) -> None:
130130- self.hash = get_repo_hash(self.fetcher, self.args)
131131-132132- def prefetch_all(self) -> int:
133133- return sum(
134134- [dep.prefetch_all() for [_, dep] in self.deps.items()],
135135- [delayed(self.prefetch)()],
136136- )
137137-138138- def flatten_repr(self) -> dict:
139139- return {"fetcher": self.fetcher, "hash": self.hash, **self.args}
140140-141141- def flatten(self, path: str) -> dict:
142142- out = {path: self.flatten_repr()}
143143- for dep_path, dep in self.deps.items():
144144- out |= dep.flatten(dep_path)
145145- return out
146146-147147- def get_file(self, filepath: str) -> str:
148148- raise NotImplementedError
149149-150150-151151-class GitRepo(Repo):
152152- def __init__(self, url: str, rev: str) -> None:
153153- super().__init__()
154154- self.fetcher = "fetchgit"
155155- self.args = {
156156- "url": url,
157157- "rev": rev,
158158- }
159159-160160-161161-class GitHubRepo(Repo):
162162- def __init__(self, owner: str, repo: str, rev: str) -> None:
163163- super().__init__()
164164- self.fetcher = "fetchFromGitHub"
165165- self.args = {
166166- "owner": owner,
167167- "repo": repo,
168168- "rev": rev,
169169- }
170170-171171- def get_file(self, filepath: str) -> str:
172172- return (
173173- urlopen(
174174- f"https://raw.githubusercontent.com/{self.args['owner']}/{self.args['repo']}/{self.args['rev']}/{filepath}"
175175- )
176176- .read()
177177- .decode("utf-8")
178178- )
179179-180180-181181-class GitilesRepo(Repo):
182182- def __init__(self, url: str, rev: str) -> None:
183183- super().__init__()
184184- self.fetcher = "fetchFromGitiles"
185185- self.args = {
186186- "url": url,
187187- "rev": rev,
188188- }
189189-190190- if url == "https://chromium.googlesource.com/chromium/src.git":
191191- self.args["postFetch"] = "rm -r $out/third_party/blink/web_tests; "
192192- self.args["postFetch"] += "rm -rf $out/third_party/hunspell/tests; "
193193- self.args["postFetch"] += "rm -r $out/content/test/data; "
194194- self.args["postFetch"] += "rm -rf $out/courgette/testdata; "
195195- self.args["postFetch"] += "rm -r $out/extensions/test/data; "
196196- self.args["postFetch"] += "rm -r $out/media/test/data; "
197197-198198- def get_file(self, filepath: str) -> str:
199199- return base64.b64decode(
200200- urlopen(
201201- f"{self.args['url']}/+/{self.args['rev']}/{filepath}?format=TEXT"
202202- ).read()
6363+def get_chromium_file(chromium_rev: str, filepath: str) -> str:
6464+ return base64.b64decode(
6565+ urlopen(
6666+ f"https://chromium.googlesource.com/chromium/src.git/+/{chromium_rev}/{filepath}?format=TEXT"
6767+ ).read()
20368 ).decode("utf-8")
2046920570206206-class ElectronBinRepo(GitHubRepo):
207207- def __init__(self, owner: str, repo: str, rev: str) -> None:
208208- super().__init__(owner, repo, rev)
209209- self.systems = {
210210- "i686-linux": "linux-ia32",
211211- "x86_64-linux": "linux-x64",
212212- "armv7l-linux": "linux-armv7l",
213213- "aarch64-linux": "linux-arm64",
214214- "x86_64-darwin": "darwin-x64",
215215- "aarch64-darwin": "darwin-arm64",
216216- }
217217-218218- def get_shasums256(self, version: str) -> list:
219219- """Returns the contents of SHASUMS256.txt"""
220220- try:
221221- called_process: subprocess.CompletedProcess = subprocess.run(
222222- [
223223- "nix-prefetch-url",
224224- "--print-path",
225225- f"https://github.com/electron/electron/releases/download/v{version}/SHASUMS256.txt",
226226- ],
227227- capture_output=True,
228228- check=True,
229229- text=True,
230230- )
231231-232232- hash_file_path = called_process.stdout.split("\n")[1]
233233-234234- with open(hash_file_path, "r") as f:
235235- return f.read().split("\n")
236236-237237- except subprocess.CalledProcessError as err:
238238- print(err.stderr)
239239- sys.exit(1)
240240-241241- def get_headers(self, version: str) -> str:
242242- """Returns the hash of the release headers tarball"""
243243- try:
244244- called_process: subprocess.CompletedProcess = subprocess.run(
245245- [
246246- "nix-prefetch-url",
247247- f"https://artifacts.electronjs.org/headers/dist/v{version}/node-v{version}-headers.tar.gz",
248248- ],
249249- capture_output=True,
250250- check=True,
251251- text=True,
252252- )
253253- return called_process.stdout.split("\n")[0]
254254- except subprocess.CalledProcessError as err:
255255- print(err.stderr)
256256- sys.exit(1)
257257-258258- def get_hashes(self, major_version: str) -> dict:
259259- """Returns a dictionary of hashes for a given major version"""
260260- m, _ = get_latest_version(major_version)
261261- version: str = m["version"]
262262-263263- out = {}
264264- out[major_version] = {
265265- "hashes": {},
266266- "version": version,
267267- }
268268-269269- hashes: list = self.get_shasums256(version)
270270-271271- for nix_system, electron_system in self.systems.items():
272272- filename = f"*electron-v{version}-{electron_system}.zip"
273273- if any([x.endswith(filename) for x in hashes]):
274274- out[major_version]["hashes"][nix_system] = [
275275- x.split(" ")[0] for x in hashes if x.endswith(filename)
276276- ][0]
277277- out[major_version]["hashes"]["headers"] = self.get_headers(version)
278278-279279- return out
280280-281281-282282-class ElectronChromedriverRepo(ElectronBinRepo):
283283- def __init__(self, rev: str) -> None:
284284- super().__init__("electron", "electron", rev)
285285- self.systems = {
286286- "i686-linux": "linux-ia32",
287287- "x86_64-linux": "linux-x64",
288288- "armv7l-linux": "linux-armv7l",
289289- "aarch64-linux": "linux-arm64",
290290- "x86_64-darwin": "darwin-x64",
291291- "aarch64-darwin": "darwin-arm64",
292292- }
293293-294294- def get_hashes(self, major_version: str) -> dict:
295295- """Returns a dictionary of hashes for a given major version"""
296296- m, _ = get_latest_version(major_version)
297297- version: str = m["version"]
298298-299299- out = {}
300300- out[major_version] = {
301301- "hashes": {},
302302- "version": version,
303303- }
304304-305305- hashes: list = self.get_shasums256(version)
306306-307307- for nix_system, electron_system in self.systems.items():
308308- filename = f"*chromedriver-v{version}-{electron_system}.zip"
309309- if any([x.endswith(filename) for x in hashes]):
310310- out[major_version]["hashes"][nix_system] = [
311311- x.split(" ")[0] for x in hashes if x.endswith(filename)
312312- ][0]
313313- out[major_version]["hashes"]["headers"] = self.get_headers(version)
314314-315315- return out
316316-317317-318318-# Releases that have reached end-of-life no longer receive any updates
319319-# and it is rather pointless trying to update those.
320320-#
321321-# https://endoflife.date/electron
322322-def supported_version_range() -> range:
323323- """Returns a range of electron releases that have not reached end-of-life yet"""
324324- releases_json = json.loads(
325325- urlopen("https://endoflife.date/api/electron.json").read()
326326- )
327327- supported_releases = [
328328- int(x["cycle"])
329329- for x in releases_json
330330- if x["eol"] == False
331331- or datetime.strptime(x["eol"], "%Y-%m-%d") > datetime.today()
332332- ]
333333-334334- return range(
335335- min(supported_releases), # incl.
336336- # We have also packaged the beta release in nixpkgs,
337337- # but it is not tracked by endoflife.date
338338- max(supported_releases) + 2, # excl.
339339- 1,
7171+def get_electron_file(electron_rev: str, filepath: str) -> str:
7272+ return (
7373+ urlopen(
7474+ f"https://raw.githubusercontent.com/electron/electron/{electron_rev}/{filepath}"
7575+ )
7676+ .read()
7777+ .decode("utf-8")
34078 )
341793428034381@memory.cache
344344-def get_repo_hash(fetcher: str, args: dict) -> str:
345345- expr = f"with import {nixpkgs_path} {{}};{fetcher}{{"
346346- for key, val in args.items():
347347- expr += f'{key}="{val}";'
348348- expr += "}"
349349- cmd = ["nurl", "-H", "--expr", expr]
350350- print(" ".join(cmd), file=sys.stderr)
351351- out = subprocess.check_output(cmd)
352352- return out.decode("utf-8").strip()
353353-8282+def get_chromium_gn_source(chromium_rev: str) -> dict:
8383+ gn_pattern = r"'gn_version': 'git_revision:([0-9a-f]{40})'"
8484+ gn_commit = re.search(gn_pattern, get_chromium_file(chromium_rev, "DEPS")).group(1)
8585+ gn_prefetch: bytes = subprocess.check_output(
8686+ [
8787+ "nix-prefetch-git",
8888+ "--quiet",
8989+ "https://gn.googlesource.com/gn",
9090+ "--rev",
9191+ gn_commit,
9292+ ]
9393+ )
9494+ gn: dict = json.loads(gn_prefetch)
9595+ return {
9696+ "gn": {
9797+ "version": datetime.fromisoformat(gn["date"]).date().isoformat(),
9898+ "url": gn["url"],
9999+ "rev": gn["rev"],
100100+ "hash": gn["hash"],
101101+ }
102102+ }
354103355104@memory.cache
356356-def _get_yarn_hash(path: str) -> str:
105105+def get_electron_yarn_hash(electron_rev: str) -> str:
357106 print(f"prefetch-yarn-deps", file=sys.stderr)
358107 with tempfile.TemporaryDirectory() as tmp_dir:
359108 with open(tmp_dir + "/yarn.lock", "w") as f:
360360- f.write(path)
109109+ f.write(get_electron_file(electron_rev, "yarn.lock"))
361110 return (
362111 subprocess.check_output(["prefetch-yarn-deps", tmp_dir + "/yarn.lock"])
363112 .decode("utf-8")
364113 .strip()
365114 )
366115367367-368368-def get_yarn_hash(repo: Repo, yarn_lock_path: str = "yarn.lock") -> str:
369369- return _get_yarn_hash(repo.get_file(yarn_lock_path))
370370-371371-372116@memory.cache
373373-def _get_npm_hash(filename: str) -> str:
117117+def get_chromium_npm_hash(chromium_rev: str) -> str:
374118 print(f"prefetch-npm-deps", file=sys.stderr)
375119 with tempfile.TemporaryDirectory() as tmp_dir:
376120 with open(tmp_dir + "/package-lock.json", "w") as f:
377377- f.write(filename)
121121+ f.write(get_chromium_file(chromium_rev, "third_party/node/package-lock.json"))
378122 return (
379123 subprocess.check_output(
380124 ["prefetch-npm-deps", tmp_dir + "/package-lock.json"]
···384128 )
385129386130387387-def get_npm_hash(repo: Repo, package_lock_path: str = "package-lock.json") -> str:
388388- return _get_npm_hash(repo.get_file(package_lock_path))
389389-390390-391391-def repo_from_dep(dep: dict) -> Optional[Repo]:
392392- if "url" in dep:
393393- url, rev = gclient_utils.SplitUrlRevision(dep["url"])
394394-395395- search_object = re.search(r"https://github.com/(.+)/(.+?)(\.git)?$", url)
396396- if search_object:
397397- return GitHubRepo(search_object.group(1), search_object.group(2), rev)
398398-399399- if re.match(r"https://.+\.googlesource.com", url):
400400- return GitilesRepo(url, rev)
401401-402402- return GitRepo(url, rev)
403403- else:
404404- # Not a git dependency; skip
405405- return None
406406-131131+def get_update(major_version: str, m: str, gclient_data: any) -> Tuple[str, dict]:
407132408408-def get_gn_source(repo: Repo) -> dict:
409409- gn_pattern = r"'gn_version': 'git_revision:([0-9a-f]{40})'"
410410- gn_commit = re.search(gn_pattern, repo.get_file("DEPS")).group(1)
411411- gn_prefetch: bytes = subprocess.check_output(
412412- [
413413- "nix-prefetch-git",
414414- "--quiet",
415415- "https://gn.googlesource.com/gn",
416416- "--rev",
417417- gn_commit,
418418- ]
419419- )
420420- gn: dict = json.loads(gn_prefetch)
421421- return {
422422- "gn": {
423423- "version": datetime.fromisoformat(gn["date"]).date().isoformat(),
424424- "url": gn["url"],
425425- "rev": gn["rev"],
426426- "hash": gn["hash"],
427427- }
428428- }
429429-430430-431431-def get_latest_version(major_version: str) -> Tuple[str, str]:
432432- """Returns the latest version for a given major version"""
433433- electron_releases: dict = json.loads(
434434- urlopen("https://releases.electronjs.org/releases.json").read()
435435- )
436436- major_version_releases = filter(
437437- lambda item: item["version"].startswith(f"{major_version}."), electron_releases
438438- )
439439- m = max(major_version_releases, key=lambda item: item["date"])
440440-441441- rev = f"v{m['version']}"
442442- return (m, rev)
443443-444444-445445-def get_electron_bin_info(major_version: str) -> Tuple[str, str, ElectronBinRepo]:
446446- m, rev = get_latest_version(major_version)
447447-448448- electron_repo: ElectronBinRepo = ElectronBinRepo("electron", "electron", rev)
449449- return (major_version, m, electron_repo)
450450-451451-452452-def get_electron_chromedriver_info(
453453- major_version: str,
454454-) -> Tuple[str, str, ElectronChromedriverRepo]:
455455- m, rev = get_latest_version(major_version)
456456-457457- electron_repo: ElectronChromedriverRepo = ElectronChromedriverRepo(rev)
458458- return (major_version, m, electron_repo)
459459-460460-461461-def get_electron_info(major_version: str) -> Tuple[str, str, GitHubRepo]:
462462- m, rev = get_latest_version(major_version)
463463-464464- electron_repo: GitHubRepo = GitHubRepo("electron", "electron", rev)
465465- electron_repo.get_deps(
466466- {
467467- **{
468468- f"checkout_{platform}": platform == "linux" or platform == "x64" or platform == "arm64" or platform == "arm"
469469- for platform in ["ios", "chromeos", "android", "mac", "win", "linux"]
470470- },
471471- **{
472472- f"checkout_{arch}": True
473473- for arch in ["x64", "arm64", "arm", "x86", "mips", "mips64", "ppc"]
474474- },
475475- },
476476- "src/electron",
477477- )
478478-479479- return (major_version, m, electron_repo)
480480-481481-482482-def get_update(repo: Tuple[str, str, Repo]) -> Tuple[str, dict]:
483483- (major_version, m, electron_repo) = repo
484484-485485- tasks = electron_repo.prefetch_all()
486486- a = lambda: (("electron_yarn_hash", get_yarn_hash(electron_repo)))
133133+ tasks = []
134134+ a = lambda: (("electron_yarn_hash", get_electron_yarn_hash(gclient_data["src/electron"]["args"]["rev"])))
487135 tasks.append(delayed(a)())
488136 a = lambda: (
489137 (
490138 "chromium_npm_hash",
491491- get_npm_hash(
492492- electron_repo.deps["src"], "third_party/node/package-lock.json"
493493- ),
139139+ get_chromium_npm_hash(gclient_data["src"]["args"]["rev"]),
494140 )
495141 )
496142 tasks.append(delayed(a)())
···501147 for n in Parallel(n_jobs=3, require="sharedmem", return_as="generator")(tasks)
502148 if n != None
503149 }
504504-505505- tree = electron_repo.flatten("src/electron")
506150507151 return (
508152 f"{major_version}",
509153 {
510510- "deps": tree,
154154+ "deps": gclient_data,
511155 **{key: m[key] for key in ["version", "modules", "chrome", "node"]},
512156 "chromium": {
513157 "version": m["chrome"],
514514- "deps": get_gn_source(electron_repo.deps["src"]),
158158+ "deps": get_chromium_gn_source(gclient_data["src"]["args"]["rev"]),
515159 },
516160 **task_results,
517161 },
518162 )
519163520164521521-def load_info_json(path: str) -> dict:
522522- """Load the contents of a JSON file
165165+def non_eol_releases(releases: Iterable[int]) -> Iterable[int]:
166166+ """Returns a list of releases that have not reached end-of-life yet."""
167167+ return tuple(filter(lambda x: x in supported_version_range(), releases))
523168524524- Args:
525525- path: The path to the JSON file
526169527527- Returns: An empty dict if the path does not exist, otherwise the contents of the JSON file.
528528- """
529529- try:
530530- with open(path, "r") as f:
531531- return json.loads(f.read())
532532- except:
533533- return {}
534534-535535-536536-def save_info_json(path: str, content: dict) -> None:
537537- """Saves the given info to a JSON file
170170+def update_source(version: str, commit: bool) -> None:
171171+ """Update a given electron-source release
538172539173 Args:
540540- path: The path where the info should be saved
541541- content: The content to be saved as JSON.
542542- """
543543- with open(path, "w") as f:
544544- f.write(json.dumps(content, indent=JSON_INDENT, default=vars, sort_keys=True))
545545- f.write("\n")
546546-547547-548548-def update_bin(major_version: str, commit: bool) -> None:
549549- """Update a given electron-bin release
550550-551551- Args:
552552- major_version: The major version number, e.g. '27'
174174+ version: The major version number, e.g. '27'
553175 commit: Whether the updater should commit the result
554176 """
555555- package_name = f"electron_{major_version}-bin"
556556- print(f"Updating {package_name}")
557557-558558- electron_bin_info = get_electron_bin_info(major_version)
559559- (_major_version, _version, repo) = electron_bin_info
560560-561561- old_info = load_info_json(BINARY_INFO_JSON)
562562- new_info = repo.get_hashes(major_version)
563563-564564- out = old_info | new_info
565565-566566- save_info_json(BINARY_INFO_JSON, out)
567567-568568- old_version = (
569569- old_info[major_version]["version"] if major_version in old_info else None
570570- )
571571- new_version = new_info[major_version]["version"]
572572- if old_version == new_version:
573573- print(f"{package_name} is up-to-date")
574574- elif commit:
575575- commit_result(package_name, old_version, new_version, BINARY_INFO_JSON)
576576-577577-578578-def update_chromedriver(major_version: str, commit: bool) -> None:
579579- """Update a given electron-chromedriver release
177177+ major_version = version
580178581581- Args:
582582- major_version: The major version number, e.g. '27'
583583- commit: Whether the updater should commit the result
584584- """
585585- package_name = f"electron-chromedriver_{major_version}"
586586- print(f"Updating {package_name}")
587587-588588- electron_chromedriver_info = get_electron_chromedriver_info(major_version)
589589- (_major_version, _version, repo) = electron_chromedriver_info
590590-591591- old_info = load_info_json(CHROMEDRIVER_INFO_JSON)
592592- new_info = repo.get_hashes(major_version)
593593-594594- out = old_info | new_info
595595-596596- save_info_json(CHROMEDRIVER_INFO_JSON, out)
597597-598598- old_version = (
599599- old_info[major_version]["version"] if major_version in old_info else None
600600- )
601601- new_version = new_info[major_version]["version"]
602602- if old_version == new_version:
603603- print(f"{package_name} is up-to-date")
604604- elif commit:
605605- commit_result(package_name, old_version, new_version, CHROMEDRIVER_INFO_JSON)
606606-607607-608608-def update_source(major_version: str, commit: bool) -> None:
609609- """Update a given electron-source release
610610-611611- Args:
612612- major_version: The major version number, e.g. '27'
613613- commit: Whether the updater should commit the result
614614- """
615179 package_name = f"electron-source.electron_{major_version}"
616180 print(f"Updating electron-source.electron_{major_version}")
617181618182 old_info = load_info_json(SOURCE_INFO_JSON)
619183 old_version = (
620620- old_info[str(major_version)]["version"]
621621- if str(major_version) in old_info
184184+ old_info[major_version]["version"]
185185+ if major_version in old_info
622186 else None
623187 )
624188625625- electron_source_info = get_electron_info(major_version)
626626- new_info = get_update(electron_source_info)
189189+ m, rev = get_latest_version(major_version)
190190+ if old_version == m["version"]:
191191+ print(f"{package_name} is up-to-date")
192192+ return
193193+194194+ gclient_data = get_gclient_data(rev)
195195+ new_info = get_update(major_version, m, gclient_data)
627196 out = old_info | {new_info[0]: new_info[1]}
628197629198 save_info_json(SOURCE_INFO_JSON, out)
630199631200 new_version = new_info[1]["version"]
632632- if old_version == new_version:
633633- print(f"{package_name} is up-to-date")
634634- elif commit:
201201+ if commit:
635202 commit_result(package_name, old_version, new_version, SOURCE_INFO_JSON)
636203637204638638-def non_eol_releases(releases: Iterable[int]) -> Iterable[int]:
639639- """Returns a list of releases that have not reached end-of-life yet."""
640640- return tuple(filter(lambda x: x in supported_version_range(), releases))
641641-642642-643643-def update_all_source(commit: bool) -> None:
644644- """Update all eletron-source releases at once
645645-646646- Args:
647647- commit: Whether to commit the result
648648- """
649649- old_info = load_info_json(SOURCE_INFO_JSON)
650650-651651- filtered_releases = non_eol_releases(tuple(map(lambda x: int(x), old_info.keys())))
652652-653653- # This might take some time
654654- repos = Parallel(n_jobs=2, require="sharedmem")(
655655- delayed(get_electron_info)(major_version) for major_version in filtered_releases
656656- )
657657- new_info = {
658658- n[0]: n[1]
659659- for n in Parallel(n_jobs=2, require="sharedmem")(
660660- delayed(get_update)(repo) for repo in repos
661661- )
662662- }
663663-664664- if commit:
665665- for major_version in filtered_releases:
666666- # Since the sources have been fetched at this point already,
667667- # fetching them again will be much faster.
668668- update_source(str(major_version), commit)
669669- else:
670670- out = old_info | {new_info[0]: new_info[1]}
671671- save_info_json(SOURCE_INFO_JSON, out)
672672-673673-674674-def parse_cve_numbers(tag_name: str) -> Iterable[str]:
675675- """Returns mentioned CVE numbers from a given release tag"""
676676- cve_pattern = r"CVE-\d{4}-\d+"
677677- url = f"https://api.github.com/repos/electron/electron/releases/tags/{tag_name}"
678678- headers = {
679679- "Accept": "application/vnd.github+json",
680680- "X-GitHub-Api-Version": "2022-11-28",
681681- }
682682- request = urllib.request.Request(url=url, headers=headers)
683683- release_note = ""
684684- try:
685685- with urlopen(request) as response:
686686- release_note = json.loads(response.read().decode("utf-8"))["body"]
687687- except:
688688- print(
689689- f"WARN: Fetching release note for {tag_name} from GitHub failed!",
690690- file=sys.stderr,
691691- )
692692-693693- return sorted(re.findall(cve_pattern, release_note))
694694-695695-696696-def commit_result(
697697- package_name: str, old_version: Optional[str], new_version: str, path: str
698698-) -> None:
699699- """Creates a git commit with a short description of the change
700700-701701- Args:
702702- package_name: The package name, e.g. `electron-source.electron-{major_version}`
703703- or `electron_{major_version}-bin`
704704-705705- old_version: Version number before the update.
706706- Can be left empty when initializing a new release.
707707-708708- new_version: Version number after the update.
709709-710710- path: Path to the lockfile to be committed
711711- """
712712- assert (
713713- isinstance(package_name, str) and len(package_name) > 0
714714- ), "Argument `package_name` cannot be empty"
715715- assert (
716716- isinstance(new_version, str) and len(new_version) > 0
717717- ), "Argument `new_version` cannot be empty"
718718-719719- if old_version != new_version:
720720- major_version = new_version.split(".")[0]
721721- cve_fixes_text = "\n".join(
722722- list(
723723- map(lambda cve: f"- Fixes {cve}", parse_cve_numbers(f"v{new_version}"))
724724- )
725725- )
726726- init_msg = f"init at {new_version}"
727727- update_msg = f"{old_version} -> {new_version}"
728728- diff = (
729729- f"- Diff: https://github.com/electron/electron/compare/refs/tags/v{old_version}...v{new_version}\n"
730730- if old_version != None
731731- else ""
732732- )
733733- commit_message = f"""{package_name}: {update_msg if old_version != None else init_msg}
734734-735735-- Changelog: https://github.com/electron/electron/releases/tag/v{new_version}
736736-{diff}{cve_fixes_text}
737737-"""
738738- subprocess.run(
739739- [
740740- "git",
741741- "add",
742742- path,
743743- ]
744744- )
745745- subprocess.run(
746746- [
747747- "git",
748748- "commit",
749749- "-m",
750750- commit_message,
751751- ]
752752- )
753753-754754-755205@click.group()
756206def cli() -> None:
757757- """A script for updating electron-bin and electron-source hashes"""
207207+ """A script for updating electron-source hashes"""
758208 pass
759209760210761761-@cli.command(
762762- "eval", help="Print the necessary sources to fetch for a given major release"
763763-)
764764-@click.option("--version", help="The major version, e.g. '23'")
765765-def eval(version):
766766- (_, _, repo) = electron_repo = get_electron_info(version)
767767- tree = repo.flatten("src/electron")
768768- print(json.dumps(tree, indent=JSON_INDENT, default=vars, sort_keys=True))
769769-770770-771771-@cli.command("update-chromedriver", help="Update a single major release")
772772-@click.option("-v", "--version", help="The major version, e.g. '23'")
773773-@click.option("-c", "--commit", is_flag=True, default=False, help="Commit the result")
774774-def update_chromedriver_cmd(version: str, commit: bool) -> None:
775775- update_chromedriver(version, commit)
776776-777777-778211@cli.command("update", help="Update a single major release")
779779-@click.option("-v", "--version", help="The major version, e.g. '23'")
780780-@click.option(
781781- "-b",
782782- "--bin-only",
783783- is_flag=True,
784784- default=False,
785785- help="Only update electron-bin packages",
786786-)
787787-@click.option(
788788- "-s",
789789- "--source-only",
790790- is_flag=True,
791791- default=False,
792792- help="Only update electron-source packages",
793793-)
212212+@click.option("-v", "--version", required=True, type=str, help="The major version, e.g. '23'")
794213@click.option("-c", "--commit", is_flag=True, default=False, help="Commit the result")
795795-def update(version: str, bin_only: bool, source_only: bool, commit: bool) -> None:
796796- assert isinstance(version, str) and len(version) > 0, "version must be non-empty"
797797-798798- if bin_only and source_only:
799799- print(
800800- "Error: Omit --bin-only and --source-only if you want to update both source and binary packages.",
801801- file=sys.stderr,
802802- )
803803- sys.exit(1)
804804-805805- elif bin_only:
806806- update_bin(version, commit)
807807-808808- elif source_only:
809809- update_source(version, commit)
810810-811811- else:
812812- update_bin(version, commit)
813813- update_source(version, commit)
814814-815815- update_chromedriver(version, commit)
214214+def update(version: str, commit: bool) -> None:
215215+ update_source(version, commit)
816216817217818218@cli.command("update-all", help="Update all releases at once")
819819-@click.option(
820820- "-b",
821821- "--bin-only",
822822- is_flag=True,
823823- default=False,
824824- help="Only update electron-bin packages",
825825-)
826826-@click.option(
827827- "-s",
828828- "--source-only",
829829- is_flag=True,
830830- default=False,
831831- help="Only update electron-source packages",
832832-)
833219@click.option("-c", "--commit", is_flag=True, default=False, help="Commit the result")
834834-def update_all(bin_only: bool, source_only: bool, commit: bool) -> None:
835835- # Filter out releases that have reached end-of-life
836836- filtered_bin_info = dict(
837837- filter(
838838- lambda entry: int(entry[0]) in supported_version_range(),
839839- load_info_json(BINARY_INFO_JSON).items(),
840840- )
841841- )
842842-843843- if bin_only and source_only:
844844- print(
845845- "Error: omit --bin-only and --source-only if you want to update both source and binary packages.",
846846- file=sys.stderr,
847847- )
848848- sys.exit(1)
220220+def update_all(commit: bool) -> None:
221221+ """Update all eletron-source releases at once
849222850850- elif bin_only:
851851- for major_version, _ in filtered_bin_info.items():
852852- update_bin(major_version, commit)
223223+ Args:
224224+ commit: Whether to commit the result
225225+ """
226226+ old_info = load_info_json(SOURCE_INFO_JSON)
853227854854- elif source_only:
855855- update_all_source(commit)
856856-857857- else:
858858- for major_version, _ in filtered_bin_info.items():
859859- update_bin(major_version, commit)
228228+ filtered_releases = non_eol_releases(tuple(map(lambda x: int(x), old_info.keys())))
860229861861- update_all_source(commit)
862862-863863- for major_version, _ in filtered_bin_info.items():
864864- update_chromedriver(major_version, commit)
230230+ for major_version in filtered_releases:
231231+ update_source(str(major_version), commit)
865232866233867234if __name__ == "__main__":
+161
pkgs/development/tools/electron/update_util.py
···11+import json
22+import re
33+import sys
44+import subprocess
55+import urllib.request
66+77+from typing import Iterable, Optional, Tuple
88+from urllib.request import urlopen
99+from datetime import datetime
1010+1111+# Number of spaces used for each indentation level
1212+JSON_INDENT = 4
1313+1414+releases_json = None
1515+1616+# Releases that have reached end-of-life no longer receive any updates
1717+# and it is rather pointless trying to update those.
1818+#
1919+# https://endoflife.date/electron
2020+def supported_version_range() -> range:
2121+ """Returns a range of electron releases that have not reached end-of-life yet"""
2222+ global releases_json
2323+ if releases_json is None:
2424+ releases_json = json.loads(
2525+ urlopen("https://endoflife.date/api/electron.json").read()
2626+ )
2727+ supported_releases = [
2828+ int(x["cycle"])
2929+ for x in releases_json
3030+ if x["eol"] == False
3131+ or datetime.strptime(x["eol"], "%Y-%m-%d") > datetime.today()
3232+ ]
3333+3434+ return range(
3535+ min(supported_releases), # incl.
3636+ # We have also packaged the beta release in nixpkgs,
3737+ # but it is not tracked by endoflife.date
3838+ max(supported_releases) + 2, # excl.
3939+ 1,
4040+ )
4141+4242+def get_latest_version(major_version: str) -> Tuple[str, str]:
4343+ """Returns the latest version for a given major version"""
4444+ electron_releases: dict = json.loads(
4545+ urlopen("https://releases.electronjs.org/releases.json").read()
4646+ )
4747+ major_version_releases = filter(
4848+ lambda item: item["version"].startswith(f"{major_version}."), electron_releases
4949+ )
5050+ m = max(major_version_releases, key=lambda item: item["date"])
5151+5252+ rev = f"v{m['version']}"
5353+ return (m, rev)
5454+5555+5656+def load_info_json(path: str) -> dict:
5757+ """Load the contents of a JSON file
5858+5959+ Args:
6060+ path: The path to the JSON file
6161+6262+ Returns: An empty dict if the path does not exist, otherwise the contents of the JSON file.
6363+ """
6464+ try:
6565+ with open(path, "r") as f:
6666+ return json.loads(f.read())
6767+ except:
6868+ return {}
6969+7070+7171+def save_info_json(path: str, content: dict) -> None:
7272+ """Saves the given info to a JSON file
7373+7474+ Args:
7575+ path: The path where the info should be saved
7676+ content: The content to be saved as JSON.
7777+ """
7878+ with open(path, "w") as f:
7979+ f.write(json.dumps(content, indent=JSON_INDENT, default=vars, sort_keys=True))
8080+ f.write("\n")
8181+8282+8383+def parse_cve_numbers(tag_name: str) -> Iterable[str]:
8484+ """Returns mentioned CVE numbers from a given release tag"""
8585+ cve_pattern = r"CVE-\d{4}-\d+"
8686+ url = f"https://api.github.com/repos/electron/electron/releases/tags/{tag_name}"
8787+ headers = {
8888+ "Accept": "application/vnd.github+json",
8989+ "X-GitHub-Api-Version": "2022-11-28",
9090+ }
9191+ request = urllib.request.Request(url=url, headers=headers)
9292+ release_note = ""
9393+ try:
9494+ with urlopen(request) as response:
9595+ release_note = json.loads(response.read().decode("utf-8"))["body"]
9696+ except:
9797+ print(
9898+ f"WARN: Fetching release note for {tag_name} from GitHub failed!",
9999+ file=sys.stderr,
100100+ )
101101+102102+ return sorted(re.findall(cve_pattern, release_note))
103103+104104+105105+def commit_result(
106106+ package_name: str, old_version: Optional[str], new_version: str, path: str
107107+) -> None:
108108+ """Creates a git commit with a short description of the change
109109+110110+ Args:
111111+ package_name: The package name, e.g. `electron-source.electron-{major_version}`
112112+ or `electron_{major_version}-bin`
113113+114114+ old_version: Version number before the update.
115115+ Can be left empty when initializing a new release.
116116+117117+ new_version: Version number after the update.
118118+119119+ path: Path to the lockfile to be committed
120120+ """
121121+ assert (
122122+ isinstance(package_name, str) and len(package_name) > 0
123123+ ), "Argument `package_name` cannot be empty"
124124+ assert (
125125+ isinstance(new_version, str) and len(new_version) > 0
126126+ ), "Argument `new_version` cannot be empty"
127127+128128+ if old_version != new_version:
129129+ major_version = new_version.split(".")[0]
130130+ cve_fixes_text = "\n".join(
131131+ list(
132132+ map(lambda cve: f"- Fixes {cve}", parse_cve_numbers(f"v{new_version}"))
133133+ )
134134+ )
135135+ init_msg = f"init at {new_version}"
136136+ update_msg = f"{old_version} -> {new_version}"
137137+ diff = (
138138+ f"- Diff: https://github.com/electron/electron/compare/refs/tags/v{old_version}...v{new_version}\n"
139139+ if old_version != None
140140+ else ""
141141+ )
142142+ commit_message = f"""{package_name}: {update_msg if old_version != None else init_msg}
143143+144144+- Changelog: https://github.com/electron/electron/releases/tag/v{new_version}
145145+{diff}{cve_fixes_text}
146146+"""
147147+ subprocess.run(
148148+ [
149149+ "git",
150150+ "add",
151151+ path,
152152+ ]
153153+ )
154154+ subprocess.run(
155155+ [
156156+ "git",
157157+ "commit",
158158+ "-m",
159159+ commit_message,
160160+ ]
161161+ )
···77 owner = "freebsd";
88 repo = "freebsd-src";
99 inherit (sourceData) rev hash;
1010+1111+ # The GitHub export excludes some files in the git source
1212+ # that were marked `export-ignore`.
1313+ # A normal git checkout will keep those files,
1414+ # matching the update script
1515+ forceFetchGit = true;
1016}
···1010 "nvidia"
1111 "panfrost"
1212 "panthor"
1313+ "v3d"
1314 ];
1415 # these GPU families are partially supported upstream, they are also tricky to build in nixpkgs
1516 # volunteers with specific hardware needed to build and test these package variants
1616- additionalGPUFamilies = [ "ascend" ];
1717+ additionalGPUFamilies = [
1818+ "ascend"
1919+ "tpu"
2020+ ];
1721 defaultSupport = builtins.listToAttrs (
1822 # apple can only build on darwin, and it can't build everything else, and vice versa
1923 builtins.map (gpu: {
+1-5
pkgs/top-level/aliases.nix
···515515 dotnet-sdk_3 = throw "'dotnet-sdk_3' has been renamed to/replaced by 'dotnetCorePackages.sdk_3_1'"; # Converted to throw 2024-10-17
516516 dotnet-sdk_5 = throw "'dotnet-sdk_5' has been renamed to/replaced by 'dotnetCorePackages.sdk_5_0'"; # Converted to throw 2024-10-17
517517 downonspot = throw "'downonspot' was removed because upstream has been taken down by a cease and desist"; # Added 2025-01-25
518518+ dozenal = throw "dozenal has been removed because it does not compile and only minimal functionality"; # Added 2025-03-30
518519 dstat = throw "'dstat' has been removed because it has been unmaintained since 2020. Use 'dool' instead."; # Added 2025-01-21
519520 drush = throw "drush as a standalone package has been removed because it's no longer supported as a standalone tool";
520521 dtv-scan-tables_linuxtv = dtv-scan-tables; # Added 2023-03-03
···12481249 nux = throw "nux has been removed because it has been abandoned for 4 years"; # Added 2025-03-22
12491250 nvidia-podman = throw "podman should use the Container Device Interface (CDI) instead. See https://web.archive.org/web/20240729183805/https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html#configuring-podman"; # Added 2024-08-02
12501251 nvidia-thrust = throw "nvidia-thrust has been removed because the project was deprecated; use cudaPackages.cuda_cccl";
12511251- nvtop = lib.warnOnInstantiate "nvtop has been renamed to nvtopPackages.full" nvtopPackages.full; # Added 2024-02-25
12521252- nvtop-amd = lib.warnOnInstantiate "nvtop-amd has been renamed to nvtopPackages.amd" nvtopPackages.amd; # Added 2024-02-25
12531253- nvtop-nvidia = lib.warnOnInstantiate "nvtop-nvidia has been renamed to nvtopPackages.nvidia" nvtopPackages.nvidia; # Added 2024-02-25
12541254- nvtop-intel = lib.warnOnInstantiate "nvtop-intel has been renamed to nvtopPackages.intel" nvtopPackages.intel; # Added 2024-02-25
12551255- nvtop-msm = lib.warnOnInstantiate "nvtop-msm has been renamed to nvtopPackages.msm" nvtopPackages.msm; # Added 2024-02-25
1256125212571253 ### O ###
12581254