7 # Look up dependencies of specified components in component-packages.nix
8 , extraComponents ? [ ]
10 # Additional packages to add to propagatedBuildInputs
11 , extraPackages ? ps: []
13 # Override Python packages using
14 # self: super: { pkg = super.pkg.overridePythonAttrs (oldAttrs: { ... }); }
15 # Applied after defaultOverrides
16 , packageOverrides ? self: super: {}
18 # Skip pip install of required packages on startup
23 # Override the version of some packages pinned in Home Assistant's setup.py
25 # Pinned due to API changes in astral>=2.0, required by the sun/moon plugins
26 # https://github.com/home-assistant/core/issues/36636
27 (mkOverride "astral" "1.10.1"
28 "d2a67243c4503131c856cafb1b1276de52a86e5b8a1d507b7e08bee51cb67bf1")
30 # Pinned due to API changes in iaqualink>=2.0, remove after
31 # https://github.com/home-assistant/core/pull/48137 was merged
33 iaqualink = super.iaqualink.overridePythonAttrs (oldAttrs: rec {
35 src = fetchFromGitHub {
37 repo = "iaqualink-py";
39 sha256 = "16mn6nd9x3hm6j6da99qhwbqs95hh8wx21r1h1m9csl76z77n9lh";
41 checkInputs = oldAttrs.checkInputs ++ [ python3.pkgs.asynctest ];
45 # Pinned due to API changes in pylilterbot>=2021.3.0
47 pylitterbot = super.pylitterbot.overridePythonAttrs (oldAttrs: rec {
49 src = fetchFromGitHub {
50 owner = "natekspencer";
53 sha256 = "142lhijm51v11cd0lhcfdnjdd143jxi2hjsrqdq0rrbbnmj6mymp";
55 # had no tests before 2021.3.0
60 # Pinned due to bug in ring-doorbell 0.7.0
61 # https://github.com/tchellomello/python-ring-doorbell/issues/240
62 (mkOverride "ring-doorbell" "0.6.2"
63 "fbd537722a27b3b854c26506d894b7399bb8dc57ff36083285971227a2d46560")
65 # hass-frontend does not exist in python3.pkgs
67 hass-frontend = self.callPackage ./frontend.nix { };
71 mkOverride = attrname: version: sha256:
73 ${attrname} = super.${attrname}.overridePythonAttrs (oldAttrs: {
75 src = oldAttrs.src.override {
76 inherit version sha256;
81 py = python3.override {
82 # Put packageOverrides at the start so they are applied after defaultOverrides
83 packageOverrides = lib.foldr lib.composeExtensions (self: super: { }) ([ packageOverrides ] ++ defaultOverrides);
86 componentPackages = import ./component-packages.nix;
88 availableComponents = builtins.attrNames componentPackages.components;
90 getPackages = component: builtins.getAttr component componentPackages.components;
92 componentBuildInputs = lib.concatMap (component: getPackages component py.pkgs) extraComponents;
94 # Ensure that we are using a consistent package set
95 extraBuildInputs = extraPackages py.pkgs;
97 # Don't forget to run parse-requirements.py after updating
98 hassVersion = "2021.4.3";
100 in with py.pkgs; buildPythonApplication rec {
101 pname = "homeassistant";
102 version = assert (componentPackages.version == hassVersion); hassVersion;
104 # check REQUIRED_PYTHON_VER in homeassistant/const.py
105 disabled = pythonOlder "3.8";
107 # don't try and fail to strip 6600+ python files, it takes minutes!
110 inherit availableComponents;
112 # PyPI tarball is missing tests/ directory
113 src = fetchFromGitHub {
114 owner = "home-assistant";
117 sha256 = "00jgnk8vssvk7mdnlijwddwaj56hs1hcyw83r1jqhn5nk5qj3b7q";
120 # leave this in, so users don't have to constantly update their downstream patch handling
125 substituteInPlace setup.py \
126 --replace "awesomeversion==21.2.3" "awesomeversion" \
127 --replace "bcrypt==3.1.7" "bcrypt" \
128 --replace "cryptography==3.3.2" "cryptography" \
129 --replace "pip>=8.0.3,<20.3" "pip" \
130 --replace "pytz>=2021.1" "pytz" \
131 --replace "pyyaml==5.4.1" "pyyaml" \
132 --replace "ruamel.yaml==0.15.100" "ruamel.yaml"
133 substituteInPlace tests/test_config.py --replace '"/usr"' '"/build/media"'
136 propagatedBuildInputs = [
137 # Only packages required in setup.py + hass-frontend
160 ] ++ componentBuildInputs ++ extraBuildInputs;
162 makeWrapperArgs = lib.optional skipPip "--add-flags --skip-pip";
164 # upstream only tests on Linux, so do we.
165 doCheck = stdenv.isLinux;
168 # test infrastructure
175 # component dependencies
178 ] ++ lib.concatMap (component: getPackages component py.pkgs) componentTests;
180 # We can reasonably test components that don't communicate with any network
181 # services. Before adding new components to this list make sure we have all
182 # its dependencies packaged and listed in ./component-packages.nix.
212 "device_sun_light_trigger"
214 "devolo_home_control"
230 "fritzbox_callmonitor"
296 "persistent_notification"
307 "rituals_perfume_genie"
364 # limit amout of runners to reduce race conditions
366 # retry racy tests that end in "RuntimeError: Event loop is closed"
368 "--only-rerun RuntimeError"
369 # assign tests grouped by file to workers
371 # tests are located in tests/
373 # screenlogic/test_config_flow.py: Tries to send out UDP broadcasts
374 "--deselect tests/components/screenlogic/test_config_flow.py::test_form_cannot_connect"
375 # dynamically add packages required for component tests
376 ] ++ map (component: "tests/components/" + component) componentTests;
378 disabledTestPaths = [
379 # don't bulk test all components
381 # pyotp since v2.4.0 complains about the short mock keys, hass pins v2.3.0
382 "tests/auth/mfa_modules/test_notify.py"
386 # AssertionError: assert 1 == 0
387 "test_error_posted_as_event"
389 # ModuleNotFoundError: No module named 'pyqwikswitch'
390 "test_merge_id_schema"
391 # keyring.errors.NoKeyringError: No recommended backend was available.
392 "test_secrets_from_unrelated_fails"
393 "test_secrets_credstash"
394 # generic/test_camera.py: AssertionError: 500 == 200
395 "test_fetching_without_verify_ssl"
396 "test_fetching_url_with_verify_ssl"
397 # util/test_package.py: AssertionError on package.is_installed('homeassistant>=999.999.999')
398 "test_check_package_version_does_not_match"
402 export HOME="$TEMPDIR"
404 # the tests require the existance of a media dir
407 # error out when component test directory is missing, otherwise hidden by xdist execution :(
408 for component in ${lib.concatStringsSep " " (map lib.escapeShellArg componentTests)}; do
409 test -d "tests/components/$component" || {
410 >2& echo "ERROR: Tests for component '$component' were enabled, but they do not exist!"
417 inherit (py.pkgs) hass-frontend;
419 inherit (nixosTests) home-assistant;
424 homepage = "https://home-assistant.io/";
425 description = "Open source home automation that puts local control and privacy first";
426 license = licenses.asl20;
427 maintainers = teams.home-assistant.members;
428 platforms = platforms.linux;