nandi/frqpublic Fork 0
a71ef8fe780fac48a1cc6081092f15fbb310ac90
Commits
Clone
git clone https://git.rickub.com/nandi/frq.git
git clone ssh://git@rickub.com/nandi/frq.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Build the APK with buck2, from pins rather than from a second checkout a71ef8f · on a71ef8fe780fac48a1cc6081092f15fbb310ac90 · nandi · 19d ago
dotslash-to-buck · 90 lines · 3.4 KBGDScript3 Blame HistoryRaw
 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
#!/usr/bin/env python3
"""Generate buck2 http_archive data from the DotSlash files beside this script.

DotSlash is where a tool's version, URL and digest are written down. buck needs
the same three facts to fetch that tool itself — it cannot use the shim, which
resolves on the machine at run time and so is neither an action input nor
anything a remote worker could be given. Rather than write them twice and let
them drift, this reads the manifests and emits the table buck reads.

    just sync-dist        # after editing any scripts/*.dotslash

The DotSlash format is JSON with a `//` shebang line on top: one entry per
platform, each with a url, a size, a digest and the path of the binary inside
the archive. Only the archive itself is wanted here; the path inside it is the
shim's business, and the toolchain rules name what they need.
"""

import json
import pathlib
import sys

HERE = pathlib.Path(__file__).resolve().parent
OUT = HERE.parent / "toolchains" / "dist" / "generated.bzl"

# The tools buck fetches for itself. buck2 is not among them: it is the thing
# doing the fetching. jolt is not either — it is fetched by DotSlash on the
# machine that runs the boot image compile, which may not be this one.
TOOLS = {
    # DotSlash itself, so an action can fetch what it needs where it runs
    # rather than being handed it from here. See android/BUCK.
    "dotslash": "dotslash",
    # jolt-native's release, so the APK's UI half and the Jolt side of the
    # tree ABI are fetched rather than built out of a second checkout.
    "libvidya-android": "libvidya-android",
    "glimmer-vidya": "glimmer-vidya",
    "android-glue": "android-glue",
}


def load(path):
    text = path.read_text()
    return json.loads(text[text.index("{") :])


def main():
    entries = {}
    for stem, name in sorted(TOOLS.items()):
        for candidate in (HERE / f"{stem}.dotslash", HERE / stem):
            if candidate.exists():
                manifest = load(candidate)
                break
        else:
            sys.exit(f"no DotSlash manifest for {stem}")

        platforms = {}
        for platform, entry in sorted(manifest["platforms"].items()):
            if entry["hash"] != "sha256":
                # http_archive takes sha256 and nothing else.
                continue
            url = entry["providers"][0]["url"]
            # The path of the binary inside the archive starts with the
            # directory the tarball unpacks into, which is what to strip.
            # A flat archive — one binary, no directory around it — has
            # nothing to strip, and naming the binary would strip the whole
            # payload.
            head, _, rest = entry["path"].partition("/")
            platforms[platform] = {
                "url": url,
                "sha256": entry["digest"],
                "strip_prefix": head if rest else "",
                "type": entry["format"],
            }
        entries[name] = platforms

    lines = [
        "# @generated by scripts/dotslash-to-buck — do not edit.",
        "#",
        "# The same archives scripts/*.dotslash pins, as facts buck can act on.",
        "# Bump the DotSlash file and run `just sync-dist`.",
        "",
        "DIST = " + json.dumps(entries, indent=4).replace(": true", ": True"),
        "",
    ]
    OUT.parent.mkdir(parents=True, exist_ok=True)
    OUT.write_text("\n".join(lines))
    print(f"wrote {OUT.relative_to(HERE.parent)}")


if __name__ == "__main__":
    main()