home-assistant/parse-requirements: write missing deps to component-packages.nix

wip/yesman
Jörg Thalheim 4 years ago
parent 0cf1e8ee05
commit de1119f5fb
No known key found for this signature in database
GPG Key ID: 003F2096411B5F92
  1. 113
      pkgs/servers/home-assistant/parse-requirements.py

@ -24,6 +24,7 @@ import sys
import tarfile
import tempfile
from io import BytesIO
from typing import Dict, Optional
from urllib.request import urlopen
COMPONENT_PREFIX = "homeassistant.components"
@ -78,22 +79,23 @@ def get_reqs(components, component):
return requirements
# Store a JSON dump of Nixpkgs' python3Packages
output = subprocess.check_output(
[
"nix-env",
"-f",
os.path.dirname(sys.argv[0]) + "/../../..",
"-qa",
"-A",
PKG_SET,
"--json",
]
)
packages = json.loads(output)
def dump_packages() -> Dict[str, Dict[str, str]]:
# Store a JSON dump of Nixpkgs' python3Packages
output = subprocess.check_output(
[
"nix-env",
"-f",
os.path.dirname(sys.argv[0]) + "/../../..",
"-qa",
"-A",
PKG_SET,
"--json",
]
)
return json.loads(output)
def name_to_attr_path(req):
def name_to_attr_path(req: str, packages: Dict[str, Dict[str, str]]) -> Optional[str]:
attr_paths = set()
names = [req]
# E.g. python-mpd2 is actually called python3.6-mpd2
@ -124,41 +126,50 @@ def name_to_attr_path(req):
return None
version = get_version()
print("Generating component-packages.nix for version {}".format(version))
components = parse_components(version=version)
build_inputs = {}
for component in sorted(components.keys()):
attr_paths = []
missing_reqs = []
reqs = sorted(get_reqs(components, component))
for req in reqs:
# Some requirements are specified by url, e.g. https://example.org/foobar#xyz==1.0.0
# Therefore, if there's a "#" in the line, only take the part after it
req = req[req.find("#") + 1 :]
name = req.split("==")[0]
attr_path = name_to_attr_path(name)
if attr_path is not None:
# Add attribute path without "python3Packages." prefix
attr_paths.append(attr_path[len(PKG_SET + ".") :])
def main() -> None:
packages = dump_packages()
version = get_version()
print("Generating component-packages.nix for version {}".format(version))
components = parse_components(version=version)
build_inputs = {}
for component in sorted(components.keys()):
attr_paths = []
missing_reqs = []
reqs = sorted(get_reqs(components, component))
for req in reqs:
# Some requirements are specified by url, e.g. https://example.org/foobar#xyz==1.0.0
# Therefore, if there's a "#" in the line, only take the part after it
req = req[req.find("#") + 1 :]
name = req.split("==")[0]
attr_path = name_to_attr_path(name, packages)
if attr_path is not None:
# Add attribute path without "python3Packages." prefix
attr_paths.append(attr_path[len(PKG_SET + ".") :])
else:
missing_reqs.append(name)
else:
missing_reqs.append(name)
else:
build_inputs[component] = attr_paths
n_diff = len(reqs) > len(build_inputs[component])
if n_diff > 0:
print("Component {} is missing {} dependencies".format(component, n_diff))
print("missing requirements: {}".format(missing_reqs))
with open(os.path.dirname(sys.argv[0]) + "/component-packages.nix", "w") as f:
f.write("# Generated by parse-requirements.py\n")
f.write("# Do not edit!\n\n")
f.write("{\n")
f.write(f' version = "{version}";\n')
f.write(" components = {\n")
for component, attr_paths in build_inputs.items():
f.write(' "{component}" = ps: with ps; [ ')
f.write(" ".join(attr_paths))
f.write(" ];\n")
f.write(" };\n")
f.write("}\n")
build_inputs[component] = (attr_paths, missing_reqs)
n_diff = len(reqs) > len(build_inputs[component])
if n_diff > 0:
print("Component {} is missing {} dependencies".format(component, n_diff))
print("missing requirements: {}".format(missing_reqs))
with open(os.path.dirname(sys.argv[0]) + "/component-packages.nix", "w") as f:
f.write("# Generated by parse-requirements.py\n")
f.write("# Do not edit!\n\n")
f.write("{\n")
f.write(f' version = "{version}";\n')
f.write(" components = {\n")
for component, deps in build_inputs.items():
available, missing = deps
f.write(f" \"{component}\" = ps: with ps; [ ")
f.write(" ".join(available))
f.write("];")
if len(missing) > 0:
f.write(f" # missing inputs: {' '.join(missing)}")
f.write("\n")
f.write(" };\n")
f.write("}\n")
if __name__ == '__main__':
main()

Loading…
Cancel
Save