From 8c87a98ce1e8850faee64a0a540acff233b66bd2 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Sat, 25 Nov 2023 14:23:49 +0100 Subject: [PATCH 1/2] buildHomeAssistantComponent: fix install with patches applied Installing from `$src` will always copy the unmodified source tree, as it appears in the /nix/store. This prevents the application of patches. --- pkgs/servers/home-assistant/build-custom-component/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/servers/home-assistant/build-custom-component/default.nix b/pkgs/servers/home-assistant/build-custom-component/default.nix index 05b7c2d4b039..5a6e76deb413 100644 --- a/pkgs/servers/home-assistant/build-custom-component/default.nix +++ b/pkgs/servers/home-assistant/build-custom-component/default.nix @@ -23,7 +23,7 @@ home-assistant.python.pkgs.buildPythonPackage ( runHook preInstall mkdir $out - cp -r $src/custom_components/ $out/ + cp -r ./custom_components/ $out/ runHook postInstall ''; From 01616e5331d2790127aa2e61c126fff9467889f2 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Sat, 25 Nov 2023 16:32:41 +0100 Subject: [PATCH 2/2] buildHomeAssistantComponent: migrate from pname to owner/domain Also make the attribute name to match the domain name. This is more in line with the home-assistant custom component ecosystem and allows additional validation between the derivation and the manifest. Also, at a later time, this will enable us to check for domain conflicts at eval time. --- nixos/tests/home-assistant.nix | 2 +- .../build-custom-component/check_manifest.py | 38 +++++++++++++------ .../build-custom-component/default.nix | 4 +- .../custom-components/README.md | 30 +++++++++++---- .../custom-components/default.nix | 2 +- .../default.nix | 3 +- 6 files changed, 56 insertions(+), 23 deletions(-) rename pkgs/servers/home-assistant/custom-components/{prometheus-sensor => prometheus_sensor}/default.nix (92%) diff --git a/nixos/tests/home-assistant.nix b/nixos/tests/home-assistant.nix index e1588088ba19..9200723f35e7 100644 --- a/nixos/tests/home-assistant.nix +++ b/nixos/tests/home-assistant.nix @@ -43,7 +43,7 @@ in { # test loading custom components customComponents = with pkgs.home-assistant-custom-components; [ - prometheus-sensor + prometheus_sensor ]; # test loading lovelace modules diff --git a/pkgs/servers/home-assistant/build-custom-component/check_manifest.py b/pkgs/servers/home-assistant/build-custom-component/check_manifest.py index bbe9535824e7..463a7579763d 100644 --- a/pkgs/servers/home-assistant/build-custom-component/check_manifest.py +++ b/pkgs/servers/home-assistant/build-custom-component/check_manifest.py @@ -1,28 +1,31 @@ #!/usr/bin/env python3 import json -import importlib_metadata +import os import sys +import importlib_metadata from packaging.requirements import Requirement +def error(msg: str) -> None: + print(f" - {msg}", file=sys.stderr) + return False + + def check_requirement(req: str): # https://packaging.pypa.io/en/stable/requirements.html requirement = Requirement(req) try: version = importlib_metadata.distribution(requirement.name).version except importlib_metadata.PackageNotFoundError: - print(f" - Dependency {requirement.name} is missing", file=sys.stderr) - return False + return error(f"{requirement.name}{requirement.specifier} not present") # https://packaging.pypa.io/en/stable/specifiers.html - if not version in requirement.specifier: - print( - f" - {requirement.name}{requirement.specifier} expected, but got {version}", - file=sys.stderr, + if version not in requirement.specifier: + return error( + f"{requirement.name}{requirement.specifier} expected, but got {version}" ) - return False return True @@ -30,13 +33,24 @@ def check_requirement(req: str): def check_manifest(manifest_file: str): with open(manifest_file) as fd: manifest = json.load(fd) + + ok = True + + derivation_domain = os.environ.get("domain") + manifest_domain = manifest["domain"] + if derivation_domain != manifest_domain: + ok = False + error( + f"Derivation attribute domain ({derivation_domain}) must match manifest domain ({manifest_domain})" + ) + if "requirements" in manifest: - ok = True for requirement in manifest["requirements"]: ok &= check_requirement(requirement) - if not ok: - print("Manifest requirements are not met", file=sys.stderr) - sys.exit(1) + + if not ok: + error("Manifest check failed.") + sys.exit(1) if __name__ == "__main__": diff --git a/pkgs/servers/home-assistant/build-custom-component/default.nix b/pkgs/servers/home-assistant/build-custom-component/default.nix index 5a6e76deb413..2948d15bb814 100644 --- a/pkgs/servers/home-assistant/build-custom-component/default.nix +++ b/pkgs/servers/home-assistant/build-custom-component/default.nix @@ -3,7 +3,8 @@ , makeSetupHook }: -{ pname +{ owner +, domain , version , format ? "other" , ... @@ -17,6 +18,7 @@ let in home-assistant.python.pkgs.buildPythonPackage ( { + pname = "${owner}/${domain}"; inherit format; installPhase = '' diff --git a/pkgs/servers/home-assistant/custom-components/README.md b/pkgs/servers/home-assistant/custom-components/README.md index a7244b25c173..d7137e5c62f7 100644 --- a/pkgs/servers/home-assistant/custom-components/README.md +++ b/pkgs/servers/home-assistant/custom-components/README.md @@ -25,7 +25,7 @@ versions into the Python environment. }: buildHomeAssistantComponent { - # pname, version + # owner, domain, version src = fetchFromGithub { # owner, repo, rev, hash @@ -40,18 +40,34 @@ buildHomeAssistantComponent { } } -## Package name normalization +## Package attribute -Apply the same normalization rules as defined for python packages in -[PEP503](https://peps.python.org/pep-0503/#normalized-names). -The name should be lowercased and dots, underlines or multiple -dashes should all be replaced by a single dash. +The attribute name must reflect the domain as seen in the +`manifest.json`, which in turn will match the python module name below +in the `custom_components/` directory. + +**Example:** + +The project [mweinelt/ha-prometheus-sensor](https://github.com/mweinelt/ha-prometheus-sensor/blob/1.0.0/custom_components/prometheus_sensor/manifest.json#L2) +would receive the attribute name `"prometheus_sensor"`, because both +domain in the `manifest.json` as well as the module name are +`prometheus_sensor`. + +## Package name + +The `pname` attribute is a composition of both `owner` and `domain`. + +Don't set `pname`, set `owner and `domain` instead. + +Exposing the `domain` attribute separately allows checking for +conflicting components at eval time. ## Manifest check The `buildHomeAssistantComponent` builder uses a hook to check whether the dependencies specified in the `manifest.json` are present and -inside the specified version range. +inside the specified version range. It also makes sure derivation +and manifest agree about the domain name. There shouldn't be a need to disable this hook, but you can set `dontCheckManifest` to `true` in the derivation to achieve that. diff --git a/pkgs/servers/home-assistant/custom-components/default.nix b/pkgs/servers/home-assistant/custom-components/default.nix index 4a96b305964a..15bd721c72e8 100644 --- a/pkgs/servers/home-assistant/custom-components/default.nix +++ b/pkgs/servers/home-assistant/custom-components/default.nix @@ -2,5 +2,5 @@ }: { - prometheus-sensor = callPackage ./prometheus-sensor {}; + prometheus_sensor = callPackage ./prometheus_sensor {}; } diff --git a/pkgs/servers/home-assistant/custom-components/prometheus-sensor/default.nix b/pkgs/servers/home-assistant/custom-components/prometheus_sensor/default.nix similarity index 92% rename from pkgs/servers/home-assistant/custom-components/prometheus-sensor/default.nix rename to pkgs/servers/home-assistant/custom-components/prometheus_sensor/default.nix index 07bcd9abec1c..2368d85552b2 100644 --- a/pkgs/servers/home-assistant/custom-components/prometheus-sensor/default.nix +++ b/pkgs/servers/home-assistant/custom-components/prometheus_sensor/default.nix @@ -4,7 +4,8 @@ }: buildHomeAssistantComponent rec { - pname = "prometheus-sensor"; + owner = "mweinelt"; + domain = "prometheus_sensor"; version = "1.0.0"; src = fetchFromGitHub {