From 92967501319358ce98a1cedec1b138d46de152bf Mon Sep 17 00:00:00 2001 From: MDW Date: Fri, 3 Mar 2023 12:31:54 +0100 Subject: [PATCH 01/11] Add pre-commit configuration, hacs check --- .github/workflows/validate-hacs.yml | 24 +++++ .pre-commit-config.yaml | 135 ++++++++++++++++++++++++++++ pyproject.toml | 82 +++++++++++++++++ 3 files changed, 241 insertions(+) create mode 100644 .github/workflows/validate-hacs.yml create mode 100644 .pre-commit-config.yaml create mode 100644 pyproject.toml diff --git a/.github/workflows/validate-hacs.yml b/.github/workflows/validate-hacs.yml new file mode 100644 index 0000000..a7540c1 --- /dev/null +++ b/.github/workflows/validate-hacs.yml @@ -0,0 +1,24 @@ +--- +name: Validate with hassfest + +on: + push: + pull_request: + schedule: + - cron: 0 0 * * * + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: home-assistant/actions/hassfest@master + hacs: + name: HACS Action + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: HACS Action + uses: hacs/action@main + with: + category: integration diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..b34febb --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,135 @@ +--- +files: ^(.*\.(py|json|md|sh|yaml|cfg|txt))$ +exclude: ^(\.[^/]*cache/.*|.*/_user.py)$ +repos: + - repo: https://github.com/verhovsky/pyupgrade-docs + rev: v0.3.0 + hooks: + - id: pyupgrade-docs + - repo: https://github.com/executablebooks/mdformat + # Do this before other tools "fixing" the line endings + rev: 0.7.16 + hooks: + - id: mdformat + name: Format Markdown + entry: mdformat # Executable to run, with fixed options + language: python + types: [markdown] + args: [--wrap, '75', --number] + additional_dependencies: + - mdformat-toc + - mdformat-beautysh + # -mdformat-shfmt + # -mdformat-tables + - mdformat-config + - mdformat-black + - mdformat-web + - mdformat-gfm + - repo: https://github.com/asottile/blacken-docs + rev: 1.13.0 + hooks: + - id: blacken-docs + additional_dependencies: [black==22.6.0] + stages: [manual] # Manual because already done by mdformat-black + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: no-commit-to-branch + args: [--branch, main] + - id: check-yaml + args: [--unsafe] + - id: debug-statements + - id: end-of-file-fixer + - id: trailing-whitespace + - id: check-json + - id: mixed-line-ending + - id: check-builtin-literals + - id: check-ast + - id: check-merge-conflict + - id: check-executables-have-shebangs + - id: check-shebang-scripts-are-executable + - id: check-docstring-first + - id: fix-byte-order-marker + - id: check-case-conflict + # - id: check-toml + - repo: https://github.com/adrienverge/yamllint.git + rev: v1.29.0 + hooks: + - id: yamllint + args: + - --no-warnings + - -d + - '{extends: relaxed, rules: {line-length: {max: 90}}}' + - repo: https://github.com/lovesegfault/beautysh.git + rev: v6.2.1 + hooks: + - id: beautysh + - repo: https://github.com/asottile/pyupgrade + rev: v3.3.1 + hooks: + - id: pyupgrade + args: + - --py310-plus + - repo: https://github.com/psf/black + rev: 22.12.0 + hooks: + - id: black + args: + - --safe + - --quiet + - -l 79 + - repo: https://github.com/Lucas-C/pre-commit-hooks-bandit + rev: v1.0.6 + hooks: + - id: python-bandit-vulnerability-check + - repo: https://github.com/fsouza/autoflake8 + rev: v0.4.0 + hooks: + - id: autoflake8 + args: + - -i + - -r + - --expand-star-imports + - custom_components + - repo: https://github.com/PyCQA/flake8 + rev: 6.0.0 + hooks: + - id: flake8 + additional_dependencies: + # - pyproject-flake8>=0.0.1a5 + - flake8-bugbear>=22.7.1 + - flake8-comprehensions>=3.10.1 + - flake8-2020>=1.7.0 + - mccabe>=0.7.0 + - pycodestyle>=2.9.1 + - pyflakes>=2.5.0 + - repo: https://github.com/PyCQA/isort + rev: 5.12.0 + hooks: + - id: isort + - repo: https://github.com/codespell-project/codespell + rev: v2.2.2 + hooks: + - id: codespell + args: [--toml, pyproject.toml] + additional_dependencies: + - tomli + - repo: https://github.com/pre-commit/mirrors-pylint + rev: v3.0.0a5 + hooks: + - id: pylint + additional_dependencies: + - voluptuous + - homeassistant-stubs==2023.3.1 + #- sqlalchemy + #- pyyaml + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v0.991 + hooks: + - id: mypy + additional_dependencies: + - voluptuous + - pydantic + - homeassistant-stubs==2023.3.1 + #- sqlalchemy + #- pyyaml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..4e81a90 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,82 @@ +[build-system] +requires = ["setuptools>=61.2"] +build-backend = "setuptools.build_meta" + +[project] +dynamic = ["version"] + +[tool.codespell] +ignore-words-list = """ +master, +slave, +hass""" +skip = """ +./.*,./assets/*,./data/*,*.svg,*.css,*.json,*.js +""" +quiet-level=2 +ignore-regex = '\\[fnrstv]' +builtin = "clear,rare,informal,usage,code,names" + +# --------- Pylint ------------- +[tool.pylint.'TYPECHECK'] +generated-members = "sh" + +[tool.pylint.'MESSAGES CONTROL'] +extension-pkg-whitelist = "pydantic" +disable = [ + "broad-except", + "invalid-name", + "line-too-long", + "missing-function-docstring", + "missing-module-docstring", + "too-few-public-methods", + "too-many-arguments", + "too-many-branches", + "too-many-instance-attributes", + "too-many-statements", + "unused-import", + "wrong-import-order", +] + +[tool.pylint.FORMAT] +expected-line-ending-format = "LF" + + + +# --------- Mypy ------------- + +[tool.mypy] +show_error_codes = true +follow_imports = "silent" +ignore_missing_imports = false +strict_optional = true +warn_redundant_casts = true +warn_unused_ignores = true +disallow_any_generics = true +check_untyped_defs = true +no_implicit_reexport = true +warn_unused_configs = true +disallow_subclassing_any = true +disallow_incomplete_defs = true +disallow_untyped_decorators = true +disallow_untyped_calls = true +disallow_untyped_defs = true +plugins = [ + "pydantic.mypy" +] + +[tool.pydantic-mypy] +init_forbid_extra = true +init_typed = true +warn_required_dynamic_aliases = true +warn_untyped_fields = true + +[[tool.mypy.overrides]] +module = "tests.*" +# Required to not have error: Untyped decorator makes function on fixtures and +# parametrize decorators +disallow_untyped_decorators = false + +[[tool.mypy.overrides]] +#module = [ ] +ignore_missing_imports = true From 167c816ea72b04f231d900e20efe1d2ba0ffca06 Mon Sep 17 00:00:00 2001 From: MDW Date: Fri, 3 Mar 2023 12:54:03 +0100 Subject: [PATCH 02/11] Add ci.yml --- .github/workflows/ci.yml | 133 +++++++++++++++++++++++++++++++++++++++ .pre-commit-config.yaml | 6 +- 2 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4e17db3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,133 @@ +name: CI + +# yamllint disable-line rule:truthy +on: + push: + pull_request: ~ + +env: + CACHE_VERSION: 1 + PYTHON_VERSION_DEFAULT: '3.10.8' + PRE_COMMIT_HOME: ~/.cache/pre-commit + +jobs: + # Separate job to pre-populate the base dependency cache + # This prevent upcoming jobs to do the same individually + prepare-base: + name: Prepare base dependencies + runs-on: ubuntu-latest + strategy: + matrix: + #python-version: ['3.8.14', '3.9.15', '3.10.8', '3.11.0'] + python-version: ['3.10.8', '3.11.0'] + steps: + - name: Check out code from GitHub + uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + id: python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Restore base Python virtual environment + id: cache-venv + uses: actions/cache@v3 + with: + path: venv + key: >- + ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ + steps.python.outputs.python-version }}-${{ + hashFiles('setup.py', 'requirements_test.txt') }} + restore-keys: | + ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}- + - name: Create Python virtual environment + if: steps.cache-venv.outputs.cache-hit != 'true' + run: | + python -m venv venv + . venv/bin/activate + pip install -U pip setuptools pre-commit + pip install -r requirements_test.txt + pip install -e . + + pre-commit: + name: Prepare pre-commit environment + runs-on: ubuntu-latest + needs: prepare-base + steps: + - name: Check out code from GitHub + uses: actions/checkout@v3 + - name: Set up Python ${{ env.PYTHON_VERSION_DEFAULT }} + uses: actions/setup-python@v4 + id: python + with: + python-version: ${{ env.PYTHON_VERSION_DEFAULT }} + - name: Restore base Python virtual environment + id: cache-venv + uses: actions/cache@v3 + with: + path: venv + key: >- + ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ + steps.python.outputs.python-version }}-${{ + hashFiles('setup.py', 'requirements_test.txt') }} + - name: Fail job if Python cache restore failed + if: steps.cache-venv.outputs.cache-hit != 'true' + run: | + echo "Failed to restore Python virtual environment from cache" + exit 1 + - name: Restore pre-commit environment from cache + id: cache-precommit + uses: actions/cache@v3 + with: + path: ${{ env.PRE_COMMIT_HOME }} + key: | + ${{ env.CACHE_VERSION}}-${{ runner.os }}-pre-commit-${{ hashFiles('.pre-commit-config.yaml') }} + restore-keys: | + ${{ env.CACHE_VERSION}}-${{ runner.os }}-pre-commit- + - name: Install pre-commit dependencies + if: steps.cache-precommit.outputs.cache-hit != 'true' + run: | + . venv/bin/activate + pre-commit install-hooks + + pre-commit: + name: Run all of pre-commit + runs-on: ubuntu-latest + needs: pre-commit + steps: + - name: Check out code from GitHub + uses: actions/checkout@v3 + - name: Set up Python ${{ env.PYTHON_VERSION_DEFAULT }} + uses: actions/setup-python@v4 + id: python + with: + python-version: ${{ env.PYTHON_VERSION_DEFAULT }} + - name: Restore base Python virtual environment + id: cache-venv + uses: actions/cache@v3 + with: + path: venv + key: >- + ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ + steps.python.outputs.python-version }}-${{ + hashFiles('setup.py', 'requirements_test.txt') }} + - name: Fail job if Python cache restore failed + if: steps.cache-venv.outputs.cache-hit != 'true' + run: | + echo "Failed to restore Python virtual environment from cache" + exit 1 + - name: Restore pre-commit environment from cache + id: cache-precommit + uses: actions/cache@v3 + with: + path: ${{ env.PRE_COMMIT_HOME }} + key: | + ${{ env.CACHE_VERSION}}-${{ runner.os }}-pre-commit-${{ hashFiles('.pre-commit-config.yaml') }} + - name: Fail job if cache restore failed + if: steps.cache-venv.outputs.cache-hit != 'true' + run: | + echo "Failed to restore Python virtual environment from cache" + exit 1 + - name: Run pre-commit + run: | + . venv/bin/activate + pre-commit run -a --show-diff-on-failure diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b34febb..f34537c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -119,7 +119,7 @@ repos: hooks: - id: pylint additional_dependencies: - - voluptuous + #- voluptuous==0.13.1 - homeassistant-stubs==2023.3.1 #- sqlalchemy #- pyyaml @@ -128,8 +128,8 @@ repos: hooks: - id: mypy additional_dependencies: - - voluptuous - - pydantic + #- voluptuous==0.13.1 + - pydantic>=1.10.5 - homeassistant-stubs==2023.3.1 #- sqlalchemy #- pyyaml From e190e09492e4e20a5c738f64046219fe4c7335dc Mon Sep 17 00:00:00 2001 From: MDW Date: Fri, 3 Mar 2023 13:01:34 +0100 Subject: [PATCH 03/11] Manual trigger --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e17db3..7302702 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,7 @@ name: CI on: push: pull_request: ~ + workflow_dispatch: env: CACHE_VERSION: 1 From c015ca967a70feeead9a3c6f7be5484b80b7a211 Mon Sep 17 00:00:00 2001 From: MDW Date: Fri, 3 Mar 2023 13:04:16 +0100 Subject: [PATCH 04/11] Fix ci.yml - duplicate key --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7302702..6a8b9a4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -90,7 +90,7 @@ jobs: . venv/bin/activate pre-commit install-hooks - pre-commit: + pre-commit-run: name: Run all of pre-commit runs-on: ubuntu-latest needs: pre-commit From b3a50f37600b3c449f81a20b5a7e39dfd52be1dc Mon Sep 17 00:00:00 2001 From: MDW Date: Fri, 3 Mar 2023 13:05:39 +0100 Subject: [PATCH 05/11] Add missing requirements_test.txt --- requirements_test.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 requirements_test.txt diff --git a/requirements_test.txt b/requirements_test.txt new file mode 100644 index 0000000..e69de29 From bd445a8b47e3bd3489a30ccba6f8ac517e100488 Mon Sep 17 00:00:00 2001 From: MDW Date: Fri, 3 Mar 2023 13:09:36 +0100 Subject: [PATCH 06/11] Disable automatic run of ci.yml --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6a8b9a4..636a22e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,8 +2,8 @@ name: CI # yamllint disable-line rule:truthy on: - push: - pull_request: ~ + #push: + #pull_request: ~ workflow_dispatch: env: From 2269a52a9d5b578f65a06b7520d4b23fc7068b3e Mon Sep 17 00:00:00 2001 From: MDW Date: Fri, 3 Mar 2023 15:31:39 +0100 Subject: [PATCH 07/11] Update pyproject for ci.yml --- pyproject.toml | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4e81a90..7efa09d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,9 +1,29 @@ -[build-system] -requires = ["setuptools>=61.2"] -build-backend = "setuptools.build_meta" - [project] +# PEP 621 project metadata +# See https://www.python.org/dev/peps/pep-0621/ dynamic = ["version"] +#authors = [ {name = "TBD", email = "TBD"}, ] +#license = {text = "TBD"} +requires-python = ">=3.9.0" +dependencies = [ +] +name = "ha_programmable_thermostat" +description = "TBD" +readme = "README.md" +classifiers=[ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + #"License :: OSI Approved :: TBD", + "Operating System :: Unix", + "Operating System :: POSIX", + "Programming Language :: Python", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Utilities", + "Natural Language :: English", +] + [tool.codespell] ignore-words-list = """ From 0d0b56beb4e1b282364ea7f0c0d5643e11248099 Mon Sep 17 00:00:00 2001 From: MDW Date: Fri, 3 Mar 2023 15:50:40 +0100 Subject: [PATCH 08/11] Remove optton to show all diffs --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 636a22e..16170ff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -131,4 +131,4 @@ jobs: - name: Run pre-commit run: | . venv/bin/activate - pre-commit run -a --show-diff-on-failure + pre-commit run -a From b59444d15c5eefd03b0024ebcb65136a68e7020b Mon Sep 17 00:00:00 2001 From: Michal Kochel Date: Fri, 25 Aug 2023 12:16:38 +0200 Subject: [PATCH 09/11] Fixed reload issue Fixes https://github.com/custom-components/climate.programmable_thermostat/issues/44. The `async_setup_reload_service()` function expects a list as the third argument, not a string. The definition: https://github.com/home-assistant/core/blob/2023.8.4/homeassistant/helpers/reload.py#L167 --- custom_components/programmable_thermostat/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/programmable_thermostat/const.py b/custom_components/programmable_thermostat/const.py index d83e807..93c7abf 100644 --- a/custom_components/programmable_thermostat/const.py +++ b/custom_components/programmable_thermostat/const.py @@ -8,7 +8,7 @@ #Generic VERSION = '8.2' DOMAIN = 'programmable_thermostat' -PLATFORM = 'climate' +PLATFORM = ['climate'] ISSUE_URL = 'https://github.com/custom-components/climate.programmable_thermostat/issues' CONFIGFLOW_VERSION = 4 From 86f8a426533ff53773eedf454ddbfb8173d8d572 Mon Sep 17 00:00:00 2001 From: Michal Kochel Date: Fri, 25 Aug 2023 12:24:41 +0200 Subject: [PATCH 10/11] Reverted const.py. --- custom_components/programmable_thermostat/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/programmable_thermostat/const.py b/custom_components/programmable_thermostat/const.py index 93c7abf..d83e807 100644 --- a/custom_components/programmable_thermostat/const.py +++ b/custom_components/programmable_thermostat/const.py @@ -8,7 +8,7 @@ #Generic VERSION = '8.2' DOMAIN = 'programmable_thermostat' -PLATFORM = ['climate'] +PLATFORM = 'climate' ISSUE_URL = 'https://github.com/custom-components/climate.programmable_thermostat/issues' CONFIGFLOW_VERSION = 4 From 3401edbeb480fa40fd2118621b34732ba0e3289a Mon Sep 17 00:00:00 2001 From: Michal Kochel Date: Fri, 25 Aug 2023 12:25:13 +0200 Subject: [PATCH 11/11] Update climate.py --- custom_components/programmable_thermostat/climate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/programmable_thermostat/climate.py b/custom_components/programmable_thermostat/climate.py index 77b7604..35c809d 100755 --- a/custom_components/programmable_thermostat/climate.py +++ b/custom_components/programmable_thermostat/climate.py @@ -73,7 +73,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Add ProgrammableThermostat entities from configuration.yaml.""" _LOGGER.info("Setup entity coming from configuration.yaml named: %s", config.get(CONF_NAME)) - await async_setup_reload_service(hass, DOMAIN, PLATFORM) + await async_setup_reload_service(hass, DOMAIN, [PLATFORM]) async_add_entities([ProgrammableThermostat(hass, config)]) async def async_setup_entry(hass, config_entry, async_add_devices): @@ -84,7 +84,7 @@ async def async_setup_entry(hass, config_entry, async_add_devices): else: result = config_entry.data _LOGGER.info("setup entity-config_entry_data=%s",result) - await async_setup_reload_service(hass, DOMAIN, PLATFORM) + await async_setup_reload_service(hass, DOMAIN, [PLATFORM]) async_add_devices([ProgrammableThermostat(hass, result)])