diff --git a/pkgs/servers/home-assistant/component-packages.nix b/pkgs/servers/home-assistant/component-packages.nix index 714087eb2e60..cf002775bc31 100644 --- a/pkgs/servers/home-assistant/component-packages.nix +++ b/pkgs/servers/home-assistant/component-packages.nix @@ -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 ]; diff --git a/pkgs/servers/home-assistant/parse-requirements.py b/pkgs/servers/home-assistant/parse-requirements.py index fbe46b237787..e7e94efefb04 100755 --- a/pkgs/servers/home-assistant/parse-requirements.py +++ b/pkgs/servers/home-assistant/parse-requirements.py @@ -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):