Improve external components error messages (#2026)

This commit is contained in:
Otto Winter 2021-07-16 10:23:08 +02:00 committed by Jesse Hills
parent 7787fa8f29
commit f1e3ff2ed2
No known key found for this signature in database
GPG key ID: BEAAE804EFD8E83A

View file

@ -109,7 +109,15 @@ def _compute_destination_path(key: str) -> Path:
return base_dir / h.hexdigest()[:8] return base_dir / h.hexdigest()[:8]
def _handle_git_response(ret): def _run_git_command(cmd):
try:
ret = subprocess.run(cmd, capture_output=True, check=False)
except FileNotFoundError as err:
raise cv.Invalid(
"git is not installed but required for external_components.\n"
"Please see https://git-scm.com/book/en/v2/Getting-Started-Installing-Git for installing git"
) from err
if ret.returncode != 0 and ret.stderr: if ret.returncode != 0 and ret.stderr:
err_str = ret.stderr.decode("utf-8") err_str = ret.stderr.decode("utf-8")
lines = [x.strip() for x in err_str.splitlines()] lines = [x.strip() for x in err_str.splitlines()]
@ -118,18 +126,17 @@ def _handle_git_response(ret):
raise cv.Invalid(err_str) raise cv.Invalid(err_str)
def _process_single_config(config: dict): def _process_git_config(config: dict, refresh) -> str:
conf = config[CONF_SOURCE] key = f"{config[CONF_URL]}@{config.get(CONF_REF)}"
if conf[CONF_TYPE] == TYPE_GIT:
key = f"{conf[CONF_URL]}@{conf.get(CONF_REF)}"
repo_dir = _compute_destination_path(key) repo_dir = _compute_destination_path(key)
if not repo_dir.is_dir(): if not repo_dir.is_dir():
_LOGGER.info("Cloning %s", key)
_LOGGER.debug("Location: %s", repo_dir)
cmd = ["git", "clone", "--depth=1"] cmd = ["git", "clone", "--depth=1"]
if CONF_REF in conf: if CONF_REF in config:
cmd += ["--branch", conf[CONF_REF]] cmd += ["--branch", config[CONF_REF]]
cmd += [conf[CONF_URL], str(repo_dir)] cmd += ["--", config[CONF_URL], str(repo_dir)]
ret = subprocess.run(cmd, capture_output=True, check=False) _run_git_command(cmd)
_handle_git_response(ret)
else: else:
# Check refresh needed # Check refresh needed
@ -140,13 +147,18 @@ def _process_single_config(config: dict):
age = datetime.datetime.now() - datetime.datetime.fromtimestamp( age = datetime.datetime.now() - datetime.datetime.fromtimestamp(
file_timestamp.stat().st_mtime file_timestamp.stat().st_mtime
) )
if age.seconds > config[CONF_REFRESH].total_seconds: if age.seconds > refresh.total_seconds:
_LOGGER.info("Executing git pull %s", key) _LOGGER.info("Updating %s", key)
cmd = ["git", "pull"] _LOGGER.debug("Location: %s", repo_dir)
ret = subprocess.run( # Stash local changes (if any)
cmd, cwd=repo_dir, capture_output=True, check=False _run_git_command(["git", "stash", "push", "--include-untracked"])
) # Fetch remote ref
_handle_git_response(ret) cmd = ["git", "fetch", "--", "origin"]
if CONF_REF in config:
cmd.append(config[CONF_REF])
_run_git_command(cmd)
# Hard reset to FETCH_HEAD (short-lived git ref corresponding to most recent fetch)
_run_git_command(["git", "reset", "--hard", "FETCH_HEAD"])
if (repo_dir / "esphome" / "components").is_dir(): if (repo_dir / "esphome" / "components").is_dir():
components_dir = repo_dir / "esphome" / "components" components_dir = repo_dir / "esphome" / "components"
@ -154,10 +166,19 @@ def _process_single_config(config: dict):
components_dir = repo_dir / "components" components_dir = repo_dir / "components"
else: else:
raise cv.Invalid( raise cv.Invalid(
"Could not find components folder for source. Please check the source contains a 'components' or 'esphome/components' folder", "Could not find components folder for source. Please check the source contains a 'components' or 'esphome/components' folder"
[CONF_SOURCE],
) )
return components_dir
def _process_single_config(config: dict):
conf = config[CONF_SOURCE]
if conf[CONF_TYPE] == TYPE_GIT:
with cv.prepend_path([CONF_SOURCE]):
components_dir = _process_git_config(
config[CONF_SOURCE], config[CONF_REFRESH]
)
elif conf[CONF_TYPE] == TYPE_LOCAL: elif conf[CONF_TYPE] == TYPE_LOCAL:
components_dir = Path(CORE.relative_config_path(conf[CONF_PATH])) components_dir = Path(CORE.relative_config_path(conf[CONF_PATH]))
else: else: