summary refs log tree commit diff
path: root/pkgs/applications/editors/emacs/elisp-packages/manual-packages/tsc/update.py
blob: a144cb77be92c975a038ff2e82a4bae4b25cfd9e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/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", "hash"]

    return {f: src[f] for f in fields}


def get_cargo_hash(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 hash: ", stderr)


if __name__ == "__main__":
    cwd = sys.argv[1]

    # This should point to the root default.nix of Nixpkgs tree
    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";
          cargoHash = lib.fakeHash;
        }
        """
            % (tag_name, f.name),
        )

    cargo_hash = get_cargo_hash(drv_path)

    with open(join(cwd, "src.json"), mode="w") as f:
        json.dump(
            {
                "src": src,
                "version": tag_name,
                "cargoHash": cargo_hash,
            },
            f,
            indent=2,
        )
        f.write("\n")