zrb 0.0.107__py3-none-any.whl → 0.0.109__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/action/runner.py CHANGED
@@ -27,10 +27,10 @@ class Runner():
27
27
  logger.info(colored('Runner created', attrs=['dark']))
28
28
 
29
29
  def register(self, task: AnyTask):
30
- cmd_name = task.get_cmd_name()
30
+ task.set_has_cli_interface()
31
+ cmd_name = task.get_complete_cmd_name()
31
32
  logger.debug(colored(f'Register task: {cmd_name}', attrs=['dark']))
32
33
  self._tasks.append(task)
33
- task.set_has_cli_interface()
34
34
  logger.debug(colored(f'Task registered: {cmd_name}', attrs=['dark']))
35
35
 
36
36
  def serve(self, cli: click.Group) -> click.Group:
zrb/task/any_task.py CHANGED
@@ -80,6 +80,10 @@ class AnyTask(ABC):
80
80
  def add_env_files(self, *env_files: EnvFile):
81
81
  pass
82
82
 
83
+ @abstractmethod
84
+ def set_execution_id(self, execution_id: str):
85
+ pass
86
+
83
87
  @abstractmethod
84
88
  def set_name(self, new_name: str):
85
89
  pass
@@ -114,6 +118,10 @@ class AnyTask(ABC):
114
118
  def set_checking_interval(self, new_checking_interval: Union[float, int]):
115
119
  pass
116
120
 
121
+ @abstractmethod
122
+ def get_execution_id(self) -> str:
123
+ pass
124
+
117
125
  @abstractmethod
118
126
  def get_icon(self) -> str:
119
127
  pass
@@ -130,6 +138,10 @@ class AnyTask(ABC):
130
138
  def get_cmd_name(self) -> str:
131
139
  pass
132
140
 
141
+ @abstractmethod
142
+ def get_complete_cmd_name(self) -> str:
143
+ pass
144
+
133
145
  @abstractmethod
134
146
  def get_env_files(self) -> List[EnvFile]:
135
147
  pass
zrb/task/base_task.py CHANGED
@@ -12,16 +12,18 @@ from zrb.task.base_task_composite import (
12
12
  )
13
13
  from zrb.advertisement import advertisements
14
14
  from zrb.task_group.group import Group
15
+ from zrb.task_env.constant import RESERVED_ENV_NAMES
15
16
  from zrb.task_env.env import Env
16
17
  from zrb.task_env.env_file import EnvFile
17
18
  from zrb.task_input.any_input import AnyInput
18
19
  from zrb.task_input.constant import RESERVED_INPUT_NAMES
19
20
  from zrb.helper.accessories.color import colored
21
+ from zrb.helper.accessories.name import get_random_name
20
22
  from zrb.helper.advertisement import get_advertisement
21
23
  from zrb.helper.string.modification import double_quote
22
24
  from zrb.helper.string.conversion import to_variable_name
23
25
  from zrb.helper.map.conversion import to_str as map_to_str
24
- from zrb.config.config import show_advertisement
26
+ from zrb.config.config import show_advertisement, env_prefix
25
27
 
26
28
  import asyncio
27
29
  import copy
