zrb 0.15.0__py3-none-any.whl → 0.17.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. zrb/__init__.py +5 -0
  2. zrb/__main__.py +0 -3
  3. zrb/action/runner.py +12 -3
  4. zrb/advertisement.py +4 -0
  5. zrb/builtin/_helper/reccuring_action.py +0 -23
  6. zrb/builtin/devtool/install/_input.py +2 -4
  7. zrb/builtin/devtool/install/helix/resource/config.toml +2 -1
  8. zrb/builtin/process/pid/get_by_name.py +1 -1
  9. zrb/builtin/project/create/template/project.sh +1 -0
  10. zrb/builtin/schedule.py +14 -10
  11. zrb/builtin/watch_changes.py +15 -14
  12. zrb/config/config.py +21 -14
  13. zrb/helper/accessories/color.py +5 -2
  14. zrb/helper/accessories/icon.py +4 -0
  15. zrb/helper/accessories/name.py +4 -0
  16. zrb/helper/accessories/untyped_color.py +10 -0
  17. zrb/helper/advertisement.py +3 -0
  18. zrb/helper/callable.py +9 -1
  19. zrb/helper/cli.py +2 -0
  20. zrb/helper/codemod/add_argument_to_function.py +6 -0
  21. zrb/helper/codemod/add_argument_to_function_call.py +6 -0
  22. zrb/helper/codemod/add_assert_resource.py +4 -0
  23. zrb/helper/codemod/add_function_call.py +4 -0
  24. zrb/helper/codemod/add_import_module.py +4 -0
  25. zrb/helper/codemod/add_key_value_to_dict.py +6 -0
  26. zrb/helper/codemod/add_property_to_class.py +6 -0
  27. zrb/helper/codemod/add_upstream_to_task.py +4 -0
  28. zrb/helper/codemod/append_code_to_function.py +6 -0
  29. zrb/helper/codemod/format_code.py +4 -0
  30. zrb/helper/default_env.py +2 -0
  31. zrb/helper/docker_compose/fetch_external_env.py +6 -0
  32. zrb/helper/docker_compose/file.py +4 -0
  33. zrb/helper/docstring.py +5 -0
  34. zrb/helper/env_map/fetch.py +4 -0
  35. zrb/helper/file/copy_tree.py +3 -0
  36. zrb/helper/file/match.py +4 -0
  37. zrb/helper/file/text.py +4 -0
  38. zrb/helper/git/detect_changes.py +4 -0
  39. zrb/helper/loader/load_module.py +2 -0
  40. zrb/helper/log.py +1 -1
  41. zrb/helper/map/conversion.py +4 -0
  42. zrb/helper/python_task.py +3 -0
  43. zrb/helper/render_data.py +4 -0
  44. zrb/helper/string/conversion.py +13 -36
  45. zrb/helper/string/jinja.py +4 -0
  46. zrb/helper/string/modification.py +4 -0
  47. zrb/helper/string/parse_replacement.py +4 -0
  48. zrb/helper/string/untyped_conversion.py +49 -0
  49. zrb/helper/task.py +4 -0
  50. zrb/helper/typecheck.py +6 -7
  51. zrb/helper/typing.py +32 -12
  52. zrb/helper/util.py +4 -0
  53. zrb/runner.py +3 -0
  54. zrb/task/any_task.py +5 -0
  55. zrb/task/any_task_event_handler.py +4 -0
  56. zrb/task/base_remote_cmd_task.py +4 -0
  57. zrb/task/base_task/base_task.py +5 -1
  58. zrb/task/checker.py +7 -3
  59. zrb/task/cmd_task.py +14 -2
  60. zrb/task/decorator.py +4 -0
  61. zrb/task/docker_compose_task.py +4 -0
  62. zrb/task/flow_task.py +4 -0
  63. zrb/task/http_checker.py +14 -1
  64. zrb/task/looper.py +40 -0
  65. zrb/task/notifier.py +4 -0
  66. zrb/task/parallel.py +4 -0
  67. zrb/task/path_checker.py +14 -1
  68. zrb/task/path_watcher.py +65 -41
  69. zrb/task/port_checker.py +14 -1
  70. zrb/task/recurring_task.py +5 -0
  71. zrb/task/remote_cmd_task.py +4 -0
  72. zrb/task/resource_maker.py +14 -1
  73. zrb/task/rsync_task.py +4 -0
  74. zrb/task/server.py +190 -0
  75. zrb/task/task.py +4 -0
  76. zrb/task/time_watcher.py +50 -18
  77. zrb/task/watcher.py +100 -0
  78. zrb/task/wiki_task.py +4 -0
  79. zrb/task_env/constant.py +5 -0
  80. zrb/task_env/env.py +4 -0
  81. zrb/task_env/env_file.py +4 -0
  82. zrb/task_group/group.py +4 -0
  83. zrb/task_input/any_input.py +4 -0
  84. zrb/task_input/base_input.py +4 -0
  85. zrb/task_input/bool_input.py +4 -0
  86. zrb/task_input/choice_input.py +4 -0
  87. zrb/task_input/constant.py +5 -0
  88. zrb/task_input/float_input.py +4 -0
  89. zrb/task_input/int_input.py +4 -0
  90. zrb/task_input/password_input.py +4 -0
  91. zrb/task_input/str_input.py +4 -0
  92. zrb/task_input/task_input.py +4 -0
  93. {zrb-0.15.0.dist-info → zrb-0.17.0.dist-info}/METADATA +1 -1
  94. {zrb-0.15.0.dist-info → zrb-0.17.0.dist-info}/RECORD +97 -92
  95. {zrb-0.15.0.dist-info → zrb-0.17.0.dist-info}/LICENSE +0 -0
  96. {zrb-0.15.0.dist-info → zrb-0.17.0.dist-info}/WHEEL +0 -0
  97. {zrb-0.15.0.dist-info → zrb-0.17.0.dist-info}/entry_points.txt +0 -0
