mirror of
https://github.com/esphome/esphome.git
synced 2025-03-15 15:18:16 +00:00
Merge branch 'dev' into bh1745
This commit is contained in:
commit
2b76391dd4
@ -31,7 +31,7 @@
|
|||||||
"ms-python.python",
|
"ms-python.python",
|
||||||
"ms-python.pylint",
|
"ms-python.pylint",
|
||||||
"ms-python.flake8",
|
"ms-python.flake8",
|
||||||
"ms-python.black-formatter",
|
"charliermarsh.ruff",
|
||||||
"visualstudioexptteam.vscodeintellicode",
|
"visualstudioexptteam.vscodeintellicode",
|
||||||
// yaml
|
// yaml
|
||||||
"redhat.vscode-yaml",
|
"redhat.vscode-yaml",
|
||||||
@ -49,14 +49,11 @@
|
|||||||
"flake8.args": [
|
"flake8.args": [
|
||||||
"--config=${workspaceFolder}/.flake8"
|
"--config=${workspaceFolder}/.flake8"
|
||||||
],
|
],
|
||||||
"black-formatter.args": [
|
"ruff.configuration": "${workspaceFolder}/pyproject.toml",
|
||||||
"--config",
|
|
||||||
"${workspaceFolder}/pyproject.toml"
|
|
||||||
],
|
|
||||||
"[python]": {
|
"[python]": {
|
||||||
// VS will say "Value is not accepted" before building the devcontainer, but the warning
|
// VS will say "Value is not accepted" before building the devcontainer, but the warning
|
||||||
// should go away after build is completed.
|
// should go away after build is completed.
|
||||||
"editor.defaultFormatter": "ms-python.black-formatter"
|
"editor.defaultFormatter": "charliermarsh.ruff"
|
||||||
},
|
},
|
||||||
"editor.formatOnPaste": false,
|
"editor.formatOnPaste": false,
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
|
4
.github/actions/build-image/action.yaml
vendored
4
.github/actions/build-image/action.yaml
vendored
@ -46,7 +46,7 @@ runs:
|
|||||||
|
|
||||||
- name: Build and push to ghcr by digest
|
- name: Build and push to ghcr by digest
|
||||||
id: build-ghcr
|
id: build-ghcr
|
||||||
uses: docker/build-push-action@v6.13.0
|
uses: docker/build-push-action@v6.14.0
|
||||||
env:
|
env:
|
||||||
DOCKER_BUILD_SUMMARY: false
|
DOCKER_BUILD_SUMMARY: false
|
||||||
DOCKER_BUILD_RECORD_UPLOAD: false
|
DOCKER_BUILD_RECORD_UPLOAD: false
|
||||||
@ -72,7 +72,7 @@ runs:
|
|||||||
|
|
||||||
- name: Build and push to dockerhub by digest
|
- name: Build and push to dockerhub by digest
|
||||||
id: build-dockerhub
|
id: build-dockerhub
|
||||||
uses: docker/build-push-action@v6.13.0
|
uses: docker/build-push-action@v6.14.0
|
||||||
env:
|
env:
|
||||||
DOCKER_BUILD_SUMMARY: false
|
DOCKER_BUILD_SUMMARY: false
|
||||||
DOCKER_BUILD_RECORD_UPLOAD: false
|
DOCKER_BUILD_RECORD_UPLOAD: false
|
||||||
|
4
.github/workflows/matchers/lint-python.json
vendored
4
.github/workflows/matchers/lint-python.json
vendored
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"problemMatcher": [
|
"problemMatcher": [
|
||||||
{
|
{
|
||||||
"owner": "black",
|
"owner": "ruff",
|
||||||
"severity": "error",
|
"severity": "error",
|
||||||
"pattern": [
|
"pattern": [
|
||||||
{
|
{
|
||||||
"regexp": "^(.*): (Please format this file with the black formatter)",
|
"regexp": "^(.*): (Please format this file with the ruff formatter)",
|
||||||
"file": 1,
|
"file": 1,
|
||||||
"message": 2
|
"message": 2
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@
|
|||||||
#define USE_OTA
|
#define USE_OTA
|
||||||
#define USE_OTA_PASSWORD
|
#define USE_OTA_PASSWORD
|
||||||
#define USE_OTA_STATE_CALLBACK
|
#define USE_OTA_STATE_CALLBACK
|
||||||
#define USE_OTA_VERSION 1
|
#define USE_OTA_VERSION 2
|
||||||
#define USE_OUTPUT
|
#define USE_OUTPUT
|
||||||
#define USE_POWER_SUPPLY
|
#define USE_POWER_SUPPLY
|
||||||
#define USE_QR_CODE
|
#define USE_QR_CODE
|
||||||
|
@ -33,6 +33,7 @@ import tornado.process
|
|||||||
import tornado.queues
|
import tornado.queues
|
||||||
import tornado.web
|
import tornado.web
|
||||||
import tornado.websocket
|
import tornado.websocket
|
||||||
|
import voluptuous as vol
|
||||||
import yaml
|
import yaml
|
||||||
from yaml.nodes import Node
|
from yaml.nodes import Node
|
||||||
|
|
||||||
@ -52,7 +53,6 @@ from .util.text import friendly_name_slugify
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from requests import Response
|
from requests import Response
|
||||||
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
ENV_DEV = "ESPHOME_DASHBOARD_DEV"
|
ENV_DEV = "ESPHOME_DASHBOARD_DEV"
|
||||||
@ -592,16 +592,39 @@ class IgnoreDeviceRequestHandler(BaseHandler):
|
|||||||
class DownloadListRequestHandler(BaseHandler):
|
class DownloadListRequestHandler(BaseHandler):
|
||||||
@authenticated
|
@authenticated
|
||||||
@bind_config
|
@bind_config
|
||||||
def get(self, configuration: str | None = None) -> None:
|
async def get(self, configuration: str | None = None) -> None:
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
try:
|
||||||
|
downloads_json = await loop.run_in_executor(None, self._get, configuration)
|
||||||
|
except vol.Invalid:
|
||||||
|
self.send_error(404)
|
||||||
|
return
|
||||||
|
if downloads_json is None:
|
||||||
|
self.send_error(404)
|
||||||
|
return
|
||||||
|
self.set_status(200)
|
||||||
|
self.set_header("content-type", "application/json")
|
||||||
|
self.write(downloads_json)
|
||||||
|
self.finish()
|
||||||
|
|
||||||
|
def _get(self, configuration: str | None = None) -> dict[str, Any] | None:
|
||||||
storage_path = ext_storage_path(configuration)
|
storage_path = ext_storage_path(configuration)
|
||||||
storage_json = StorageJSON.load(storage_path)
|
storage_json = StorageJSON.load(storage_path)
|
||||||
if storage_json is None:
|
if storage_json is None:
|
||||||
self.send_error(404)
|
return None
|
||||||
return
|
|
||||||
|
config = yaml_util.load_yaml(settings.rel_path(configuration))
|
||||||
|
|
||||||
|
if const.CONF_EXTERNAL_COMPONENTS in config:
|
||||||
|
from esphome.components.external_components import (
|
||||||
|
do_external_components_pass,
|
||||||
|
)
|
||||||
|
|
||||||
|
do_external_components_pass(config)
|
||||||
|
|
||||||
from esphome.components.esp32 import VARIANTS as ESP32_VARIANTS
|
from esphome.components.esp32 import VARIANTS as ESP32_VARIANTS
|
||||||
|
|
||||||
downloads = []
|
downloads: list[dict[str, Any]] = []
|
||||||
platform: str = storage_json.target_platform.lower()
|
platform: str = storage_json.target_platform.lower()
|
||||||
|
|
||||||
if platform.upper() in ESP32_VARIANTS:
|
if platform.upper() in ESP32_VARIANTS:
|
||||||
@ -615,12 +638,7 @@ class DownloadListRequestHandler(BaseHandler):
|
|||||||
except AttributeError as exc:
|
except AttributeError as exc:
|
||||||
raise ValueError(f"Unknown platform {platform}") from exc
|
raise ValueError(f"Unknown platform {platform}") from exc
|
||||||
downloads = get_download_types(storage_json)
|
downloads = get_download_types(storage_json)
|
||||||
|
return json.dumps(downloads)
|
||||||
self.set_status(200)
|
|
||||||
self.set_header("content-type", "application/json")
|
|
||||||
self.write(json.dumps(downloads))
|
|
||||||
self.finish()
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
class DownloadBinaryRequestHandler(BaseHandler):
|
class DownloadBinaryRequestHandler(BaseHandler):
|
||||||
|
@ -51,10 +51,6 @@ version = {attr = "esphome.const.__version__"}
|
|||||||
[tool.setuptools.packages.find]
|
[tool.setuptools.packages.find]
|
||||||
include = ["esphome*"]
|
include = ["esphome*"]
|
||||||
|
|
||||||
[tool.black]
|
|
||||||
target-version = ["py39", "py310"]
|
|
||||||
exclude = 'generated'
|
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
testpaths = [
|
testpaths = [
|
||||||
"tests",
|
"tests",
|
||||||
@ -108,6 +104,8 @@ expected-line-ending-format = "LF"
|
|||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
required-version = ">=0.5.0"
|
required-version = ">=0.5.0"
|
||||||
|
target-version = "py39"
|
||||||
|
exclude = ['generated']
|
||||||
|
|
||||||
[tool.ruff.lint]
|
[tool.ruff.lint]
|
||||||
select = [
|
select = [
|
||||||
|
@ -13,7 +13,7 @@ platformio==6.1.16 # When updating platformio, also update Dockerfile
|
|||||||
esptool==4.7.0
|
esptool==4.7.0
|
||||||
click==8.1.7
|
click==8.1.7
|
||||||
esphome-dashboard==20250212.0
|
esphome-dashboard==20250212.0
|
||||||
aioesphomeapi==29.1.0
|
aioesphomeapi==29.1.1
|
||||||
zeroconf==0.145.1
|
zeroconf==0.145.1
|
||||||
puremagic==1.27
|
puremagic==1.27
|
||||||
ruamel.yaml==0.18.6 # dashboard_import
|
ruamel.yaml==0.18.6 # dashboard_import
|
||||||
|
@ -19,7 +19,7 @@ curfile = None
|
|||||||
|
|
||||||
|
|
||||||
def print_error(file, lineno, msg):
|
def print_error(file, lineno, msg):
|
||||||
global curfile
|
global curfile # noqa: PLW0603
|
||||||
|
|
||||||
if curfile != file:
|
if curfile != file:
|
||||||
print_error_for_file(file, None)
|
print_error_for_file(file, None)
|
||||||
@ -31,6 +31,22 @@ def print_error(file, lineno, msg):
|
|||||||
print(f"{styled(colorama.Style.BRIGHT, f'{file}:')} {msg}")
|
print(f"{styled(colorama.Style.BRIGHT, f'{file}:')} {msg}")
|
||||||
|
|
||||||
|
|
||||||
|
def split_args_platform_compatible(args):
|
||||||
|
if os.name == "posix":
|
||||||
|
return [args]
|
||||||
|
|
||||||
|
char_length = 0
|
||||||
|
argsets = []
|
||||||
|
for index, arg in enumerate(args):
|
||||||
|
# Windows is techincally 8191, but we need to leave some room for the command itself
|
||||||
|
if char_length + len(arg) > 8000:
|
||||||
|
argsets.append(args[:index])
|
||||||
|
args = args[index:]
|
||||||
|
char_length = 0
|
||||||
|
char_length += len(arg)
|
||||||
|
return argsets
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
colorama.init()
|
colorama.init()
|
||||||
|
|
||||||
@ -69,61 +85,70 @@ def main():
|
|||||||
|
|
||||||
errors = 0
|
errors = 0
|
||||||
|
|
||||||
cmd = ["black", "--verbose"] + ([] if args.apply else ["--check"]) + files
|
# Needed to get around command-line string limits in Windows.
|
||||||
print("Running black...")
|
filesets = split_args_platform_compatible(files)
|
||||||
print()
|
|
||||||
log = get_err(*cmd)
|
print("Running ruff...")
|
||||||
for line in log.splitlines():
|
print()
|
||||||
WOULD_REFORMAT = "would reformat"
|
for fileset in filesets:
|
||||||
if line.startswith(WOULD_REFORMAT):
|
cmd = ["ruff", "format"] + ([] if args.apply else ["--check"]) + fileset
|
||||||
file_ = line[len(WOULD_REFORMAT) + 1 :]
|
log = get_err(*cmd)
|
||||||
print_error(file_, None, "Please format this file with the black formatter")
|
for line in log.splitlines():
|
||||||
errors += 1
|
WOULD_REFORMAT = "would reformat"
|
||||||
|
if line.startswith(WOULD_REFORMAT):
|
||||||
|
file_ = line[len(WOULD_REFORMAT) + 1 :]
|
||||||
|
print_error(
|
||||||
|
file_, None, "Please format this file with the ruff formatter"
|
||||||
|
)
|
||||||
|
errors += 1
|
||||||
|
|
||||||
cmd = ["flake8"] + files
|
|
||||||
print()
|
print()
|
||||||
print("Running flake8...")
|
print("Running flake8...")
|
||||||
print()
|
print()
|
||||||
log = get_output(*cmd)
|
for files in filesets:
|
||||||
for line in log.splitlines():
|
cmd = ["flake8"] + files
|
||||||
line = line.split(":", 4)
|
log = get_output(*cmd)
|
||||||
if len(line) < 4:
|
for line in log.splitlines():
|
||||||
continue
|
line = line.split(":", 4)
|
||||||
file_ = line[0]
|
if len(line) < 4:
|
||||||
linno = line[1]
|
continue
|
||||||
msg = (":".join(line[3:])).strip()
|
file_ = line[0]
|
||||||
print_error(file_, linno, msg)
|
linno = line[1]
|
||||||
errors += 1
|
msg = (":".join(line[3:])).strip()
|
||||||
|
print_error(file_, linno, msg)
|
||||||
|
errors += 1
|
||||||
|
|
||||||
cmd = ["pylint", "-f", "parseable", "--persistent=n"] + files
|
|
||||||
print()
|
print()
|
||||||
print("Running pylint...")
|
print("Running pylint...")
|
||||||
print()
|
print()
|
||||||
log = get_output(*cmd)
|
for files in filesets:
|
||||||
for line in log.splitlines():
|
cmd = ["pylint", "-f", "parseable", "--persistent=n"] + files
|
||||||
line = line.split(":", 3)
|
log = get_output(*cmd)
|
||||||
if len(line) < 3:
|
for line in log.splitlines():
|
||||||
continue
|
line = line.split(":", 3)
|
||||||
file_ = line[0]
|
if len(line) < 3:
|
||||||
linno = line[1]
|
continue
|
||||||
msg = (":".join(line[2:])).strip()
|
file_ = line[0]
|
||||||
print_error(file_, linno, msg)
|
linno = line[1]
|
||||||
errors += 1
|
msg = (":".join(line[2:])).strip()
|
||||||
|
print_error(file_, linno, msg)
|
||||||
|
errors += 1
|
||||||
|
|
||||||
PYUPGRADE_TARGET = "--py39-plus"
|
|
||||||
cmd = ["pyupgrade", PYUPGRADE_TARGET] + files
|
|
||||||
print()
|
print()
|
||||||
print("Running pyupgrade...")
|
print("Running pyupgrade...")
|
||||||
print()
|
print()
|
||||||
log = get_err(*cmd)
|
PYUPGRADE_TARGET = "--py39-plus"
|
||||||
for line in log.splitlines():
|
for files in filesets:
|
||||||
REWRITING = "Rewriting"
|
cmd = ["pyupgrade", PYUPGRADE_TARGET] + files
|
||||||
if line.startswith(REWRITING):
|
log = get_err(*cmd)
|
||||||
file_ = line[len(REWRITING) + 1 :]
|
for line in log.splitlines():
|
||||||
print_error(
|
REWRITING = "Rewriting"
|
||||||
file_, None, f"Please run pyupgrade {PYUPGRADE_TARGET} on this file"
|
if line.startswith(REWRITING):
|
||||||
)
|
file_ = line[len(REWRITING) + 1 :]
|
||||||
errors += 1
|
print_error(
|
||||||
|
file_, None, f"Please run pyupgrade {PYUPGRADE_TARGET} on this file"
|
||||||
|
)
|
||||||
|
errors += 1
|
||||||
|
|
||||||
sys.exit(errors)
|
sys.exit(errors)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user