@@ -281,6 +283,8 @@ class BaseTask(
281
283
  self._allow_add_env_files = False
282
284
  all_envs: Mapping[str, Env] = {}
283
285
  for env_name in os.environ:
286
+ if env_name in RESERVED_ENV_NAMES:
287
+ continue
284
288
  all_envs[env_name] = Env(
285
289
  name=env_name, os_name=env_name, renderable=False
286
290
  )
@@ -305,6 +309,8 @@ class BaseTask(
305
309
  ):
306
310
  try:
307
311
  self._start_timer()
312
+ if self.get_execution_id() == '':
313
+ self.set_execution_id(get_random_name())
308
314
  self.log_info('Set input and env map')
309
315
  await self._set_keyval(kwargs=kwargs, env_prefix=env_prefix)
310
316
  self.log_info('Set run kwargs')
@@ -333,6 +339,7 @@ class BaseTask(
333
339
  if raise_error:
334
340
  raise
335
341
  finally:
342
+ self._show_env_prefix()
336
343
  self._show_run_command()
337
344
  self._play_bell()
338
345
 
@@ -356,6 +363,11 @@ class BaseTask(
356
363
  if you want to show the result differently.
357
364
  '''
358
365
  print(result)
366
+
367
+ def set_execution_id(self, execution_id: str):
368
+ super().set_execution_id(execution_id)
369
+ self._set_env_map('_ZRB_EXECUTION_ID', execution_id)
370
+ self._set_input_map('_execution_id', execution_id)
359
371
 
360
372
  async def _loop_check(self, show_done: bool = False) -> bool:
361
373
  self.log_info('Start readiness checking')
@@ -372,6 +384,13 @@ class BaseTask(
372
384
  await self.on_ready()
373
385
  return True
374
386
 
387
+ def _show_env_prefix(self):
388
+ if env_prefix == '':
389
+ return
390
+ colored_env_prefix = colored(env_prefix, color='yellow')
391
+ colored_label = colored('Your current environment: ', attrs=['dark'])
392
+ print(colored(f'{colored_label}{colored_env_prefix}'), file=sys.stderr)
393
+
375
394
  def _show_run_command(self):
376
395
  params: List[str] = [double_quote(arg) for arg in self._args]
377
396
  for task_input in self.get_all_inputs():
@@ -381,14 +400,14 @@ class BaseTask(
381
400
  kwarg_key = self._get_normalized_input_key(key)
382
401
  quoted_value = double_quote(str(self._kwargs[kwarg_key]))
383
402
  params.append(f'--{key} {quoted_value}')
384
- run_cmd = self._get_complete_name()
403
+ run_cmd = self.get_complete_cmd_name()
385
404
  run_cmd_with_param = run_cmd
386
405
  if len(params) > 0:
387
406
  param_str = ' '.join(params)
388
407
  run_cmd_with_param += ' ' + param_str
389
- colored_run_cmd = colored(f'{run_cmd_with_param}', color='yellow')
408
+ colored_command = colored(run_cmd_with_param, color='yellow')
390
409
  colored_label = colored('To run again: ', attrs=['dark'])
391
- print(colored(f'{colored_label}{colored_run_cmd}'), file=sys.stderr)
410
+ print(colored(f'{colored_label}{colored_command}'), file=sys.stderr)
392
411
 
393
412
  async def _cached_check(self) -> bool:
394
413
  if self._is_check_triggered:
@@ -418,6 +437,7 @@ class BaseTask(
418
437
  await asyncio.sleep(0.1)
419
438
  check_coroutines: Iterable[asyncio.Task] = []
420
439
  for checker_task in self._checkers:
440
+ checker_task.set_execution_id(self.get_execution_id())
421
441
  check_coroutines.append(
422
442
  asyncio.create_task(checker_task._run_all())
423
443
  )
@@ -430,6 +450,7 @@ class BaseTask(
430
450
  # Add upstream tasks to processes
431
451
  self._allow_add_upstreams = False
432
452
  for upstream_task in self._upstreams:
453
+ upstream_task.set_execution_id(self.get_execution_id())
433
454
  coroutines.append(asyncio.create_task(
434
455
  upstream_task._run_all(**kwargs)
435
456
  ))
@@ -66,6 +66,10 @@ class CommonTaskModel():
66
66
  self._allow_add_envs = True
67
67
  self._allow_add_env_files = True
68
68
  self._allow_add_inputs = True
69
+ self._execution_id = ''
70
+
71
+ def set_execution_id(self, execution_id: str):
72
+ self._execution_id = execution_id
69
73
 
70
74
  def set_name(self, new_name: str):
71
75
  if self._description == self._name:
@@ -110,6 +114,9 @@ class CommonTaskModel():
110
114
  raise Exception(f'Cannot add env_files on `{self._name}`')
111
115
  self._env_files += env_files
112
116
 
117
+ def get_execution_id(self) -> str:
118
+ return self._execution_id
119
+
113
120
  def get_icon(self) -> str:
114
121
  return self._icon
115
122
 
@@ -462,11 +469,11 @@ class TaskModelWithPrinterAndTracker(
462
469
  def _get_filled_complete_name(self) -> str:
463
470
  if self._filled_complete_name is not None:
464
471
  return self._filled_complete_name
465
- complete_name = self._get_complete_name()
472
+ complete_name = self.get_complete_cmd_name()
466
473
  self._filled_complete_name = complete_name.rjust(LOG_NAME_LENGTH, ' ')
467
474
  return self._filled_complete_name
468
475
 
469
- def _get_complete_name(self) -> str:
476
+ def get_complete_cmd_name(self) -> str:
470
477
  if self._complete_name is not None:
471
478
  return self._complete_name
472
479
  executable_prefix = ''
zrb/task/cmd_task.py CHANGED
@@ -168,9 +168,9 @@ class CmdTask(BaseTask):
168
168
  self, cwd: Optional[Union[str, pathlib.Path]]
169
169
  ):
170
170
  if cwd is None:
171
- self.cwd: Union[str, pathlib.Path] = os.getcwd()
171
+ self._cwd: Union[str, pathlib.Path] = os.getcwd()
172
172
  return
173
- self.cwd: Union[str, pathlib.Path] = cwd
173
+ self._cwd: Union[str, pathlib.Path] = os.path.abspath(cwd)
174
174
 
175
175
  def to_function(
176
176
  self, env_prefix: str = '', raise_error: bool = True
@@ -195,12 +195,12 @@ class CmdTask(BaseTask):
195
195
  cmd = self._get_cmd_str(*args, **kwargs)
196
196
  env_map = self._get_shell_env_map()
197
197
  self.print_out_dark('Run script: ' + self._get_multiline_repr(cmd))
198
- self.print_out_dark('Working directory: ' + self.cwd)
198
+ self.print_out_dark('Working directory: ' + self._cwd)
199
199
  self._output_buffer = []
200
200
  self._error_buffer = []
201
201
  process = await asyncio.create_subprocess_shell(
202
202
  cmd,
203
- cwd=self.cwd,
203
+ cwd=self._cwd,
204
204
  stdout=asyncio.subprocess.PIPE,
205
205
  stderr=asyncio.subprocess.PIPE,
206
206
  env=env_map,
@@ -7,6 +7,7 @@ from zrb.task.any_task import AnyTask
7
7
  from zrb.task.any_task_event_handler import (
8
8
  OnTriggered, OnWaiting, OnSkipped, OnStarted, OnReady, OnRetry, OnFailed
9
9
  )
10
+ from zrb.task_env.constant import RESERVED_ENV_NAMES
10
11
  from zrb.task_env.env import Env
11
12
  from zrb.task_env.env_file import EnvFile
12
13
  from zrb.task_group.group import Group
@@ -150,11 +151,9 @@ class DockerComposeTask(CmdTask):
150
151
  self._compose_runtime_file = self._get_compose_runtime_file(
151
152
  self._compose_template_file
152
153
  )
153
- # append services env and env_files to current task
154
- for _, service_config in self._compose_service_configs.items():
155
- self._env_files += service_config.get_env_files()
156
- self._envs += service_config.get_envs()
157
- self._add_compose_envs()
154
+ # Flag to make mark whether service config and compose environments
155
+ # has been added to this task's envs and env_files
156
+ self._is_additional_env_added = False
158
157
 
159
158
  def copy(self) -> TDockerComposeTask:
160
159
  return super().copy()
@@ -167,6 +166,46 @@ class DockerComposeTask(CmdTask):
167
166
  os.remove(self._compose_runtime_file)
168
167
  return result
169
168
 
169
+ def _get_all_envs(self) -> Mapping[str, Env]:
170
+ '''
171
+ This method override BaseTask's _get_all_envs.
172
+ Whenever _get_all_envs is called, we want to make sure that:
173
+ - Service config's envs and env_files are included
174
+ - Any environment defined in docker compose file is also included
175
+ '''
176
+ if self._is_additional_env_added:
177
+ return super()._get_all_envs()
178
+ self._is_additional_env_added = True
179
+ # define additional envs and additonal env_files
180
+ additional_envs: List[Env] = []
181
+ additional_env_files: List[EnvFile] = []
182
+ # populate additional envs and additional env_files
183
+ # with service configs
184
+ for _, service_config in self._compose_service_configs.items():
185
+ additional_env_files += service_config.get_env_files()
186
+ additional_envs += service_config.get_envs()
187
+ # populate additional envs and additional env_files with
188
+ # compose envs
189
+ data = read_compose_file(self._compose_template_file)
190
+ env_map = fetch_compose_file_env_map(data)
191
+ added_env_map: Mapping[str, bool] = {}
192
+ for key, value in env_map.items():
193
+ # Need to get this everytime because we only want
194
+ # the first compose file env value for a certain key
195
+ if key in RESERVED_ENV_NAMES or key in added_env_map:
196
+ continue
197
+ os_name = key
198
+ if self._compose_env_prefix != '':
199
+ os_name = f'{self._compose_env_prefix}_{os_name}'
200
+ compose_env = Env(name=key, os_name=os_name, default=value)
201
+ additional_envs.append(compose_env)
202
+ added_env_map[key] = True
203
+ # Add additional envs and addition env files to this task
204
+ self._envs = additional_envs + list(self._envs)
205
+ self._env_files = additional_env_files + list(self._env_files)
206
+ # get all envs
207
+ return super()._get_all_envs()
208
+
170
209
  def _generate_compose_runtime_file(self):
171
210
  compose_data = read_compose_file(self._compose_template_file)
172
211
  for service, service_config in self._compose_service_configs.items():
@@ -175,10 +214,10 @@ class DockerComposeTask(CmdTask):
175
214
  for env_file in env_files:
176
215
  envs += env_file.get_envs()
177
216
  envs += service_config.get_envs()
178
- compose_data = self._add_service_env(compose_data, service, envs)
217
+ compose_data = self._apply_service_env(compose_data, service, envs)
179
218
  write_compose_file(self._compose_runtime_file, compose_data)
180
219
 
181
- def _add_service_env(
220
+ def _apply_service_env(
182
221
  self, compose_data: Any, service: str, envs: List[Env]
183
222
  ) -> Any:
184
223
  # service not found
@@ -237,32 +276,6 @@ class DockerComposeTask(CmdTask):
237
276
  def _get_env_compose_value(self, env: Env) -> str:
238
277
  return '${' + env.name + ':-' + env.default + '}'
239
278
 
240
- def _add_compose_envs(self):
241
- data = read_compose_file(self._compose_template_file)
242
- env_map = fetch_compose_file_env_map(data)
243
- for key, value in env_map.items():
244
- # Need to get this everytime because we only want
245
- # the first compose file env value for a certain key
246
- existing_env_map = self._get_existing_env_map()
247
- if key in existing_env_map:
248
- continue
249
- os_name = key
250
- if self._compose_env_prefix != '':
251
- os_name = f'{self._compose_env_prefix}_{os_name}'
252
- self.add_envs(Env(name=key, os_name=os_name, default=value))
253
-
254
- def _get_existing_env_map(self) -> Mapping[str, str]:
255
- env_map: Mapping[str, str] = {}
256
- for env_file in self._env_files:
257
- envs = env_file.get_envs()
258
- env_map.update({
259
- env.name: env.default for env in envs
260
- })
261
- env_map.update({
262
- env.name: env.default for env in self._envs
263
- })
264
- return env_map
265
-
266
279
  def _get_compose_runtime_file(self, compose_file_name: str) -> str:
267
280
  directory, file = os.path.split(compose_file_name)
268
281
  prefix = '_' if file.startswith('.') else '._'
@@ -288,14 +301,14 @@ class DockerComposeTask(CmdTask):
288
301
  'compose.yml', 'compose.yaml',
289
302
  'docker-compose.yml', 'docker-compose.yaml'
290
303
  ]:
291
- if os.path.exists(os.path.join(self.cwd, _compose_file)):
292
- return os.path.join(self.cwd, _compose_file)
304
+ if os.path.exists(os.path.join(self._cwd, _compose_file)):
305
+ return os.path.join(self._cwd, _compose_file)
293
306
  return
294
- raise Exception(f'Cannot find compose file on {self.cwd}')
307
+ raise Exception(f'Cannot find compose file on {self._cwd}')
295
308
  if os.path.isabs(compose_file) and os.path.exists(compose_file):
296
309
  return compose_file
297
- if os.path.exists(os.path.join(self.cwd, compose_file)):
298
- return os.path.join(self.cwd, compose_file)
310
+ if os.path.exists(os.path.join(self._cwd, compose_file)):
311
+ return os.path.join(self._cwd, compose_file)
299
312
  raise Exception(f'Invalid compose file: {compose_file}')
300
313
 
301
314
  def _get_cmd_str(self, *args: Any, **kwargs: Any) -> str:
@@ -0,0 +1 @@
1
+ RESERVED_ENV_NAMES = ('_ZRB_EXECUTION_ID',)
zrb/task_env/env.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from zrb.helper.typing import Optional
2
2
  from zrb.helper.typecheck import typechecked
3
+ from zrb.task_env.constant import RESERVED_ENV_NAMES
3
4
  import os
4
5
 
5
6
 
@@ -16,6 +17,8 @@ class Env():
16
17
  default: str = '',
17
18
  renderable: bool = True,
18
19
  ):
20
+ if name in RESERVED_ENV_NAMES:
21
+ raise ValueError(f'Forbidden input name: {name}')
19
22
  self.name: str = name
20
23
  self.os_name: str = os_name if os_name is not None else name
21
24
  self.default: str = default
zrb/task_env/env_file.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from zrb.helper.typing import List, Optional
2
2
  from zrb.helper.typecheck import typechecked
3
3
  from dotenv import dotenv_values
4
+ from zrb.task_env.constant import RESERVED_ENV_NAMES
4
5
  from zrb.task_env.env import Env
5
6
 
6
7
 
@@ -25,6 +26,8 @@ class EnvFile():
25
26
  env_list: List[Env] = []
26
27
  env_map = dotenv_values(self.env_file)
27
28
  for key, value in env_map.items():
29
+ if key in RESERVED_ENV_NAMES:
30
+ continue
28
31
  os_name: Optional[str] = None
29
32
  if self.prefix is not None and self.prefix != '':
30
33
  os_name = f'{self.prefix}_{key}'
@@ -1 +1 @@
1
- RESERVED_INPUT_NAMES = ('_task', '_args')
1
+ RESERVED_INPUT_NAMES = ('_task', '_args', '_execution_id')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: zrb
3
- Version: 0.0.107
3
+ Version: 0.0.109
4
4
  Summary: Super framework for your super app
5
5
  Author-email: Go Frendi Gunawan <gofrendiasgard@gmail.com>
6
6
  Requires-Python: >=3.10.0
@@ -30,15 +30,17 @@ Provides-Extra: test
30
30
 
31
31
  # 🤖 Zrb (Read: Zaruba) : A Super Framework for Your Super App
32
32
 
33
- ![](https://raw.githubusercontent.com/state-alchemists/zrb/main/images/zrb/android-chrome-192x192.png)
33
+ ![](https://raw.githubusercontent.com/state-alchemists/zrb/main/_images/zrb/android-chrome-192x192.png)
34
34
 
35
- [📖 Documentation](https://github.com/state-alchemists/zrb/blob/main/docs/README.md) | [🏁 Getting started](https://github.com/state-alchemists/zrb/blob/main/docs/getting-started.md)
35
+ [📖 Documentation](https://github.com/state-alchemists/zrb/blob/main/docs/README.md) | [🏁 Getting Started](https://github.com/state-alchemists/zrb/blob/main/docs/getting-started.md) | [💃 Oops, I did it Again](https://github.com/state-alchemists/zrb/blob/main/docs/oops-i-did-it-again/README.md) | [❓ FAQ](https://github.com/state-alchemists/zrb/blob/main/docs/faq/README.md)
36
36
 
37
- Zrb is a [CLI-based](https://en.wikipedia.org/wiki/Command-line_interface) automation [tool](https://en.wikipedia.org/wiki/Programming_tool) and [low-code](https://en.wikipedia.org/wiki/Low-code_development_platform) platform. Once installed, you can automate day-to-day tasks, generate projects and applications, and even deploy your applications to Kubernetes with a few commands.
37
+ Zrb is a [CLI-based](https://en.wikipedia.org/wiki/Command-line_interface) automation [tool](https://en.wikipedia.org/wiki/Programming_tool) and [low-code](https://en.wikipedia.org/wiki/Low-code_development_platform) platform. Once installed, Zrb will help you automate day-to-day tasks, generate projects and applications, and even deploy your applications to Kubernetes with a few commands.
38
38
 
39
39
  To use Zrb, you need to be familiar with CLI.
40
40
 
41
- ## Zrb as a low-code framework
41
+ Zrb task definitions are written in [Python](https://www.python.org/), and we have a [very good reason](https://github.com/state-alchemists/zrb/blob/main/docs/faq/why-python.md) behind the decision.
42
+
43
+ ## Zrb is A Low-Code Framework
42
44
 
43
45
  Let's see how you can build and run a [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) application.
44
46
 
@@ -67,9 +69,9 @@ zrb project start-fastapp --fastapp-run-mode "monolith"
67
69
 
68
70
  You will be able to access the application by pointing your browser to [http://localhost:3000](http://localhost:3000)
69
71
 
70
- ![](https://raw.githubusercontent.com/state-alchemists/zrb/main/images/fastapp.png)
72
+ ![](https://raw.githubusercontent.com/state-alchemists/zrb/main/_images/fastapp.png)
71
73
 
72
- Furthermore, you can also run the same application as `microservices`, run the application as `docker containers`, and even doing some deployments into your `kubernetes cluster`.
74
+ Furthermore, you can run the same application as `microservices`, run the application as `docker containers`, and even do some deployments into your `kubernetes cluster`.
73
75
 
74
76
 
75
77
  ```bash
@@ -88,9 +90,9 @@ zrb project deploy-fastapp --fastapp-deploy-mode "microservices"
88
90
  You can visit [our tutorials](https://github.com/state-alchemists/zrb/blob/main/docs/tutorials/README.md) to see more cool tricks.
89
91
 
90
92
 
91
- ## Zrb as a task-automation framework
93
+ ## Zrb is A Task-Automation Tool
92
94
 
93
- Aside from the builtin capabilities, Zrb also allows you to define your automation commands in Python. To do so, you need to create/modify a file named `zrb_init.py`.
95
+ Aside from the built-in capabilities, Zrb also allows you to define your automation commands in Python. To do so, you must create/modify a file named `zrb_init.py`.
94
96
 
95
97
  ```python
96
98
  # filename: zrb_init.py
@@ -131,7 +133,7 @@ To learn more about this, you can visit [our getting started guide](https://gith
131
133
 
132
134
  # 🫰 Installation
133
135
 
134
- ## ⚙️ In local machine
136
+ ## ⚙️ In Local Machine
135
137
 
136
138
  Installing Zrb in your system is as easy as typing the following command in your terminal:
137
139
 
@@ -139,11 +141,11 @@ Installing Zrb in your system is as easy as typing the following command in your
139
141
  pip install zrb
140
142
  ```
141
143
 
142
- Just like any other Python package, you can also install Zrb in your [virtual environment](https://docs.python.org/3/library/venv.html). This will allow you to have many versions of Zrb on the same computer.
144
+ Like any other Python package, you can install Zrb in your [virtual environment](https://docs.python.org/3/library/venv.html). This will allow you to have many versions of Zrb on the same computer.
143
145
 
144
146
  > ⚠️ If the command doesn't work, you probably don't have Pip/Python on your computer. See `Main prerequisites` subsection to install them.
145
147
 
146
- ## 🐋 With docker
148
+ ## 🐋 With Docker
147
149
 
148
150
  If you prefer to work with Docker, you can create a file named `docker-compose.yml`
149
151
 
@@ -182,7 +184,7 @@ You will be able to access Zrb by using docker exec:
182
184
  docker exec -it zrb zsh
183
185
  ```
184
186
 
185
- # ✅ Main prerequisites
187
+ # ✅ Main Prerequisites
186
188
 
187
189
  Since Zrb is written in Python, you need to install a few things before installing Zrb:
188
190
 
@@ -207,11 +209,11 @@ ln -s venv/bin/python3 /usr/local/bin/python
207
209
 
208
210
  If you prefer Python distribution like [conda](https://docs.conda.io/en/latest/), that might work as well.
209
211
 
210
- # ✔️ Other prerequisites
212
+ # ✔️ Other Prerequisites
211
213
 
212
214
  If you want to generate applications using Zrb and run them on your computer, you will also need:
213
215
 
214
- - 🐸 `Node.Js` and `Npm`.
216
+ - 🐸 `Node.Js` and `Npm`.
215
217
  - You need Node.Js to modify/transpile frontend code into static files.
216
218
  - You can visit the [Node.Js website](https://nodejs.org/en) for installation instructions.
217
219
  - 🐋 `Docker` and `Docker-compose` plugin.
@@ -226,9 +228,9 @@ If you want to generate applications using Zrb and run them on your computer, yo
226
228
  - 🦆 `Pulumi`
227
229
  - You need Pulumi to deploy your applications
228
230
 
229
- # 🏁 Getting started
231
+ # 🏁 Getting Started
230
232
 
231
- We have a nice [getting started guide](https://github.com/state-alchemists/zrb/blob/main/docs/getting-started.md) to help you cover the basics. Make sure to check it out😉.
233
+ We have an excellent [getting started guide](https://github.com/state-alchemists/zrb/blob/main/docs/getting-started.md) to help you cover the basics. Make sure to check it out😉.
232
234
 
233
235
  # 📖 Documentation
234
236
 
@@ -238,11 +240,11 @@ You can visit [Zrb documentation](https://github.com/state-alchemists/zrb/blob/m
238
240
 
239
241
  Help Red Skull to click the donation button:
240
242
 
241
- [![](https://raw.githubusercontent.com/state-alchemists/zrb/main/images/donator.png)](https://stalchmst.com/donation)
243
+ [![](https://raw.githubusercontent.com/state-alchemists/zrb/main/_images/donator.png)](https://stalchmst.com/donation)
242
244
 
243
- # 🎉 Fun fact
245
+ # 🎉 Fun Fact
244
246
 
245
247
  > Madou Ring Zaruba (魔導輪ザルバ, Madōrin Zaruba) is a Madougu which supports bearers of the Garo Armor. [(Garo Wiki | Fandom)](https://garo.fandom.com/wiki/Zaruba)
246
248
 
247
- ![Madou Ring Zaruba on Kouga's Hand](https://raw.githubusercontent.com/state-alchemists/zrb/main/images/madou-ring-zaruba.jpg)
249
+ ![Madou Ring Zaruba on Kouga's Hand](https://raw.githubusercontent.com/state-alchemists/zrb/main/_images/madou-ring-zaruba.jpg)
248
250
 
@@ -3,7 +3,7 @@ zrb/__main__.py,sha256=CdfuYSxqlJhnsJPOBOL2_uzEaTZHC3MtpyTuz8QUfUI,314
3
3
  zrb/advertisement.py,sha256=e-1tFPlmEuz8IqaIJ_9-2p9x5cuGsxssJGu5F0wHthI,505
4
4
  zrb/runner.py,sha256=MPCNPMCyiYNZeubSxd1eM2Zr6PCIKF-9pkG385AXElw,118
5
5
  zrb/action/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- zrb/action/runner.py,sha256=hBV6JO5A-Ua-pXVXGQj8MEY7pVbkZwiak29aCiD9eDc,4465
6
+ zrb/action/runner.py,sha256=AtGiru_OJcdX8en18jysVqr26nWl6bfV0M5GLpk7dYc,4474
7
7
  zrb/builtin/__init__.py,sha256=VpmpsDJmL2Qe1MDiVTaGgGgW9MxRz8sR21Blclg6MDE,580
8
8
  zrb/builtin/base64.py,sha256=_Ff8eQi0pMa4qqDUqZqA-u-2LpSA5s3AN0Nj2M7ibnQ,1318
9
9
  zrb/builtin/env.py,sha256=hEjQios0i-3DantczxQnZnolzwZAGIQOE0Ygka330EU,1146
@@ -1140,14 +1140,14 @@ zrb/shell-scripts/ensure-ssh-is-installed.sh,sha256=TM0PLXT2vNfgv2ffcW_l-IqtMqHI
1140
1140
  zrb/shell-scripts/rsync-util.sh,sha256=E4Of-AugCFKabQvk-mC0RrQ4JexS7JLT5p6Ux92ETcY,326
1141
1141
  zrb/shell-scripts/ssh-util.sh,sha256=9lXDzw6oO8HuA4vdbfps_uQMMwKyNYX9fZkZgpK52g8,401
1142
1142
  zrb/task/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1143
- zrb/task/any_task.py,sha256=WSTWXlWvuGHxTHi03AV3FYNTSMQwyaWtt4Am-DKozfg,5568
1143
+ zrb/task/any_task.py,sha256=nygWeqJw2zVIvbGBU4j24MvJzrHnAKLQ-nrFZlCWc98,5804
1144
1144
  zrb/task/any_task_event_handler.py,sha256=vpO9t0fck8-oFu1KYptfcg2hXKRsk6V5je4Dg-Bl21o,359
1145
1145
  zrb/task/base_remote_cmd_task.py,sha256=mRizRbkvZwWeBU_MO7qiF89co5Y30ICpxD7cwbpRN3Y,8033
1146
- zrb/task/base_task.py,sha256=KUtqu_9SfW0bTn0xfL5E_bY5rnu1wudYuX8aAas69ZY,20528
1147
- zrb/task/base_task_composite.py,sha256=sn21YqL2aWpBkqL7L6LQ85Bvp23mnbItcRYnw3-plyI,16093
1148
- zrb/task/cmd_task.py,sha256=cIuc7lcaPZYYbqTfPSMROWGZzX8BSU3SMVbEmviNeIw,12783
1146
+ zrb/task/base_task.py,sha256=cxPRuAA87BTcF9ppRdpwh7BAQTEeLCxUOIlSkEAMaMU,21520
1147
+ zrb/task/base_task_composite.py,sha256=nKgnm9YyXfIlA0UYdI7dHYT9r9S66vvzhIkGDUxJbhc,16299
1148
+ zrb/task/cmd_task.py,sha256=zpoLkwt77PPeVc1YZCzjq1Kg4jUZ84OR6TpVPK166CM,12804
1149
1149
  zrb/task/decorator.py,sha256=6mJuDhmyHnVwx8SzBf8el5KwYJdA06VTeb1BABgLmTc,2399
1150
- zrb/task/docker_compose_task.py,sha256=apTP6YKqrpYRdHvvBOsjIAbHxK6ybcOubqlcZw_2USw,12978
1150
+ zrb/task/docker_compose_task.py,sha256=GjpWYPyY_3B9rLEUmbTEECkvXixKaZ_FF6UZnqCwWgM,13852
1151
1151
  zrb/task/flow_task.py,sha256=w5MaHCQ5KGyongjLo6YjLy9GYM0rTF6yEBGQ4GqbRp0,3933
1152
1152
  zrb/task/http_checker.py,sha256=ajsBDRgpp2OMeLlgyCL15UECYr2SoKAWfU3PGOJY24Q,5519
1153
1153
  zrb/task/path_checker.py,sha256=EhPJHDPYGAJG3XPUaiN_iN9Y-vtf96gEsWwqagy4IIM,3879
@@ -1156,8 +1156,9 @@ zrb/task/remote_cmd_task.py,sha256=LYWmnZ4mPsU-RIdAUyhui7mlIunx4vY8upwjhctnkEs,3
1156
1156
  zrb/task/resource_maker.py,sha256=QwB4S7aFjxX52onCqIu5OOMnm5omoZBl6OqZz9TqSOs,6379
1157
1157
  zrb/task/rsync_task.py,sha256=3vxENH-unD1VLgZI09Ts_lAQRMi2i1UiJpsaI1dltzI,3966
1158
1158
  zrb/task/task.py,sha256=aOwBVPl3U_dXCMcnrtcN0wPR8cDKbYkzgwa86BZMqBE,236
1159
- zrb/task_env/env.py,sha256=1m1GUK4RhdCRfKtEfuCazppQceVAIO05UhJ5Xp-0FOk,1800
1160
- zrb/task_env/env_file.py,sha256=Ku7WnPu-IkWi0fdjjXjTEvleYHfXO5v-g-0RUO2vVk4,1359
1159
+ zrb/task_env/constant.py,sha256=JdPhtZCTZlbW-jzG5vyFtpEXgTJ-Yx863LcrX_LiURY,44
1160
+ zrb/task_env/env.py,sha256=4oS4Y6_qwbzFqO08fzLb0TcSDAe9kxCW5cmbOFO1PSs,1954
1161
+ zrb/task_env/env_file.py,sha256=wQQmIQeK8-bRyl3KYe1xSFfebgHVFjXoXm8mQoVk7dY,1479
1161
1162
  zrb/task_group/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1162
1163
  zrb/task_group/group.py,sha256=qPZ79UZzLh5UPqsu2NflE6QAQzV568OPtXHcWloZX1o,1420
1163
1164
  zrb/task_input/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1165,14 +1166,14 @@ zrb/task_input/any_input.py,sha256=pLHMnH8VteIXS1ZBuBAVz8_WlAcikTUk1WyU_EEXxX4,5
1165
1166
  zrb/task_input/base_input.py,sha256=98z4bQDvgKlhf8CFMtakbWjvFwn_Y4XKb4YdSB-OTwE,3144
1166
1167
  zrb/task_input/bool_input.py,sha256=8-Kc4Rdc1dykMHxGUuAnRdnRcyEYfVM8ECtZqT071Fc,1594
1167
1168
  zrb/task_input/choice_input.py,sha256=V7BvsI-cI1CCX1DrQQY9bvwEHBYfNvS1WW5QWreMF_0,1672
1168
- zrb/task_input/constant.py,sha256=yvYY-Cc5eRAUQbe5aJcVVy846yyQYYg7v1hgiFyNikg,42
1169
+ zrb/task_input/constant.py,sha256=QgG5alvaRVQYQ5yFNEwj_1DvSmebW0xEDU1JXktSlO4,59
1169
1170
  zrb/task_input/float_input.py,sha256=flaZvFY55us8vtYuBxuAvvr4mTTAVZ-S8uTUt9AGfNg,1595
1170
1171
  zrb/task_input/int_input.py,sha256=mtNrgs65SL0GCzW5qr6c869UjiJ__zJaiXmJZCaqIJs,1592
1171
1172
  zrb/task_input/password_input.py,sha256=5bkUWyPumryigIy-S_z3nBDCo8sQB8_5PeS_gvPI0HQ,1611
1172
1173
  zrb/task_input/str_input.py,sha256=7cubJJKLCWRoGIRIM0_0WUhya18wvURoytrhVZA4xYI,1592
1173
1174
  zrb/task_input/task_input.py,sha256=HotqM1iYSzwE4PIj8grnEUsvJqjx1dS6Ek7i6ZJLq2Y,83
1174
- zrb-0.0.107.dist-info/entry_points.txt,sha256=xTgXc1kBKYhJHEujdaSPHUcJT3-hbyP1mLgwkv-5sSk,40
1175
- zrb-0.0.107.dist-info/LICENSE,sha256=WfnGCl8G60EYOPAEkuc8C9m9pdXWDe08NsKj3TBbxsM,728
1176
- zrb-0.0.107.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
1177
- zrb-0.0.107.dist-info/METADATA,sha256=wr1huEmawYsq5AOGuRk6HegbxWCCJZd2eXZL-Q5M7Xw,9348
1178
- zrb-0.0.107.dist-info/RECORD,,
1175
+ zrb-0.0.109.dist-info/entry_points.txt,sha256=xTgXc1kBKYhJHEujdaSPHUcJT3-hbyP1mLgwkv-5sSk,40
1176
+ zrb-0.0.109.dist-info/LICENSE,sha256=WfnGCl8G60EYOPAEkuc8C9m9pdXWDe08NsKj3TBbxsM,728
1177
+ zrb-0.0.109.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
1178
+ zrb-0.0.109.dist-info/METADATA,sha256=JVZQiW3JECOeGOHZpVyAJioJreEe8Q_O1WV6TbDlUgU,9740
1179
+ zrb-0.0.109.dist-info/RECORD,,
File without changes
File without changes