zrb/task/time_watcher.py CHANGED
@@ -1,13 +1,17 @@
1
+ import asyncio
1
2
  import datetime
2
3
 
3
4
  import croniter
4
5
 
6
+ from zrb.helper.accessories.color import colored
7
+ from zrb.helper.log import logger
5
8
  from zrb.helper.typecheck import typechecked
6
9
  from zrb.helper.typing import (
7
10
  Any,
8
11
  Callable,
9
12
  Iterable,
10
13
  JinjaTemplate,
14
+ Mapping,
11
15
  Optional,
12
16
  TypeVar,
13
17
  Union,
@@ -22,17 +26,19 @@ from zrb.task.any_task_event_handler import (
22
26
  OnTriggered,
23
27
  OnWaiting,
24
28
  )
25
- from zrb.task.checker import Checker
29
+ from zrb.task.watcher import Watcher
26
30
  from zrb.task_env.env import Env
27
31
  from zrb.task_env.env_file import EnvFile
28
32
  from zrb.task_group.group import Group
29
33
  from zrb.task_input.any_input import AnyInput
30
34
 
35
+ logger.debug(colored("Loading zrb.task.time_watcher", attrs=["dark"]))
36
+
31
37
  TTimeWatcher = TypeVar("TTimeWatcher", bound="TimeWatcher")
32
38
 
33
39
 
34
40
  @typechecked
35
- class TimeWatcher(Checker):
41
+ class TimeWatcher(Watcher):
36
42
  """
37
43
  TimeWatcher will wait for any changes specified on path.
38
44
 
@@ -40,6 +46,8 @@ class TimeWatcher(Checker):
40
46
  and <task-name>.scheduled-time xcom will be set.
41
47
  """
42
48
 
49
+ __scheduled_times: Mapping[str, Mapping[str, datetime.datetime]] = {}
50
+
43
51
  def __init__(
44
52
  self,
45
53
  name: str = "watch-path",
@@ -64,7 +72,7 @@ class TimeWatcher(Checker):
64
72
  progress_interval: Union[int, float] = 30,
65
73
  should_execute: Union[bool, JinjaTemplate, Callable[..., bool]] = True,
66
74
  ):
67
- Checker.__init__(
75
+ Watcher.__init__(
68
76
  self,
69
77
  name=name,
70
78
  group=group,
@@ -88,7 +96,6 @@ class TimeWatcher(Checker):
88
96
  should_execute=should_execute,
89
97
  )
90
98
  self._schedule = schedule
91
- self._scheduled_time: Optional[datetime.datetime] = None
92
99
  self._rendered_schedule: str = ""
93
100
 
94
101
  def copy(self) -> TTimeWatcher:
@@ -100,23 +107,48 @@ class TimeWatcher(Checker):
100
107
  raise_error: bool = True,
101
108
  is_async: bool = False,
102
109
  show_done_info: bool = True,
110
+ should_clear_xcom: bool = False,
111
+ should_stop_looper: bool = False,
103
112
  ) -> Callable[..., bool]:
104
- return super().to_function(env_prefix, raise_error, is_async, show_done_info)
113
+ return super().to_function(
114
+ env_prefix=env_prefix,
115
+ raise_error=raise_error,
116
+ is_async=is_async,
117
+ show_done_info=show_done_info,
118
+ should_clear_xcom=should_clear_xcom,
119
+ should_stop_looper=should_stop_looper,
120
+ )
105
121
 
106
122
  async def run(self, *args: Any, **kwargs: Any) -> bool:
107
123
  self._rendered_schedule = self.render_str(self._schedule)
108
- margin = datetime.timedelta(seconds=0.001)
109
- slightly_before_check_time = datetime.datetime.now() - margin
110
- cron = croniter.croniter(self._rendered_schedule, slightly_before_check_time)
111
- self._scheduled_time = cron.get_next(datetime.datetime)
112
- self.set_task_xcom(key="scheduled-time", value=self._scheduled_time)
124
+ identifier = self.get_identifier()
125
+ if identifier not in self.__scheduled_times:
126
+ self.__scheduled_times[identifier] = self._get_next_schedule_time()
113
127
  return await super().run(*args, **kwargs)
114
128
 
115
- async def inspect(self, *args: Any, **kwargs: Any) -> bool:
116
- label = f"Watching {self._rendered_schedule}"
117
- now = datetime.datetime.now()
118
- if now > self._scheduled_time:
119
- self.print_out_dark(f"{label} (Meet {self._scheduled_time})")
120
- return True
121
- self.show_progress(f"{label} (Waiting for {self._scheduled_time})")
122
- return False
129
+ def create_loop_inspector(self) -> Callable[..., Optional[bool]]:
130
+ async def loop_inspect() -> bool:
131
+ await asyncio.sleep(0.1)
132
+ label = f"Watching {self._rendered_schedule}"
133
+ identifier = self.get_identifier()
134
+ scheduled_time = self.__scheduled_times[identifier]
135
+ self.set_task_xcom(key="scheduled-time", value=scheduled_time)
136
+ now = datetime.datetime.now()
137
+ if now > scheduled_time:
138
+ self.print_out_dark(f"{label} (Meet {scheduled_time})")
139
+ self.__scheduled_times[identifier] = self._get_next_schedule_time()
140
+ return True
141
+ self.show_progress(f"{label} (Waiting for {scheduled_time})")
142
+ return False
143
+
144
+ return loop_inspect
145
+
146
+ def _get_next_schedule_time(self) -> datetime.datetime:
147
+ cron = self._get_cron()
148
+ return cron.get_next(datetime.datetime)
149
+
150
+ def _get_cron(self) -> Any:
151
+ margin = datetime.timedelta(seconds=0.001)
152
+ slightly_before_now = datetime.datetime.now() - margin
153
+ cron = croniter.croniter(self._rendered_schedule, slightly_before_now)
154
+ return cron
zrb/task/watcher.py ADDED
@@ -0,0 +1,100 @@
1
+ import asyncio
2
+
3
+ from zrb.helper.accessories.color import colored
4
+ from zrb.helper.accessories.name import get_random_name
5
+ from zrb.helper.log import logger
6
+ from zrb.helper.typecheck import typechecked
7
+ from zrb.helper.typing import Any, Callable, Iterable, Optional, Union
8
+ from zrb.task.any_task import AnyTask
9
+ from zrb.task.any_task_event_handler import (
10
+ OnFailed,
11
+ OnReady,
12
+ OnRetry,
13
+ OnSkipped,
14
+ OnStarted,
15
+ OnTriggered,
16
+ OnWaiting,
17
+ )
18
+ from zrb.task.checker import Checker
19
+ from zrb.task.looper import looper
20
+ from zrb.task_env.env import Env
21
+ from zrb.task_env.env_file import EnvFile
22
+ from zrb.task_group.group import Group
23
+ from zrb.task_input.any_input import AnyInput
24
+
25
+ logger.debug(colored("Loading zrb.task.watcher", attrs=["dark"]))
26
+
27
+
28
+ @typechecked
29
+ class Watcher(Checker):
30
+ __looper = looper
31
+
32
+ def __init__(
33
+ self,
34
+ name: str = "watch",
35
+ group: Optional[Group] = None,
36
+ inputs: Iterable[AnyInput] = [],
37
+ envs: Iterable[Env] = [],
38
+ env_files: Iterable[EnvFile] = [],
39
+ icon: Optional[str] = None,
40
+ color: Optional[str] = None,
41
+ description: str = "",
42
+ upstreams: Iterable[AnyTask] = [],
43
+ fallbacks: Iterable[AnyTask] = [],
44
+ on_triggered: Optional[OnTriggered] = None,
45
+ on_waiting: Optional[OnWaiting] = None,
46
+ on_skipped: Optional[OnSkipped] = None,
47
+ on_started: Optional[OnStarted] = None,
48
+ on_ready: Optional[OnReady] = None,
49
+ on_retry: Optional[OnRetry] = None,
50
+ on_failed: Optional[OnFailed] = None,
51
+ checking_interval: Union[int, float] = 0.1,
52
+ progress_interval: Union[int, float] = 30,
53
+ expected_result: bool = True,
54
+ should_execute: Union[bool, str, Callable[..., bool]] = True,
55
+ ):
56
+ Checker.__init__(
57
+ self,
58
+ name=name,
59
+ group=group,
60
+ inputs=inputs,
61
+ envs=envs,
62
+ env_files=env_files,
63
+ icon=icon,
64
+ color=color,
65
+ description=description,
66
+ upstreams=upstreams,
67
+ fallbacks=fallbacks,
68
+ on_triggered=on_triggered,
69
+ on_waiting=on_waiting,
70
+ on_skipped=on_skipped,
71
+ on_started=on_started,
72
+ on_ready=on_ready,
73
+ on_retry=on_retry,
74
+ on_failed=on_failed,
75
+ checking_interval=checking_interval,
76
+ should_execute=should_execute,
77
+ progress_interval=progress_interval,
78
+ expected_result=expected_result,
79
+ )
80
+ self._identifier = get_random_name()
81
+
82
+ def get_identifier(self):
83
+ return self._identifier
84
+
85
+ async def run(self, *args: Any, **kwargs: Any) -> bool:
86
+ if not looper.is_registered(self._identifier):
87
+ asyncio.create_task(
88
+ looper.register(self._identifier, self.create_loop_inspector())
89
+ )
90
+ return await super().run(*args, **kwargs)
91
+
92
+ async def inspect(self, *args, **kwargs: Any) -> Optional[bool]:
93
+ result = await looper.pop(self._identifier)
94
+ return result
95
+
96
+ def create_loop_inspector(self) -> Callable[..., Optional[bool]]:
97
+ def loop_inspect() -> Optional[bool]:
98
+ return None
99
+
100
+ return loop_inspect
zrb/task/wiki_task.py CHANGED
@@ -1,6 +1,8 @@
1
1
  import os
2
2
 
3
3
  from zrb.action.runner import Runner
4
+ from zrb.helper.accessories.color import colored
5
+ from zrb.helper.log import logger
4
6
  from zrb.helper.task import show_lines
5
7
  from zrb.helper.typecheck import typechecked
6
8
  from zrb.helper.typing import Any, Callable, Iterable, List, Mapping, Optional, Union
@@ -21,6 +23,8 @@ from zrb.task_env.env_file import EnvFile
21
23
  from zrb.task_group.group import Group
22
24
  from zrb.task_input.any_input import AnyInput
23
25
 
26
+ logger.debug(colored("Loading zrb.task.wiki_task", attrs=["dark"]))
27
+
24
28
 
25
29
  @typechecked
26
30
  def create_wiki_tasks(
zrb/task_env/constant.py CHANGED
@@ -1 +1,6 @@
1
+ from zrb.helper.accessories.color import colored
2
+ from zrb.helper.log import logger
3
+
4
+ logger.debug(colored("Loading zrb.task_env.constant", attrs=["dark"]))
5
+
1
6
  RESERVED_ENV_NAMES = ("_ZRB_EXECUTION_ID", "_ZRB_EXECUTION_ID")
zrb/task_env/env.py CHANGED
@@ -1,10 +1,14 @@
1
1
  import os
2
2
 
3
+ from zrb.helper.accessories.color import colored
4
+ from zrb.helper.log import logger
3
5
  from zrb.helper.string.modification import double_quote
4
6
  from zrb.helper.typecheck import typechecked
5
7
  from zrb.helper.typing import JinjaTemplate, Optional
6
8
  from zrb.task_env.constant import RESERVED_ENV_NAMES
7
9
 
10
+ logger.debug(colored("Loading zrb.task_env.env", attrs=["dark"]))
11
+
8
12
  # flake8: noqa E501
9
13
 
10
14
 
zrb/task_env/env_file.py CHANGED
@@ -1,11 +1,15 @@
1
1
  from dotenv import dotenv_values
2
2
 
3
+ from zrb.helper.accessories.color import colored
4
+ from zrb.helper.log import logger
3
5
  from zrb.helper.string.modification import double_quote
4
6
  from zrb.helper.typecheck import typechecked
5
7
  from zrb.helper.typing import List, Optional
6
8
  from zrb.task_env.constant import RESERVED_ENV_NAMES
7
9
  from zrb.task_env.env import Env
8
10
 
11
+ logger.debug(colored("Loading zrb.task_env.env_file", attrs=["dark"]))
12
+
9
13
  # flake8: noqa E501
10
14
 
11
15
 
zrb/task_group/group.py CHANGED
@@ -1,9 +1,13 @@
1
+ from zrb.helper.accessories.color import colored
2
+ from zrb.helper.log import logger
1
3
  from zrb.helper.string.conversion import to_cli_name
2
4
  from zrb.helper.string.modification import double_quote
3
5
  from zrb.helper.typecheck import typechecked
4
6
  from zrb.helper.typing import List, Optional, TypeVar
5
7
  from zrb.task.any_task import AnyTask
6
8
 
9
+ logger.debug(colored("Loading zrb.task_group.group", attrs=["dark"]))
10
+
7
11
  # flake8: noqa E501
8
12
  TGroup = TypeVar("TGroup", bound="Group")
9
13
 
@@ -1,7 +1,11 @@
1
1
  from abc import ABC, abstractmethod
2
2
 
3
+ from zrb.helper.accessories.color import colored
4
+ from zrb.helper.log import logger
3
5
  from zrb.helper.typing import Any, List, Mapping
4
6
 
7
+ logger.debug(colored("Loading zrb.task_input.any_input", attrs=["dark"]))
8
+
5
9
  # flake8: noqa E501
6
10
 
7
11
 
@@ -1,9 +1,13 @@
1
1
  from zrb.config.config import show_prompt
2
+ from zrb.helper.accessories.color import colored
3
+ from zrb.helper.log import logger
2
4
  from zrb.helper.typecheck import typechecked
3
5
  from zrb.helper.typing import Any, List, Mapping, Optional, Union
4
6
  from zrb.task_input.any_input import AnyInput
5
7
  from zrb.task_input.constant import RESERVED_INPUT_NAMES
6
8
 
9
+ logger.debug(colored("Loading zrb.task_input.base_input", attrs=["dark"]))
10
+
7
11
  # flake8: noqa E501
8
12
 
9
13
 
@@ -1,7 +1,11 @@
1
+ from zrb.helper.accessories.color import colored
2
+ from zrb.helper.log import logger
1
3
  from zrb.helper.typecheck import typechecked
2
4
  from zrb.helper.typing import Any, Optional, Union
3
5
  from zrb.task_input.base_input import BaseInput
4
6
 
7
+ logger.debug(colored("Loading zrb.task_input.bool_input", attrs=["dark"]))
8
+
5
9
  # flake8: noqa E501
6
10
 
7
11
 
@@ -1,9 +1,13 @@
1
1
  import click
2
2
 
3
+ from zrb.helper.accessories.color import colored
4
+ from zrb.helper.log import logger
3
5
  from zrb.helper.typecheck import typechecked
4
6
  from zrb.helper.typing import Any, Iterable, Optional, Union
5
7
  from zrb.task_input.base_input import BaseInput
6
8
 
9
+ logger.debug(colored("Loading zrb.task_input.choice_input", attrs=["dark"]))
10
+
7
11
  # flake8: noqa E501
8
12
 
9
13
 
@@ -1 +1,6 @@
1
+ from zrb.helper.accessories.color import colored
2
+ from zrb.helper.log import logger
3
+
4
+ logger.debug(colored("Loading zrb.task_input.constant", attrs=["dark"]))
5
+
1
6
  RESERVED_INPUT_NAMES = ("_task", "_args")
@@ -1,7 +1,11 @@
1
+ from zrb.helper.accessories.color import colored
2
+ from zrb.helper.log import logger
1
3
  from zrb.helper.typecheck import typechecked
2
4
  from zrb.helper.typing import Any, Optional, Union
3
5
  from zrb.task_input.base_input import BaseInput
4
6
 
7
+ logger.debug(colored("Loading zrb.task_input.float_input", attrs=["dark"]))
8
+
5
9
  # flake8: noqa E501
6
10
 
7
11
 
@@ -1,7 +1,11 @@
1
+ from zrb.helper.accessories.color import colored
2
+ from zrb.helper.log import logger
1
3
  from zrb.helper.typecheck import typechecked
2
4
  from zrb.helper.typing import Any, Optional, Union
3
5
  from zrb.task_input.base_input import BaseInput
4
6
 
7
+ logger.debug(colored("Loading zrb.task_input.int_input", attrs=["dark"]))
8
+
5
9
  # flake8: noqa E501
6
10
 
7
11
 
@@ -1,7 +1,11 @@
1
+ from zrb.helper.accessories.color import colored
2
+ from zrb.helper.log import logger
1
3
  from zrb.helper.typecheck import typechecked
2
4
  from zrb.helper.typing import Any, Optional, Union
3
5
  from zrb.task_input.base_input import BaseInput
4
6
 
7
+ logger.debug(colored("Loading zrb.task_input.password_input", attrs=["dark"]))
8
+
5
9
  # flake8: noqa E501
6
10
 
7
11
 
@@ -1,7 +1,11 @@
1
+ from zrb.helper.accessories.color import colored
2
+ from zrb.helper.log import logger
1
3
  from zrb.helper.typecheck import typechecked
2
4
  from zrb.helper.typing import Any, Optional, Union
3
5
  from zrb.task_input.base_input import BaseInput
4
6
 
7
+ logger.debug(colored("Loading zrb.task_input.str_input", attrs=["dark"]))
8
+
5
9
  # flake8: noqa E501
6
10
 
7
11
 
@@ -1,5 +1,9 @@
1
+ from zrb.helper.accessories.color import colored
2
+ from zrb.helper.log import logger
1
3
  from zrb.task_input.base_input import BaseInput
2
4
 
5
+ logger.debug(colored("Loading zrb.task_input.task_input", attrs=["dark"]))
6
+
3
7
  # flake8: noqa E501
4
8
 
5
9
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: zrb
3
- Version: 0.15.0
3
+ Version: 0.17.0
4
4
  Summary: A Framework to Enhance Your Workflow
5
5
  Home-page: https://github.com/state-alchemists/zrb
6
6
  License: AGPL-3.0-or-later