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 +2 -2
- zrb/task/any_task.py +12 -0
- zrb/task/base_task.py +25 -4
- zrb/task/base_task_composite.py +9 -2
- zrb/task/cmd_task.py +4 -4
- zrb/task/docker_compose_task.py +51 -38
- zrb/task_env/constant.py +1 -0
- zrb/task_env/env.py +3 -0
- zrb/task_env/env_file.py +3 -0
- zrb/task_input/constant.py +1 -1
- {zrb-0.0.107.dist-info → zrb-0.0.109.dist-info}/METADATA +22 -20
- {zrb-0.0.107.dist-info → zrb-0.0.109.dist-info}/RECORD +15 -14
- {zrb-0.0.107.dist-info → zrb-0.0.109.dist-info}/LICENSE +0 -0
- {zrb-0.0.107.dist-info → zrb-0.0.109.dist-info}/WHEEL +0 -0
- {zrb-0.0.107.dist-info → zrb-0.0.109.dist-info}/entry_points.txt +0 -0
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
|
-
|
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.
|
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
|
-
|
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}{
|
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
|
))
|
zrb/task/base_task_composite.py
CHANGED
@@ -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.
|
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
|
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.
|
171
|
+
self._cwd: Union[str, pathlib.Path] = os.getcwd()
|
172
172
|
return
|
173
|
-
self.
|
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.
|
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.
|
203
|
+
cwd=self._cwd,
|
204
204
|
stdout=asyncio.subprocess.PIPE,
|
205
205
|
stderr=asyncio.subprocess.PIPE,
|
206
206
|
env=env_map,
|
zrb/task/docker_compose_task.py
CHANGED
@@ -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
|
-
#
|
154
|
-
|
155
|
-
|
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.
|
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
|
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.
|
292
|
-
return os.path.join(self.
|
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.
|
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.
|
298
|
-
return os.path.join(self.
|
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:
|
zrb/task_env/constant.py
ADDED
@@ -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}'
|
zrb/task_input/constant.py
CHANGED
@@ -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.
|
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
|
-

|
34
34
|
|
35
|
-
[📖 Documentation](https://github.com/state-alchemists/zrb/blob/main/docs/README.md) | [🏁 Getting
|
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
|
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
|
-
|
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
|
-

|
71
73
|
|
72
|
-
Furthermore, you can
|
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
|
93
|
+
## Zrb is A Task-Automation Tool
|
92
94
|
|
93
|
-
Aside from the
|
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
|
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
|
-
|
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
|
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
|
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
|
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
|
231
|
+
# 🏁 Getting Started
|
230
232
|
|
231
|
-
We have
|
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://stalchmst.com/donation)
|
242
244
|
|
243
|
-
# 🎉 Fun
|
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
|
-

|
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=
|
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=
|
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=
|
1147
|
-
zrb/task/base_task_composite.py,sha256=
|
1148
|
-
zrb/task/cmd_task.py,sha256=
|
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=
|
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/
|
1160
|
-
zrb/task_env/
|
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=
|
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.
|
1175
|
-
zrb-0.0.
|
1176
|
-
zrb-0.0.
|
1177
|
-
zrb-0.0.
|
1178
|
-
zrb-0.0.
|
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
|
File without changes
|