summary refs log tree commit diff
path: root/pkgs/development/tools/poetry2nix/poetry2nix/bin/poetry2nix
blob: 355cebfd50c46fd16f7f68e3581aec12d9ea6338 (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
#!/usr/bin/env python
from concurrent.futures import ThreadPoolExecutor
import subprocess
import textwrap
import argparse
import toml
import json
import sys


argparser = argparse.ArgumentParser(description="Poetry2nix CLI")

subparsers = argparser.add_subparsers(dest="subcommand")
subparsers.required = True

parser_lock = subparsers.add_parser("lock", help="Generate overrides for git hashes",)
parser_lock.add_argument(
    "--lock", default="poetry.lock", help="Path to input poetry.lock",
)
parser_lock.add_argument(
    "--out", default="poetry-git-overlay.nix", help="Output file",
)


def fetch_git(pkg):
    return (
        pkg["name"],
        subprocess.run(
            [
                "nix-prefetch-git",
                "--fetch-submodules",
                "--url",
                pkg["source"]["url"],
                "--rev",
                pkg["source"]["reference"],
            ],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        ),
    )


def indent(expr, spaces=2):
    i = " " * spaces
    return "\n".join([(i if l != "" else "") + l for l in expr.split("\n")])


if __name__ == "__main__":
    args = argparser.parse_args()

    with open(args.lock) as lockf:
        lock = toml.load(lockf)

    pkgs = []
    for pkg in lock["package"]:
        if "source" in pkg:
            pkgs.append(pkg)

    with ThreadPoolExecutor() as e:
        futures = []

        for pkg in pkgs:
            futures.append(e.submit(fetch_git, pkg))

        lines = [
            "{ pkgs }:",
            "self: super: {",
        ]

        for f in futures:
            drv_name, p = f.result()
            if p.returncode != 0:
                sys.stderr.buffer.write(p.stderr)
                sys.stderr.buffer.flush()
                exit(p.returncode)

            meta = json.loads(p.stdout.decode())
            lines.append(
                indent(
                    textwrap.dedent(
                        """
              %s = super.%s.overridePythonAttrs (
                _: {
                  src = pkgs.fetchgit {
                    url = "%s";
                    rev = "%s";
                    sha256 = "%s";
                  };
                }
              );"""
                        % (drv_name, drv_name, meta["url"], meta["rev"], meta["sha256"])
                    )
                )
            )

        lines.extend(["", "}", ""])

        expr = "\n".join(lines)

    with open(args.out, "w") as fout:
        fout.write(expr)

    print(f"Wrote {args.out}")