From 028a9348963e73a5998aeb1b3265b005ff06b6b2 Mon Sep 17 00:00:00 2001 From: adisbladis Date: Sun, 24 Apr 2022 02:08:29 +1200 Subject: [PATCH] emacs.pkgs.tsc: Add update script --- .../emacs/elisp-packages/tsc/default.nix | 21 +++ .../emacs/elisp-packages/tsc/update.py | 122 ++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 pkgs/applications/editors/emacs/elisp-packages/tsc/update.py diff --git a/pkgs/applications/editors/emacs/elisp-packages/tsc/default.nix b/pkgs/applications/editors/emacs/elisp-packages/tsc/default.nix index dcb950824d0d..ae0c5c28736c 100644 --- a/pkgs/applications/editors/emacs/elisp-packages/tsc/default.nix +++ b/pkgs/applications/editors/emacs/elisp-packages/tsc/default.nix @@ -6,6 +6,12 @@ , writeText , clang , llvmPackages + +, runtimeShell +, writeScript +, python3 +, nix-prefetch-github +, nix }: let @@ -63,6 +69,21 @@ in symlinkJoin { name = "tsc-${version}"; paths = [ tsc tsc-dyn ]; + passthru = { + updateScript = let + pythonEnv = python3.withPackages(ps: [ ps.requests ]); + in writeScript "tsc-update" '' + #!${runtimeShell} + set -euo pipefail + export PATH=${lib.makeBinPath [ + nix-prefetch-github + nix + pythonEnv + ]}:$PATH + exec python3 ${builtins.toString ./update.py} ${builtins.toString ./.} + ''; + }; + meta = { description = "The core APIs of the Emacs binding for tree-sitter."; license = lib.licenses.mit; diff --git a/pkgs/applications/editors/emacs/elisp-packages/tsc/update.py b/pkgs/applications/editors/emacs/elisp-packages/tsc/update.py new file mode 100644 index 000000000000..ce2054f909ef --- /dev/null +++ b/pkgs/applications/editors/emacs/elisp-packages/tsc/update.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 +from textwrap import dedent +from os.path import ( + abspath, + dirname, + join, +) +from typing import ( + Dict, + Any, +) +import subprocess +import tempfile +import json +import sys +import re + +import requests + + +def eval_drv(nixpkgs: str, expr: str) -> Any: + expr = "\n".join( + ( + "with (import %s {});" % nixpkgs, + expr, + ) + ) + + with tempfile.NamedTemporaryFile(mode="w") as f: + f.write(dedent(expr)) + f.flush() + p = subprocess.run( + ["nix-instantiate", "--json", f.name], stdout=subprocess.PIPE, check=True + ) + + return p.stdout.decode().strip() + + +def get_src(tag_name: str) -> Dict[str, str]: + p = subprocess.run( + [ + "nix-prefetch-github", + "--rev", + tag_name, + "--json", + "emacs-tree-sitter", + "elisp-tree-sitter", + ], + stdout=subprocess.PIPE, + check=True, + ) + src = json.loads(p.stdout) + + fields = ["owner", "repo", "rev", "sha256"] + + return {f: src[f] for f in fields} + + +def get_cargo_sha256(drv_path: str): + # Note: No check=True since we expect this command to fail + p = subprocess.run(["nix-store", "-r", drv_path], stderr=subprocess.PIPE) + + stderr = p.stderr.decode() + lines = iter(stderr.split("\n")) + + for l in lines: + if l.startswith("error: hash mismatch in fixed-output derivation"): + break + else: + raise ValueError("Did not find expected hash mismatch message") + + for l in lines: + m = re.match(r"\s+got:\s+(.+)$", l) + if m: + return m.group(1) + + raise ValueError("Could not extract actual sha256 hash: ", stderr) + + +if __name__ == "__main__": + cwd = sys.argv[1] + + nixpkgs = abspath(join(cwd, "../../../../../..")) + + tag_name = requests.get( + "https://api.github.com/repos/emacs-tree-sitter/elisp-tree-sitter/releases/latest" + ).json()["tag_name"] + + src = get_src(tag_name) + + with tempfile.NamedTemporaryFile(mode="w") as f: + json.dump(src, f) + f.flush() + + drv_path = eval_drv( + nixpkgs, + """ + rustPlatform.buildRustPackage { + pname = "tsc-dyn"; + version = "%s"; + nativeBuildInputs = [ clang ]; + src = fetchFromGitHub (lib.importJSON %s); + sourceRoot = "source/core"; + cargoSha256 = lib.fakeSha256; + } + """ + % (tag_name, f.name), + ) + + cargo_sha256 = get_cargo_sha256(drv_path) + + with open(join(cwd, "src.json"), mode="w") as f: + json.dump( + { + "src": src, + "version": tag_name, + "cargoSha256": cargo_sha256, + }, + f, + indent=2, + ) + f.write("\n")