diff --git a/embark/domain/tasks/task.py b/embark/domain/tasks/task.py index 7407307..2eb88c0 100644 --- a/embark/domain/tasks/task.py +++ b/embark/domain/tasks/task.py @@ -78,54 +78,70 @@ def __init__( self.requirements = requirements self.target = target self.context_factory = context_factory - self.logger: AbstractTaskLogger | None = None + self._playbook_context: AbstractPlaybookExecutionContext | None = None + self._task_context: TaskExecutionContext | None = None + self._logger: AbstractTaskLogger | None = None + + @property + def playbook_context(self) -> AbstractPlaybookExecutionContext: + if self._playbook_context is not None: + return self._playbook_context + raise ValueError("Playbook context is None", self) + + @property + def task_context(self) -> TaskExecutionContext: + if self._task_context is not None: + return self._task_context + raise ValueError("Task context is None", self) + + @property + def logger(self) -> AbstractTaskLogger: + if self._logger is not None: + return self._logger + raise ValueError("Logger is None", self) def get_display_name(self): return self.name def execute(self, context: AbstractPlaybookExecutionContext) -> bool: """Execute this task""" - task_context = self.context_factory.create_task_context(context, self) - self.logger = context.playbook.logger.create_child_task_logger(self) - should_execute = self.criteria.should_execute(task_context) + self._playbook_context = context + self._task_context = self.context_factory.create_task_context( + self.playbook_context, self + ) + self._logger = context.playbook.logger.create_child_task_logger(self) + should_execute = self.criteria.should_execute(self.task_context) if not should_execute: self.logger.task_skipped() return True self.logger.task_started() - should_proceed = self._check_requirements(context, task_context) + should_proceed = self._check_requirements() if not should_proceed: return False self.logger.info("Executing task") - should_proceed = self._check_requirements(context, task_context) + should_proceed = self._check_requirements() if not should_proceed: return False - is_successful, is_cancelled = self._try_to_execute_target( - context, - task_context, - ) + is_successful, is_cancelled = self._try_to_execute_target() if not is_successful: return False if is_cancelled: - raise TaskExecutionException(task_context, "Cancel") + raise TaskExecutionException(self.task_context, "Cancel") self.logger.task_ended(is_successful=True) return True - def _check_requirements( - self, - context: AbstractPlaybookExecutionContext, - task_context: TaskExecutionContext, - ) -> bool: + def _check_requirements(self) -> bool: """Check task requirements.""" try: for requirement in self.requirements: - requirement.ensure_requirement_met(task_context) + requirement.ensure_requirement_met(self.task_context) return True except RequirementCannotBeMetException as e: self.logger.task_ended( is_successful=False, error_message="Cannot execute task, because requirements cannot be met" ) - should_proceed = context.ask_should_proceed( + should_proceed = self.playbook_context.ask_should_proceed( "Task failed to execute. Proceed playbook?" ) if should_proceed: @@ -134,21 +150,17 @@ def _check_requirements( self.logger.error("Cannot proceed. Playbook cancelled") raise e - def _try_to_execute_target( - self, - context: AbstractPlaybookExecutionContext, - task_context: TaskExecutionContext, - ) -> tuple[bool, bool]: + def _try_to_execute_target(self) -> tuple[bool, bool]: """Try to execute target.""" cancel = False try: - success = self.target.execute(task_context) + success = self.target.execute(self.task_context) if not success: self.logger.task_ended( is_successful=False, error_message="Task was not executed successfully" ) - should_proceed = context.ask_should_proceed( + should_proceed = self.playbook_context.ask_should_proceed( "Proceed playbook?" ) if should_proceed: @@ -161,7 +173,7 @@ def _try_to_execute_target( is_successful=False, error_message="Unknown exception occurred: %s" % str(e) ) - should_proceed = context.ask_should_proceed( + should_proceed = self.playbook_context.ask_should_proceed( f"Task failed to execute:\n{str(e)}.\nProceed playbook?" ) if should_proceed: diff --git a/embark/impl/cli_loggers.py b/embark/impl/cli_loggers.py index 15c3499..137a3be 100644 --- a/embark/impl/cli_loggers.py +++ b/embark/impl/cli_loggers.py @@ -1,5 +1,5 @@ import logging -from abc import abstractmethod, ABC +from abc import abstractmethod from embark import log_config from embark.domain.execution.playbook import Playbook diff --git a/embark/resources.py b/embark/resources.py index f266c36..76579b9 100644 --- a/embark/resources.py +++ b/embark/resources.py @@ -6,7 +6,7 @@ def get_resource(relative_path): """Get absolute path to resource""" try: # PyInstaller creates a temp folder and stores path in _MEIPASS - base_path = sys._MEIPASS + base_path = sys._MEIPASS # type: ignore except Exception: base_path = os.path.abspath(".") diff --git a/embark/std/target/web_tasks.py b/embark/std/target/web_tasks.py index b96e60c..e14951e 100644 --- a/embark/std/target/web_tasks.py +++ b/embark/std/target/web_tasks.py @@ -1,6 +1,5 @@ """Provides targets and tools for web requests.""" -import sys import uuid import requests @@ -34,9 +33,10 @@ def execute(self, context: TaskExecutionContext) -> bool: total_length_str = response.headers.get('content-length') if total_length_str is None: f.write(response.content) + return True total_length = int(total_length_str) dl = 0 - prev_progress = -1 + prev_progress: float = -1 for data in response.iter_content(chunk_size=4096): dl += len(data) f.write(data) diff --git a/embark/ui/debug_frames/exec_frame.py b/embark/ui/debug_frames/exec_frame.py index 62e8c46..9c30853 100644 --- a/embark/ui/debug_frames/exec_frame.py +++ b/embark/ui/debug_frames/exec_frame.py @@ -1,6 +1,6 @@ """Eval debug UI frame""" -from customtkinter import CTk, CTkFont, CTkLabel, CTkEntry, CTkButton, CTkTextbox +from customtkinter import CTk, CTkFont, CTkButton, CTkTextbox from embark.domain.execution.playbook import Playbook from embark.localization.i18n import L diff --git a/embark/ui/logger_frame/components.py b/embark/ui/logger_frame/components.py index a83664b..0af5a1b 100644 --- a/embark/ui/logger_frame/components.py +++ b/embark/ui/logger_frame/components.py @@ -51,7 +51,7 @@ class Progress: class ProgressMixin: - def __init__(self): + def __init__(self) -> None: self._progresses: dict[str, Progress] = {} @property @@ -96,7 +96,7 @@ def finish_progress(self, uid: str): class GUILoggerFrame(CTkFrame, ProgressMixin, AbstractLoggerFrame): def __init__(self, root): - super().__init__(root) + super().__init__(root) # type: ignore ProgressMixin.__init__(self) self.playbook = None self._progresses: dict[str, Progress] = {} @@ -146,7 +146,7 @@ def default_inform(self, message, *args): class TaskLoggerFrame(CTkFrame, ProgressMixin, AbstractLoggerFrame): def __init__(self, root, task): - super().__init__(root) + super().__init__(root) # type: ignore ProgressMixin.__init__(self) self.task = task self._header_pane = CTkFrame(self) diff --git a/project_scripts.py b/project_scripts.py index fd1cf02..ea7050a 100644 --- a/project_scripts.py +++ b/project_scripts.py @@ -31,6 +31,16 @@ def check_imports(): exit(process.returncode) +def check_ruff(): + process = subprocess.run( + "ruff check", + stderr=sys.stderr, + stdout=sys.stdout + ) + if process.returncode != 0: + exit(process.returncode) + + def check_wps(): process = subprocess.run( "flake8 ./embark", @@ -49,6 +59,7 @@ def check_all(): def check_all_no_wps(): check_mypy() check_imports() + check_ruff() def clean_build(): diff --git a/pyproject.toml b/pyproject.toml index fff5908..1c21262 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "embark" -version = "0.4.1-beta" +version = "0.6-beta" description = "Embark playbook executor and development kit" authors = ["Tapeline"] license = "GNU GPL 3.0" @@ -32,3 +32,10 @@ check_imports = "project_scripts:check_imports" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" + +[[tool.mypy.overrides]] +module = ["customtkinter.*"] +ignore_missing_imports = true + +[tool.mypy] +check_untyped_defs = true