summary refs log tree commit diff
diff options
context:
space:
mode:
authorGraham Bennett <graham@grahambennett.org>2023-11-06 22:50:16 +0100
committerMartin Weinelt <hexa@darmstadt.ccc.de>2023-11-10 22:00:35 +0100
commit31e60c2fbbb6d3502a4ab2834ea240f1009aafa2 (patch)
tree66db5a605cd3c0e9336e958b4aeae1be63124653
parentb1ddeedea67a49e0abe3e5422dab34625281c0f1 (diff)
downloadnixpkgs-31e60c2fbbb6d3502a4ab2834ea240f1009aafa2.tar
nixpkgs-31e60c2fbbb6d3502a4ab2834ea240f1009aafa2.tar.gz
nixpkgs-31e60c2fbbb6d3502a4ab2834ea240f1009aafa2.tar.bz2
nixpkgs-31e60c2fbbb6d3502a4ab2834ea240f1009aafa2.tar.lz
nixpkgs-31e60c2fbbb6d3502a4ab2834ea240f1009aafa2.tar.xz
nixpkgs-31e60c2fbbb6d3502a4ab2834ea240f1009aafa2.tar.zst
nixpkgs-31e60c2fbbb6d3502a4ab2834ea240f1009aafa2.zip
buildHomeAssistantComponent: init
Builder to package up custom components for Home Assistant.

These packages use `buildPythonPackage` with `format = "other"` and
rely on a custom install phase, that expects a standardized path,
and a custom check phase, that for now verifies python dependencies have
been satisified.

Co-Authored-By: Martin Weinelt <hexa@darmstadt.ccc.de>
Co-Authored-By: Sandro Jäckel <sandro.jaeckel@gmail.com>
-rw-r--r--pkgs/servers/home-assistant/build-custom-component/check_manifest.py46
-rw-r--r--pkgs/servers/home-assistant/build-custom-component/default.nix38
-rw-r--r--pkgs/servers/home-assistant/build-custom-component/manifest-requirements-check-hook.nix11
-rw-r--r--pkgs/servers/home-assistant/build-custom-component/manifest-requirements-check-hook.sh25
-rw-r--r--pkgs/servers/home-assistant/custom-components/default.nix5
-rw-r--r--pkgs/top-level/all-packages.nix5
6 files changed, 130 insertions, 0 deletions
diff --git a/pkgs/servers/home-assistant/build-custom-component/check_manifest.py b/pkgs/servers/home-assistant/build-custom-component/check_manifest.py
new file mode 100644
index 00000000000..bbe9535824e
--- /dev/null
+++ b/pkgs/servers/home-assistant/build-custom-component/check_manifest.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+
+import json
+import importlib_metadata
+import sys
+
+from packaging.requirements import Requirement
+
+
+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
+
+    # 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,
+        )
+        return False
+
+    return True
+
+
+def check_manifest(manifest_file: str):
+    with open(manifest_file) as fd:
+        manifest = json.load(fd)
+    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 __name__ == "__main__":
+    if len(sys.argv) < 2:
+        raise RuntimeError(f"Usage {sys.argv[0]} <manifest>")
+    manifest_file = sys.argv[1]
+    check_manifest(manifest_file)
diff --git a/pkgs/servers/home-assistant/build-custom-component/default.nix b/pkgs/servers/home-assistant/build-custom-component/default.nix
new file mode 100644
index 00000000000..05b7c2d4b03
--- /dev/null
+++ b/pkgs/servers/home-assistant/build-custom-component/default.nix
@@ -0,0 +1,38 @@
+{ lib
+, home-assistant
+, makeSetupHook
+}:
+
+{ pname
+, version
+, format ? "other"
+, ...
+}@args:
+
+let
+  manifestRequirementsCheckHook = import ./manifest-requirements-check-hook.nix {
+    inherit makeSetupHook;
+    inherit (home-assistant) python;
+  };
+in
+home-assistant.python.pkgs.buildPythonPackage (
+  {
+    inherit format;
+
+    installPhase = ''
+      runHook preInstall
+
+      mkdir $out
+      cp -r $src/custom_components/ $out/
+
+      runHook postInstall
+    '';
+
+    nativeCheckInputs = with home-assistant.python.pkgs; [
+      importlib-metadata
+      manifestRequirementsCheckHook
+      packaging
+    ] ++ (args.nativeCheckInputs or []);
+
+  } // builtins.removeAttrs args [ "nativeCheckInputs" ]
+)
diff --git a/pkgs/servers/home-assistant/build-custom-component/manifest-requirements-check-hook.nix b/pkgs/servers/home-assistant/build-custom-component/manifest-requirements-check-hook.nix
new file mode 100644
index 00000000000..76317c9d0bc
--- /dev/null
+++ b/pkgs/servers/home-assistant/build-custom-component/manifest-requirements-check-hook.nix
@@ -0,0 +1,11 @@
+{ python
+, makeSetupHook
+}:
+
+makeSetupHook {
+  name = "manifest-requirements-check-hook";
+  substitutions = {
+    pythonCheckInterpreter = python.interpreter;
+    checkManifest = ./check_manifest.py;
+  };
+} ./manifest-requirements-check-hook.sh
diff --git a/pkgs/servers/home-assistant/build-custom-component/manifest-requirements-check-hook.sh b/pkgs/servers/home-assistant/build-custom-component/manifest-requirements-check-hook.sh
new file mode 100644
index 00000000000..74f29ca399e
--- /dev/null
+++ b/pkgs/servers/home-assistant/build-custom-component/manifest-requirements-check-hook.sh
@@ -0,0 +1,25 @@
+# Setup hook to check HA manifest requirements
+echo "Sourcing manifest-requirements-check-hook"
+
+function manifestCheckPhase() {
+    echo "Executing manifestCheckPhase"
+    runHook preCheck
+
+    manifests=$(shopt -s nullglob; echo $out/custom_components/*/manifest.json)
+
+    if [ ! -z "$manifests" ]; then
+        echo Checking manifests $manifests
+        @pythonCheckInterpreter@ @checkManifest@ $manifests
+    else
+        echo "No custom component manifests found in $out" >&2
+        exit 1
+    fi
+
+    runHook postCheck
+    echo "Finished executing manifestCheckPhase"
+}
+
+if [ -z "${dontCheckManifest-}" ] && [ -z "${installCheckPhase-}" ]; then
+    echo "Using manifestCheckPhase"
+    preDistPhases+=" manifestCheckPhase"
+fi
diff --git a/pkgs/servers/home-assistant/custom-components/default.nix b/pkgs/servers/home-assistant/custom-components/default.nix
new file mode 100644
index 00000000000..babfe90af35
--- /dev/null
+++ b/pkgs/servers/home-assistant/custom-components/default.nix
@@ -0,0 +1,5 @@
+{ callPackage
+}:
+
+{
+}
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 4ad2591c831..b043595dbcc 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -26459,6 +26459,11 @@ with pkgs;
 
   home-assistant = callPackage ../servers/home-assistant { };
 
+  buildHomeAssistantComponent = callPackage ../servers/home-assistant/build-custom-component { };
+  home-assistant-custom-components = lib.recurseIntoAttrs
+    (callPackage ../servers/home-assistant/custom-components {
+      inherit (home-assistant.python.pkgs) callPackage;
+    });
   home-assistant-custom-lovelace-modules = lib.recurseIntoAttrs
     (callPackage ../servers/home-assistant/custom-lovelace-modules {});