zrb 1.0.0a1__py3-none-any.whl → 1.0.0a3__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/__init__.py +48 -39
- zrb/__main__.py +3 -3
- zrb/attr/type.py +2 -1
- zrb/builtin/__init__.py +40 -2
- zrb/builtin/base64.py +32 -0
- zrb/builtin/git.py +156 -0
- zrb/builtin/git_subtree.py +88 -0
- zrb/builtin/group.py +34 -0
- zrb/builtin/llm.py +31 -0
- zrb/builtin/md5.py +34 -0
- zrb/builtin/project/__init__.py +0 -0
- zrb/builtin/project/add/__init__.py +0 -0
- zrb/builtin/project/add/fastapp.py +72 -0
- zrb/builtin/project/add/fastapp_template/.gitignore +4 -0
- zrb/builtin/project/add/fastapp_template/README.md +7 -0
- zrb/builtin/project/add/fastapp_template/__init__.py +0 -0
- zrb/builtin/project/add/fastapp_template/_zrb/config.py +17 -0
- zrb/builtin/project/add/fastapp_template/_zrb/group.py +16 -0
- zrb/builtin/project/add/fastapp_template/_zrb/helper.py +97 -0
- zrb/builtin/project/add/fastapp_template/_zrb/main.py +132 -0
- zrb/builtin/project/add/fastapp_template/_zrb/venv_task.py +22 -0
- zrb/builtin/project/add/fastapp_template/common/__init__.py +0 -0
- zrb/builtin/project/add/fastapp_template/common/app.py +18 -0
- zrb/builtin/project/add/fastapp_template/common/db_engine.py +5 -0
- zrb/builtin/project/add/fastapp_template/common/db_repository.py +134 -0
- zrb/builtin/project/add/fastapp_template/common/error.py +8 -0
- zrb/builtin/project/add/fastapp_template/common/schema.py +5 -0
- zrb/builtin/project/add/fastapp_template/common/usecase.py +232 -0
- zrb/builtin/project/add/fastapp_template/config.py +29 -0
- zrb/builtin/project/add/fastapp_template/main.py +7 -0
- zrb/builtin/project/add/fastapp_template/migrate.py +3 -0
- zrb/builtin/project/add/fastapp_template/module/__init__.py +0 -0
- zrb/builtin/project/add/fastapp_template/module/auth/alembic.ini +117 -0
- zrb/builtin/project/add/fastapp_template/module/auth/client/api_client.py +7 -0
- zrb/builtin/project/add/fastapp_template/module/auth/client/base_client.py +27 -0
- zrb/builtin/project/add/fastapp_template/module/auth/client/direct_client.py +6 -0
- zrb/builtin/project/add/fastapp_template/module/auth/client/factory.py +9 -0
- zrb/builtin/project/add/fastapp_template/module/auth/migration/README +1 -0
- zrb/builtin/project/add/fastapp_template/module/auth/migration/env.py +108 -0
- zrb/builtin/project/add/fastapp_template/module/auth/migration/script.py.mako +26 -0
- zrb/builtin/project/add/fastapp_template/module/auth/migration/versions/3093c7336477_add_user_table.py +37 -0
- zrb/builtin/project/add/fastapp_template/module/auth/migration_metadata.py +6 -0
- zrb/builtin/project/add/fastapp_template/module/auth/route.py +22 -0
- zrb/builtin/project/add/fastapp_template/module/auth/service/__init__.py +0 -0
- zrb/builtin/project/add/fastapp_template/module/auth/service/user/__init__.py +0 -0
- zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/__init__.py +0 -0
- zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/db_repository.py +39 -0
- zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/factory.py +13 -0
- zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/repository.py +34 -0
- zrb/builtin/project/add/fastapp_template/module/auth/service/user/usecase.py +45 -0
- zrb/builtin/project/add/fastapp_template/module/gateway/alembic.ini +117 -0
- zrb/builtin/project/add/fastapp_template/module/gateway/migration/README +1 -0
- zrb/builtin/project/add/fastapp_template/module/gateway/migration/env.py +108 -0
- zrb/builtin/project/add/fastapp_template/module/gateway/migration/script.py.mako +26 -0
- zrb/builtin/project/add/fastapp_template/module/gateway/migration/versions/.gitkeep +0 -0
- zrb/builtin/project/add/fastapp_template/module/gateway/migration_metadata.py +3 -0
- zrb/builtin/project/add/fastapp_template/module/gateway/route.py +27 -0
- zrb/builtin/project/add/fastapp_template/requirements.txt +6 -0
- zrb/builtin/project/add/fastapp_template/schema/__init__.py +0 -0
- zrb/builtin/project/add/fastapp_template/schema/role.py +31 -0
- zrb/builtin/project/add/fastapp_template/schema/user.py +31 -0
- zrb/builtin/project/add/fastapp_template/template.env +2 -0
- zrb/builtin/project/create/__init__.py +0 -0
- zrb/builtin/project/create/create.py +41 -0
- zrb/builtin/project/create/project-template/README.md +3 -0
- zrb/builtin/project/create/project-template/zrb_init.py +7 -0
- zrb/builtin/python.py +11 -0
- zrb/builtin/shell/__init__.py +0 -5
- zrb/builtin/shell/autocomplete/__init__.py +0 -9
- zrb/builtin/shell/autocomplete/bash.py +5 -6
- zrb/builtin/shell/autocomplete/subcmd.py +7 -8
- zrb/builtin/shell/autocomplete/zsh.py +5 -6
- zrb/builtin/todo.py +186 -0
- zrb/callback/any_callback.py +1 -1
- zrb/callback/callback.py +5 -5
- zrb/cmd/cmd_val.py +2 -2
- zrb/config.py +4 -1
- zrb/content_transformer/any_content_transformer.py +1 -1
- zrb/content_transformer/content_transformer.py +2 -2
- zrb/context/any_context.py +5 -1
- zrb/context/any_shared_context.py +3 -3
- zrb/context/context.py +15 -9
- zrb/context/shared_context.py +9 -8
- zrb/env/__init__.py +0 -3
- zrb/env/any_env.py +2 -2
- zrb/env/env.py +4 -5
- zrb/env/env_file.py +4 -4
- zrb/env/env_map.py +4 -4
- zrb/group/__init__.py +0 -3
- zrb/group/any_group.py +3 -3
- zrb/group/group.py +7 -6
- zrb/input/any_input.py +1 -1
- zrb/input/base_input.py +4 -4
- zrb/input/bool_input.py +5 -5
- zrb/input/float_input.py +3 -3
- zrb/input/int_input.py +3 -3
- zrb/input/option_input.py +51 -0
- zrb/input/password_input.py +2 -2
- zrb/input/str_input.py +1 -1
- zrb/input/text_input.py +12 -10
- zrb/runner/cli.py +79 -44
- zrb/runner/web_app/group_info_ui/controller.py +7 -8
- zrb/runner/web_app/group_info_ui/view.html +2 -2
- zrb/runner/web_app/home_page/controller.py +7 -6
- zrb/runner/web_app/home_page/view.html +2 -2
- zrb/runner/web_app/task_ui/controller.py +13 -13
- zrb/runner/web_app/task_ui/partial/common-util.js +37 -0
- zrb/runner/web_app/task_ui/partial/main.js +9 -2
- zrb/runner/web_app/task_ui/partial/show-existing-session.js +20 -5
- zrb/runner/web_app/task_ui/partial/visualize-history.js +1 -41
- zrb/runner/web_app/task_ui/view.html +4 -2
- zrb/runner/web_server.py +137 -211
- zrb/runner/web_util.py +5 -35
- zrb/session/any_session.py +13 -7
- zrb/session/session.py +80 -41
- zrb/session_state_log/session_state_log.py +7 -5
- zrb/session_state_logger/any_session_state_logger.py +1 -1
- zrb/session_state_logger/default_session_state_logger.py +2 -2
- zrb/session_state_logger/file_session_state_logger.py +19 -27
- zrb/task/any_task.py +8 -3
- zrb/task/base_task.py +47 -33
- zrb/task/base_trigger.py +11 -12
- zrb/task/cmd_task.py +55 -43
- zrb/task/http_check.py +8 -8
- zrb/task/llm_task.py +160 -0
- zrb/task/make_task.py +9 -9
- zrb/task/rsync_task.py +7 -7
- zrb/task/scaffolder.py +14 -11
- zrb/task/scheduler.py +6 -7
- zrb/task/task.py +1 -1
- zrb/task/tcp_check.py +8 -8
- zrb/util/attr.py +19 -3
- zrb/util/cli/style.py +71 -2
- zrb/util/cli/subcommand.py +2 -2
- zrb/util/codemod/__init__.py +0 -0
- zrb/util/codemod/add_code_to_class.py +35 -0
- zrb/util/codemod/add_code_to_function.py +36 -0
- zrb/util/codemod/add_code_to_method.py +55 -0
- zrb/util/codemod/add_key_to_dict.py +51 -0
- zrb/util/codemod/add_param_to_function_call.py +39 -0
- zrb/util/codemod/add_property_to_class.py +55 -0
- zrb/util/git.py +156 -0
- zrb/util/git_subtree.py +94 -0
- zrb/util/group.py +2 -2
- zrb/util/llm/tool.py +63 -0
- zrb/util/string/conversion.py +7 -0
- zrb/util/todo.py +135 -0
- {zrb-1.0.0a1.dist-info → zrb-1.0.0a3.dist-info}/METADATA +11 -7
- zrb-1.0.0a3.dist-info/RECORD +194 -0
- zrb/builtin/shell/_group.py +0 -9
- zrb/builtin/shell/autocomplete/_group.py +0 -6
- zrb/runner/web_app/any_request_handler.py +0 -24
- zrb/runner/web_server.bak.py +0 -208
- zrb-1.0.0a1.dist-info/RECORD +0 -120
- {zrb-1.0.0a1.dist-info → zrb-1.0.0a3.dist-info}/WHEEL +0 -0
- {zrb-1.0.0a1.dist-info → zrb-1.0.0a3.dist-info}/entry_points.txt +0 -0
zrb/builtin/todo.py
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
import datetime
|
2
|
+
import os
|
3
|
+
|
4
|
+
from zrb.builtin.group import todo_group
|
5
|
+
from zrb.config import TODO_DIR
|
6
|
+
from zrb.context.any_context import AnyContext
|
7
|
+
from zrb.input.str_input import StrInput
|
8
|
+
from zrb.input.text_input import TextInput
|
9
|
+
from zrb.task.make_task import make_task
|
10
|
+
from zrb.util.cli.style import (
|
11
|
+
stylize_bold_green,
|
12
|
+
stylize_cyan,
|
13
|
+
stylize_magenta,
|
14
|
+
stylize_yellow,
|
15
|
+
)
|
16
|
+
from zrb.util.string.name import get_random_name
|
17
|
+
from zrb.util.todo import (
|
18
|
+
TodoTask,
|
19
|
+
parse_todo_line,
|
20
|
+
read_todo_from_file,
|
21
|
+
todo_task_to_line,
|
22
|
+
write_todo_to_file,
|
23
|
+
)
|
24
|
+
|
25
|
+
|
26
|
+
@make_task(
|
27
|
+
name="todo-add",
|
28
|
+
input=[
|
29
|
+
StrInput(
|
30
|
+
name="description",
|
31
|
+
description="Task description",
|
32
|
+
prompt="Task description",
|
33
|
+
),
|
34
|
+
StrInput(
|
35
|
+
name="priority",
|
36
|
+
description="Task priority",
|
37
|
+
prompt="Task priority",
|
38
|
+
default_str="E",
|
39
|
+
),
|
40
|
+
StrInput(
|
41
|
+
name="project",
|
42
|
+
description="Task project",
|
43
|
+
prompt="Task project (space separated)",
|
44
|
+
),
|
45
|
+
StrInput(
|
46
|
+
name="context",
|
47
|
+
description="Task context",
|
48
|
+
prompt="Task context (space separated)",
|
49
|
+
),
|
50
|
+
],
|
51
|
+
description="➕ Add todo",
|
52
|
+
group=todo_group,
|
53
|
+
alias="add",
|
54
|
+
)
|
55
|
+
def todo_add(ctx: AnyContext):
|
56
|
+
todo_file_path = os.path.join(TODO_DIR, "todo.txt")
|
57
|
+
todo_tasks: list[TodoTask] = []
|
58
|
+
if os.path.isfile(todo_file_path):
|
59
|
+
todo_tasks = read_todo_from_file(todo_file_path)
|
60
|
+
else:
|
61
|
+
os.makedirs(TODO_DIR, exist_ok=True)
|
62
|
+
todo_tasks.append(
|
63
|
+
_complete_todo_task(
|
64
|
+
TodoTask(
|
65
|
+
priority=ctx.input.priority.upper(),
|
66
|
+
description=ctx.input.description,
|
67
|
+
contexts=[
|
68
|
+
context.strip()
|
69
|
+
for context in ctx.input.context.split(" ")
|
70
|
+
if context.strip() != ""
|
71
|
+
],
|
72
|
+
projects=[
|
73
|
+
project.strip()
|
74
|
+
for project in ctx.input.project.split(" ")
|
75
|
+
if project.strip() != ""
|
76
|
+
],
|
77
|
+
)
|
78
|
+
)
|
79
|
+
)
|
80
|
+
write_todo_to_file(todo_file_path, todo_tasks)
|
81
|
+
return _get_visual_todo_list()
|
82
|
+
|
83
|
+
|
84
|
+
@make_task(name="todo-list", description="📋 List todo", group=todo_group, alias="list")
|
85
|
+
def todo_list(ctx: AnyContext):
|
86
|
+
return _get_visual_todo_list()
|
87
|
+
|
88
|
+
|
89
|
+
@make_task(
|
90
|
+
name="todo-edit",
|
91
|
+
input=[
|
92
|
+
TextInput(
|
93
|
+
name="text",
|
94
|
+
description="Todo.txt content",
|
95
|
+
prompt="Todo.txt content (will override existing)",
|
96
|
+
default_str=lambda _: _get_todo_txt_content(),
|
97
|
+
),
|
98
|
+
],
|
99
|
+
description="✏️ Edit todo",
|
100
|
+
group=todo_group,
|
101
|
+
alias="edit",
|
102
|
+
)
|
103
|
+
def todo_edit(ctx: AnyContext):
|
104
|
+
todo_tasks = [
|
105
|
+
_complete_todo_task(parse_todo_line(line))
|
106
|
+
for line in ctx.input.text.split("\n")
|
107
|
+
if line.strip() != ""
|
108
|
+
]
|
109
|
+
new_content = "\n".join(todo_task_to_line(todo_task) for todo_task in todo_tasks)
|
110
|
+
todo_file_path = os.path.join(TODO_DIR, "todo.txt")
|
111
|
+
with open(todo_file_path, "w") as f:
|
112
|
+
f.write(new_content)
|
113
|
+
return _get_visual_todo_list()
|
114
|
+
|
115
|
+
|
116
|
+
def _complete_todo_task(todo_task: TodoTask):
|
117
|
+
if todo_task.creation_date is None:
|
118
|
+
todo_task.creation_date = datetime.date.today()
|
119
|
+
if "id" not in todo_task.keyval:
|
120
|
+
todo_task.keyval["id"] = get_random_name()
|
121
|
+
return todo_task
|
122
|
+
|
123
|
+
|
124
|
+
def _get_visual_todo_list() -> str:
|
125
|
+
todo_file_path = os.path.join(TODO_DIR, "todo.txt")
|
126
|
+
if not os.path.isfile(todo_file_path):
|
127
|
+
return "\n".join(["", " Todo.txt not found... 🌵🦖", ""])
|
128
|
+
todo_tasks = read_todo_from_file(todo_file_path)
|
129
|
+
if len(todo_tasks) == 0:
|
130
|
+
return "\n".join(["", " Empty todo list... 🌵🦖", ""])
|
131
|
+
max_desc_name_length = max(len(todo_task.description) for todo_task in todo_tasks)
|
132
|
+
if max_desc_name_length < len("DESCRIPTION"):
|
133
|
+
max_desc_name_length = len("DESCRIPTION")
|
134
|
+
# Headers
|
135
|
+
results = [
|
136
|
+
stylize_bold_green(
|
137
|
+
" ".join(
|
138
|
+
[
|
139
|
+
"".ljust(3), # priority
|
140
|
+
"".ljust(3), # completed
|
141
|
+
"COMPLETED AT".rjust(14), # completed date
|
142
|
+
"CREATED AT".rjust(14), # completed date
|
143
|
+
"DESCRIPTION".ljust(max_desc_name_length),
|
144
|
+
"PROJECT/CONTEXT/OTHERS",
|
145
|
+
]
|
146
|
+
)
|
147
|
+
)
|
148
|
+
]
|
149
|
+
for todo_task in todo_tasks:
|
150
|
+
completed = "[x]" if todo_task.completed else "[ ]"
|
151
|
+
priority = " " if todo_task.priority is None else f"({todo_task.priority})"
|
152
|
+
completion_date = stylize_yellow(_date_to_str(todo_task.completion_date))
|
153
|
+
creation_date = stylize_cyan(_date_to_str(todo_task.creation_date))
|
154
|
+
description = todo_task.description.ljust(max_desc_name_length)
|
155
|
+
additions = ", ".join(
|
156
|
+
[stylize_yellow(f"+{project}") for project in todo_task.projects]
|
157
|
+
+ [stylize_cyan(f"@{context}") for context in todo_task.contexts]
|
158
|
+
+ [stylize_magenta(f"{key}:{val}") for key, val in todo_task.keyval.items()]
|
159
|
+
)
|
160
|
+
results.append(
|
161
|
+
" ".join(
|
162
|
+
[
|
163
|
+
completed,
|
164
|
+
priority,
|
165
|
+
completion_date,
|
166
|
+
creation_date,
|
167
|
+
description,
|
168
|
+
additions,
|
169
|
+
]
|
170
|
+
)
|
171
|
+
)
|
172
|
+
return "\n".join(results)
|
173
|
+
|
174
|
+
|
175
|
+
def _date_to_str(date: datetime.date | None) -> str:
|
176
|
+
if date is None:
|
177
|
+
return "".ljust(14)
|
178
|
+
return date.strftime("%a %Y-%m-%d")
|
179
|
+
|
180
|
+
|
181
|
+
def _get_todo_txt_content() -> str:
|
182
|
+
todo_file_path = os.path.join(TODO_DIR, "todo.txt")
|
183
|
+
if not os.path.isfile(todo_file_path):
|
184
|
+
return ""
|
185
|
+
with open(todo_file_path, "r") as f:
|
186
|
+
return f.read()
|
zrb/callback/any_callback.py
CHANGED
zrb/callback/callback.py
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
from typing import Any
|
2
2
|
|
3
|
-
from
|
4
|
-
from
|
5
|
-
from
|
6
|
-
from
|
7
|
-
from .
|
3
|
+
from zrb.attr.type import StrDictAttr
|
4
|
+
from zrb.callback.any_callback import AnyCallback
|
5
|
+
from zrb.session.any_session import AnySession
|
6
|
+
from zrb.task.any_task import AnyTask
|
7
|
+
from zrb.util.attr import get_str_dict_attr
|
8
8
|
|
9
9
|
|
10
10
|
class Callback(AnyCallback):
|
zrb/cmd/cmd_val.py
CHANGED
zrb/config.py
CHANGED
@@ -3,7 +3,7 @@ import logging
|
|
3
3
|
import os
|
4
4
|
import platform
|
5
5
|
|
6
|
-
from .util.string.conversion import to_boolean
|
6
|
+
from zrb.util.string.conversion import to_boolean
|
7
7
|
|
8
8
|
|
9
9
|
def _get_current_shell() -> str:
|
@@ -53,8 +53,11 @@ SHOW_PROMPT = to_boolean(os.getenv("ZRB_SHOW_PROMPT", "1"))
|
|
53
53
|
SESSION_LOG_DIR = os.getenv(
|
54
54
|
"ZRB_SESSION_LOG_DIR", os.path.expanduser(os.path.join("~", ".zrb-session"))
|
55
55
|
)
|
56
|
+
TODO_DIR = os.getenv("ZRB_TODO_DIR", os.path.expanduser(os.path.join("~", "todo")))
|
56
57
|
VERSION = metadata.version("zrb")
|
57
58
|
WEB_HTTP_PORT = int(os.getenv("ZRB_WEB_HTTP_PORT", "21213"))
|
59
|
+
LLM_MODEL = os.getenv("ZRB_LLM_MODEL", "ollama_chat/llama3.1")
|
60
|
+
LLM_SYSTEM_PROMPT = os.getenv("ZRB_LLM_SYSTEM_PROMPT", "You are a helpful assistant")
|
58
61
|
|
59
62
|
BANNER = f"""
|
60
63
|
bb
|
@@ -2,8 +2,8 @@ import fnmatch
|
|
2
2
|
import re
|
3
3
|
from collections.abc import Callable
|
4
4
|
|
5
|
-
from
|
6
|
-
from .
|
5
|
+
from zrb.content_transformer.any_content_transformer import AnyContentTransformer
|
6
|
+
from zrb.context.any_context import AnyContext
|
7
7
|
|
8
8
|
|
9
9
|
class ContentTransformer(AnyContentTransformer):
|
zrb/context/any_context.py
CHANGED
@@ -2,7 +2,7 @@ import sys
|
|
2
2
|
from abc import abstractmethod
|
3
3
|
from typing import TextIO
|
4
4
|
|
5
|
-
from .any_shared_context import AnySharedContext
|
5
|
+
from zrb.context.any_shared_context import AnySharedContext
|
6
6
|
|
7
7
|
|
8
8
|
class AnyContext(AnySharedContext):
|
@@ -31,6 +31,10 @@ class AnyContext(AnySharedContext):
|
|
31
31
|
"""
|
32
32
|
pass
|
33
33
|
|
34
|
+
@abstractmethod
|
35
|
+
def update_task_env(self, task_env: dict[str, str]):
|
36
|
+
pass
|
37
|
+
|
34
38
|
@abstractmethod
|
35
39
|
def print(
|
36
40
|
self,
|
@@ -3,11 +3,11 @@ from __future__ import annotations # Enables forward references
|
|
3
3
|
from abc import ABC, abstractmethod
|
4
4
|
from typing import TYPE_CHECKING, Any
|
5
5
|
|
6
|
-
from
|
7
|
-
from
|
6
|
+
from zrb.dot_dict.dot_dict import DotDict
|
7
|
+
from zrb.xcom.xcom import Xcom
|
8
8
|
|
9
9
|
if TYPE_CHECKING:
|
10
|
-
from
|
10
|
+
from zrb.session import any_session
|
11
11
|
|
12
12
|
|
13
13
|
class AnySharedContext(ABC):
|
zrb/context/context.py
CHANGED
@@ -4,12 +4,12 @@ import re
|
|
4
4
|
import sys
|
5
5
|
from typing import Any, TextIO
|
6
6
|
|
7
|
-
from
|
8
|
-
from
|
9
|
-
from
|
10
|
-
from
|
11
|
-
from .
|
12
|
-
from .
|
7
|
+
from zrb.context.any_context import AnyContext
|
8
|
+
from zrb.context.any_shared_context import AnySharedContext
|
9
|
+
from zrb.dot_dict.dot_dict import DotDict
|
10
|
+
from zrb.session.any_session import AnySession
|
11
|
+
from zrb.util.cli.style import stylize, stylize_error, stylize_log, stylize_warning
|
12
|
+
from zrb.util.string.conversion import to_boolean
|
13
13
|
|
14
14
|
|
15
15
|
def _remove_ansi_escape_sequences(text):
|
@@ -22,6 +22,7 @@ class Context(AnyContext):
|
|
22
22
|
self, shared_ctx: AnySharedContext, task_name: str, color: int, icon: str
|
23
23
|
):
|
24
24
|
self._shared_ctx = shared_ctx
|
25
|
+
self._env = shared_ctx.env.copy()
|
25
26
|
self._task_name = task_name
|
26
27
|
self._color = color
|
27
28
|
self._icon = icon
|
@@ -38,7 +39,7 @@ class Context(AnyContext):
|
|
38
39
|
|
39
40
|
@property
|
40
41
|
def env(self) -> DotDict:
|
41
|
-
return self.
|
42
|
+
return self._env
|
42
43
|
|
43
44
|
@property
|
44
45
|
def args(self) -> list[Any]:
|
@@ -56,6 +57,9 @@ class Context(AnyContext):
|
|
56
57
|
def session(self) -> AnySession | None:
|
57
58
|
return self._shared_ctx._session
|
58
59
|
|
60
|
+
def update_task_env(self, task_env: dict[str, str]):
|
61
|
+
self._env.update(task_env)
|
62
|
+
|
59
63
|
def append_to_shared_log(self, message: str):
|
60
64
|
self._shared_ctx.append_to_shared_log(message)
|
61
65
|
|
@@ -99,14 +103,16 @@ class Context(AnyContext):
|
|
99
103
|
):
|
100
104
|
color = self._color
|
101
105
|
icon = self._icon
|
102
|
-
|
106
|
+
max_name_length = max(len(name) + len(icon) for name in self.session.task_names)
|
107
|
+
styled_task_name = f"{icon} {self._task_name}"
|
108
|
+
padded_styled_task_name = styled_task_name.rjust(max_name_length + 1)
|
103
109
|
if self._attempt == 0:
|
104
110
|
attempt_status = "".ljust(5)
|
105
111
|
else:
|
106
112
|
attempt_status = f"{self._attempt}/{self._max_attempt}".ljust(5)
|
107
113
|
now = datetime.datetime.now()
|
108
114
|
formatted_time = now.strftime("%y%m%d %H:%M:%S.%f")[:19]
|
109
|
-
prefix = f"{formatted_time} {attempt_status} {
|
115
|
+
prefix = f"{formatted_time} {attempt_status} {padded_styled_task_name} ⬤ "
|
110
116
|
message = sep.join([f"{value}" for value in values])
|
111
117
|
self.append_to_shared_log(_remove_ansi_escape_sequences(f"{prefix} {message}"))
|
112
118
|
stylized_prefix = stylize(prefix, color=color)
|
zrb/context/shared_context.py
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
import datetime
|
2
2
|
from typing import Any
|
3
3
|
|
4
|
-
from
|
5
|
-
from
|
6
|
-
from
|
7
|
-
from
|
4
|
+
from zrb.config import LOGGING_LEVEL
|
5
|
+
from zrb.context.any_shared_context import AnySharedContext
|
6
|
+
from zrb.dot_dict.dot_dict import DotDict
|
7
|
+
from zrb.session.any_session import AnySession
|
8
|
+
from zrb.util.string.conversion import (
|
9
|
+
double_quote,
|
8
10
|
to_boolean,
|
9
11
|
to_camel_case,
|
10
12
|
to_human_case,
|
@@ -12,9 +14,8 @@ from ..util.string.conversion import (
|
|
12
14
|
to_pascal_case,
|
13
15
|
to_snake_case,
|
14
16
|
)
|
15
|
-
from
|
16
|
-
from
|
17
|
-
from .any_shared_context import AnySharedContext
|
17
|
+
from zrb.util.string.format import fstring_format
|
18
|
+
from zrb.xcom.xcom import Xcom
|
18
19
|
|
19
20
|
|
20
21
|
class SharedContext(AnySharedContext):
|
@@ -86,12 +87,12 @@ class SharedContext(AnySharedContext):
|
|
86
87
|
data={
|
87
88
|
"ctx": self,
|
88
89
|
"datetime": datetime,
|
89
|
-
"Xcom": Xcom,
|
90
90
|
"to_boolean": to_boolean,
|
91
91
|
"to_camel_case": to_camel_case,
|
92
92
|
"to_human_case": to_human_case,
|
93
93
|
"to_kebab_case": to_kebab_case,
|
94
94
|
"to_pascal_case": to_pascal_case,
|
95
95
|
"to_snake_case": to_snake_case,
|
96
|
+
"double_quote": double_quote,
|
96
97
|
},
|
97
98
|
)
|
zrb/env/__init__.py
CHANGED
zrb/env/any_env.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
2
|
|
3
|
-
from
|
3
|
+
from zrb.context.any_shared_context import AnySharedContext
|
4
4
|
|
5
5
|
|
6
6
|
class AnyEnv(ABC):
|
7
7
|
@abstractmethod
|
8
|
-
def
|
8
|
+
def update_context(self, shared_ctx: AnySharedContext):
|
9
9
|
pass
|
zrb/env/env.py
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
import os
|
2
2
|
|
3
|
+
from zrb.attr.type import StrAttr
|
3
4
|
from zrb.context.any_shared_context import AnySharedContext
|
4
|
-
|
5
|
-
from
|
6
|
-
from ..util.attr import get_str_attr
|
7
|
-
from .any_env import AnyEnv
|
5
|
+
from zrb.env.any_env import AnyEnv
|
6
|
+
from zrb.util.attr import get_str_attr
|
8
7
|
|
9
8
|
|
10
9
|
class Env(AnyEnv):
|
@@ -22,7 +21,7 @@ class Env(AnyEnv):
|
|
22
21
|
self._link_to_os = link_to_os
|
23
22
|
self._os_name = os_name
|
24
23
|
|
25
|
-
def
|
24
|
+
def update_context(self, shared_ctx: AnySharedContext):
|
26
25
|
if self._link_to_os:
|
27
26
|
os_name = self._name if self._os_name is None else self._os_name
|
28
27
|
value = os.getenv(os_name, self._get_default_value(shared_ctx))
|
zrb/env/env_file.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
from dotenv import dotenv_values
|
2
2
|
|
3
|
-
from
|
4
|
-
from
|
5
|
-
from
|
6
|
-
from .
|
3
|
+
from zrb.attr.type import StrAttr
|
4
|
+
from zrb.context.shared_context import SharedContext
|
5
|
+
from zrb.env.env_map import EnvMap
|
6
|
+
from zrb.util.attr import get_str_attr
|
7
7
|
|
8
8
|
|
9
9
|
class EnvFile(EnvMap):
|
zrb/env/env_map.py
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
import os
|
2
2
|
from collections.abc import Callable
|
3
3
|
|
4
|
-
from
|
5
|
-
from .any_env import AnyEnv
|
4
|
+
from zrb.context.shared_context import SharedContext
|
5
|
+
from zrb.env.any_env import AnyEnv
|
6
6
|
|
7
7
|
|
8
8
|
class EnvMap(AnyEnv):
|
@@ -18,7 +18,7 @@ class EnvMap(AnyEnv):
|
|
18
18
|
self._os_prefix = os_prefix
|
19
19
|
self._auto_render = auto_render
|
20
20
|
|
21
|
-
def
|
21
|
+
def update_context(self, shared_ctx: SharedContext) -> dict[str, str]:
|
22
22
|
env_map = self._get_env_map(shared_ctx)
|
23
23
|
for name, default_value in env_map.items():
|
24
24
|
if self._link_to_os:
|
@@ -27,7 +27,7 @@ class EnvMap(AnyEnv):
|
|
27
27
|
value = os.getenv(os_name, default_value)
|
28
28
|
else:
|
29
29
|
value = default_value
|
30
|
-
shared_ctx.env[
|
30
|
+
shared_ctx.env[name] = value
|
31
31
|
|
32
32
|
def _get_env_map(self, shared_ctx: SharedContext) -> dict[str, str]:
|
33
33
|
if callable(self._env_map):
|
zrb/group/__init__.py
CHANGED
zrb/group/any_group.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
from typing import Optional
|
2
|
+
from typing import Optional, Union
|
3
3
|
|
4
|
-
from
|
4
|
+
from zrb.task.any_task import AnyTask
|
5
5
|
|
6
6
|
|
7
7
|
class AnyGroup(ABC):
|
@@ -36,7 +36,7 @@ class AnyGroup(ABC):
|
|
36
36
|
pass
|
37
37
|
|
38
38
|
@abstractmethod
|
39
|
-
def add_group(self, group: "AnyGroup") -> "AnyGroup":
|
39
|
+
def add_group(self, group: Union["AnyGroup", str]) -> "AnyGroup":
|
40
40
|
pass
|
41
41
|
|
42
42
|
@abstractmethod
|
zrb/group/group.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
from
|
2
|
-
from .
|
1
|
+
from zrb.group.any_group import AnyGroup
|
2
|
+
from zrb.task.any_task import AnyTask
|
3
3
|
|
4
4
|
|
5
5
|
class Group(AnyGroup):
|
@@ -42,10 +42,11 @@ class Group(AnyGroup):
|
|
42
42
|
alias.sort()
|
43
43
|
return {name: self._tasks.get(name) for name in alias}
|
44
44
|
|
45
|
-
def add_group(self, group: AnyGroup, alias: str | None = None) -> AnyGroup:
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
def add_group(self, group: AnyGroup | str, alias: str | None = None) -> AnyGroup:
|
46
|
+
real_group = Group(group) if isinstance(group, str) else group
|
47
|
+
alias = alias if alias is not None else real_group.name
|
48
|
+
self._groups[alias] = real_group
|
49
|
+
return real_group
|
49
50
|
|
50
51
|
def add_task(self, task: AnyTask, alias: str | None = None) -> AnyTask:
|
51
52
|
alias = alias if alias is not None else task.name
|
zrb/input/any_input.py
CHANGED
zrb/input/base_input.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
from typing import Any
|
2
2
|
|
3
|
-
from
|
4
|
-
from
|
5
|
-
from
|
6
|
-
from .
|
3
|
+
from zrb.attr.type import StrAttr
|
4
|
+
from zrb.context.any_shared_context import AnySharedContext
|
5
|
+
from zrb.input.any_input import AnyInput
|
6
|
+
from zrb.util.attr import get_str_attr
|
7
7
|
|
8
8
|
|
9
9
|
class BaseInput(AnyInput):
|
zrb/input/bool_input.py
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
from
|
2
|
-
from
|
3
|
-
from
|
4
|
-
from .
|
1
|
+
from zrb.attr.type import StrAttr
|
2
|
+
from zrb.context.any_shared_context import AnySharedContext
|
3
|
+
from zrb.input.base_input import BaseInput
|
4
|
+
from zrb.util.string.conversion import to_boolean
|
5
5
|
|
6
6
|
|
7
|
-
class
|
7
|
+
class BoolInput(BaseInput):
|
8
8
|
def __init__(
|
9
9
|
self,
|
10
10
|
name: str,
|
zrb/input/float_input.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
from
|
2
|
-
from
|
3
|
-
from .base_input import BaseInput
|
1
|
+
from zrb.attr.type import StrAttr
|
2
|
+
from zrb.context.any_shared_context import AnySharedContext
|
3
|
+
from zrb.input.base_input import BaseInput
|
4
4
|
|
5
5
|
|
6
6
|
class FloatInput(BaseInput):
|
zrb/input/int_input.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
from
|
2
|
-
from
|
3
|
-
from .base_input import BaseInput
|
1
|
+
from zrb.attr.type import StrAttr
|
2
|
+
from zrb.context.any_shared_context import AnySharedContext
|
3
|
+
from zrb.input.base_input import BaseInput
|
4
4
|
|
5
5
|
|
6
6
|
class IntInput(BaseInput):
|
@@ -0,0 +1,51 @@
|
|
1
|
+
from zrb.attr.type import StrAttr, StrListAttr
|
2
|
+
from zrb.context.any_shared_context import AnySharedContext
|
3
|
+
from zrb.input.base_input import BaseInput
|
4
|
+
from zrb.util.attr import get_str_list_attr
|
5
|
+
|
6
|
+
|
7
|
+
class OptionInput(BaseInput):
|
8
|
+
def __init__(
|
9
|
+
self,
|
10
|
+
name: str,
|
11
|
+
description: str | None = None,
|
12
|
+
prompt: str | None = None,
|
13
|
+
options: StrListAttr = [],
|
14
|
+
default_str: StrAttr = "",
|
15
|
+
auto_render: bool = True,
|
16
|
+
allow_empty: bool = True,
|
17
|
+
):
|
18
|
+
super().__init__(
|
19
|
+
name=name,
|
20
|
+
description=description,
|
21
|
+
prompt=prompt,
|
22
|
+
default_str=default_str,
|
23
|
+
auto_render=auto_render,
|
24
|
+
allow_empty=allow_empty,
|
25
|
+
)
|
26
|
+
self._options = options
|
27
|
+
|
28
|
+
def to_html(self, ctx: AnySharedContext) -> str:
|
29
|
+
name = self.name
|
30
|
+
description = self.description
|
31
|
+
default = self._get_default_str(ctx)
|
32
|
+
html = [f'<select name="{name}" placeholder="{description}">']
|
33
|
+
for value in get_str_list_attr(ctx, self._options, self._auto_render):
|
34
|
+
selected = "selected" if value == default else ""
|
35
|
+
html.append(f'<option value="{value}" {selected}>{value}</option>')
|
36
|
+
html.append("</select>")
|
37
|
+
return "\n".join(html)
|
38
|
+
|
39
|
+
def _prompt_cli_str(self, shared_ctx: AnySharedContext) -> str:
|
40
|
+
prompt_message = self.prompt_message
|
41
|
+
default_value = self._get_default_str(shared_ctx)
|
42
|
+
options = get_str_list_attr(shared_ctx, self._options, self._auto_render)
|
43
|
+
option_str = ", ".join(options)
|
44
|
+
if default_value != "":
|
45
|
+
prompt_message = f"{prompt_message} ({option_str}) [{default_value}]"
|
46
|
+
value = input(f"{prompt_message}: ")
|
47
|
+
if value.strip() != "" and value.strip() not in options:
|
48
|
+
value = self._prompt_cli_str(shared_ctx)
|
49
|
+
if value.strip() == "":
|
50
|
+
value = default_value
|
51
|
+
return value
|