zrb 0.0.117__py3-none-any.whl → 0.0.119__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.
- zrb/builtin/__init__.py +2 -2
- zrb/builtin/helper/__init__.py +0 -0
- zrb/builtin/helper/reccuring_action.py +46 -0
- zrb/builtin/schedule.py +12 -22
- zrb/builtin/watch_changes.py +31 -0
- zrb/helper/env_map/fetch.py +6 -6
- zrb/shell-scripts/notify.ps1 +16 -0
- zrb/task/base_remote_cmd_task.py +4 -1
- zrb/task/base_task/__init__.py +0 -0
- zrb/task/{base_task.py → base_task/base_task.py} +62 -201
- zrb/task/base_task/component/__init__.py +0 -0
- zrb/task/base_task/component/base_task_model.py +258 -0
- zrb/task/base_task/component/common_task_model.py +282 -0
- zrb/task/base_task/component/pid_model.py +17 -0
- zrb/task/base_task/component/renderer.py +119 -0
- zrb/task/base_task/component/trackers.py +76 -0
- zrb/task/checker.py +4 -1
- zrb/task/cmd_task.py +56 -36
- zrb/task/docker_compose_task.py +23 -19
- zrb/task/flow_task.py +1 -1
- zrb/task/notifier.py +157 -0
- zrb/task/recurring_task.py +20 -5
- zrb/task/resource_maker.py +1 -1
- zrb/task/task.py +1 -1
- zrb/task/time_watcher.py +2 -2
- zrb/task_env/env.py +26 -14
- zrb/task_env/env_file.py +15 -15
- zrb/task_input/base_input.py +2 -2
- {zrb-0.0.117.dist-info → zrb-0.0.119.dist-info}/METADATA +2 -2
- {zrb-0.0.117.dist-info → zrb-0.0.119.dist-info}/RECORD +33 -23
- zrb/builtin/watch.py +0 -44
- zrb/task/base_task_composite.py +0 -558
- {zrb-0.0.117.dist-info → zrb-0.0.119.dist-info}/LICENSE +0 -0
- {zrb-0.0.117.dist-info → zrb-0.0.119.dist-info}/WHEEL +0 -0
- {zrb-0.0.117.dist-info → zrb-0.0.119.dist-info}/entry_points.txt +0 -0
zrb/task/base_task_composite.py
DELETED
@@ -1,558 +0,0 @@
|
|
1
|
-
from zrb.helper.typing import (
|
2
|
-
Any, Callable, Iterable, List, Mapping, Optional, Union
|
3
|
-
)
|
4
|
-
from zrb.helper.typecheck import typechecked
|
5
|
-
from zrb.config.config import show_time
|
6
|
-
from zrb.task.any_task import AnyTask
|
7
|
-
from zrb.helper.string.conversion import to_boolean, to_cmd_name
|
8
|
-
from zrb.helper.string.jinja import is_probably_jinja
|
9
|
-
from zrb.helper.render_data import DEFAULT_RENDER_DATA
|
10
|
-
from zrb.helper.log import logger
|
11
|
-
from zrb.helper.accessories.color import colored, get_random_color
|
12
|
-
from zrb.helper.accessories.icon import get_random_icon
|
13
|
-
from zrb.helper.util import coalesce_str
|
14
|
-
from zrb.task_input.any_input import AnyInput
|
15
|
-
from zrb.task_group.group import Group
|
16
|
-
from zrb.task_env.env import Env
|
17
|
-
from zrb.task_env.env_file import EnvFile
|
18
|
-
|
19
|
-
import asyncio
|
20
|
-
import datetime
|
21
|
-
import os
|
22
|
-
import time
|
23
|
-
import jinja2
|
24
|
-
import sys
|
25
|
-
|
26
|
-
LOG_NAME_LENGTH = 20
|
27
|
-
|
28
|
-
|
29
|
-
@typechecked
|
30
|
-
class CommonTaskModel():
|
31
|
-
def __init__(
|
32
|
-
self,
|
33
|
-
name: str,
|
34
|
-
group: Optional[Group] = None,
|
35
|
-
description: str = '',
|
36
|
-
inputs: List[AnyInput] = [],
|
37
|
-
envs: Iterable[Env] = [],
|
38
|
-
env_files: Iterable[EnvFile] = [],
|
39
|
-
icon: Optional[str] = None,
|
40
|
-
color: Optional[str] = None,
|
41
|
-
retry: int = 2,
|
42
|
-
retry_interval: Union[float, int] = 1,
|
43
|
-
upstreams: Iterable[AnyTask] = [],
|
44
|
-
checkers: Iterable[AnyTask] = [],
|
45
|
-
checking_interval: Union[float, int] = 0,
|
46
|
-
run: Optional[Callable[..., Any]] = None,
|
47
|
-
should_execute: Union[bool, str, Callable[..., bool]] = True
|
48
|
-
):
|
49
|
-
self._name = name
|
50
|
-
self._group = group
|
51
|
-
if group is not None:
|
52
|
-
group.add_task(self)
|
53
|
-
self._description = coalesce_str(description, name)
|
54
|
-
self._inputs = inputs
|
55
|
-
self._envs = envs
|
56
|
-
self._env_files = env_files
|
57
|
-
self._icon = coalesce_str(icon, get_random_icon())
|
58
|
-
self._color = coalesce_str(color, get_random_color())
|
59
|
-
self._retry = retry
|
60
|
-
self._retry_interval = retry_interval
|
61
|
-
self._upstreams = upstreams
|
62
|
-
self._checkers = checkers
|
63
|
-
self._checking_interval = checking_interval
|
64
|
-
self._run_function: Optional[Callable[..., Any]] = run
|
65
|
-
self._should_execute = should_execute
|
66
|
-
self._allow_add_envs = True
|
67
|
-
self._allow_add_env_files = True
|
68
|
-
self._allow_add_inputs = True
|
69
|
-
self._allow_add_upstreams: bool = True
|
70
|
-
self._has_already_inject_env_files: bool = False
|
71
|
-
self._has_already_inject_envs: bool = False
|
72
|
-
self._has_already_inject_inputs: bool = False
|
73
|
-
self._has_already_inject_checkers: bool = False
|
74
|
-
self._has_already_inject_upstreams: bool = False
|
75
|
-
self._execution_id = ''
|
76
|
-
|
77
|
-
def _set_execution_id(self, execution_id: str):
|
78
|
-
if self._execution_id == '':
|
79
|
-
self._execution_id = execution_id
|
80
|
-
|
81
|
-
def set_name(self, new_name: str):
|
82
|
-
if self._description == self._name:
|
83
|
-
self._description = new_name
|
84
|
-
self._name = new_name
|
85
|
-
|
86
|
-
def set_description(self, new_description: str):
|
87
|
-
self._description = new_description
|
88
|
-
|
89
|
-
def set_icon(self, new_icon: str):
|
90
|
-
self._icon = new_icon
|
91
|
-
|
92
|
-
def set_color(self, new_color: str):
|
93
|
-
self._color = new_color
|
94
|
-
|
95
|
-
def set_retry(self, new_retry: int):
|
96
|
-
self._retry = new_retry
|
97
|
-
|
98
|
-
def set_should_execute(
|
99
|
-
self, should_execute: Union[bool, str, Callable[..., bool]]
|
100
|
-
):
|
101
|
-
self._should_execute = should_execute
|
102
|
-
|
103
|
-
def set_retry_interval(self, new_retry_interval: Union[float, int]):
|
104
|
-
self._retry_interval = new_retry_interval
|
105
|
-
|
106
|
-
def set_checking_interval(self, new_checking_interval: Union[float, int]):
|
107
|
-
self._checking_interval = new_checking_interval
|
108
|
-
|
109
|
-
def insert_input(self, *inputs: AnyInput):
|
110
|
-
if not self._allow_add_inputs:
|
111
|
-
raise Exception(f'Cannot insert inputs for `{self._name}`')
|
112
|
-
self._inputs = list(inputs) + list(self._inputs)
|
113
|
-
|
114
|
-
def add_input(self, *inputs: AnyInput):
|
115
|
-
if not self._allow_add_inputs:
|
116
|
-
raise Exception(f'Cannot add inputs for `{self._name}`')
|
117
|
-
self._inputs = list(self._inputs) + list(inputs)
|
118
|
-
|
119
|
-
def insert_env(self, *envs: Env):
|
120
|
-
if not self._allow_add_envs:
|
121
|
-
raise Exception(f'Cannot insert envs to `{self._name}`')
|
122
|
-
self._envs = list(envs) + list(self._envs)
|
123
|
-
|
124
|
-
def add_env(self, *envs: Env):
|
125
|
-
if not self._allow_add_envs:
|
126
|
-
raise Exception(f'Cannot add envs to `{self._name}`')
|
127
|
-
self._envs = list(self._envs) + list(envs)
|
128
|
-
|
129
|
-
def insert_env_file(self, *env_files: EnvFile):
|
130
|
-
if not self._allow_add_env_files:
|
131
|
-
raise Exception(f'Cannot insert env_files to `{self._name}`')
|
132
|
-
self._env_files = list(env_files) + list(self._env_files)
|
133
|
-
|
134
|
-
def add_env_file(self, *env_files: EnvFile):
|
135
|
-
if not self._allow_add_env_files:
|
136
|
-
raise Exception(f'Cannot add env_files to `{self._name}`')
|
137
|
-
self._env_files = list(self._env_files) + list(env_files)
|
138
|
-
|
139
|
-
def insert_upstream(self, *upstreams: AnyTask):
|
140
|
-
if not self._allow_add_upstreams:
|
141
|
-
raise Exception(f'Cannot insert upstreams to `{self._name}`')
|
142
|
-
self._upstreams = list(upstreams) + list(self._upstreams)
|
143
|
-
|
144
|
-
def add_upstream(self, *upstreams: AnyTask):
|
145
|
-
if not self._allow_add_upstreams:
|
146
|
-
raise Exception(f'Cannot add upstreams to `{self._name}`')
|
147
|
-
self._upstreams = list(self._upstreams) + list(upstreams)
|
148
|
-
|
149
|
-
def get_execution_id(self) -> str:
|
150
|
-
return self._execution_id
|
151
|
-
|
152
|
-
def get_icon(self) -> str:
|
153
|
-
return self._icon
|
154
|
-
|
155
|
-
def get_color(self) -> str:
|
156
|
-
return self._color
|
157
|
-
|
158
|
-
def inject_env_files(self):
|
159
|
-
pass
|
160
|
-
|
161
|
-
def _get_env_files(self) -> List[EnvFile]:
|
162
|
-
if not self._has_already_inject_env_files:
|
163
|
-
self.inject_env_files()
|
164
|
-
self._has_already_inject_env_files = True
|
165
|
-
return self._env_files
|
166
|
-
|
167
|
-
def inject_envs(self):
|
168
|
-
pass
|
169
|
-
|
170
|
-
def _get_envs(self) -> List[Env]:
|
171
|
-
if not self._has_already_inject_envs:
|
172
|
-
self.inject_envs()
|
173
|
-
self._has_already_inject_envs = True
|
174
|
-
return list(self._envs)
|
175
|
-
|
176
|
-
def inject_inputs(self):
|
177
|
-
pass
|
178
|
-
|
179
|
-
def _get_inputs(self) -> List[AnyInput]:
|
180
|
-
if not self._has_already_inject_inputs:
|
181
|
-
self.inject_inputs()
|
182
|
-
self._has_already_inject_inputs = True
|
183
|
-
return list(self._inputs)
|
184
|
-
|
185
|
-
def inject_checkers(self):
|
186
|
-
pass
|
187
|
-
|
188
|
-
def _get_checkers(self) -> List[AnyTask]:
|
189
|
-
if not self._has_already_inject_checkers:
|
190
|
-
self.inject_checkers()
|
191
|
-
self._has_already_inject_checkers = True
|
192
|
-
return list(self._checkers)
|
193
|
-
|
194
|
-
def inject_upstreams(self):
|
195
|
-
pass
|
196
|
-
|
197
|
-
def _get_upstreams(self) -> List[AnyTask]:
|
198
|
-
if not self._has_already_inject_upstreams:
|
199
|
-
self.inject_upstreams()
|
200
|
-
self._has_already_inject_upstreams = True
|
201
|
-
return list(self._upstreams)
|
202
|
-
|
203
|
-
def get_description(self) -> str:
|
204
|
-
return self._description
|
205
|
-
|
206
|
-
def get_cmd_name(self) -> str:
|
207
|
-
return to_cmd_name(self._name)
|
208
|
-
|
209
|
-
|
210
|
-
@typechecked
|
211
|
-
class TimeTracker():
|
212
|
-
|
213
|
-
def __init__(self):
|
214
|
-
self.__start_time: float = 0
|
215
|
-
self.__end_time: float = 0
|
216
|
-
|
217
|
-
def _start_timer(self):
|
218
|
-
self.__start_time = time.time()
|
219
|
-
|
220
|
-
def _end_timer(self):
|
221
|
-
self.__end_time = time.time()
|
222
|
-
|
223
|
-
def _get_elapsed_time(self) -> float:
|
224
|
-
return self.__end_time - self.__start_time
|
225
|
-
|
226
|
-
|
227
|
-
@typechecked
|
228
|
-
class AttemptTracker():
|
229
|
-
|
230
|
-
def __init__(self, retry: int = 2):
|
231
|
-
self.__retry = retry
|
232
|
-
self.__attempt: int = 1
|
233
|
-
self.__no_more_attempt: bool = False
|
234
|
-
|
235
|
-
def _get_max_attempt(self) -> int:
|
236
|
-
return self.__retry + 1
|
237
|
-
|
238
|
-
def _get_attempt(self) -> int:
|
239
|
-
return self.__attempt
|
240
|
-
|
241
|
-
def _increase_attempt(self):
|
242
|
-
self.__attempt += 1
|
243
|
-
|
244
|
-
def _should_attempt(self) -> bool:
|
245
|
-
attempt = self._get_attempt()
|
246
|
-
max_attempt = self._get_max_attempt()
|
247
|
-
return attempt <= max_attempt
|
248
|
-
|
249
|
-
def _is_last_attempt(self) -> bool:
|
250
|
-
attempt = self._get_attempt()
|
251
|
-
max_attempt = self._get_max_attempt()
|
252
|
-
return attempt >= max_attempt
|
253
|
-
|
254
|
-
|
255
|
-
@typechecked
|
256
|
-
class FinishTracker():
|
257
|
-
|
258
|
-
def __init__(self):
|
259
|
-
self.__execution_queue: Optional[asyncio.Queue] = None
|
260
|
-
self.__counter = 0
|
261
|
-
|
262
|
-
async def _mark_awaited(self):
|
263
|
-
if self.__execution_queue is None:
|
264
|
-
self.__execution_queue = asyncio.Queue()
|
265
|
-
self.__counter += 1
|
266
|
-
|
267
|
-
async def _mark_done(self):
|
268
|
-
# Tracker might be started several times
|
269
|
-
# However, when the execution is marked as done, it applied globally
|
270
|
-
# Thus, we need to send event as much as the counter.
|
271
|
-
for i in range(self.__counter):
|
272
|
-
await self.__execution_queue.put(True)
|
273
|
-
|
274
|
-
async def _is_done(self) -> bool:
|
275
|
-
while self.__execution_queue is None:
|
276
|
-
await asyncio.sleep(0.05)
|
277
|
-
return await self.__execution_queue.get()
|
278
|
-
|
279
|
-
|
280
|
-
@typechecked
|
281
|
-
class PidModel():
|
282
|
-
|
283
|
-
def __init__(self):
|
284
|
-
self.__task_pid: int = os.getpid()
|
285
|
-
|
286
|
-
def _set_task_pid(self, pid: int):
|
287
|
-
self.__task_pid = pid
|
288
|
-
|
289
|
-
def _get_task_pid(self) -> int:
|
290
|
-
return self.__task_pid
|
291
|
-
|
292
|
-
|
293
|
-
class AnyExtensionFileSystemLoader(jinja2.FileSystemLoader):
|
294
|
-
def get_source(self, environment, template):
|
295
|
-
for search_dir in self.searchpath:
|
296
|
-
file_path = os.path.join(search_dir, template)
|
297
|
-
if os.path.exists(file_path):
|
298
|
-
with open(file_path, 'r') as file:
|
299
|
-
contents = file.read()
|
300
|
-
return contents, file_path, lambda: False
|
301
|
-
raise jinja2.TemplateNotFound(template)
|
302
|
-
|
303
|
-
|
304
|
-
@typechecked
|
305
|
-
class Renderer():
|
306
|
-
|
307
|
-
def __init__(self):
|
308
|
-
self.__input_map: Mapping[str, Any] = {}
|
309
|
-
self.__env_map: Mapping[str, str] = {}
|
310
|
-
self.__render_data: Optional[Mapping[str, Any]] = None
|
311
|
-
self.__rendered_str: Mapping[str, str] = {}
|
312
|
-
|
313
|
-
def get_input_map(self) -> Mapping[str, Any]:
|
314
|
-
# This return reference to input map, so input map can be updated
|
315
|
-
return self.__input_map
|
316
|
-
|
317
|
-
def _set_input_map(self, key: str, val: Any):
|
318
|
-
self.__input_map[key] = val
|
319
|
-
|
320
|
-
def get_env_map(self) -> Mapping[str, str]:
|
321
|
-
# This return reference to env map, so env map can be updated
|
322
|
-
return self.__env_map
|
323
|
-
|
324
|
-
def _set_env_map(self, key: str, val: str):
|
325
|
-
self.__env_map[key] = val
|
326
|
-
|
327
|
-
def render_any(
|
328
|
-
self, val: Any, data: Optional[Mapping[str, Any]] = None
|
329
|
-
) -> Any:
|
330
|
-
if isinstance(val, str):
|
331
|
-
return self.render_str(val, data)
|
332
|
-
return val
|
333
|
-
|
334
|
-
def render_float(
|
335
|
-
self, val: Union[str, float], data: Optional[Mapping[str, Any]] = None
|
336
|
-
) -> float:
|
337
|
-
if isinstance(val, str):
|
338
|
-
return float(self.render_str(val, data))
|
339
|
-
return val
|
340
|
-
|
341
|
-
def render_int(
|
342
|
-
self, val: Union[str, int], data: Optional[Mapping[str, Any]] = None
|
343
|
-
) -> int:
|
344
|
-
if isinstance(val, str):
|
345
|
-
return int(self.render_str(val, data))
|
346
|
-
return val
|
347
|
-
|
348
|
-
def render_bool(
|
349
|
-
self, val: Union[str, bool], data: Optional[Mapping[str, Any]] = None
|
350
|
-
) -> bool:
|
351
|
-
if isinstance(val, str):
|
352
|
-
return to_boolean(self.render_str(val, data))
|
353
|
-
return val
|
354
|
-
|
355
|
-
def render_str(
|
356
|
-
self, val: str, data: Optional[Mapping[str, Any]] = None
|
357
|
-
) -> str:
|
358
|
-
if val in self.__rendered_str:
|
359
|
-
return self.__rendered_str[val]
|
360
|
-
if not is_probably_jinja(val):
|
361
|
-
return val
|
362
|
-
template = jinja2.Template(val)
|
363
|
-
render_data = self._get_render_data(additional_data=data)
|
364
|
-
try:
|
365
|
-
rendered_text = template.render(render_data)
|
366
|
-
except Exception:
|
367
|
-
raise Exception(f'Fail to render "{val}" with data: {render_data}')
|
368
|
-
self.__rendered_str[val] = rendered_text
|
369
|
-
return rendered_text
|
370
|
-
|
371
|
-
def render_file(
|
372
|
-
self, location: str, data: Optional[Mapping[str, Any]] = None
|
373
|
-
) -> str:
|
374
|
-
location_dir = os.path.dirname(location)
|
375
|
-
env = jinja2.Environment(
|
376
|
-
loader=AnyExtensionFileSystemLoader([location_dir])
|
377
|
-
)
|
378
|
-
template = env.get_template(location)
|
379
|
-
render_data = self._get_render_data(additional_data=data)
|
380
|
-
render_data['TEMPLATE_DIR'] = location_dir
|
381
|
-
rendered_text = template.render(render_data)
|
382
|
-
return rendered_text
|
383
|
-
|
384
|
-
def _get_render_data(
|
385
|
-
self, additional_data: Optional[Mapping[str, Any]] = None
|
386
|
-
) -> Mapping[str, Any]:
|
387
|
-
self._ensure_cached_render_data()
|
388
|
-
if additional_data is None:
|
389
|
-
return self.__render_data
|
390
|
-
return {**self.__render_data, **additional_data}
|
391
|
-
|
392
|
-
def _ensure_cached_render_data(self):
|
393
|
-
if self.__render_data is not None:
|
394
|
-
return self.__render_data
|
395
|
-
render_data = dict(DEFAULT_RENDER_DATA)
|
396
|
-
render_data.update({
|
397
|
-
'env': self.__env_map,
|
398
|
-
'input': self.__input_map,
|
399
|
-
})
|
400
|
-
self.__render_data = render_data
|
401
|
-
return render_data
|
402
|
-
|
403
|
-
|
404
|
-
@typechecked
|
405
|
-
class TaskModelWithPrinterAndTracker(
|
406
|
-
CommonTaskModel, PidModel, TimeTracker
|
407
|
-
):
|
408
|
-
def __init__(
|
409
|
-
self,
|
410
|
-
name: str,
|
411
|
-
group: Optional[Group] = None,
|
412
|
-
description: str = '',
|
413
|
-
inputs: List[AnyInput] = [],
|
414
|
-
envs: Iterable[Env] = [],
|
415
|
-
env_files: Iterable[EnvFile] = [],
|
416
|
-
icon: Optional[str] = None,
|
417
|
-
color: Optional[str] = None,
|
418
|
-
retry: int = 2,
|
419
|
-
retry_interval: Union[int, float] = 1,
|
420
|
-
upstreams: Iterable[AnyTask] = [],
|
421
|
-
checkers: Iterable[AnyTask] = [],
|
422
|
-
checking_interval: Union[int, float] = 0,
|
423
|
-
run: Optional[Callable[..., Any]] = None,
|
424
|
-
should_execute: Union[bool, str, Callable[..., bool]] = True
|
425
|
-
):
|
426
|
-
self._rjust_full_cmd_name: Optional[str] = None
|
427
|
-
self._has_cli_interface = False
|
428
|
-
self._complete_name: Optional[str] = None
|
429
|
-
CommonTaskModel.__init__(
|
430
|
-
self,
|
431
|
-
name=name,
|
432
|
-
group=group,
|
433
|
-
description=description,
|
434
|
-
inputs=inputs,
|
435
|
-
envs=envs,
|
436
|
-
env_files=env_files,
|
437
|
-
icon=icon,
|
438
|
-
color=color,
|
439
|
-
retry=retry,
|
440
|
-
retry_interval=retry_interval,
|
441
|
-
upstreams=upstreams,
|
442
|
-
checkers=checkers,
|
443
|
-
checking_interval=checking_interval,
|
444
|
-
run=run,
|
445
|
-
should_execute=should_execute,
|
446
|
-
)
|
447
|
-
PidModel.__init__(self)
|
448
|
-
TimeTracker.__init__(self)
|
449
|
-
|
450
|
-
def log_debug(self, message: Any):
|
451
|
-
prefix = self._get_log_prefix()
|
452
|
-
colored_message = colored(
|
453
|
-
f'{prefix} • {message}', attrs=['dark']
|
454
|
-
)
|
455
|
-
logger.debug(colored_message)
|
456
|
-
|
457
|
-
def log_warn(self, message: Any):
|
458
|
-
prefix = self._get_log_prefix()
|
459
|
-
colored_message = colored(
|
460
|
-
f'{prefix} • {message}', attrs=['dark']
|
461
|
-
)
|
462
|
-
logger.warning(colored_message)
|
463
|
-
|
464
|
-
def log_info(self, message: Any):
|
465
|
-
prefix = self._get_log_prefix()
|
466
|
-
colored_message = colored(
|
467
|
-
f'{prefix} • {message}', attrs=['dark']
|
468
|
-
)
|
469
|
-
logger.info(colored_message)
|
470
|
-
|
471
|
-
def log_error(self, message: Any):
|
472
|
-
prefix = self._get_log_prefix()
|
473
|
-
colored_message = colored(
|
474
|
-
f'{prefix} • {message}', color='red', attrs=['bold']
|
475
|
-
)
|
476
|
-
logger.error(colored_message, exc_info=True)
|
477
|
-
|
478
|
-
def log_critical(self, message: Any):
|
479
|
-
prefix = self._get_log_prefix()
|
480
|
-
colored_message = colored(
|
481
|
-
f'{prefix} • {message}', color='red', attrs=['bold']
|
482
|
-
)
|
483
|
-
logger.critical(colored_message, exc_info=True)
|
484
|
-
|
485
|
-
def print_out(self, message: Any, trim_message: bool = True):
|
486
|
-
prefix = self._get_colored_print_prefix()
|
487
|
-
message_str = f'{message}'.rstrip() if trim_message else f'{message}'
|
488
|
-
print(f'🤖 ○ {prefix} • {message_str}', file=sys.stderr)
|
489
|
-
sys.stderr.flush()
|
490
|
-
|
491
|
-
def print_err(self, message: Any, trim_message: bool = True):
|
492
|
-
prefix = self._get_colored_print_prefix()
|
493
|
-
message_str = f'{message}'.rstrip() if trim_message else f'{message}'
|
494
|
-
print(f'🤖 △ {prefix} • {message_str}', file=sys.stderr)
|
495
|
-
sys.stderr.flush()
|
496
|
-
|
497
|
-
def print_out_dark(self, message: Any, trim_message: bool = True):
|
498
|
-
message_str = f'{message}'
|
499
|
-
self.print_out(colored(message_str, attrs=['dark']), trim_message)
|
500
|
-
|
501
|
-
def _play_bell(self):
|
502
|
-
print('\a', end='', file=sys.stderr)
|
503
|
-
|
504
|
-
def _get_colored_print_prefix(self) -> str:
|
505
|
-
return self._get_colored(self._get_print_prefix())
|
506
|
-
|
507
|
-
def _get_colored(self, text: str) -> str:
|
508
|
-
return colored(text, color=self.get_color())
|
509
|
-
|
510
|
-
def _get_print_prefix(self) -> str:
|
511
|
-
common_prefix = self._get_common_prefix(show_time=show_time)
|
512
|
-
icon = self.get_icon()
|
513
|
-
rjust_cmd_name = self._get_rjust_full_cmd_name()
|
514
|
-
return f'{common_prefix} {icon} {rjust_cmd_name}'
|
515
|
-
|
516
|
-
def _get_log_prefix(self) -> str:
|
517
|
-
common_prefix = self._get_common_prefix(show_time=False)
|
518
|
-
icon = self.get_icon()
|
519
|
-
filled_name = self._get_rjust_full_cmd_name()
|
520
|
-
return f'{common_prefix} {icon} {filled_name}'
|
521
|
-
|
522
|
-
def _get_common_prefix(self, show_time: bool) -> str:
|
523
|
-
attempt = self._get_attempt()
|
524
|
-
max_attempt = self._get_max_attempt()
|
525
|
-
pid = str(self._get_task_pid()).rjust(6)
|
526
|
-
if show_time:
|
527
|
-
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
|
528
|
-
return f'◷ {now} ❁ {pid} → {attempt}/{max_attempt}'
|
529
|
-
return f'❁ {pid} → {attempt}/{max_attempt}'
|
530
|
-
|
531
|
-
def _get_rjust_full_cmd_name(self) -> str:
|
532
|
-
if self._rjust_full_cmd_name is not None:
|
533
|
-
return self._rjust_full_cmd_name
|
534
|
-
complete_name = self._get_full_cmd_name()
|
535
|
-
self._rjust_full_cmd_name = complete_name.rjust(LOG_NAME_LENGTH, ' ')
|
536
|
-
return self._rjust_full_cmd_name
|
537
|
-
|
538
|
-
def _get_full_cmd_name(self) -> str:
|
539
|
-
if self._complete_name is not None:
|
540
|
-
return self._complete_name
|
541
|
-
executable_prefix = ''
|
542
|
-
if self._has_cli_interface:
|
543
|
-
executable_prefix += self._get_executable_name() + ' '
|
544
|
-
cmd_name = self.get_cmd_name()
|
545
|
-
if self._group is None:
|
546
|
-
self._complete_name = f'{executable_prefix}{cmd_name}'
|
547
|
-
return self._complete_name
|
548
|
-
group_cmd_name = self._group.get_complete_name()
|
549
|
-
self._complete_name = f'{executable_prefix}{group_cmd_name} {cmd_name}'
|
550
|
-
return self._complete_name
|
551
|
-
|
552
|
-
def _get_executable_name(self) -> str:
|
553
|
-
if len(sys.argv) > 0 and sys.argv[0] != '':
|
554
|
-
return os.path.basename(sys.argv[0])
|
555
|
-
return 'zrb'
|
556
|
-
|
557
|
-
def _set_has_cli_interface(self):
|
558
|
-
self._has_cli_interface = True
|
File without changes
|
File without changes
|
File without changes
|