1# Packaging guidelines
2
3## buildHomeAssistantComponent
4
5Custom components should be packaged using the
6 `buildHomeAssistantComponent` function, that is provided at top-level.
7It builds upon `buildPythonPackage` but uses a custom install and check
8phase.
9
10Python runtime dependencies can be directly consumed as unqualified
11function arguments. Pass them into `dependencies`, for them to
12be available to Home Assistant.
13
14Out-of-tree components need to use Python packages from
15`home-assistant.python.pkgs` as to not introduce conflicting package
16versions into the Python environment.
17
18
19**Example Boilerplate:**
20
21```nix
22{
23 lib,
24 buildHomeAssistantComponent,
25 fetchFromGitHub,
26}:
27
28buildHomeAssistantComponent {
29 # owner, domain, version
30
31 src = fetchFromGithub {
32 # owner, repo, rev, hash
33 };
34
35 dependencies = [
36 # python requirements, as specified in manifest.json
37 ];
38
39 meta = with lib; {
40 # changelog, description, homepage, license, maintainers
41 };
42}
43```
44
45## Package attribute
46
47The attribute name must reflect the domain as seen in the
48`manifest.json`, which in turn will match the python module name below
49in the `custom_components/` directory.
50
51**Example:**
52
53The project [mweinelt/ha-prometheus-sensor](https://github.com/mweinelt/ha-prometheus-sensor/blob/1.0.0/custom_components/prometheus_sensor/manifest.json#L2)
54would receive the attribute name `"prometheus_sensor"`, because both
55domain in the `manifest.json` as well as the module name are
56`prometheus_sensor`.
57
58## Package name
59
60The `pname` attribute is a composition of both `owner` and `domain`.
61
62Don't set `pname`, set `owner` and `domain` instead.
63
64Exposing the `domain` attribute separately allows checking for
65conflicting components at eval time.
66
67## Manifest check
68
69The `buildHomeAssistantComponent` builder uses a hook to check whether
70the dependencies specified in the `manifest.json` are present and
71inside the specified version range. It also makes sure derivation
72and manifest agree about the domain name.
73
74There shouldn't be a need to disable this hook, but you can set
75`dontCheckManifest` to `true` in the derivation to achieve that.
76
77### Too narrow version constraints
78
79Every once in a while a dependency constraint is more narrow than it
80needs to be. Instead of applying brittle substitutions the version constraint
81can be ignored on a per requirement basis.
82
83```nix
84{
85 dependencies = [ pyemvue ];
86
87 # don't check the version constraint of pyemvue
88 ignoreVersionRequirement = [ "pyemvue" ];
89}
90```