home-assistant: revamp manual package choosing

main
Robert Schütz 2 years ago
parent d7c433094b
commit 2e8071c4e2
  1. 2
      pkgs/servers/home-assistant/component-packages.nix
  2. 44
      pkgs/servers/home-assistant/parse-requirements.py

@ -216,7 +216,7 @@
"ecobee" = ps: with ps; [ python-ecobee-api ];
"econet" = ps: with ps; [ pyeconet ];
"ecovacs" = ps: with ps; [ ]; # missing inputs: sucks
"eddystone_temperature" = ps: with ps; [ construct ]; # missing inputs: beacontools[scan]
"eddystone_temperature" = ps: with ps; [ construct ]; # missing inputs: beacontools
"edimax" = ps: with ps; [ pyedimax ];
"edl21" = ps: with ps; [ pysml ];
"efergy" = ps: with ps; [ pyefergy ];

@ -34,16 +34,11 @@ from rich.table import Table
COMPONENT_PREFIX = "homeassistant.components"
PKG_SET = "home-assistant.python.pkgs"
# If some requirements are matched by multiple Python packages,
# the following can be used to choose one of them
# If some requirements are matched by multiple or no Python packages, the
# following can be used to choose the correct one
PKG_PREFERENCES = {
# Use python3Packages.youtube-dl-light instead of python3Packages.youtube-dl
"youtube-dl": "youtube-dl-light",
"tensorflow-bin": "tensorflow",
"tensorflow-bin_2": "tensorflow",
"tensorflowWithoutCuda": "tensorflow",
"tensorflow-build_2": "tensorflow",
"whois": "python-whois",
"youtube_dl": "youtube-dl-light",
"tensorflow": "tensorflow",
}
@ -120,39 +115,28 @@ def dump_packages() -> Dict[str, Dict[str, str]]:
def name_to_attr_path(req: str, packages: Dict[str, Dict[str, str]]) -> Optional[str]:
attr_paths = set()
if req in PKG_PREFERENCES:
return f"{PKG_SET}.{PKG_PREFERENCES[req]}"
attr_paths = []
names = [req]
# E.g. python-mpd2 is actually called python3.6-mpd2
# instead of python-3.6-python-mpd2 inside Nixpkgs
if req.startswith("python-") or req.startswith("python_"):
names.append(req[len("python-") :])
# Add name variant without extra_require, e.g. samsungctl
# instead of samsungctl[websocket]
if req.endswith("]"):
names.append(req[:req.find("[")])
for name in names:
# treat "-" and "_" equally
name = re.sub("[-_]", "[-_]", name)
# python(minor).(major)-(pname)-(version or unstable-date)
# we need the version qualifier, or we'll have multiple matches
# (e.g. pyserial and pyserial-asyncio when looking for pyserial)
pattern = re.compile("^python\\d\\.\\d-{}-(?:\\d|unstable-.*)".format(name), re.I)
pattern = re.compile(f"^python\\d\\.\\d-{name}-(?:\\d|unstable-.*)", re.I)
for attr_path, package in packages.items():
if pattern.match(package["name"]):
attr_paths.add(attr_path)
if len(attr_paths) > 1:
for to_replace, replacement in PKG_PREFERENCES.items():
try:
attr_paths.remove(PKG_SET + "." + to_replace)
attr_paths.add(PKG_SET + "." + replacement)
except KeyError:
pass
attr_paths.append(attr_path)
# Let's hope there's only one derivation with a matching name
assert len(attr_paths) <= 1, "{} matches more than one derivation: {}".format(
req, attr_paths
)
if len(attr_paths) == 1:
return attr_paths.pop()
assert len(attr_paths) <= 1, f"{req} matches more than one derivation: {attr_paths}"
if attr_paths:
return attr_paths[0]
else:
return None
@ -180,6 +164,10 @@ def main() -> None:
# Therefore, if there's a "#" in the line, only take the part after it
req = req[req.find("#") + 1 :]
name, required_version = req.split("==", maxsplit=1)
# Remove extra_require from name, e.g. samsungctl instead of
# samsungctl[websocket]
if name.endswith("]"):
name = name[:name.find("[")]
attr_path = name_to_attr_path(name, packages)
if our_version := get_pkg_version(name, packages):
if Version.parse(our_version) < Version.parse(required_version):

Loading…
Cancel
Save